aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llfilepicker.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:45:11 -0500
committerJacek Antonelli2008-08-15 23:45:11 -0500
commit215f423cbe18fe9ca14a26caef918d303bad28ff (patch)
tree0743442b286216cc8e19aa487c26f4e9345ffd64 /linden/indra/newview/llfilepicker.cpp
parentSecond Life viewer sources 1.18.3.5-RC (diff)
downloadmeta-impy-215f423cbe18fe9ca14a26caef918d303bad28ff.zip
meta-impy-215f423cbe18fe9ca14a26caef918d303bad28ff.tar.gz
meta-impy-215f423cbe18fe9ca14a26caef918d303bad28ff.tar.bz2
meta-impy-215f423cbe18fe9ca14a26caef918d303bad28ff.tar.xz
Second Life viewer sources 1.18.4.0-RC
Diffstat (limited to 'linden/indra/newview/llfilepicker.cpp')
-rw-r--r--linden/indra/newview/llfilepicker.cpp273
1 files changed, 181 insertions, 92 deletions
diff --git a/linden/indra/newview/llfilepicker.cpp b/linden/indra/newview/llfilepicker.cpp
index 3620c05..c73b331 100644
--- a/linden/indra/newview/llfilepicker.cpp
+++ b/linden/indra/newview/llfilepicker.cpp
@@ -2,6 +2,8 @@
2 * @file llfilepicker.cpp 2 * @file llfilepicker.cpp
3 * @brief OS-specific file picker 3 * @brief OS-specific file picker
4 * 4 *
5 * $LicenseInfo:firstyear=2001&license=viewergpl$
6 *
5 * Copyright (c) 2001-2007, Linden Research, Inc. 7 * Copyright (c) 2001-2007, Linden Research, Inc.
6 * 8 *
7 * Second Life Viewer Source Code 9 * Second Life Viewer Source Code
@@ -24,13 +26,12 @@
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO 26 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, 27 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE. 28 * COMPLETENESS OR PERFORMANCE.
29 * $/LicenseInfo$
27 */ 30 */
28 31
29#include "llviewerprecompiledheaders.h" 32#include "llviewerprecompiledheaders.h"
30 33
31#include "llfilepicker.h" 34#include "llfilepicker.h"
32//#include "viewer.h"
33//#include "llviewermessage.h"
34#include "llworld.h" 35#include "llworld.h"
35#include "llviewerwindow.h" 36#include "llviewerwindow.h"
36#include "llkeyboard.h" 37#include "llkeyboard.h"
@@ -957,6 +958,10 @@ void LLFilePicker::reset()
957#elif LL_LINUX 958#elif LL_LINUX
958 959
959# if LL_GTK 960# if LL_GTK
961// This caches the previously-accessed path for a given context of the file
962// chooser, for user convenience.
963std::map <std::string, std::string> LLFilePicker::sContextToPathMap;
964
960LLFilePicker::LLFilePicker() 965LLFilePicker::LLFilePicker()
961{ 966{
962 reset(); 967 reset();
@@ -966,51 +971,83 @@ LLFilePicker::~LLFilePicker()
966{ 971{
967} 972}
968 973
969static void store_filenames(GtkWidget *widget, gpointer user_data) { 974
975static void add_to_sfs(gpointer data, gpointer user_data)
976{
970 StoreFilenamesStruct *sfs = (StoreFilenamesStruct*) user_data; 977 StoreFilenamesStruct *sfs = (StoreFilenamesStruct*) user_data;
971 GtkWidget *win = sfs->win; 978 gchar* filename_utf8 = g_filename_to_utf8((gchar*)data,
979 -1, NULL,
980 NULL,
981 NULL);
982 sfs->fileVector.push_back(LLString(filename_utf8));
983 g_free(filename_utf8);
984}
972 985
973 llinfos <<"store_filesnames: marker A" << llendl;
974 986
975 // get NULL-terminated list of strings allocated for us by GTK 987void chooser_responder(GtkWidget *widget,
976 gchar** string_list = 988 gint response,
977 gtk_file_selection_get_selections(GTK_FILE_SELECTION(win)); 989 gpointer user_data) {
990 StoreFilenamesStruct *sfs = (StoreFilenamesStruct*) user_data;
978 991
979 llinfos <<"store_filesnames: marker B" << llendl; 992 lldebugs << "GTK DIALOG RESPONSE " << response << llendl;
980 993
981 int idx = 0; 994 if (response == GTK_RESPONSE_ACCEPT)
982 while (string_list[idx])
983 { 995 {
984 // platform-string to utf8 996 GSList *file_list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(widget));
985 gchar* filename_utf8 = g_filename_from_utf8(string_list[idx], 997 g_slist_foreach(file_list, (GFunc)add_to_sfs, sfs);
986 -1, NULL, 998 g_slist_foreach(file_list, (GFunc)g_free, NULL);
987 NULL, 999 g_slist_free (file_list);
988 NULL);
989 sfs->fileVector.push_back(LLString(filename_utf8));
990 ++idx;
991 } 1000 }
992 1001
993 llinfos <<"store_filesnames: marker C" << llendl; 1002 // set the default path for this usage context.
994 1003 LLFilePicker::sContextToPathMap[sfs->contextName] =
995 g_strfreev(string_list); 1004 gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(widget));
996 1005
997 llinfos <<"store_filesnames: marker D" << llendl; 1006 gtk_widget_destroy(widget);
998 1007 gtk_main_quit();
999 llinfos << sfs->fileVector.size() << " filename(s) selected:" << llendl;
1000 U32 x;
1001 for (x=0; x<sfs->fileVector.size(); ++x)
1002 llinfos << x << ":" << sfs->fileVector[x] << llendl;
1003} 1008}
1004 1009
1005GtkWindow* LLFilePicker::buildFilePicker(void) 1010
1011GtkWindow* LLFilePicker::buildFilePicker(bool is_save, bool is_folder,
1012 std::string context)
1006{ 1013{
1007 if (ll_try_gtk_init() && 1014 if (ll_try_gtk_init() &&
1008 ! gViewerWindow->getWindow()->getFullscreen()) 1015 ! gViewerWindow->getWindow()->getFullscreen())
1009 { 1016 {
1010 GtkWidget *win = NULL; 1017 GtkWidget *win = NULL;
1011 1018 GtkFileChooserAction pickertype =
1012 win = gtk_file_selection_new(NULL); 1019 is_save?
1020 (is_folder?
1021 GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER :
1022 GTK_FILE_CHOOSER_ACTION_SAVE) :
1023 (is_folder?
1024 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER :
1025 GTK_FILE_CHOOSER_ACTION_OPEN);
1026
1027 win = gtk_file_chooser_dialog_new(NULL, NULL,
1028 pickertype,
1029 GTK_STOCK_CANCEL,
1030 GTK_RESPONSE_CANCEL,
1031 is_folder ?
1032 GTK_STOCK_APPLY :
1033 (is_save ?
1034 GTK_STOCK_SAVE :
1035 GTK_STOCK_OPEN),
1036 GTK_RESPONSE_ACCEPT,
1037 NULL);
1013 mStoreFilenames.win = win; 1038 mStoreFilenames.win = win;
1039 mStoreFilenames.contextName = context;
1040
1041 // get the default path for this usage context if it's been
1042 // seen before.
1043 std::map<std::string,std::string>::iterator
1044 this_path = sContextToPathMap.find(context);
1045 if (this_path != sContextToPathMap.end())
1046 {
1047 gtk_file_chooser_set_current_folder
1048 (GTK_FILE_CHOOSER(win),
1049 this_path->second.c_str());
1050 }
1014 1051
1015# if LL_X11 1052# if LL_X11
1016 // Make GTK tell the window manager to associate this 1053 // Make GTK tell the window manager to associate this
@@ -1030,33 +1067,17 @@ GtkWindow* LLFilePicker::buildFilePicker(void)
1030 } 1067 }
1031# endif //LL_X11 1068# endif //LL_X11
1032 1069
1033 g_signal_connect (G_OBJECT(win), "destroy", 1070 g_signal_connect (GTK_FILE_CHOOSER(win),
1034 G_CALLBACK(gtk_main_quit), NULL); 1071 "response",
1035 1072 G_CALLBACK(chooser_responder),
1036 // on 'ok', grab the file selection list
1037 g_signal_connect (GTK_FILE_SELECTION(win)->ok_button,
1038 "clicked",
1039 G_CALLBACK(store_filenames),
1040 &mStoreFilenames); 1073 &mStoreFilenames);
1041 1074
1042 // both 'ok' and 'cancel' will end the dialog
1043 g_signal_connect_swapped (G_OBJECT(GTK_FILE_SELECTION(win)->
1044 ok_button),
1045 "clicked",
1046 G_CALLBACK(gtk_widget_destroy),
1047 G_OBJECT(win));
1048 g_signal_connect_swapped (G_OBJECT(GTK_FILE_SELECTION(win)->
1049 cancel_button),
1050 "clicked",
1051 G_CALLBACK(gtk_widget_destroy),
1052 G_OBJECT(win));
1053
1054 gtk_file_selection_show_fileop_buttons(GTK_FILE_SELECTION(win));
1055 gtk_file_selection_set_select_multiple(GTK_FILE_SELECTION(win),
1056 FALSE);
1057
1058 gtk_window_set_modal(GTK_WINDOW(win), TRUE); 1075 gtk_window_set_modal(GTK_WINDOW(win), TRUE);
1059 1076
1077 /* GTK 2.6: if (is_folder)
1078 gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(win),
1079 TRUE); */
1080
1060 return GTK_WINDOW(win); 1081 return GTK_WINDOW(win);
1061 } 1082 }
1062 else 1083 else
@@ -1065,6 +1086,65 @@ GtkWindow* LLFilePicker::buildFilePicker(void)
1065 } 1086 }
1066} 1087}
1067 1088
1089static void add_common_filters_to_gtkchooser(GtkFileFilter *gfilter,
1090 GtkWindow *picker,
1091 std::string filtername)
1092{
1093 gtk_file_filter_set_name(gfilter, filtername.c_str());
1094 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker),
1095 gfilter);
1096 GtkFileFilter *allfilter = gtk_file_filter_new();
1097 gtk_file_filter_add_pattern(allfilter, "*");
1098 gtk_file_filter_set_name(allfilter, "All Files");
1099 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker), allfilter);
1100 gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(picker), gfilter);
1101}
1102
1103static std::string add_simple_pattern_filter_to_gtkchooser(GtkWindow *picker,
1104 std::string pattern,
1105 std::string filtername)
1106{
1107 GtkFileFilter *gfilter = gtk_file_filter_new();
1108 gtk_file_filter_add_pattern(gfilter, pattern.c_str());
1109 add_common_filters_to_gtkchooser(gfilter, picker, filtername);
1110 return filtername;
1111}
1112
1113static std::string add_simple_mime_filter_to_gtkchooser(GtkWindow *picker,
1114 std::string mime,
1115 std::string filtername)
1116{
1117 GtkFileFilter *gfilter = gtk_file_filter_new();
1118 gtk_file_filter_add_mime_type(gfilter, mime.c_str());
1119 add_common_filters_to_gtkchooser(gfilter, picker, filtername);
1120 return filtername;
1121}
1122
1123static std::string add_wav_filter_to_gtkchooser(GtkWindow *picker)
1124{
1125 return add_simple_mime_filter_to_gtkchooser(picker, "audio/x-wav",
1126 "Sounds (*.wav)");
1127}
1128
1129static std::string add_bvh_filter_to_gtkchooser(GtkWindow *picker)
1130{
1131 return add_simple_pattern_filter_to_gtkchooser(picker, "*.bvh",
1132 "Animations (*.bvh)");
1133}
1134
1135static std::string add_imageload_filter_to_gtkchooser(GtkWindow *picker)
1136{
1137 GtkFileFilter *gfilter = gtk_file_filter_new();
1138 gtk_file_filter_add_pattern(gfilter, "*.tga");
1139 gtk_file_filter_add_mime_type(gfilter, "image/jpeg");
1140 gtk_file_filter_add_mime_type(gfilter, "image/png");
1141 gtk_file_filter_add_mime_type(gfilter, "image/bmp");
1142 std::string filtername = "Images (*.tga; *.bmp; *.jpg; *.png)";
1143 add_common_filters_to_gtkchooser(gfilter, picker, filtername);
1144 return filtername;
1145}
1146
1147
1068BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const char* filename ) 1148BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const char* filename )
1069{ 1149{
1070 BOOL rtn = FALSE; 1150 BOOL rtn = FALSE;
@@ -1072,7 +1152,7 @@ BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const char* filename )
1072 gViewerWindow->mWindow->beforeDialog(); 1152 gViewerWindow->mWindow->beforeDialog();
1073 1153
1074 reset(); 1154 reset();
1075 GtkWindow* picker = buildFilePicker(); 1155 GtkWindow* picker = buildFilePicker(true, false, "savefile");
1076 1156
1077 if (picker) 1157 if (picker)
1078 { 1158 {
@@ -1082,36 +1162,45 @@ BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const char* filename )
1082 switch (filter) 1162 switch (filter)
1083 { 1163 {
1084 case FFSAVE_WAV: 1164 case FFSAVE_WAV:
1085 caption += "Sounds (*.wav)"; 1165 caption += add_wav_filter_to_gtkchooser(picker);
1086 suggest_ext += ".wav"; 1166 suggest_ext = ".wav";
1087 break; 1167 break;
1088 case FFSAVE_TGA: 1168 case FFSAVE_TGA:
1089 caption += "Targa Images (*.tga)"; 1169 caption += add_simple_pattern_filter_to_gtkchooser
1090 suggest_ext += ".tga"; 1170 (picker, "*.tga", "Targa Images (*.tga)");
1171 suggest_ext = ".tga";
1091 break; 1172 break;
1092 case FFSAVE_BMP: 1173 case FFSAVE_BMP:
1093 caption += "Bitmap Images (*.bmp)"; 1174 caption += add_simple_mime_filter_to_gtkchooser
1094 suggest_ext += ".bmp"; 1175 (picker, "image/bmp", "Bitmap Images (*.bmp)");
1176 suggest_ext = ".bmp";
1095 break; 1177 break;
1096 case FFSAVE_AVI: 1178 case FFSAVE_AVI:
1097 caption += "AVI Movie File (*.avi)"; 1179 caption += add_simple_mime_filter_to_gtkchooser
1098 suggest_ext += ".avi"; 1180 (picker, "video/x-msvideo",
1181 "AVI Movie File (*.avi)");
1182 suggest_ext = ".avi";
1099 break; 1183 break;
1100 case FFSAVE_ANIM: 1184 case FFSAVE_ANIM:
1101 caption += "XAF Anim File (*.xaf)"; 1185 caption += add_simple_pattern_filter_to_gtkchooser
1102 suggest_ext += ".xaf"; 1186 (picker, "*.xaf", "XAF Anim File (*.xaf)");
1187 suggest_ext = ".xaf";
1103 break; 1188 break;
1104 case FFSAVE_XML: 1189 case FFSAVE_XML:
1105 caption += "XML File (*.xml)"; 1190 caption += add_simple_pattern_filter_to_gtkchooser
1106 suggest_ext += ".xml"; 1191 (picker, "*.xml", "XML File (*.xml)");
1192 suggest_ext = ".xml";
1107 break; 1193 break;
1108 case FFSAVE_RAW: 1194 case FFSAVE_RAW:
1109 caption += "RAW File (*.raw)"; 1195 caption += add_simple_pattern_filter_to_gtkchooser
1110 suggest_ext += ".raw"; 1196 (picker, "*.raw", "RAW File (*.raw)");
1197 suggest_ext = ".raw";
1111 break; 1198 break;
1112 case FFSAVE_J2C: 1199 case FFSAVE_J2C:
1113 caption += "Compressed Images (*.j2c)"; 1200 caption += add_simple_mime_filter_to_gtkchooser
1114 suggest_ext += ".j2c"; 1201 (picker, "images/jp2",
1202 "Compressed Images (*.j2c)");
1203 suggest_ext = ".j2c";
1115 break; 1204 break;
1116 default:; 1205 default:;
1117 break; 1206 break;
@@ -1123,27 +1212,19 @@ BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const char* filename )
1123 { 1212 {
1124 suggest_name += suggest_ext; 1213 suggest_name += suggest_ext;
1125 1214
1126 gtk_file_selection_set_filename 1215 gtk_file_chooser_set_current_name
1127 (GTK_FILE_SELECTION(picker), 1216 (GTK_FILE_CHOOSER(picker),
1128 g_filename_from_utf8(suggest_name.c_str(), 1217 suggest_name.c_str());
1129 -1, NULL,
1130 NULL,
1131 NULL));
1132 gtk_editable_select_region(GTK_EDITABLE(GTK_FILE_SELECTION(picker)->selection_entry), 0, suggest_name.length() - suggest_ext.length() );
1133 } 1218 }
1134 else 1219 else
1135 { 1220 {
1136 gtk_file_selection_set_filename 1221 gtk_file_chooser_set_current_name
1137 (GTK_FILE_SELECTION(picker), 1222 (GTK_FILE_CHOOSER(picker), filename);
1138 g_filename_from_utf8(filename,
1139 -1, NULL,
1140 NULL,
1141 NULL));
1142 gtk_editable_select_region(GTK_EDITABLE(GTK_FILE_SELECTION(picker)->selection_entry), 0, -1 );
1143 } 1223 }
1144 1224
1145 gtk_widget_show_all(GTK_WIDGET(picker)); 1225 gtk_widget_show_all(GTK_WIDGET(picker));
1146 gtk_main(); 1226 gtk_main();
1227
1147 rtn = (mStoreFilenames.fileVector.size() == 1); 1228 rtn = (mStoreFilenames.fileVector.size() == 1);
1148 } 1229 }
1149 1230
@@ -1159,27 +1240,34 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter )
1159 gViewerWindow->mWindow->beforeDialog(); 1240 gViewerWindow->mWindow->beforeDialog();
1160 1241
1161 reset(); 1242 reset();
1162 GtkWindow* picker = buildFilePicker(); 1243 GtkWindow* picker = buildFilePicker(false, false, "openfile");
1163 1244
1164 if (picker) 1245 if (picker)
1165 { 1246 {
1166 std::string caption = "Load "; 1247 std::string caption = "Load ";
1248 std::string filtername = "";
1167 switch (filter) 1249 switch (filter)
1168 { 1250 {
1169 case FFLOAD_WAV: 1251 case FFLOAD_WAV:
1170 caption += "Sounds (*.wav)"; break; 1252 filtername = add_wav_filter_to_gtkchooser(picker);
1253 break;
1171 case FFLOAD_ANIM: 1254 case FFLOAD_ANIM:
1172 caption += "Animations (*.bvh)"; break; 1255 filtername = add_bvh_filter_to_gtkchooser(picker);
1256 break;
1173 case FFLOAD_IMAGE: 1257 case FFLOAD_IMAGE:
1174 caption += "Images (*.tga; *.bmp; *.jpg; *.jpeg; *.png)"; break; 1258 filtername = add_imageload_filter_to_gtkchooser(picker);
1259 break;
1175 default:; 1260 default:;
1176 break; 1261 break;
1177 } 1262 }
1263
1264 caption += filtername;
1178 1265
1179 gtk_window_set_title(GTK_WINDOW(picker), caption.c_str()); 1266 gtk_window_set_title(GTK_WINDOW(picker), caption.c_str());
1180 1267
1181 gtk_widget_show_all(GTK_WIDGET(picker)); 1268 gtk_widget_show_all(GTK_WIDGET(picker));
1182 gtk_main(); 1269 gtk_main();
1270
1183 rtn = (mStoreFilenames.fileVector.size() == 1); 1271 rtn = (mStoreFilenames.fileVector.size() == 1);
1184 } 1272 }
1185 1273
@@ -1195,12 +1283,12 @@ BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter )
1195 gViewerWindow->mWindow->beforeDialog(); 1283 gViewerWindow->mWindow->beforeDialog();
1196 1284
1197 reset(); 1285 reset();
1198 GtkWindow* picker = buildFilePicker(); 1286 GtkWindow* picker = buildFilePicker(false, false, "openfile");
1199 1287
1200 if (picker) 1288 if (picker)
1201 { 1289 {
1202 gtk_file_selection_set_select_multiple(GTK_FILE_SELECTION(picker), 1290 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER(picker),
1203 TRUE); 1291 TRUE);
1204 1292
1205 gtk_window_set_title(GTK_WINDOW(picker), "Load Files"); 1293 gtk_window_set_title(GTK_WINDOW(picker), "Load Files");
1206 1294
@@ -1241,7 +1329,8 @@ const char* LLFilePicker::getDirname()
1241 const char* fullpath = mStoreFilenames.fileVector[index].c_str(); 1329 const char* fullpath = mStoreFilenames.fileVector[index].c_str();
1242 const char* finalpart = NULL; 1330 const char* finalpart = NULL;
1243 const char* thispart = fullpath; 1331 const char* thispart = fullpath;
1244 // walk through the string looking for the final dirsep, i.e. / 1332 // (Hmm, is the strstr of dirsep UTF-8-correct? Yes, reckon.)
1333 // Walk through the string looking for the final dirsep, i.e. /
1245 do 1334 do
1246 { 1335 {
1247 thispart = strstr(thispart, dirsep); 1336 thispart = strstr(thispart, dirsep);