| 2000 |
2001 |
| 2001 return data; |
2002 return data; |
| 2002 } |
2003 } |
| 2003 |
2004 |
| 2004 static void |
2005 static void |
| 2005 pidgin_request_file_folder_response_cb(G_GNUC_UNUSED GtkWidget *widget, |
2006 pidgin_request_file_response_cb(GObject *obj, GAsyncResult *result, |
| 2006 gint response, PidginRequestData *data) |
2007 gpointer user_data) |
| 2007 { |
2008 { |
| 2008 GFile *current_path; |
2009 PidginRequestData *data = user_data; |
| 2009 |
2010 GFile *path = NULL; |
| 2010 if (response != GTK_RESPONSE_ACCEPT) { |
2011 GFile *parent = NULL; |
| 2011 if (data->cbs[0] != NULL) |
2012 GError *error = NULL; |
| 2012 ((PurpleRequestFileCb)data->cbs[0])(data->user_data, NULL); |
2013 |
| 2013 purple_request_close(data->type, data); |
2014 if(data->u.file.savedialog) { |
| |
2015 path = gtk_file_dialog_save_finish(GTK_FILE_DIALOG(obj), result, |
| |
2016 &error); |
| |
2017 } else { |
| |
2018 path = gtk_file_dialog_open_finish(GTK_FILE_DIALOG(obj), result, |
| |
2019 &error); |
| |
2020 } |
| |
2021 if(path == NULL) { |
| |
2022 if(!g_error_matches(error, GTK_DIALOG_ERROR, GTK_DIALOG_ERROR_CANCELLED)) { |
| |
2023 if(data->cbs[0] != NULL) { |
| |
2024 ((PurpleRequestFileCb)data->cbs[0])(data->user_data, NULL); |
| |
2025 } |
| |
2026 purple_request_close(data->type, data); |
| |
2027 } |
| |
2028 g_clear_error(&error); |
| 2014 return; |
2029 return; |
| 2015 } |
2030 } |
| 2016 |
2031 |
| 2017 current_path = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(data->dialog)); |
2032 parent = g_file_get_parent(path); |
| 2018 if (current_path != NULL) { |
2033 if(parent != NULL) { |
| 2019 gchar *current_folder = g_file_get_path(current_path); |
2034 char *current_folder = g_file_get_path(parent); |
| 2020 if (data->u.file.savedialog) { |
2035 if (data->u.file.savedialog) { |
| 2021 purple_prefs_set_path(PIDGIN_PREFS_ROOT "/filelocations/last_save_folder", current_folder); |
2036 purple_prefs_set_path(PIDGIN_PREFS_ROOT "/filelocations/last_save_folder", |
| |
2037 current_folder); |
| 2022 } else { |
2038 } else { |
| 2023 purple_prefs_set_path(PIDGIN_PREFS_ROOT "/filelocations/last_open_folder", current_folder); |
2039 purple_prefs_set_path(PIDGIN_PREFS_ROOT "/filelocations/last_open_folder", |
| |
2040 current_folder); |
| 2024 } |
2041 } |
| 2025 g_free(current_folder); |
2042 g_free(current_folder); |
| 2026 } |
2043 } |
| 2027 if (data->cbs[1] != NULL) { |
2044 |
| 2028 GFile *file = gtk_file_chooser_get_file(GTK_FILE_CHOOSER(data->dialog)); |
2045 if(data->cbs[1] != NULL) { |
| 2029 char *filename = g_file_get_path(file); |
2046 char *filename = g_file_get_path(path); |
| 2030 ((PurpleRequestFileCb)data->cbs[1])(data->user_data, filename); |
2047 ((PurpleRequestFileCb)data->cbs[1])(data->user_data, filename); |
| 2031 g_free(filename); |
2048 g_free(filename); |
| 2032 g_object_unref(file); |
2049 } |
| 2033 } |
2050 |
| |
2051 g_clear_object(&parent); |
| |
2052 g_clear_object(&path); |
| |
2053 g_clear_object(&data->cancellable); |
| 2034 purple_request_close(data->type, data); |
2054 purple_request_close(data->type, data); |
| 2035 |
2055 } |
| 2036 g_clear_object(¤t_path); |
2056 |
| |
2057 static void |
| |
2058 pidgin_request_folder_response_cb(GObject *obj, GAsyncResult *result, |
| |
2059 gpointer user_data) |
| |
2060 { |
| |
2061 PidginRequestData *data = user_data; |
| |
2062 GFile *path = NULL; |
| |
2063 char *folder = NULL; |
| |
2064 GError *error = NULL; |
| |
2065 |
| |
2066 path = gtk_file_dialog_select_folder_finish(GTK_FILE_DIALOG(obj), result, |
| |
2067 &error); |
| |
2068 if(path == NULL) { |
| |
2069 if(!g_error_matches(error, GTK_DIALOG_ERROR, GTK_DIALOG_ERROR_CANCELLED)) { |
| |
2070 if(data->cbs[0] != NULL) { |
| |
2071 ((PurpleRequestFileCb)data->cbs[0])(data->user_data, NULL); |
| |
2072 } |
| |
2073 purple_request_close(data->type, data); |
| |
2074 } |
| |
2075 g_clear_error(&error); |
| |
2076 return; |
| |
2077 } |
| |
2078 |
| |
2079 folder = g_file_get_path(path); |
| |
2080 purple_prefs_set_path(PIDGIN_PREFS_ROOT "/filelocations/last_open_folder", |
| |
2081 folder); |
| |
2082 |
| |
2083 if(data->cbs[1] != NULL) { |
| |
2084 ((PurpleRequestFileCb)data->cbs[1])(data->user_data, folder); |
| |
2085 } |
| |
2086 |
| |
2087 g_free(folder); |
| |
2088 g_clear_object(&path); |
| |
2089 g_clear_object(&data->cancellable); |
| |
2090 purple_request_close(data->type, data); |
| 2037 } |
2091 } |
| 2038 |
2092 |
| 2039 static void * |
2093 static void * |
| 2040 pidgin_request_file(const char *title, const char *filename, |
2094 pidgin_request_file(const char *title, const char *filename, |
| 2041 gboolean savedialog, GCallback ok_cb, GCallback cancel_cb, |
2095 gboolean savedialog, GCallback ok_cb, GCallback cancel_cb, |
| 2042 G_GNUC_UNUSED PurpleRequestCommonParameters *cpar, |
2096 G_GNUC_UNUSED PurpleRequestCommonParameters *cpar, |
| 2043 gpointer user_data) |
2097 gpointer user_data) |
| 2044 { |
2098 { |
| 2045 PidginRequestData *data; |
2099 PidginRequestData *data; |
| 2046 GtkFileChooserNative *filesel; |
2100 GtkFileDialog *dialog = NULL; |
| 2047 #ifdef _WIN32 |
2101 #ifdef _WIN32 |
| 2048 GFile *file = NULL; |
|
| 2049 const gchar *current_folder; |
2102 const gchar *current_folder; |
| 2050 gboolean folder_set = FALSE; |
2103 gboolean folder_set = FALSE; |
| 2051 #endif |
2104 #endif |
| 2052 |
2105 |
| 2053 data = g_new0(PidginRequestData, 1); |
2106 data = g_new0(PidginRequestData, 1); |
| 2057 data->cbs = g_new0(GCallback, 2); |
2110 data->cbs = g_new0(GCallback, 2); |
| 2058 data->cbs[0] = cancel_cb; |
2111 data->cbs[0] = cancel_cb; |
| 2059 data->cbs[1] = ok_cb; |
2112 data->cbs[1] = ok_cb; |
| 2060 data->u.file.savedialog = savedialog; |
2113 data->u.file.savedialog = savedialog; |
| 2061 |
2114 |
| 2062 filesel = gtk_file_chooser_native_new( |
2115 data->dialog = dialog = gtk_file_dialog_new(); |
| 2063 title ? title |
2116 gtk_file_dialog_set_title(dialog, |
| 2064 : (savedialog ? _("Save File...") : _("Open File...")), |
2117 title ? title |
| 2065 NULL, |
2118 : (savedialog ? _("Save File...") |
| 2066 savedialog ? GTK_FILE_CHOOSER_ACTION_SAVE |
2119 : _("Open File..."))); |
| 2067 : GTK_FILE_CHOOSER_ACTION_OPEN, |
2120 |
| 2068 savedialog ? _("_Save") : _("_Open"), _("_Cancel")); |
2121 if(!purple_strempty(filename)) { |
| 2069 |
|
| 2070 if ((filename != NULL) && (*filename != '\0')) { |
|
| 2071 GFile *path = g_file_new_for_path(filename); |
2122 GFile *path = g_file_new_for_path(filename); |
| 2072 |
2123 |
| 2073 if(savedialog) { |
2124 if(savedialog || g_file_test(filename, G_FILE_TEST_EXISTS)) { |
| 2074 gtk_file_chooser_set_file(GTK_FILE_CHOOSER(filesel), path, NULL); |
2125 gtk_file_dialog_set_initial_file(dialog, path); |
| 2075 } else if (g_file_test(filename, G_FILE_TEST_EXISTS)) { |
|
| 2076 gtk_file_chooser_set_file(GTK_FILE_CHOOSER(filesel), path, NULL); |
|
| 2077 } |
2126 } |
| 2078 |
2127 |
| 2079 g_object_unref(path); |
2128 g_object_unref(path); |
| 2080 } |
2129 } |
| 2081 |
2130 |
| 2084 current_folder = purple_prefs_get_path(PIDGIN_PREFS_ROOT "/filelocations/last_save_folder"); |
2133 current_folder = purple_prefs_get_path(PIDGIN_PREFS_ROOT "/filelocations/last_save_folder"); |
| 2085 } else { |
2134 } else { |
| 2086 current_folder = purple_prefs_get_path(PIDGIN_PREFS_ROOT "/filelocations/last_open_folder"); |
2135 current_folder = purple_prefs_get_path(PIDGIN_PREFS_ROOT "/filelocations/last_open_folder"); |
| 2087 } |
2136 } |
| 2088 |
2137 |
| 2089 if ((filename == NULL || *filename == '\0' || !g_file_test(filename, G_FILE_TEST_EXISTS)) && |
2138 if((purple_strempty(filename) || !g_file_test(filename, G_FILE_TEST_EXISTS)) && |
| 2090 (current_folder != NULL) && (*current_folder != '\0')) |
2139 !purple_strempty(current_folder)) |
| 2091 { |
2140 { |
| 2092 file = g_file_new_for_path(current_folder); |
2141 GFile *file = g_file_new_for_path(current_folder); |
| 2093 folder_set = gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(filesel), file, NULL); |
2142 gtk_file_dialog_set_initial_folder(dialog, file, NULL); |
| 2094 } |
2143 folder_set = TRUE; |
| 2095 |
2144 g_clear_object(&file); |
| 2096 if (!folder_set && (filename == NULL || *filename == '\0' || !g_file_test(filename, G_FILE_TEST_EXISTS))) { |
2145 } |
| |
2146 |
| |
2147 if(!folder_set && |
| |
2148 (purple_strempty(filename) || !g_file_test(filename, G_FILE_TEST_EXISTS))) |
| |
2149 { |
| 2097 char *my_documents = wpurple_get_special_folder(CSIDL_PERSONAL); |
2150 char *my_documents = wpurple_get_special_folder(CSIDL_PERSONAL); |
| 2098 |
2151 |
| 2099 g_clear_object(&file); |
|
| 2100 |
|
| 2101 if (my_documents != NULL) { |
2152 if (my_documents != NULL) { |
| 2102 file = g_file_new_for_path(my_documents); |
2153 GFile *file = g_file_new_for_path(my_documents); |
| 2103 gtk_file_chooser_set_current_folder( |
2154 |
| 2104 GTK_FILE_CHOOSER(filesel), file, NULL); |
2155 gtk_file_dialog_set_initial_folder(dialog, file); |
| 2105 |
2156 |
| 2106 g_free(my_documents); |
2157 g_free(my_documents); |
| 2107 } |
2158 g_clear_object(&file); |
| 2108 } |
2159 } |
| 2109 |
2160 } |
| 2110 g_clear_object(&file); |
|
| 2111 #endif |
2161 #endif |
| 2112 |
2162 |
| 2113 g_signal_connect(G_OBJECT(filesel), "response", |
2163 data->cancellable = g_cancellable_new(); |
| 2114 G_CALLBACK(pidgin_request_file_folder_response_cb), data); |
2164 if(savedialog) { |
| 2115 |
2165 gtk_file_dialog_save(dialog, NULL, data->cancellable, |
| 2116 #if 0 |
2166 pidgin_request_file_response_cb, data); |
| 2117 /* FIXME: Not implemented for native dialogs. */ |
2167 } else { |
| 2118 pidgin_auto_parent_window(filesel); |
2168 gtk_file_dialog_open(dialog, NULL, data->cancellable, |
| 2119 #endif |
2169 pidgin_request_file_response_cb, data); |
| 2120 |
2170 } |
| 2121 data->dialog = filesel; |
|
| 2122 gtk_native_dialog_show(GTK_NATIVE_DIALOG(filesel)); |
|
| 2123 |
2171 |
| 2124 return (void *)data; |
2172 return (void *)data; |
| 2125 } |
2173 } |
| 2126 |
2174 |
| 2127 static void * |
2175 static void * |
| 2129 GCallback cancel_cb, |
2177 GCallback cancel_cb, |
| 2130 G_GNUC_UNUSED PurpleRequestCommonParameters *cpar, |
2178 G_GNUC_UNUSED PurpleRequestCommonParameters *cpar, |
| 2131 gpointer user_data) |
2179 gpointer user_data) |
| 2132 { |
2180 { |
| 2133 PidginRequestData *data; |
2181 PidginRequestData *data; |
| 2134 GtkFileChooserNative *dirsel; |
2182 GtkFileDialog *dialog = NULL; |
| 2135 |
2183 |
| 2136 data = g_new0(PidginRequestData, 1); |
2184 data = g_new0(PidginRequestData, 1); |
| 2137 data->type = PURPLE_REQUEST_FOLDER; |
2185 data->type = PURPLE_REQUEST_FOLDER; |
| 2138 data->user_data = user_data; |
2186 data->user_data = user_data; |
| 2139 data->cb_count = 2; |
2187 data->cb_count = 2; |
| 2140 data->cbs = g_new0(GCallback, 2); |
2188 data->cbs = g_new0(GCallback, 2); |
| 2141 data->cbs[0] = cancel_cb; |
2189 data->cbs[0] = cancel_cb; |
| 2142 data->cbs[1] = ok_cb; |
2190 data->cbs[1] = ok_cb; |
| 2143 data->u.file.savedialog = FALSE; |
2191 data->u.file.savedialog = FALSE; |
| 2144 |
2192 |
| 2145 dirsel = gtk_file_chooser_native_new( |
2193 data->cancellable = g_cancellable_new(); |
| 2146 title ? title : _("Select Folder..."), NULL, |
2194 data->dialog = dialog = gtk_file_dialog_new(); |
| 2147 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, _("_OK"), _("_Cancel")); |
2195 gtk_file_dialog_set_title(dialog, title ? title : _("Select Folder...")); |
| 2148 |
2196 |
| 2149 if ((dirname != NULL) && (*dirname != '\0')) { |
2197 if(!purple_strempty(dirname)) { |
| 2150 GFile *path = g_file_new_for_path(dirname); |
2198 GFile *path = g_file_new_for_path(dirname); |
| 2151 |
2199 gtk_file_dialog_set_initial_folder(dialog, path); |
| 2152 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dirsel), path, |
|
| 2153 NULL); |
|
| 2154 |
|
| 2155 g_object_unref(path); |
2200 g_object_unref(path); |
| 2156 } |
2201 } |
| 2157 |
2202 |
| 2158 g_signal_connect(G_OBJECT(dirsel), "response", |
2203 gtk_file_dialog_select_folder(dialog, NULL, data->cancellable, |
| 2159 G_CALLBACK(pidgin_request_file_folder_response_cb), data); |
2204 pidgin_request_folder_response_cb, data); |
| 2160 |
|
| 2161 data->dialog = dirsel; |
|
| 2162 #if 0 |
|
| 2163 /* FIXME: Not implemented for native dialogs. */ |
|
| 2164 pidgin_auto_parent_window(dirsel); |
|
| 2165 #endif |
|
| 2166 |
|
| 2167 gtk_native_dialog_show(GTK_NATIVE_DIALOG(dirsel)); |
|
| 2168 |
2205 |
| 2169 return (void *)data; |
2206 return (void *)data; |
| 2170 } |
2207 } |
| 2171 |
2208 |
| 2172 /* if request callback issues another request, it should be attached to the |
2209 /* if request callback issues another request, it should be attached to the |
| 2200 static void |
2237 static void |
| 2201 pidgin_close_request(PurpleRequestType type, void *ui_handle) |
2238 pidgin_close_request(PurpleRequestType type, void *ui_handle) |
| 2202 { |
2239 { |
| 2203 PidginRequestData *data = (PidginRequestData *)ui_handle; |
2240 PidginRequestData *data = (PidginRequestData *)ui_handle; |
| 2204 |
2241 |
| 2205 g_free(data->cbs); |
2242 if(data->cancellable != NULL) { |
| |
2243 g_cancellable_cancel(data->cancellable); |
| |
2244 } |
| 2206 |
2245 |
| 2207 if (type == PURPLE_REQUEST_FILE || type == PURPLE_REQUEST_FOLDER) { |
2246 if (type == PURPLE_REQUEST_FILE || type == PURPLE_REQUEST_FOLDER) { |
| 2208 /* Will be a GtkNativeDialog, not GtkDialog. */ |
2247 /* Will be a GtkFileDialog, not GtkDialog. */ |
| 2209 g_object_unref(data->dialog); |
2248 g_clear_object(&data->dialog); |
| 2210 } else { |
2249 } else { |
| 2211 pidgin_window_detach_children(GTK_WINDOW(data->dialog)); |
2250 pidgin_window_detach_children(GTK_WINDOW(data->dialog)); |
| 2212 |
2251 |
| 2213 gtk_window_destroy(GTK_WINDOW(data->dialog)); |
2252 gtk_window_destroy(GTK_WINDOW(data->dialog)); |
| 2214 } |
2253 } |
| 2215 |
2254 |
| 2216 if(type == PURPLE_REQUEST_FIELDS) { |
2255 if(type == PURPLE_REQUEST_FIELDS) { |
| 2217 g_clear_object(&data->u.multifield.page); |
2256 g_clear_object(&data->u.multifield.page); |
| 2218 } |
2257 } |
| 2219 |
2258 |
| |
2259 g_clear_object(&data->cancellable); |
| |
2260 g_free(data->cbs); |
| 2220 g_free(data); |
2261 g_free(data); |
| 2221 } |
2262 } |
| 2222 |
2263 |
| 2223 GtkWindow * |
2264 GtkWindow * |
| 2224 pidgin_request_get_dialog_window(void *ui_handle) |
2265 pidgin_request_get_dialog_window(void *ui_handle) |