diff options
Diffstat (limited to 'indra/newview/llfilepicker.cpp')
-rw-r--r-- | indra/newview/llfilepicker.cpp | 641 |
1 files changed, 447 insertions, 194 deletions
diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index 2516bece8d..9e2bcc5148 100644 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -36,16 +36,8 @@ #include "llviewercontrol.h" #include "llwindow.h" // beforeDialog() -#if LL_SDL -#include "llwindowsdl.h" // for some X/GTK utils to help with filepickers -#endif // LL_SDL - -#ifdef LL_FLTK - #include "FL/Fl.H" - #include "FL/Fl_Native_File_Chooser.H" -#endif - #if LL_LINUX || __FreeBSD__ +#include "llwindowsdl.h" // for some X/GTK utils to help with filepickers #include "llhttpconstants.h" // file picker uses some of thes constants on Linux #endif @@ -70,6 +62,7 @@ LLFilePicker LLFilePicker::sInstance; #define MATERIAL_TEXTURES_FILTER L"GLTF Import (*.gltf; *.glb; *.tga; *.bmp; *.jpg; *.jpeg; *.png)\0*.gltf;*.glb;*.tga;*.bmp;*.jpg;*.jpeg;*.png\0" #define SCRIPT_FILTER L"Script files (*.lsl)\0*.lsl\0" #define DICTIONARY_FILTER L"Dictionary files (*.dic; *.xcu)\0*.dic;*.xcu\0" +#define LUA_FILTER L"Script files (*.lua)\0*.lua\0" #endif #ifdef LL_DARWIN @@ -246,6 +239,10 @@ bool LLFilePicker::setupFilter(ELoadFilter filter) mOFN.lpstrFilter = DICTIONARY_FILTER \ L"\0"; break; + case FFLOAD_LUA: + mOFN.lpstrFilter = LUA_FILTER \ + L"\0"; + break; default: res = false; break; @@ -675,7 +672,6 @@ std::unique_ptr<std::vector<std::string>> LLFilePicker::navOpenFilterProc(ELoadF break; case FFLOAD_HDRI: allowedv->push_back("exr"); - case FFLOAD_MODEL: case FFLOAD_COLLADA: allowedv->push_back("dae"); break; @@ -1108,231 +1104,488 @@ bool LLFilePicker::getSaveFileModeless(ESaveFilter filter, #elif LL_LINUX || __FreeBSD__ -#if LL_FLTK +# if LL_GTK -bool LLFilePicker::getSaveFileModeless(ESaveFilter filter, - const std::string& filename, - void (*callback)(bool, std::string&, void*), - void *userdata) +// static +void LLFilePicker::add_to_selectedfiles(gpointer data, gpointer user_data) { - LL_ERRS() << "NOT IMPLEMENTED" << LL_ENDL; - return FALSE; + // We need to run g_filename_to_utf8 in the user's locale + std::string saved_locale(setlocale(LC_ALL, NULL)); + setlocale(LC_ALL, ""); + + LLFilePicker* picker = (LLFilePicker*) user_data; + GError *error = NULL; + gchar* filename_utf8 = g_filename_to_utf8((gchar*)data, + -1, NULL, NULL, &error); + if (error) + { + // *FIXME. + // This condition should really be notified to the user, e.g. + // through a message box. Just logging it is inappropriate. + + // g_filename_display_name is ideal, but >= glib 2.6, so: + // a hand-rolled hacky makeASCII which disallows control chars + std::string display_name; + for (const gchar *str = (const gchar *)data; *str; str++) + { + display_name += (char)((*str >= 0x20 && *str <= 0x7E) ? *str : '?'); + } + LL_WARNS() << "g_filename_to_utf8 failed on \"" << display_name << "\": " << error->message << LL_ENDL; + } + + if (filename_utf8) + { + picker->mFiles.push_back(std::string(filename_utf8)); + LL_DEBUGS() << "ADDED FILE " << filename_utf8 << LL_ENDL; + g_free(filename_utf8); + } + + setlocale(LC_ALL, saved_locale.c_str()); } -bool LLFilePicker::getOpenFileModeless(ELoadFilter filter, - void (*callback)(bool, std::vector<std::string> &, void*), - void *userdata) +// static +void LLFilePicker::chooser_responder(GtkWidget *widget, gint response, gpointer user_data) { - LL_ERRS() << "NOT IMPLEMENTED" << LL_ENDL; - return FALSE; + LLFilePicker* picker = (LLFilePicker*)user_data; + + LL_DEBUGS() << "GTK DIALOG RESPONSE " << response << LL_ENDL; + + if (response == GTK_RESPONSE_ACCEPT) + { + GSList *file_list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(widget)); + g_slist_foreach(file_list, (GFunc)add_to_selectedfiles, user_data); + g_slist_foreach(file_list, (GFunc)g_free, NULL); + g_slist_free (file_list); + } + + // let's save the extension of the last added file(considering current filter) + GtkFileFilter *gfilter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(widget)); + if(gfilter) + { + std::string filter = gtk_file_filter_get_name(gfilter); + + if(filter == LLTrans::getString("png_image_files")) + { + picker->mCurrentExtension = ".png"; + } + else if(filter == LLTrans::getString("targa_image_files")) + { + picker->mCurrentExtension = ".tga"; + } + } + + // set the default path for this usage context. + const char* cur_folder = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(widget)); + if (cur_folder != NULL) + { + picker->mContextToPathMap[picker->mCurContextName] = cur_folder; + } + + gtk_widget_destroy(widget); + gtk_main_quit(); } -bool LLFilePicker::getMultipleOpenFilesModeless(ELoadFilter filter, - void (*callback)(bool, std::vector<std::string> &, void*), - void *userdata ) + +GtkWindow* LLFilePicker::buildFilePicker(bool is_save, bool is_folder, std::string context) { - LL_ERRS() << "NOT IMPLEMENTED" << LL_ENDL; - return FALSE; +#ifndef LL_MESA_HEADLESS + if (LLWindowSDL::ll_try_gtk_init()) + { + GtkWidget *win = NULL; + GtkFileChooserAction pickertype = + is_save? + (is_folder? + GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER : + GTK_FILE_CHOOSER_ACTION_SAVE) : + (is_folder? + GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER : + GTK_FILE_CHOOSER_ACTION_OPEN); + + win = gtk_file_chooser_dialog_new(NULL, NULL, + pickertype, + GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL, + is_folder ? + GTK_STOCK_APPLY : + (is_save ? + GTK_STOCK_SAVE : + GTK_STOCK_OPEN), + GTK_RESPONSE_ACCEPT, + (gchar *)NULL); + mCurContextName = context; + + // get the default path for this usage context if it's been + // seen before. + std::map<std::string,std::string>::iterator + this_path = mContextToPathMap.find(context); + if (this_path != mContextToPathMap.end()) + { + gtk_file_chooser_set_current_folder + (GTK_FILE_CHOOSER(win), + this_path->second.c_str()); + } + +# if LL_X11 + // Make GTK tell the window manager to associate this + // dialog with our non-GTK raw X11 window, which should try + // to keep it on top etc. + Window XWindowID = LLWindowSDL::get_SDL_XWindowID(); + if (None != XWindowID) + { + gtk_widget_realize(GTK_WIDGET(win)); // so we can get its gdkwin + GdkWindow *gdkwin = gdk_window_foreign_new(XWindowID); + gdk_window_set_transient_for(GTK_WIDGET(win)->window, + gdkwin); + } + else + { + LL_WARNS() << "Hmm, couldn't get xwid to use for transient." << LL_ENDL; + } +# endif //LL_X11 + + g_signal_connect (GTK_FILE_CHOOSER(win), + "response", + G_CALLBACK(LLFilePicker::chooser_responder), + this); + + gtk_window_set_modal(GTK_WINDOW(win), TRUE); + + /* GTK 2.6: if (is_folder) + gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(win), + TRUE); */ + + return GTK_WINDOW(win); + } + else + { + return NULL; + } +#else + return NULL; +#endif //LL_MESA_HEADLESS } +static void add_common_filters_to_gtkchooser(GtkFileFilter *gfilter, + GtkWindow *picker, + std::string filtername) +{ + gtk_file_filter_set_name(gfilter, filtername.c_str()); + gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker), + gfilter); + GtkFileFilter *allfilter = gtk_file_filter_new(); + gtk_file_filter_add_pattern(allfilter, "*"); + gtk_file_filter_set_name(allfilter, LLTrans::getString("all_files").c_str()); + gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker), allfilter); + gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(picker), gfilter); +} +static std::string add_simple_pattern_filter_to_gtkchooser(GtkWindow *picker, + std::string pattern, + std::string filtername) +{ + GtkFileFilter *gfilter = gtk_file_filter_new(); + gtk_file_filter_add_pattern(gfilter, pattern.c_str()); + add_common_filters_to_gtkchooser(gfilter, picker, filtername); + return filtername; +} -bool LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename, bool blocking ) +static std::string add_simple_mime_filter_to_gtkchooser(GtkWindow *picker, + std::string mime, + std::string filtername) { - return openFileDialog( filter, blocking, eSaveFile ); + GtkFileFilter *gfilter = gtk_file_filter_new(); + gtk_file_filter_add_mime_type(gfilter, mime.c_str()); + add_common_filters_to_gtkchooser(gfilter, picker, filtername); + return filtername; } -bool LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking ) +static std::string add_wav_filter_to_gtkchooser(GtkWindow *picker) { - return openFileDialog( filter, blocking, eOpenFile ); + return add_simple_mime_filter_to_gtkchooser(picker, "audio/x-wav", + LLTrans::getString("sound_files") + " (*.wav)"); } -bool LLFilePicker::getMultipleOpenFiles( ELoadFilter filter, bool blocking) +static std::string add_anim_filter_to_gtkchooser(GtkWindow *picker) +{ + GtkFileFilter *gfilter = gtk_file_filter_new(); + gtk_file_filter_add_pattern(gfilter, "*.bvh"); + gtk_file_filter_add_pattern(gfilter, "*.anim"); + std::string filtername = LLTrans::getString("animation_files") + " (*.bvh; *.anim)"; + add_common_filters_to_gtkchooser(gfilter, picker, filtername); + return filtername; +} + +static std::string add_xml_filter_to_gtkchooser(GtkWindow *picker) +{ + return add_simple_pattern_filter_to_gtkchooser(picker, "*.xml", + LLTrans::getString("xml_files") + " (*.xml)"); +} + +static std::string add_collada_filter_to_gtkchooser(GtkWindow *picker) +{ + return add_simple_pattern_filter_to_gtkchooser(picker, "*.dae", + LLTrans::getString("scene_files") + " (*.dae)"); +} + +static std::string add_imageload_filter_to_gtkchooser(GtkWindow *picker) +{ + GtkFileFilter *gfilter = gtk_file_filter_new(); + gtk_file_filter_add_pattern(gfilter, "*.tga"); + gtk_file_filter_add_mime_type(gfilter, HTTP_CONTENT_IMAGE_JPEG.c_str()); + gtk_file_filter_add_mime_type(gfilter, HTTP_CONTENT_IMAGE_PNG.c_str()); + gtk_file_filter_add_mime_type(gfilter, HTTP_CONTENT_IMAGE_BMP.c_str()); + std::string filtername = LLTrans::getString("image_files") + " (*.tga; *.bmp; *.jpg; *.png)"; + add_common_filters_to_gtkchooser(gfilter, picker, filtername); + return filtername; +} + +static std::string add_script_filter_to_gtkchooser(GtkWindow *picker) +{ + return add_simple_mime_filter_to_gtkchooser(picker, HTTP_CONTENT_TEXT_PLAIN, + LLTrans::getString("script_files") + " (*.lsl)"); +} + +static std::string add_dictionary_filter_to_gtkchooser(GtkWindow *picker) +{ + return add_simple_mime_filter_to_gtkchooser(picker, HTTP_CONTENT_TEXT_PLAIN, + LLTrans::getString("dictionary_files") + " (*.dic; *.xcu)"); +} + +static std::string add_save_texture_filter_to_gtkchooser(GtkWindow *picker) { - return openFileDialog( filter, blocking, eOpenMultiple ); + GtkFileFilter *gfilter_tga = gtk_file_filter_new(); + GtkFileFilter *gfilter_png = gtk_file_filter_new(); + + gtk_file_filter_add_pattern(gfilter_tga, "*.tga"); + gtk_file_filter_add_mime_type(gfilter_png, "image/png"); + std::string caption = LLTrans::getString("save_texture_image_files") + " (*.tga; *.png)"; + gtk_file_filter_set_name(gfilter_tga, LLTrans::getString("targa_image_files").c_str()); + gtk_file_filter_set_name(gfilter_png, LLTrans::getString("png_image_files").c_str()); + + gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker), + gfilter_png); + gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker), + gfilter_tga); + return caption; } -bool LLFilePicker::openFileDialog( int32_t filter, bool blocking, EType aType ) +bool LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename, bool blocking ) { - if ( check_local_file_access_enabled() == false ) + bool rtn = false; + + // if local file browsing is turned off, return without opening dialog + if (!check_local_file_access_enabled()) + { return false; + } + gViewerWindow->getWindow()->beforeDialog(); + reset(); - Fl_Native_File_Chooser::Type flType = Fl_Native_File_Chooser::BROWSE_FILE; - if( aType == eOpenMultiple ) - flType = Fl_Native_File_Chooser::BROWSE_MULTI_FILE; - else if( aType == eSaveFile ) - flType = Fl_Native_File_Chooser::BROWSE_SAVE_FILE; - Fl_Native_File_Chooser flDlg; - std::string file_dialog_title; - std::string file_dialog_filter; - if (aType == EType::eSaveFile) - { - std::string file_type("all_files"); - switch ((ESaveFilter) filter) + + GtkWindow* picker = buildFilePicker(true, false, "savefile"); + + if (picker) + { + std::string suggest_name = "untitled"; + std::string suggest_ext = ""; + std::string caption = LLTrans::getString("save_file_verb") + " "; + switch (filter) { - case FFSAVE_ALL: - break; - case FFSAVE_TGA: - file_type = "targa_image_files"; - file_dialog_filter = "*.tga"; - break; - case FFSAVE_BMP: - file_type = "bitmap_image_files"; - file_dialog_filter = "*.bmp"; - break; - case FFSAVE_AVI: - file_type = "avi_movie_file"; - file_dialog_filter = "*.avi"; - break; - case FFSAVE_ANIM: - file_type = "xaf_animation_file"; - file_dialog_filter = "*.xaf"; - break; - case FFSAVE_XML: - file_type = "xml_file"; - file_dialog_filter = "*.xml"; - break; - case FFSAVE_COLLADA: - file_type = "collada_files"; - file_dialog_filter = "*.dae"; - break; - case FFSAVE_RAW: - file_type = "raw_file"; - file_dialog_filter = "*.raw"; - break; - case FFSAVE_J2C: - file_type = "compressed_image_files"; - file_dialog_filter = "*.j2c"; - break; - case FFSAVE_PNG: - file_type = "png_image_files"; - file_dialog_filter = "*.png"; - break; - case FFSAVE_JPEG: - file_type = "jpeg_image_files"; - file_dialog_filter = "*.{jpg,jpeg}"; - break; - case FFSAVE_SCRIPT: - file_type = "script_files"; - file_dialog_filter = "*.lsl"; - break; - case FFSAVE_TGAPNG: - file_type = "save_texture_image_files"; - file_dialog_filter = "*.{tga,png}"; - break; - case FFSAVE_WAV: - file_type = "sound_files"; - file_dialog_filter = "*.wav"; - break; - case FFSAVE_GLTF: - file_type = "gltf_asset_file"; - file_dialog_filter = "*.{gltf,glb}"; - break; + case FFSAVE_WAV: + caption += add_wav_filter_to_gtkchooser(picker); + suggest_ext = ".wav"; + break; + case FFSAVE_TGA: + caption += add_simple_pattern_filter_to_gtkchooser + (picker, "*.tga", LLTrans::getString("targa_image_files") + " (*.tga)"); + suggest_ext = ".tga"; + break; + case FFSAVE_BMP: + caption += add_simple_mime_filter_to_gtkchooser + (picker, HTTP_CONTENT_IMAGE_BMP, LLTrans::getString("bitmap_image_files") + " (*.bmp)"); + suggest_ext = ".bmp"; + break; + case FFSAVE_PNG: + caption += add_simple_mime_filter_to_gtkchooser + (picker, "image/png", LLTrans::getString("png_image_files") + " (*.png)"); + suggest_ext = ".png"; + break; + case FFSAVE_TGAPNG: + caption += add_save_texture_filter_to_gtkchooser(picker); + suggest_ext = ".png"; + break; + case FFSAVE_AVI: + caption += add_simple_mime_filter_to_gtkchooser + (picker, "video/x-msvideo", + LLTrans::getString("avi_movie_file") + " (*.avi)"); + suggest_ext = ".avi"; + break; + case FFSAVE_ANIM: + caption += add_simple_pattern_filter_to_gtkchooser + (picker, "*.xaf", LLTrans::getString("xaf_animation_file") + " (*.xaf)"); + suggest_ext = ".xaf"; + break; + case FFSAVE_XML: + caption += add_simple_pattern_filter_to_gtkchooser + (picker, "*.xml", LLTrans::getString("xml_file") + " (*.xml)"); + suggest_ext = ".xml"; + break; + case FFSAVE_RAW: + caption += add_simple_pattern_filter_to_gtkchooser + (picker, "*.raw", LLTrans::getString("raw_file") + " (*.raw)"); + suggest_ext = ".raw"; + break; + case FFSAVE_J2C: + // *TODO: Should this be 'image/j2c' ? + caption += add_simple_mime_filter_to_gtkchooser + (picker, "images/jp2", + LLTrans::getString("compressed_image_files") + " (*.j2c)"); + suggest_ext = ".j2c"; + break; + case FFSAVE_SCRIPT: + caption += add_script_filter_to_gtkchooser(picker); + suggest_ext = ".lsl"; + break; + default:; + break; } - file_dialog_title = LLTrans::getString("save_file_verb") + " " + LLTrans::getString(file_type); - file_dialog_filter = LLTrans::getString(file_type) + " \t" + file_dialog_filter; - } - else - { - std::string file_type("all_files"); - switch ((ELoadFilter) filter) + + gtk_window_set_title(GTK_WINDOW(picker), caption.c_str()); + + if (filename.empty()) { - case FFLOAD_ALL: - break; - case FFLOAD_WAV: - file_type = "sound_files"; - file_dialog_filter = "*.wav"; - break; - case FFLOAD_IMAGE: - file_type = "image_files"; - file_dialog_filter = "*.{tga,bmp,jpg,jpeg,png}"; - break; - case FFLOAD_ANIM: - file_type = "animation_files"; - file_dialog_filter = "*.{bvh,anim}"; - break; - case FFLOAD_XML: - file_type = "xml_file"; - file_dialog_filter = "*.xml"; - break; - case FFLOAD_SLOBJECT: - file_type = "xml_file"; - file_dialog_filter = "*.slobject"; - break; - case FFLOAD_RAW: - file_type = "raw_file"; - file_dialog_filter = "*.raw"; - break; - case FFLOAD_MODEL: - case FFLOAD_COLLADA: - file_type = "collada_files"; - file_dialog_filter = "*.dae"; - break; - case FFLOAD_SCRIPT: - file_type = "script_files"; - file_dialog_filter = "*.lsl"; - break; - case FFLOAD_DICTIONARY: - file_type = "dictionary_files"; - file_dialog_filter = "*.{dic,xcu}"; - break; - case FFLOAD_DIRECTORY: - file_type = "choose_the_directory"; - break; - case FFLOAD_EXE: - file_type = "executable_files"; - break; - case FFLOAD_GLTF: - case FFLOAD_MATERIAL: - file_type = "gltf_asset_file"; - file_dialog_filter = "*.{gltg,glb}"; - break; - case FFLOAD_MATERIAL_TEXTURE: - file_dialog_filter = "*.{gltf,glb,tga,bmp,jpg,jpeg,png}"; - file_type = "image_files"; - break; - case FFLOAD_HDRI: - file_dialog_filter = "*.exr"; + suggest_name += suggest_ext; + gtk_file_chooser_set_current_name + (GTK_FILE_CHOOSER(picker), + suggest_name.c_str()); } - if (aType == EType::eOpenMultiple) + else { - file_dialog_title = LLTrans::getString("load_files"); + gtk_file_chooser_set_current_name + (GTK_FILE_CHOOSER(picker), filename.c_str()); } - else + + gtk_widget_show_all(GTK_WIDGET(picker)); + + gtk_main(); + + rtn = (getFileCount() == 1); + + if(rtn && filter == FFSAVE_TGAPNG) { - file_dialog_title = LLTrans::getString("load_file_verb") + " " + LLTrans::getString(file_type); - file_dialog_filter = LLTrans::getString(file_type) + " \t" + file_dialog_filter; + std::string selected_file = mFiles.back(); + mFiles.pop_back(); + mFiles.push_back(selected_file + mCurrentExtension); } } - flDlg.title(file_dialog_title.c_str()); - flDlg.type(flType); - if (!file_dialog_filter.empty()) + + gViewerWindow->getWindow()->afterDialog(); + + return rtn; +} + +bool LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking ) +{ + bool rtn = false; + + // if local file browsing is turned off, return without opening dialog + if (!check_local_file_access_enabled()) { - flDlg.filter(file_dialog_filter.c_str()); + return false; } - int res = flDlg.show(); - gViewerWindow->getWindow()->afterDialog(); - if( res == 0 ) + + gViewerWindow->getWindow()->beforeDialog(); + + reset(); + + GtkWindow* picker = buildFilePicker(false, false, "openfile"); + + if (picker) { - int32_t count = flDlg.count(); - if( count < 0 ) - count = 0; - for( int32_t i = 0; i < count; ++i ) + std::string caption = LLTrans::getString("load_file_verb") + " "; + std::string filtername = ""; + switch (filter) { - char const *pFile = flDlg.filename(i); - if( pFile && strlen(pFile) > 0 ) - mFiles.push_back( pFile ); + case FFLOAD_WAV: + filtername = add_wav_filter_to_gtkchooser(picker); + break; + case FFLOAD_ANIM: + filtername = add_anim_filter_to_gtkchooser(picker); + break; + case FFLOAD_XML: + filtername = add_xml_filter_to_gtkchooser(picker); + break; + case FFLOAD_GLTF: + filtername = dead_code_should_blow_up_here(picker); + break; + case FFLOAD_COLLADA: + filtername = add_collada_filter_to_gtkchooser(picker); + break; + case FFLOAD_IMAGE: + filtername = add_imageload_filter_to_gtkchooser(picker); + break; + case FFLOAD_SCRIPT: + filtername = add_script_filter_to_gtkchooser(picker); + break; + case FFLOAD_DICTIONARY: + filtername = add_dictionary_filter_to_gtkchooser(picker); + break; + default:; + break; } + + caption += filtername; + + gtk_window_set_title(GTK_WINDOW(picker), caption.c_str()); + + gtk_widget_show_all(GTK_WIDGET(picker)); + gtk_main(); + + rtn = (getFileCount() == 1); } - else if( res == -1 ) + + gViewerWindow->getWindow()->afterDialog(); + + return rtn; +} + +bool LLFilePicker::getMultipleOpenFiles( ELoadFilter filter, bool blocking) +{ + bool rtn = false; + + // if local file browsing is turned off, return without opening dialog + if (!check_local_file_access_enabled()) { - LL_WARNS() << "FLTK failed: " << flDlg.errmsg() << LL_ENDL; + return false; } - return mFiles.empty()?FALSE:TRUE; + + gViewerWindow->getWindow()->beforeDialog(); + + reset(); + + GtkWindow* picker = buildFilePicker(false, false, "openfile"); + + if (picker) + { + gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER(picker), + TRUE); + + gtk_window_set_title(GTK_WINDOW(picker), LLTrans::getString("load_files").c_str()); + + gtk_widget_show_all(GTK_WIDGET(picker)); + gtk_main(); + rtn = !mFiles.empty(); + } + + gViewerWindow->getWindow()->afterDialog(); + + return rtn; } -#else + +# else // LL_GTK + // Hacky stubs designed to facilitate fake getSaveFile and getOpenFile with // static results, when we don't have a real filepicker. @@ -1420,17 +1673,17 @@ bool LLFilePicker::getMultipleOpenFilesModeless(ELoadFilter filter, return false; } -#endif // LL_FLTK +#endif // LL_GTK #else // not implemented -bool LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename, bool blocking ) +bool LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename ) { reset(); return false; } -bool LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking ) +bool LLFilePicker::getOpenFile( ELoadFilter filter ) { reset(); return false; |