aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llfilepicker.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-09-06 18:24:57 -0500
committerJacek Antonelli2008-09-06 18:25:07 -0500
commit798d367d54a6c6379ad355bd8345fa40e31e7fe9 (patch)
tree1921f1708cd0240648c97bc02df2c2ab5f2fc41e /linden/indra/newview/llfilepicker.cpp
parentSecond Life viewer sources 1.20.15 (diff)
downloadmeta-impy-798d367d54a6c6379ad355bd8345fa40e31e7fe9.zip
meta-impy-798d367d54a6c6379ad355bd8345fa40e31e7fe9.tar.gz
meta-impy-798d367d54a6c6379ad355bd8345fa40e31e7fe9.tar.bz2
meta-impy-798d367d54a6c6379ad355bd8345fa40e31e7fe9.tar.xz
Second Life viewer sources 1.21.0-RC
Diffstat (limited to 'linden/indra/newview/llfilepicker.cpp')
-rw-r--r--linden/indra/newview/llfilepicker.cpp563
1 files changed, 188 insertions, 375 deletions
diff --git a/linden/indra/newview/llfilepicker.cpp b/linden/indra/newview/llfilepicker.cpp
index 1be1199..bbcfba6 100644
--- a/linden/indra/newview/llfilepicker.cpp
+++ b/linden/indra/newview/llfilepicker.cpp
@@ -63,12 +63,14 @@ LLFilePicker LLFilePicker::sInstance;
63// 63//
64// Implementation 64// Implementation
65// 65//
66#if LL_WINDOWS 66LLFilePicker::LLFilePicker()
67 : mCurrentFile(0),
68 mLocked(FALSE)
67 69
68LLFilePicker::LLFilePicker()
69{ 70{
70 reset(); 71 reset();
71 72
73#if LL_WINDOWS
72 mOFN.lStructSize = sizeof(OPENFILENAMEW); 74 mOFN.lStructSize = sizeof(OPENFILENAMEW);
73 mOFN.hwndOwner = NULL; // Set later 75 mOFN.hwndOwner = NULL; // Set later
74 mOFN.hInstance = NULL; 76 mOFN.hInstance = NULL;
@@ -87,6 +89,16 @@ LLFilePicker::LLFilePicker()
87 mOFN.lCustData = 0L; 89 mOFN.lCustData = 0L;
88 mOFN.lpfnHook = NULL; 90 mOFN.lpfnHook = NULL;
89 mOFN.lpTemplateName = NULL; 91 mOFN.lpTemplateName = NULL;
92#endif
93
94#if LL_DARWIN
95 memset(&mNavOptions, 0, sizeof(mNavOptions));
96 OSStatus error = NavGetDefaultDialogCreationOptions(&mNavOptions);
97 if (error == noErr)
98 {
99 mNavOptions.modality = kWindowModalityAppModal;
100 }
101#endif
90} 102}
91 103
92LLFilePicker::~LLFilePicker() 104LLFilePicker::~LLFilePicker()
@@ -94,6 +106,48 @@ LLFilePicker::~LLFilePicker()
94 // nothing 106 // nothing
95} 107}
96 108
109
110const std::string LLFilePicker::getFirstFile()
111{
112 mCurrentFile = 0;
113 return getNextFile();
114}
115
116const std::string LLFilePicker::getNextFile()
117{
118 if (mCurrentFile >= (S32)mFiles.size())
119 {
120 mLocked = FALSE;
121 return std::string();
122 }
123 else
124 {
125 return mFiles[mCurrentFile++];
126 }
127}
128
129const std::string LLFilePicker::getCurFile()
130{
131 if (mCurrentFile >= (S32)mFiles.size())
132 {
133 mLocked = FALSE;
134 return std::string();
135 }
136 else
137 {
138 return mFiles[mCurrentFile];
139 }
140}
141
142void LLFilePicker::reset()
143{
144 mLocked = FALSE;
145 mFiles.clear();
146 mCurrentFile = 0;
147}
148
149#if LL_WINDOWS
150
97BOOL LLFilePicker::setupFilter(ELoadFilter filter) 151BOOL LLFilePicker::setupFilter(ELoadFilter filter)
98{ 152{
99 BOOL res = TRUE; 153 BOOL res = TRUE;
@@ -150,7 +204,6 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter)
150 return FALSE; 204 return FALSE;
151 } 205 }
152 BOOL success = FALSE; 206 BOOL success = FALSE;
153 mMultiFile = FALSE;
154 207
155 // don't provide default file selection 208 // don't provide default file selection
156 mFilesW[0] = '\0'; 209 mFilesW[0] = '\0';
@@ -165,13 +218,15 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter)
165 218
166 // Modal, so pause agent 219 // Modal, so pause agent
167 send_agent_pause(); 220 send_agent_pause();
221
222 reset();
223
168 // NOTA BENE: hitting the file dialog triggers a window focus event, destroying the selection manager!! 224 // NOTA BENE: hitting the file dialog triggers a window focus event, destroying the selection manager!!
169 success = GetOpenFileName(&mOFN); 225 success = GetOpenFileName(&mOFN);
170 if (success) 226 if (success)
171 { 227 {
172 LLString tstr = utf16str_to_utf8str(llutf16string(mFilesW)); 228 std::string filename = utf16str_to_utf8str(llutf16string(mFilesW));
173 memcpy(mFiles, tstr.c_str(), tstr.size()+1); /*Flawfinder: ignore*/ 229 mFiles.push_back(filename);
174 mCurrentFile = mFiles;
175 } 230 }
176 send_agent_resume(); 231 send_agent_resume();
177 232
@@ -187,7 +242,6 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter)
187 return FALSE; 242 return FALSE;
188 } 243 }
189 BOOL success = FALSE; 244 BOOL success = FALSE;
190 mMultiFile = FALSE;
191 245
192 // don't provide default file selection 246 // don't provide default file selection
193 mFilesW[0] = '\0'; 247 mFilesW[0] = '\0';
@@ -200,6 +254,8 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter)
200 OFN_EXPLORER | OFN_ALLOWMULTISELECT; 254 OFN_EXPLORER | OFN_ALLOWMULTISELECT;
201 255
202 setupFilter(filter); 256 setupFilter(filter);
257
258 reset();
203 259
204 // Modal, so pause agent 260 // Modal, so pause agent
205 send_agent_pause(); 261 send_agent_pause();
@@ -212,31 +268,26 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter)
212 // lengths. 268 // lengths.
213 if( wcslen(mOFN.lpstrFile) > mOFN.nFileOffset ) /*Flawfinder: ignore*/ 269 if( wcslen(mOFN.lpstrFile) > mOFN.nFileOffset ) /*Flawfinder: ignore*/
214 { 270 {
215 mMultiFile = FALSE; 271 std::string filename = utf16str_to_utf8str(llutf16string(mFilesW));
216 mCurrentFile = mFiles; 272 mFiles.push_back(filename);
217 LLString tstr = utf16str_to_utf8str(llutf16string(mFilesW));
218 memcpy(mFiles, tstr.c_str(), tstr.size()+1); /*Flawfinder: ignore*/
219
220 mCurrentFile = &mFiles[mOFN.nFileOffset];
221 } 273 }
222 else 274 else
223 { 275 {
224 mMultiFile = TRUE;
225 mCurrentFile = 0;
226 mLocked = TRUE; 276 mLocked = TRUE;
227 WCHAR* tptrw = mFilesW; 277 WCHAR* tptrw = mFilesW;
228 char* tptr = mFiles; 278 std::string dirname;
229 memset( mFiles, 0, FILENAME_BUFFER_SIZE );
230 while(1) 279 while(1)
231 { 280 {
232 if (*tptrw == 0 && *(tptrw+1) == 0) // double '\0' 281 if (*tptrw == 0 && *(tptrw+1) == 0) // double '\0'
233 break; 282 break;
234 if (*tptrw == 0 && !mCurrentFile) 283 if (*tptrw == 0)
235 mCurrentFile = tptr+1; 284 tptrw++; // shouldn't happen?
236 S32 tlen16,tlen8; 285 std::string filename = utf16str_to_utf8str(llutf16string(tptrw));
237 tlen16 = utf16chars_to_utf8chars(tptrw, tptr, &tlen8); 286 if (dirname.empty())
238 tptrw += tlen16; 287 dirname = filename + "\\";
239 tptr += tlen8; 288 else
289 mFiles.push_back(dirname + filename);
290 tptrw += filename.size();
240 } 291 }
241 } 292 }
242 } 293 }
@@ -247,17 +298,16 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter)
247 return success; 298 return success;
248} 299}
249 300
250BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const char* filename) 301BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename)
251{ 302{
252 if( mLocked ) 303 if( mLocked )
253 { 304 {
254 return FALSE; 305 return FALSE;
255 } 306 }
256 BOOL success = FALSE; 307 BOOL success = FALSE;
257 mMultiFile = FALSE;
258 308
259 mOFN.lpstrFile = mFilesW; 309 mOFN.lpstrFile = mFilesW;
260 if (filename) 310 if (!filename.empty())
261 { 311 {
262 llutf16string tstring = utf8str_to_utf16str(filename); 312 llutf16string tstring = utf8str_to_utf16str(filename);
263 wcsncpy(mFilesW, tstring.c_str(), FILENAME_BUFFER_SIZE); } /*Flawfinder: ignore*/ 313 wcsncpy(mFilesW, tstring.c_str(), FILENAME_BUFFER_SIZE); } /*Flawfinder: ignore*/
@@ -278,7 +328,7 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const char* filename)
278 L"\0"; 328 L"\0";
279 break; 329 break;
280 case FFSAVE_WAV: 330 case FFSAVE_WAV:
281 if (!filename) 331 if (filename.empty())
282 { 332 {
283 wcsncpy( mFilesW,L"untitled.wav", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ 333 wcsncpy( mFilesW,L"untitled.wav", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
284 } 334 }
@@ -288,7 +338,7 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const char* filename)
288 L"\0"; 338 L"\0";
289 break; 339 break;
290 case FFSAVE_TGA: 340 case FFSAVE_TGA:
291 if (!filename) 341 if (filename.empty())
292 { 342 {
293 wcsncpy( mFilesW,L"untitled.tga", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ 343 wcsncpy( mFilesW,L"untitled.tga", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
294 } 344 }
@@ -298,7 +348,7 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const char* filename)
298 L"\0"; 348 L"\0";
299 break; 349 break;
300 case FFSAVE_BMP: 350 case FFSAVE_BMP:
301 if (!filename) 351 if (filename.empty())
302 { 352 {
303 wcsncpy( mFilesW,L"untitled.bmp", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ 353 wcsncpy( mFilesW,L"untitled.bmp", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
304 } 354 }
@@ -307,8 +357,28 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const char* filename)
307 L"Bitmap Images (*.bmp)\0*.bmp\0" \ 357 L"Bitmap Images (*.bmp)\0*.bmp\0" \
308 L"\0"; 358 L"\0";
309 break; 359 break;
360 case FFSAVE_PNG:
361 if (filename.empty())
362 {
363 wcsncpy( mFilesW,L"untitled.png", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
364 }
365 mOFN.lpstrDefExt = L"png";
366 mOFN.lpstrFilter =
367 L"PNG Images (*.png)\0*.png\0" \
368 L"\0";
369 break;
370 case FFSAVE_JPEG:
371 if (filename.empty())
372 {
373 wcsncpy( mFilesW,L"untitled.jpeg", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
374 }
375 mOFN.lpstrDefExt = L"jpeg";
376 mOFN.lpstrFilter =
377 L"JPEG Images (*.jpeg)\0*.jpeg\0" \
378 L"\0";
379 break;
310 case FFSAVE_AVI: 380 case FFSAVE_AVI:
311 if (!filename) 381 if (filename.empty())
312 { 382 {
313 wcsncpy( mFilesW,L"untitled.avi", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ 383 wcsncpy( mFilesW,L"untitled.avi", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
314 } 384 }
@@ -318,7 +388,7 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const char* filename)
318 L"\0"; 388 L"\0";
319 break; 389 break;
320 case FFSAVE_ANIM: 390 case FFSAVE_ANIM:
321 if (!filename) 391 if (filename.empty())
322 { 392 {
323 wcsncpy( mFilesW,L"untitled.xaf", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ 393 wcsncpy( mFilesW,L"untitled.xaf", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
324 } 394 }
@@ -329,7 +399,7 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const char* filename)
329 break; 399 break;
330#ifdef _CORY_TESTING 400#ifdef _CORY_TESTING
331 case FFSAVE_GEOMETRY: 401 case FFSAVE_GEOMETRY:
332 if (!filename) 402 if (filename.empty())
333 { 403 {
334 wcsncpy( mFilesW,L"untitled.slg", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ 404 wcsncpy( mFilesW,L"untitled.slg", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
335 } 405 }
@@ -340,7 +410,7 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const char* filename)
340 break; 410 break;
341#endif 411#endif
342 case FFSAVE_XML: 412 case FFSAVE_XML:
343 if (!filename) 413 if (filename.empty())
344 { 414 {
345 wcsncpy( mFilesW,L"untitled.xml", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ 415 wcsncpy( mFilesW,L"untitled.xml", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
346 } 416 }
@@ -351,7 +421,7 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const char* filename)
351 L"\0"; 421 L"\0";
352 break; 422 break;
353 case FFSAVE_COLLADA: 423 case FFSAVE_COLLADA:
354 if (!filename) 424 if (filename.empty())
355 { 425 {
356 wcsncpy( mFilesW,L"untitled.collada", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ 426 wcsncpy( mFilesW,L"untitled.collada", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
357 } 427 }
@@ -361,7 +431,7 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const char* filename)
361 L"\0"; 431 L"\0";
362 break; 432 break;
363 case FFSAVE_RAW: 433 case FFSAVE_RAW:
364 if (!filename) 434 if (filename.empty())
365 { 435 {
366 wcsncpy( mFilesW,L"untitled.raw", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ 436 wcsncpy( mFilesW,L"untitled.raw", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
367 } 437 }
@@ -370,7 +440,7 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const char* filename)
370 L"\0"; 440 L"\0";
371 break; 441 break;
372 case FFSAVE_J2C: 442 case FFSAVE_J2C:
373 if (!filename) 443 if (filename.empty())
374 { 444 {
375 wcsncpy( mFilesW,L"untitled.j2c", FILENAME_BUFFER_SIZE); 445 wcsncpy( mFilesW,L"untitled.j2c", FILENAME_BUFFER_SIZE);
376 } 446 }
@@ -387,6 +457,8 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const char* filename)
387 mOFN.nMaxFile = SINGLE_FILENAME_BUFFER_SIZE; 457 mOFN.nMaxFile = SINGLE_FILENAME_BUFFER_SIZE;
388 mOFN.Flags = OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST; 458 mOFN.Flags = OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST;
389 459
460 reset();
461
390 // Modal, so pause agent 462 // Modal, so pause agent
391 send_agent_pause(); 463 send_agent_pause();
392 { 464 {
@@ -394,9 +466,8 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const char* filename)
394 success = GetSaveFileName(&mOFN); 466 success = GetSaveFileName(&mOFN);
395 if (success) 467 if (success)
396 { 468 {
397 LLString tstr = utf16str_to_utf8str(llutf16string(mFilesW)); 469 std::string filename = utf16str_to_utf8str(llutf16string(mFilesW));
398 memcpy(mFiles, tstr.c_str(), tstr.size()+1); /*Flawfinder: ignore*/ 470 mFiles.push_back(filename);
399 mCurrentFile = mFiles;
400 } 471 }
401 gKeyboard->resetKeys(); 472 gKeyboard->resetKeys();
402 } 473 }
@@ -407,84 +478,8 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const char* filename)
407 return success; 478 return success;
408} 479}
409 480
410const char* LLFilePicker::getFirstFile()
411{
412 if(mMultiFile)
413 {
414 buildFilename();
415 return mFilename;
416 }
417 return mFiles;
418}
419
420const char* LLFilePicker::getNextFile()
421{
422 if(mMultiFile)
423 {
424 mCurrentFile += strlen(mCurrentFile) + 1; /*Flawfinder: ignore*/
425 if( '\0' != mCurrentFile[0] )
426 {
427 buildFilename();
428 return mFilename;
429 }
430 else
431 {
432 mLocked = FALSE;
433 }
434 }
435 return NULL;
436}
437
438const char* LLFilePicker::getDirname()
439{
440 if( '\0' != mCurrentFile[0] )
441 {
442 return mCurrentFile;
443 }
444 return NULL;
445}
446
447void LLFilePicker::reset()
448{
449 mLocked = FALSE;
450 memset( mFiles, 0, FILENAME_BUFFER_SIZE );
451 memset( mFilename, 0, LL_MAX_PATH );
452 mCurrentFile = mFiles;
453}
454
455void LLFilePicker::buildFilename( void )
456{
457 strncpy( mFilename, mFiles, LL_MAX_PATH );
458 mFilename[LL_MAX_PATH-1] = '\0'; // stupid strncpy
459 S32 len = strlen( mFilename );
460
461 strncat(mFilename,gDirUtilp->getDirDelimiter().c_str(), sizeof(mFilename)-len+1); /*Flawfinder: ignore*/
462 len += strlen(gDirUtilp->getDirDelimiter().c_str()); /*Flawfinder: ignore*/
463
464// mFilename[len++] = '\\';
465 LLString::copy( mFilename + len, mCurrentFile, LL_MAX_PATH - len );
466}
467
468#elif LL_DARWIN 481#elif LL_DARWIN
469 482
470LLFilePicker::LLFilePicker()
471{
472 reset();
473
474 memset(&mNavOptions, 0, sizeof(mNavOptions));
475 OSStatus error = NavGetDefaultDialogCreationOptions(&mNavOptions);
476 if (error == noErr)
477 {
478 mNavOptions.modality = kWindowModalityAppModal;
479 }
480 mFileIndex = 0;
481}
482
483LLFilePicker::~LLFilePicker()
484{
485 // nothing
486}
487
488Boolean LLFilePicker::navOpenFilterProc(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode) 483Boolean LLFilePicker::navOpenFilterProc(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode)
489{ 484{
490 Boolean result = true; 485 Boolean result = true;
@@ -589,8 +584,6 @@ OSStatus LLFilePicker::doNavChooseDialog(ELoadFilter filter)
589 NavReplyRecord navReply; 584 NavReplyRecord navReply;
590 585
591 memset(&navReply, 0, sizeof(navReply)); 586 memset(&navReply, 0, sizeof(navReply));
592 mFiles[0] = '\0';
593 mFileVector.clear();
594 587
595 // NOTE: we are passing the address of a local variable here. 588 // NOTE: we are passing the address of a local variable here.
596 // This is fine, because the object this call creates will exist for less than the lifetime of this function. 589 // This is fine, because the object this call creates will exist for less than the lifetime of this function.
@@ -632,22 +625,20 @@ OSStatus LLFilePicker::doNavChooseDialog(ELoadFilter filter)
632 error = FSRefMakePath(&fsRef, (UInt8*) path, sizeof(path)); 625 error = FSRefMakePath(&fsRef, (UInt8*) path, sizeof(path));
633 626
634 if (error == noErr) 627 if (error == noErr)
635 mFileVector.push_back(LLString(path)); 628 mFiles.push_back(std::string(path));
636 } 629 }
637 } 630 }
638 631
639 return error; 632 return error;
640} 633}
641 634
642OSStatus LLFilePicker::doNavSaveDialog(ESaveFilter filter, const char* filename) 635OSStatus LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filename)
643{ 636{
644 OSStatus error = noErr; 637 OSStatus error = noErr;
645 NavDialogRef navRef = NULL; 638 NavDialogRef navRef = NULL;
646 NavReplyRecord navReply; 639 NavReplyRecord navReply;
647 640
648 memset(&navReply, 0, sizeof(navReply)); 641 memset(&navReply, 0, sizeof(navReply));
649 mFiles[0] = '\0';
650 mFileVector.clear();
651 642
652 // Setup the type, creator, and extension 643 // Setup the type, creator, and extension
653 OSType type, creator; 644 OSType type, creator;
@@ -671,7 +662,16 @@ OSStatus LLFilePicker::doNavSaveDialog(ESaveFilter filter, const char* filename)
671 creator = 'prvw'; 662 creator = 'prvw';
672 extension = CFSTR(".bmp"); 663 extension = CFSTR(".bmp");
673 break; 664 break;
674 665 case FFSAVE_JPEG:
666 type = 'JPEG';
667 creator = 'prvw';
668 extension = CFSTR(".jpeg");
669 break;
670 case FFSAVE_PNG:
671 type = 'PNG ';
672 creator = 'prvw';
673 extension = CFSTR(".png");
674 break;
675 case FFSAVE_AVI: 675 case FFSAVE_AVI:
676 type = '\?\?\?\?'; 676 type = '\?\?\?\?';
677 creator = '\?\?\?\?'; 677 creator = '\?\?\?\?';
@@ -719,8 +719,8 @@ OSStatus LLFilePicker::doNavSaveDialog(ESaveFilter filter, const char* filename)
719 bool hasExtension = true; 719 bool hasExtension = true;
720 720
721 // Create a CFString of the initial file name 721 // Create a CFString of the initial file name
722 if (filename) 722 if (!filename.empty())
723 nameString = CFStringCreateWithCString(NULL, filename, kCFStringEncodingUTF8); 723 nameString = CFStringCreateWithCString(NULL, filename.c_str(), kCFStringEncodingUTF8);
724 else 724 else
725 nameString = CFSTR("Untitled"); 725 nameString = CFSTR("Untitled");
726 726
@@ -786,7 +786,7 @@ OSStatus LLFilePicker::doNavSaveDialog(ESaveFilter filter, const char* filename)
786 { 786 {
787 if (CFStringGetCString(navReply.saveFileName, newFileName, sizeof(newFileName), kCFStringEncodingUTF8)) 787 if (CFStringGetCString(navReply.saveFileName, newFileName, sizeof(newFileName), kCFStringEncodingUTF8))
788 { 788 {
789 mFileVector.push_back(LLString(path) + LLString("/") + LLString(newFileName)); 789 mFiles.push_back(std::string(path) + "/" + std::string(newFileName));
790 } 790 }
791 else 791 else
792 { 792 {
@@ -806,13 +806,15 @@ OSStatus LLFilePicker::doNavSaveDialog(ESaveFilter filter, const char* filename)
806 806
807BOOL LLFilePicker::getOpenFile(ELoadFilter filter) 807BOOL LLFilePicker::getOpenFile(ELoadFilter filter)
808{ 808{
809 if( mLocked ) return FALSE; 809 if( mLocked )
810 mMultiFile = FALSE; 810 return FALSE;
811
811 BOOL success = FALSE; 812 BOOL success = FALSE;
812 813
813 OSStatus error = noErr; 814 OSStatus error = noErr;
814 815
815 mFileVector.clear(); 816 reset();
817
816 mNavOptions.optionFlags &= ~kNavAllowMultipleFiles; 818 mNavOptions.optionFlags &= ~kNavAllowMultipleFiles;
817 // Modal, so pause agent 819 // Modal, so pause agent
818 send_agent_pause(); 820 send_agent_pause();
@@ -822,7 +824,7 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter)
822 send_agent_resume(); 824 send_agent_resume();
823 if (error == noErr) 825 if (error == noErr)
824 { 826 {
825 if (mFileVector.size()) 827 if (mFiles.size())
826 success = true; 828 success = true;
827 } 829 }
828 830
@@ -833,13 +835,15 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter)
833 835
834BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter) 836BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter)
835{ 837{
836 if( mLocked ) return FALSE; 838 if( mLocked )
837 mMultiFile = TRUE; 839 return FALSE;
840
838 BOOL success = FALSE; 841 BOOL success = FALSE;
839 842
840 OSStatus error = noErr; 843 OSStatus error = noErr;
844
845 reset();
841 846
842 mFileVector.clear();
843 mNavOptions.optionFlags |= kNavAllowMultipleFiles; 847 mNavOptions.optionFlags |= kNavAllowMultipleFiles;
844 // Modal, so pause agent 848 // Modal, so pause agent
845 send_agent_pause(); 849 send_agent_pause();
@@ -849,9 +853,9 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter)
849 send_agent_resume(); 853 send_agent_resume();
850 if (error == noErr) 854 if (error == noErr)
851 { 855 {
852 if (mFileVector.size()) 856 if (mFiles.size())
853 success = true; 857 success = true;
854 if (mFileVector.size() > 1) 858 if (mFiles.size() > 1)
855 mLocked = TRUE; 859 mLocked = TRUE;
856 } 860 }
857 861
@@ -860,38 +864,15 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter)
860 return success; 864 return success;
861} 865}
862 866
863void LLFilePicker::getFilePath(SInt32 index) 867BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename)
864{
865 mFiles[0] = 0;
866 if (mFileVector.size())
867 {
868 strncpy(mFiles, mFileVector[index].c_str(), sizeof(mFiles));
869 mFiles[sizeof(mFiles)-1] = '\0'; // stupid strncpy
870 }
871}
872
873void LLFilePicker::getFileName(SInt32 index)
874{
875 mFilename[0] = 0;
876 if (mFileVector.size())
877 {
878 char *start = strrchr(mFileVector[index].c_str(), '/');
879 if (start && ((start + 1 - mFileVector[index].c_str()) < (mFileVector[index].size())))
880 {
881 strncpy(mFilename, start + 1, sizeof(mFilename));
882 mFilename[sizeof(mFilename)-1] = '\0';// stupid strncpy
883 }
884 }
885}
886
887BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const char* filename)
888{ 868{
889 if( mLocked ) return FALSE; 869 if( mLocked )
870 return FALSE;
890 BOOL success = FALSE; 871 BOOL success = FALSE;
891 OSStatus error = noErr; 872 OSStatus error = noErr;
892 873
893 mFileVector.clear(); 874 reset();
894 mMultiFile = FALSE; 875
895 mNavOptions.optionFlags &= ~kNavAllowMultipleFiles; 876 mNavOptions.optionFlags &= ~kNavAllowMultipleFiles;
896 877
897 // Modal, so pause agent 878 // Modal, so pause agent
@@ -902,7 +883,7 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const char* filename)
902 send_agent_resume(); 883 send_agent_resume();
903 if (error == noErr) 884 if (error == noErr)
904 { 885 {
905 if (mFileVector.size()) 886 if (mFiles.size())
906 success = true; 887 success = true;
907 } 888 }
908 889
@@ -911,98 +892,38 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const char* filename)
911 return success; 892 return success;
912} 893}
913 894
914const char* LLFilePicker::getFirstFile()
915{
916 mFileIndex = 0;
917 getFilePath(mFileIndex);
918 return mFiles;
919}
920
921const char* LLFilePicker::getNextFile()
922{
923 if(mMultiFile)
924 {
925 mFileIndex++;
926 if (mFileIndex < mFileVector.size())
927 {
928 getFilePath(mFileIndex);
929 return mFiles;
930 }
931 else
932 {
933 mLocked = FALSE;
934 }
935 }
936 return NULL;
937}
938
939const char* LLFilePicker::getDirname()
940{
941 if (mFileIndex < mFileVector.size())
942 {
943 getFileName(mFileIndex);
944 return mFilename;
945 }
946 return NULL;
947}
948
949void LLFilePicker::reset()
950{
951 mLocked = FALSE;
952 memset( mFiles, 0, FILENAME_BUFFER_SIZE );
953 memset( mFilename, 0, LL_MAX_PATH );
954 mCurrentFile = mFiles;
955
956 mFileIndex = 0;
957 mFileVector.clear();
958}
959
960#elif LL_LINUX 895#elif LL_LINUX
961 896
962# if LL_GTK 897# if LL_GTK
963// This caches the previously-accessed path for a given context of the file
964// chooser, for user convenience.
965std::map <std::string, std::string> LLFilePicker::sContextToPathMap;
966
967LLFilePicker::LLFilePicker()
968{
969 reset();
970}
971
972LLFilePicker::~LLFilePicker()
973{
974}
975
976 898
977static void add_to_sfs(gpointer data, gpointer user_data) 899// static
900void LLFilePicker::add_to_selectedfiles(gpointer data, gpointer user_data)
978{ 901{
979 StoreFilenamesStruct *sfs = (StoreFilenamesStruct*) user_data; 902 LLFilePicker* picker = (LLFilePicker*) user_data;
980 gchar* filename_utf8 = g_filename_to_utf8((gchar*)data, 903 gchar* filename_utf8 = g_filename_to_utf8((gchar*)data,
981 -1, NULL, 904 -1, NULL, NULL, NULL);
982 NULL, 905 picker->mFiles.push_back(std::string(filename_utf8));
983 NULL); 906 lldebugs << "ADDED FILE " << filename_utf8 << llendl;
984 sfs->fileVector.push_back(LLString(filename_utf8));
985 g_free(filename_utf8); 907 g_free(filename_utf8);
986} 908}
987 909
988 910// static
989void chooser_responder(GtkWidget *widget, 911void LLFilePicker::chooser_responder(GtkWidget *widget, gint response, gpointer user_data)
990 gint response, 912{
991 gpointer user_data) { 913 LLFilePicker* picker = (LLFilePicker*)user_data;
992 StoreFilenamesStruct *sfs = (StoreFilenamesStruct*) user_data;
993 914
994 lldebugs << "GTK DIALOG RESPONSE " << response << llendl; 915 lldebugs << "GTK DIALOG RESPONSE " << response << llendl;
995 916
996 if (response == GTK_RESPONSE_ACCEPT) 917 if (response == GTK_RESPONSE_ACCEPT)
997 { 918 {
998 GSList *file_list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(widget)); 919 GSList *file_list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(widget));
999 g_slist_foreach(file_list, (GFunc)add_to_sfs, sfs); 920 g_slist_foreach(file_list, (GFunc)add_to_selectedfiles, user_data);
1000 g_slist_foreach(file_list, (GFunc)g_free, NULL); 921 g_slist_foreach(file_list, (GFunc)g_free, NULL);
1001 g_slist_free (file_list); 922 g_slist_free (file_list);
1002 } 923 }
1003 924
1004 // set the default path for this usage context. 925 // set the default path for this usage context.
1005 LLFilePicker::sContextToPathMap[sfs->contextName] = 926 picker->mContextToPathMap[picker->mCurContextName] =
1006 gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(widget)); 927 gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(widget));
1007 928
1008 gtk_widget_destroy(widget); 929 gtk_widget_destroy(widget);
@@ -1010,8 +931,7 @@ void chooser_responder(GtkWidget *widget,
1010} 931}
1011 932
1012 933
1013GtkWindow* LLFilePicker::buildFilePicker(bool is_save, bool is_folder, 934GtkWindow* LLFilePicker::buildFilePicker(bool is_save, bool is_folder, std::string context)
1014 std::string context)
1015{ 935{
1016 if (ll_try_gtk_init() && 936 if (ll_try_gtk_init() &&
1017 ! gViewerWindow->getWindow()->getFullscreen()) 937 ! gViewerWindow->getWindow()->getFullscreen())
@@ -1037,14 +957,13 @@ GtkWindow* LLFilePicker::buildFilePicker(bool is_save, bool is_folder,
1037 GTK_STOCK_OPEN), 957 GTK_STOCK_OPEN),
1038 GTK_RESPONSE_ACCEPT, 958 GTK_RESPONSE_ACCEPT,
1039 (gchar *)NULL); 959 (gchar *)NULL);
1040 mStoreFilenames.win = win; 960 mCurContextName = context;
1041 mStoreFilenames.contextName = context;
1042 961
1043 // get the default path for this usage context if it's been 962 // get the default path for this usage context if it's been
1044 // seen before. 963 // seen before.
1045 std::map<std::string,std::string>::iterator 964 std::map<std::string,std::string>::iterator
1046 this_path = sContextToPathMap.find(context); 965 this_path = mContextToPathMap.find(context);
1047 if (this_path != sContextToPathMap.end()) 966 if (this_path != mContextToPathMap.end())
1048 { 967 {
1049 gtk_file_chooser_set_current_folder 968 gtk_file_chooser_set_current_folder
1050 (GTK_FILE_CHOOSER(win), 969 (GTK_FILE_CHOOSER(win),
@@ -1071,8 +990,8 @@ GtkWindow* LLFilePicker::buildFilePicker(bool is_save, bool is_folder,
1071 990
1072 g_signal_connect (GTK_FILE_CHOOSER(win), 991 g_signal_connect (GTK_FILE_CHOOSER(win),
1073 "response", 992 "response",
1074 G_CALLBACK(chooser_responder), 993 G_CALLBACK(LLFilePicker::chooser_responder),
1075 &mStoreFilenames); 994 this);
1076 995
1077 gtk_window_set_modal(GTK_WINDOW(win), TRUE); 996 gtk_window_set_modal(GTK_WINDOW(win), TRUE);
1078 997
@@ -1147,13 +1066,14 @@ static std::string add_imageload_filter_to_gtkchooser(GtkWindow *picker)
1147} 1066}
1148 1067
1149 1068
1150BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const char* filename ) 1069BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename )
1151{ 1070{
1152 BOOL rtn = FALSE; 1071 BOOL rtn = FALSE;
1153 1072
1154 gViewerWindow->mWindow->beforeDialog(); 1073 gViewerWindow->mWindow->beforeDialog();
1155 1074
1156 reset(); 1075 reset();
1076
1157 GtkWindow* picker = buildFilePicker(true, false, "savefile"); 1077 GtkWindow* picker = buildFilePicker(true, false, "savefile");
1158 1078
1159 if (picker) 1079 if (picker)
@@ -1210,7 +1130,7 @@ BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const char* filename )
1210 1130
1211 gtk_window_set_title(GTK_WINDOW(picker), caption.c_str()); 1131 gtk_window_set_title(GTK_WINDOW(picker), caption.c_str());
1212 1132
1213 if (!filename) 1133 if (filename.empty())
1214 { 1134 {
1215 suggest_name += suggest_ext; 1135 suggest_name += suggest_ext;
1216 1136
@@ -1221,13 +1141,13 @@ BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const char* filename )
1221 else 1141 else
1222 { 1142 {
1223 gtk_file_chooser_set_current_name 1143 gtk_file_chooser_set_current_name
1224 (GTK_FILE_CHOOSER(picker), filename); 1144 (GTK_FILE_CHOOSER(picker), filename.c_str());
1225 } 1145 }
1226 1146
1227 gtk_widget_show_all(GTK_WIDGET(picker)); 1147 gtk_widget_show_all(GTK_WIDGET(picker));
1228 gtk_main(); 1148 gtk_main();
1229 1149
1230 rtn = (mStoreFilenames.fileVector.size() == 1); 1150 rtn = (mFiles.size() == 1);
1231 } 1151 }
1232 1152
1233 gViewerWindow->mWindow->afterDialog(); 1153 gViewerWindow->mWindow->afterDialog();
@@ -1242,6 +1162,7 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter )
1242 gViewerWindow->mWindow->beforeDialog(); 1162 gViewerWindow->mWindow->beforeDialog();
1243 1163
1244 reset(); 1164 reset();
1165
1245 GtkWindow* picker = buildFilePicker(false, false, "openfile"); 1166 GtkWindow* picker = buildFilePicker(false, false, "openfile");
1246 1167
1247 if (picker) 1168 if (picker)
@@ -1270,7 +1191,7 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter )
1270 gtk_widget_show_all(GTK_WIDGET(picker)); 1191 gtk_widget_show_all(GTK_WIDGET(picker));
1271 gtk_main(); 1192 gtk_main();
1272 1193
1273 rtn = (mStoreFilenames.fileVector.size() == 1); 1194 rtn = (mFiles.size() == 1);
1274 } 1195 }
1275 1196
1276 gViewerWindow->mWindow->afterDialog(); 1197 gViewerWindow->mWindow->afterDialog();
@@ -1285,6 +1206,7 @@ BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter )
1285 gViewerWindow->mWindow->beforeDialog(); 1206 gViewerWindow->mWindow->beforeDialog();
1286 1207
1287 reset(); 1208 reset();
1209
1288 GtkWindow* picker = buildFilePicker(false, false, "openfile"); 1210 GtkWindow* picker = buildFilePicker(false, false, "openfile");
1289 1211
1290 if (picker) 1212 if (picker)
@@ -1296,7 +1218,7 @@ BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter )
1296 1218
1297 gtk_widget_show_all(GTK_WIDGET(picker)); 1219 gtk_widget_show_all(GTK_WIDGET(picker));
1298 gtk_main(); 1220 gtk_main();
1299 rtn = !mStoreFilenames.fileVector.empty(); 1221 rtn = !mFiles.empty();
1300 } 1222 }
1301 1223
1302 gViewerWindow->mWindow->afterDialog(); 1224 gViewerWindow->mWindow->afterDialog();
@@ -1304,178 +1226,69 @@ BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter )
1304 return rtn; 1226 return rtn;
1305} 1227}
1306 1228
1307const char* LLFilePicker::getFirstFile()
1308{
1309 mNextFileIndex = 0;
1310 return getNextFile();
1311}
1312
1313const char* LLFilePicker::getNextFile()
1314{
1315 if (mStoreFilenames.fileVector.size() > mNextFileIndex)
1316 return mStoreFilenames.fileVector[mNextFileIndex++].c_str();
1317 else
1318 return NULL;
1319}
1320
1321const char* LLFilePicker::getDirname()
1322{
1323 // getDirname is badly named... it really means getBasename.
1324 S32 index = mNextFileIndex - 1; // want index before the 'next' cursor
1325 if (index >= 0 && index < (S32)mStoreFilenames.fileVector.size())
1326 {
1327 // we do this using C strings so we don't have to
1328 // convert a LLString/std::string character offset into a
1329 // byte-offset for the return (which is a C string anyway).
1330 const char* dirsep = gDirUtilp->getDirDelimiter().c_str();
1331 const char* fullpath = mStoreFilenames.fileVector[index].c_str();
1332 const char* finalpart = NULL;
1333 const char* thispart = fullpath;
1334 // (Hmm, is the strstr of dirsep UTF-8-correct? Yes, reckon.)
1335 // Walk through the string looking for the final dirsep, i.e. /
1336 do
1337 {
1338 thispart = strstr(thispart, dirsep);
1339 if (NULL != thispart)
1340 finalpart = thispart = &thispart[1];
1341 }
1342 while (NULL != thispart);
1343 return finalpart;
1344 }
1345 else
1346 return NULL;
1347}
1348
1349void LLFilePicker::reset()
1350{
1351 mNextFileIndex = 0;
1352 mStoreFilenames.win = NULL;
1353 mStoreFilenames.fileVector.clear();
1354}
1355
1356# else // LL_GTK 1229# else // LL_GTK
1357 1230
1358// Hacky stubs designed to facilitate fake getSaveFile and getOpenFile with 1231// Hacky stubs designed to facilitate fake getSaveFile and getOpenFile with
1359// static results, when we don't have a real filepicker. 1232// static results, when we don't have a real filepicker.
1360 1233
1361static LLString hackyfilename; 1234BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename )
1362
1363LLFilePicker::LLFilePicker()
1364{ 1235{
1365 reset(); 1236 reset();
1366} 1237
1367
1368LLFilePicker::~LLFilePicker()
1369{
1370}
1371
1372BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const char* filename )
1373{
1374 llinfos << "getSaveFile suggested filename is [" << filename 1238 llinfos << "getSaveFile suggested filename is [" << filename
1375 << "]" << llendl; 1239 << "]" << llendl;
1376 if (filename && filename[0]) 1240 if (!filename.empty())
1377 { 1241 {
1378 hackyfilename.assign(gDirUtilp->getLindenUserDir()); 1242 mFiles.push_back(gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter() + filename);
1379 hackyfilename += gDirUtilp->getDirDelimiter();
1380 hackyfilename += filename;
1381 return TRUE; 1243 return TRUE;
1382 } 1244 }
1383 hackyfilename.clear();
1384 return FALSE; 1245 return FALSE;
1385} 1246}
1386 1247
1387BOOL LLFilePicker::getOpenFile( ELoadFilter filter ) 1248BOOL LLFilePicker::getOpenFile( ELoadFilter filter )
1388{ 1249{
1250 reset();
1251
1389 // HACK: Static filenames for 'open' until we implement filepicker 1252 // HACK: Static filenames for 'open' until we implement filepicker
1390 hackyfilename.assign(gDirUtilp->getLindenUserDir()); 1253 std::string filename = gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter() + "upload";
1391 hackyfilename += gDirUtilp->getDirDelimiter();
1392 hackyfilename += "upload";
1393 switch (filter) 1254 switch (filter)
1394 { 1255 {
1395 case FFLOAD_WAV: hackyfilename += ".wav"; break; 1256 case FFLOAD_WAV: filename += ".wav"; break;
1396 case FFLOAD_IMAGE: hackyfilename += ".tga"; break; 1257 case FFLOAD_IMAGE: filename += ".tga"; break;
1397 case FFLOAD_ANIM: hackyfilename += ".bvh"; break; 1258 case FFLOAD_ANIM: filename += ".bvh"; break;
1398 default: break; 1259 default: break;
1399 } 1260 }
1400 llinfos << "getOpenFile: Will try to open file: " << hackyfilename 1261 mFiles.push_back(filename);
1401 << llendl; 1262 llinfos << "getOpenFile: Will try to open file: " << hackyfilename << llendl;
1402 return TRUE; 1263 return TRUE;
1403} 1264}
1404 1265
1405BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter ) 1266BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter )
1406{ 1267{
1407 hackyfilename.clear(); 1268 reset();
1408 return FALSE; 1269 return FALSE;
1409} 1270}
1410 1271
1411const char* LLFilePicker::getFirstFile()
1412{
1413 if (!hackyfilename.empty())
1414 {
1415 return hackyfilename.c_str();
1416 }
1417 return NULL;
1418}
1419
1420const char* LLFilePicker::getNextFile()
1421{
1422 hackyfilename.clear();
1423 return NULL;
1424}
1425
1426const char* LLFilePicker::getDirname()
1427{
1428 return NULL;
1429}
1430
1431void LLFilePicker::reset()
1432{
1433}
1434#endif // LL_GTK 1272#endif // LL_GTK
1435 1273
1436#else // not implemented 1274#else // not implemented
1437 1275
1438LLFilePicker::LLFilePicker() 1276BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename )
1439{
1440 reset();
1441}
1442
1443LLFilePicker::~LLFilePicker()
1444{
1445}
1446
1447BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const char* filename )
1448{ 1277{
1278 reset();
1449 return FALSE; 1279 return FALSE;
1450} 1280}
1451 1281
1452BOOL LLFilePicker::getOpenFile( ELoadFilter filter ) 1282BOOL LLFilePicker::getOpenFile( ELoadFilter filter )
1453{ 1283{
1284 reset();
1454 return FALSE; 1285 return FALSE;
1455} 1286}
1456 1287
1457BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter ) 1288BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter )
1458{ 1289{
1290 reset();
1459 return FALSE; 1291 return FALSE;
1460} 1292}
1461 1293
1462const char* LLFilePicker::getFirstFile()
1463{
1464 return NULL;
1465}
1466
1467const char* LLFilePicker::getNextFile()
1468{
1469 return NULL;
1470}
1471
1472const char* LLFilePicker::getDirname()
1473{
1474 return NULL;
1475}
1476
1477void LLFilePicker::reset()
1478{
1479}
1480
1481#endif 1294#endif