NS_IMETHODIMP nsFilePicker::Show(PRInt16 *aReturn) { NS_ENSURE_ARG_POINTER(aReturn); nsXPIDLCString title; title.Adopt(ToNewUTF8String(mTitle)); GtkWindow *parent_widget = get_gtk_window_for_nsiwidget(mParentWidget); GtkFileChooserAction action = GetGtkFileChooserAction(mMode); const gchar *accept_button = (mMode == GTK_FILE_CHOOSER_ACTION_SAVE) ? GTK_STOCK_SAVE : GTK_STOCK_OPEN; GtkWidget *file_chooser = _gtk_file_chooser_dialog_new(title, parent_widget, action, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, accept_button, GTK_RESPONSE_ACCEPT, NULL); if (mAllowURLs) { _gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(file_chooser), FALSE); } if (mMode == GTK_FILE_CHOOSER_ACTION_OPEN || mMode == GTK_FILE_CHOOSER_ACTION_SAVE) { GtkWidget *img_preview = _gtk_image_new(); _gtk_file_chooser_set_preview_widget(GTK_FILE_CHOOSER(file_chooser), img_preview); g_signal_connect(file_chooser, "update-preview", G_CALLBACK(UpdateFilePreviewWidget), img_preview); } if (parent_widget && parent_widget->group) { gtk_window_group_add_window(parent_widget->group, GTK_WINDOW(file_chooser)); } if (mMode == nsIFilePicker::modeOpenMultiple) { _gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER(file_chooser), TRUE); } else if (mMode == nsIFilePicker::modeSave) { char *default_filename = ToNewUTF8String(mDefault); _gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(file_chooser), static_cast<const gchar*>(default_filename)); nsMemory::Free(default_filename); } gtk_dialog_set_default_response(GTK_DIALOG(file_chooser), GTK_RESPONSE_ACCEPT); nsCAutoString directory; if (mDisplayDirectory) { mDisplayDirectory->GetNativePath(directory); } else if (mPrevDisplayDirectory) { mPrevDisplayDirectory->GetNativePath(directory); } if (!directory.IsEmpty()) { _gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(file_chooser), directory.get()); } PRInt32 count = mFilters.Count(); for (PRInt32 i = 0; i < count; ++i) { // This is fun... the GTK file picker does not accept a list of filters // so we need to split out each string, and add it manually. char **patterns = g_strsplit(mFilters[i]->get(), ";", -1); if (!patterns) { return NS_ERROR_OUT_OF_MEMORY; } GtkFileFilter *filter = _gtk_file_filter_new (); for (int j = 0; patterns[j] != NULL; ++j) { _gtk_file_filter_add_pattern (filter, g_strstrip (patterns[j])); } g_strfreev(patterns); if (!mFilterNames[i]->IsEmpty()) { // If we have a name for our filter, let's use that. const char *filter_name = mFilterNames[i]->get(); _gtk_file_filter_set_name (filter, filter_name); } else { // If we don't have a name, let's just use the filter pattern. const char *filter_pattern = mFilters[i]->get(); _gtk_file_filter_set_name (filter, filter_pattern); } _gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (file_chooser), filter); // Set the initially selected filter if (mSelectedType == i) { _gtk_file_chooser_set_filter (GTK_FILE_CHOOSER(file_chooser), filter); } } PRBool checkForOverwrite = PR_TRUE; if (_gtk_file_chooser_set_do_overwrite_confirmation) { checkForOverwrite = PR_FALSE; // Only available in GTK 2.8 _gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(file_chooser), PR_TRUE); } gint response = RunDialog(GTK_DIALOG (file_chooser)); switch (response) { case GTK_RESPONSE_ACCEPT: ReadValuesFromFileChooser(file_chooser); *aReturn = nsIFilePicker::returnOK; if (mMode == nsIFilePicker::modeSave) { nsCOMPtr<nsILocalFile> file; GetFile(getter_AddRefs(file)); if (file) { PRBool exists = PR_FALSE; file->Exists(&exists); if (exists) { PRBool overwrite = !checkForOverwrite || confirm_overwrite_file (file_chooser, file); if (overwrite) { *aReturn = nsIFilePicker::returnReplace; } else { *aReturn = nsIFilePicker::returnCancel; } } } } break; case GTK_RESPONSE_CANCEL: case GTK_RESPONSE_CLOSE: case GTK_RESPONSE_DELETE_EVENT: *aReturn = nsIFilePicker::returnCancel; break; default: NS_WARNING("Unexpected response"); *aReturn = nsIFilePicker::returnCancel; break; } gtk_widget_destroy(file_chooser); return NS_OK; }
NS_IMETHODIMP nsFilePicker::Show(PRInt16 *aReturn) { NS_ENSURE_ARG_POINTER(aReturn); nsXPIDLCString title; title.Adopt(ToNewUTF8String(mTitle)); GtkWindow *parent_widget = get_gtk_window_for_nsiwidget(mParentWidget); GtkFileChooserAction action = GetGtkFileChooserAction(mMode); const gchar *accept_button = (action == GTK_FILE_CHOOSER_ACTION_SAVE) ? GTK_STOCK_SAVE : GTK_STOCK_OPEN; #if (MOZ_PLATFORM_MAEMO == 5) GtkWidget *file_chooser = hildon_file_chooser_dialog_new_with_properties(parent_widget, "action", action, "open-button-text", accept_button, NULL); gtk_window_set_title(GTK_WINDOW(file_chooser), title); #else GtkWidget *file_chooser = gtk_file_chooser_dialog_new(title, parent_widget, action, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, accept_button, GTK_RESPONSE_ACCEPT, NULL); gtk_dialog_set_alternative_button_order(GTK_DIALOG(file_chooser), GTK_RESPONSE_ACCEPT, GTK_RESPONSE_CANCEL, -1); if (mAllowURLs) { gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(file_chooser), FALSE); } #endif if (action == GTK_FILE_CHOOSER_ACTION_OPEN || action == GTK_FILE_CHOOSER_ACTION_SAVE) { GtkWidget *img_preview = gtk_image_new(); gtk_file_chooser_set_preview_widget(GTK_FILE_CHOOSER(file_chooser), img_preview); g_signal_connect(file_chooser, "update-preview", G_CALLBACK(UpdateFilePreviewWidget), img_preview); } if (parent_widget && parent_widget->group) { gtk_window_group_add_window(parent_widget->group, GTK_WINDOW(file_chooser)); } NS_ConvertUTF16toUTF8 defaultName(mDefault); switch (mMode) { case nsIFilePicker::modeOpenMultiple: gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(file_chooser), TRUE); break; case nsIFilePicker::modeSave: gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(file_chooser), defaultName.get()); break; } nsCOMPtr<nsIFile> defaultPath; if (mDisplayDirectory) { mDisplayDirectory->Clone(getter_AddRefs(defaultPath)); } else if (mPrevDisplayDirectory) { mPrevDisplayDirectory->Clone(getter_AddRefs(defaultPath)); } if (defaultPath) { if (!defaultName.IsEmpty() && mMode != nsIFilePicker::modeSave) { // Try to select the intended file. Even if it doesn't exist, GTK still switches // directories. defaultPath->AppendNative(defaultName); nsCAutoString path; defaultPath->GetNativePath(path); gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(file_chooser), path.get()); } else { nsCAutoString directory; defaultPath->GetNativePath(directory); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(file_chooser), directory.get()); } } gtk_dialog_set_default_response(GTK_DIALOG(file_chooser), GTK_RESPONSE_ACCEPT); PRInt32 count = mFilters.Length(); for (PRInt32 i = 0; i < count; ++i) { // This is fun... the GTK file picker does not accept a list of filters // so we need to split out each string, and add it manually. char **patterns = g_strsplit(mFilters[i].get(), ";", -1); if (!patterns) { return NS_ERROR_OUT_OF_MEMORY; } GtkFileFilter *filter = gtk_file_filter_new(); for (int j = 0; patterns[j] != NULL; ++j) { nsCAutoString caseInsensitiveFilter = MakeCaseInsensitiveShellGlob(g_strstrip(patterns[j])); gtk_file_filter_add_pattern(filter, caseInsensitiveFilter.get()); } g_strfreev(patterns); if (!mFilterNames[i].IsEmpty()) { // If we have a name for our filter, let's use that. const char *filter_name = mFilterNames[i].get(); gtk_file_filter_set_name(filter, filter_name); } else { // If we don't have a name, let's just use the filter pattern. const char *filter_pattern = mFilters[i].get(); gtk_file_filter_set_name(filter, filter_pattern); } gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_chooser), filter); // Set the initially selected filter if (mSelectedType == i) { gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(file_chooser), filter); } } gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(file_chooser), PR_TRUE); gint response = RunDialog(GTK_DIALOG(file_chooser)); switch (response) { case GTK_RESPONSE_OK: case GTK_RESPONSE_ACCEPT: ReadValuesFromFileChooser(file_chooser); *aReturn = nsIFilePicker::returnOK; if (mMode == nsIFilePicker::modeSave) { nsCOMPtr<nsILocalFile> file; GetFile(getter_AddRefs(file)); if (file) { PRBool exists = PR_FALSE; file->Exists(&exists); if (exists) *aReturn = nsIFilePicker::returnReplace; } } break; case GTK_RESPONSE_CANCEL: case GTK_RESPONSE_CLOSE: case GTK_RESPONSE_DELETE_EVENT: *aReturn = nsIFilePicker::returnCancel; break; default: NS_WARNING("Unexpected response"); *aReturn = nsIFilePicker::returnCancel; break; } gtk_widget_destroy(file_chooser); return NS_OK; }