summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2023-01-26 16:58:00 +0200
committerakleshchev <117672381+akleshchev@users.noreply.github.com>2023-01-27 17:25:18 +0200
commit27080dc7f7f9a733706e0d9120b8ed805e8170c8 (patch)
tree9fcc1b583744035a72a1fe784d567ace44c64234 /indra
parent2398a28af6f6c225c77b77bef422d1d2dec4a2bb (diff)
SL-18996 make MacOS picker dialogs modeless to avoid disconnects #2
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/llfilepicker.cpp284
-rw-r--r--indra/newview/llfilepicker.h12
-rw-r--r--indra/newview/llfilepicker_mac.h8
-rw-r--r--indra/newview/llfilepicker_mac.mm50
-rw-r--r--indra/newview/llviewermenufile.cpp53
-rw-r--r--indra/newview/llviewermenufile.h3
6 files changed, 287 insertions, 123 deletions
diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index 06cb78741e..e6b6c22cc3 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -285,6 +285,15 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking)
return success;
}
+BOOL LLFilePicker::getOpenFileModeless(ELoadFilter filter,
+ void (*callback)(bool, std::vector<std::string> &, void*),
+ void *userdata)
+{
+ // not supposed to be used yet, use LLFilePickerThread
+ LL_ERRS() << "NOT IMPLEMENTED" << LL_ENDL;
+ return FALSE;
+}
+
BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter, bool blocking)
{
if( mLocked )
@@ -362,6 +371,15 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter, bool blocking)
return success;
}
+BOOL LLFilePicker::getMultipleOpenFilesModeless(ELoadFilter filter,
+ void (*callback)(bool, std::vector<std::string> &, void*),
+ void *userdata )
+{
+ // not supposed to be used yet, use LLFilePickerThread
+ LL_ERRS() << "NOT IMPLEMENTED" << LL_ENDL;
+ return FALSE;
+}
+
BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename, bool blocking)
{
if( mLocked )
@@ -584,6 +602,16 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename,
return success;
}
+BOOL LLFilePicker::getSaveFileModeless(ESaveFilter filter,
+ const std::string& filename,
+ void (*callback)(bool, std::string&, void*),
+ void *userdata)
+{
+ // not supposed to be used yet, use LLFilePickerThread
+ LL_ERRS() << "NOT IMPLEMENTED" << LL_ENDL;
+ return FALSE;
+}
+
#elif LL_DARWIN
std::vector<std::string>* LLFilePicker::navOpenFilterProc(ELoadFilter filter) //(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode)
@@ -688,119 +716,113 @@ bool LLFilePicker::doNavChooseDialogModeless(ELoadFilter filter,
return false;
}
- gViewerWindow->getWindow()->beforeDialog();
-
std::vector<std::string> *allowed_types=navOpenFilterProc(filter);
doLoadDialogModeless(allowed_types,
mPickOptions,
callback,
userdata);
-
- gViewerWindow->getWindow()->afterDialog();
return true;
}
-bool LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filename)
+void set_nav_save_data(LLFilePicker::ESaveFilter filter, std::string &extension, std::string &type, std::string &creator)
{
-
- // Setup the type, creator, and extension
- std::string extension, type, creator;
-
- switch (filter)
- {
- case FFSAVE_WAV:
- type = "WAVE";
- creator = "TVOD";
- extension = "wav";
- break;
- case FFSAVE_TGA:
- type = "TPIC";
- creator = "prvw";
- extension = "tga";
- break;
- case FFSAVE_TGAPNG:
- type = "PNG";
- creator = "prvw";
- extension = "png,tga";
- break;
- case FFSAVE_BMP:
- type = "BMPf";
- creator = "prvw";
- extension = "bmp";
- break;
- case FFSAVE_JPEG:
- type = "JPEG";
- creator = "prvw";
- extension = "jpeg";
- break;
- case FFSAVE_PNG:
- type = "PNG ";
- creator = "prvw";
- extension = "png";
- break;
- case FFSAVE_AVI:
- type = "\?\?\?\?";
- creator = "\?\?\?\?";
- extension = "mov";
- break;
+ switch (filter)
+ {
+ case LLFilePicker::FFSAVE_WAV:
+ type = "WAVE";
+ creator = "TVOD";
+ extension = "wav";
+ break;
+ case LLFilePicker::FFSAVE_TGA:
+ type = "TPIC";
+ creator = "prvw";
+ extension = "tga";
+ break;
+ case LLFilePicker::FFSAVE_TGAPNG:
+ type = "PNG";
+ creator = "prvw";
+ extension = "png,tga";
+ break;
+ case LLFilePicker::FFSAVE_BMP:
+ type = "BMPf";
+ creator = "prvw";
+ extension = "bmp";
+ break;
+ case LLFilePicker::FFSAVE_JPEG:
+ type = "JPEG";
+ creator = "prvw";
+ extension = "jpeg";
+ break;
+ case LLFilePicker::FFSAVE_PNG:
+ type = "PNG ";
+ creator = "prvw";
+ extension = "png";
+ break;
+ case LLFilePicker::FFSAVE_AVI:
+ type = "\?\?\?\?";
+ creator = "\?\?\?\?";
+ extension = "mov";
+ break;
- case FFSAVE_ANIM:
- type = "\?\?\?\?";
- creator = "\?\?\?\?";
- extension = "xaf";
- break;
+ case LLFilePicker::FFSAVE_ANIM:
+ type = "\?\?\?\?";
+ creator = "\?\?\?\?";
+ extension = "xaf";
+ break;
#ifdef _CORY_TESTING
- case FFSAVE_GEOMETRY:
- type = "\?\?\?\?";
- creator = "\?\?\?\?";
- extension = "slg";
- break;
-#endif
-
- case FFSAVE_XML:
- type = "\?\?\?\?";
- creator = "\?\?\?\?";
- extension = "xml";
- break;
-
- case FFSAVE_RAW:
- type = "\?\?\?\?";
- creator = "\?\?\?\?";
- extension = "raw";
- break;
+ case LLFilePicker::FFSAVE_GEOMETRY:
+ type = "\?\?\?\?";
+ creator = "\?\?\?\?";
+ extension = "slg";
+ break;
+#endif
+
+ case LLFilePicker::FFSAVE_XML:
+ type = "\?\?\?\?";
+ creator = "\?\?\?\?";
+ extension = "xml";
+ break;
+
+ case LLFilePicker::FFSAVE_RAW:
+ type = "\?\?\?\?";
+ creator = "\?\?\?\?";
+ extension = "raw";
+ break;
- case FFSAVE_J2C:
- type = "\?\?\?\?";
- creator = "prvw";
- extension = "j2c";
- break;
-
- case FFSAVE_SCRIPT:
- type = "LSL ";
- creator = "\?\?\?\?";
- extension = "lsl";
- break;
-
- case FFSAVE_ALL:
- default:
- type = "\?\?\?\?";
- creator = "\?\?\?\?";
- extension = "";
- break;
- }
+ case LLFilePicker::FFSAVE_J2C:
+ type = "\?\?\?\?";
+ creator = "prvw";
+ extension = "j2c";
+ break;
+
+ case LLFilePicker::FFSAVE_SCRIPT:
+ type = "LSL ";
+ creator = "\?\?\?\?";
+ extension = "lsl";
+ break;
+
+ case LLFilePicker::FFSAVE_ALL:
+ default:
+ type = "\?\?\?\?";
+ creator = "\?\?\?\?";
+ extension = "";
+ break;
+ }
+}
+
+bool LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filename)
+{
+ // Setup the type, creator, and extension
+ std::string extension, type, creator;
+
+ set_nav_save_data(filter, extension, type, creator);
std::string namestring = filename;
if (namestring.empty()) namestring="Untitled";
-// if (! boost::algorithm::ends_with(namestring, extension) )
-// {
-// namestring = namestring + "." + extension;
-//
-// }
-
gViewerWindow->getWindow()->beforeDialog();
// Run the dialog
@@ -821,6 +843,30 @@ bool LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filena
return false;
}
+bool LLFilePicker::doNavSaveDialogModeless(ESaveFilter filter,
+ const std::string& filename,
+ void (*callback)(bool, std::string&, void*),
+ void *userdata)
+{
+ // Setup the type, creator, and extension
+ std::string extension, type, creator;
+
+ set_nav_save_data(filter, extension, type, creator);
+
+ std::string namestring = filename;
+ if (namestring.empty()) namestring="Untitled";
+
+ // Run the dialog
+ doSaveDialogModeless(&namestring,
+ &type,
+ &creator,
+ &extension,
+ mPickOptions,
+ callback,
+ userdata);
+ return true;
+}
+
BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking)
{
if( mLocked )
@@ -956,7 +1002,9 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter, bool blocking)
}
-BOOL LLFilePicker::getMultipleOpenFilesModeless( ELoadFilter filter, void (*callback)(bool, std::vector<std::string> &, void*), void *userdata )
+BOOL LLFilePicker::getMultipleOpenFilesModeless(ELoadFilter filter,
+ void (*callback)(bool, std::vector<std::string> &, void*),
+ void *userdata )
{
if( mLocked )
return FALSE;
@@ -1016,6 +1064,27 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename,
LLFrameTimer::updateFrameTime();
return success;
}
+
+BOOL LLFilePicker::getSaveFileModeless(ESaveFilter filter,
+ const std::string& filename,
+ void (*callback)(bool, std::string&, void*),
+ void *userdata)
+{
+ if( mLocked )
+ return false;
+
+ // if local file browsing is turned off, return without opening dialog
+ if ( check_local_file_access_enabled() == false )
+ {
+ return false;
+ }
+
+ reset();
+
+ mPickOptions &= ~F_MULTIPLE;
+
+ return doNavSaveDialogModeless(filter, filename, callback, userdata);
+}
//END LL_DARWIN
#elif LL_LINUX
@@ -1523,6 +1592,15 @@ BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename
return FALSE;
}
+BOOL LLFilePicker::getSaveFileModeless(ESaveFilter filter,
+ const std::string& filename,
+ void (*callback)(bool, std::string&, void*),
+ void *userdata)
+{
+ LL_ERRS() << "NOT IMPLEMENTED" << LL_ENDL;
+ return FALSE;
+}
+
BOOL LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking )
{
// if local file browsing is turned off, return without opening dialog
@@ -1548,6 +1626,14 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking )
return TRUE;
}
+BOOL LLFilePicker::getOpenFileModeless(ELoadFilter filter,
+ void (*callback)(bool, std::vector<std::string> &, void*),
+ void *userdata)
+{
+ LL_ERRS() << "NOT IMPLEMENTED" << LL_ENDL;
+ return FALSE;
+}
+
BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter, bool blocking)
{
// if local file browsing is turned off, return without opening dialog
@@ -1561,6 +1647,14 @@ BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter, bool blocking)
return FALSE;
}
+BOOL LLFilePicker::getMultipleOpenFilesModeless(ELoadFilter filter,
+ void (*callback)(bool, std::vector<std::string> &, void*),
+ void *userdata )
+{
+ LL_ERRS() << "NOT IMPLEMENTED" << LL_ENDL;
+ return FALSE;
+}
+
#endif // LL_GTK
#else // not implemented
diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h
index 04adeb8526..5e2b7f51f2 100644
--- a/indra/newview/llfilepicker.h
+++ b/indra/newview/llfilepicker.h
@@ -114,6 +114,10 @@ public:
// open the dialog. This is a modal operation
BOOL getSaveFile( ESaveFilter filter = FFSAVE_ALL, const std::string& filename = LLStringUtil::null, bool blocking = true);
+ BOOL getSaveFileModeless(ESaveFilter filter,
+ const std::string& filename,
+ void (*callback)(bool, std::string&, void*),
+ void *userdata);
BOOL getOpenFile( ELoadFilter filter = FFLOAD_ALL, bool blocking = true );
// Todo: implement getOpenFileModeless and getMultipleOpenFilesModeless
// for windows and use directly instead of ugly LLFilePickerThread
@@ -170,9 +174,15 @@ private:
std::vector<std::string> mFileVector;
bool doNavChooseDialog(ELoadFilter filter);
- bool doNavChooseDialogModeless(ELoadFilter filter, void (*callback)(bool, std::vector<std::string>&, void*), void *userdata);
+ bool doNavChooseDialogModeless(ELoadFilter filter,
+ void (*callback)(bool, std::vector<std::string>&, void*),
+ void *userdata);
bool doNavSaveDialog(ESaveFilter filter, const std::string& filename);
std::vector<std::string>* navOpenFilterProc(ELoadFilter filter);
+ bool doNavSaveDialogModeless(ESaveFilter filter,
+ const std::string& filename,
+ void (*callback)(bool, std::string&, void*),
+ void *userdata);
#endif
#if LL_GTK
diff --git a/indra/newview/llfilepicker_mac.h b/indra/newview/llfilepicker_mac.h
index d6b69bb856..2ec9d0c4e6 100644
--- a/indra/newview/llfilepicker_mac.h
+++ b/indra/newview/llfilepicker_mac.h
@@ -52,6 +52,14 @@ std::string* doSaveDialog(const std::string* file,
const std::string* creator,
const std::string* extension,
unsigned int flags);
+
+void doSaveDialogModeless(const std::string* file,
+ const std::string* type,
+ const std::string* creator,
+ const std::string* extension,
+ unsigned int flags,
+ void (*callback)(bool, std::string&, void*),
+ void *userdata);
enum {
F_FILE = 0x00000001,
F_DIRECTORY = 0x00000002,
diff --git a/indra/newview/llfilepicker_mac.mm b/indra/newview/llfilepicker_mac.mm
index f6892f40fa..8f5b3030db 100644
--- a/indra/newview/llfilepicker_mac.mm
+++ b/indra/newview/llfilepicker_mac.mm
@@ -112,9 +112,9 @@ void doLoadDialogModeless(const std::vector<std::string>* allowed_types,
[panel beginWithCompletionHandler:^(NSModalResponse result)
{
+ std::vector<std::string> outfiles;
if (result == NSOKButton)
{
- std::vector<std::string> outfiles;
NSArray *filesToOpen = [panel URLs];
int i, count = [filesToOpen count];
@@ -128,11 +128,15 @@ void doLoadDialogModeless(const std::vector<std::string>* allowed_types,
}
callback(true, outfiles, userdata);
}
- else
+ else // no valid result
{
callback(false, outfiles, userdata);
}
}
+ else // cancel
+ {
+ callback(false, outfiles, userdata);
+ }
}];
}
@@ -168,4 +172,46 @@ std::string* doSaveDialog(const std::string* file,
return outfile;
}
+void doSaveDialogModeless(const std::string* file,
+ const std::string* type,
+ const std::string* creator,
+ const std::string* extension,
+ unsigned int flags,
+ void (*callback)(bool, std::string&, void*),
+ void *userdata)
+{
+ NSSavePanel *panel = [NSSavePanel savePanel];
+
+ NSString *extensionns = [NSString stringWithCString:extension->c_str() encoding:[NSString defaultCStringEncoding]];
+ NSArray *fileType = [extensionns componentsSeparatedByString:@","];
+
+ //[panel setMessage:@"Save Image File"];
+ [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ];
+ [panel setCanSelectHiddenExtension:true];
+ [panel setAllowedFileTypes:fileType];
+ NSString *fileName = [NSString stringWithCString:file->c_str() encoding:[NSString defaultCStringEncoding]];
+
+ NSURL* url = [NSURL fileURLWithPath:fileName];
+ [panel setNameFieldStringValue: fileName];
+ [panel setDirectoryURL: url];
+
+
+ [panel beginWithCompletionHandler:^(NSModalResponse result)
+ {
+ if (result == NSOKButton)
+ {
+ NSURL* url = [panel URL];
+ NSString* p = [url path];
+ std::string outfile([p UTF8String]);
+
+ callback(true, outfile, userdata);
+ }
+ else // cancel
+ {
+ std::string outfile;
+ callback(false, outfile, userdata);
+ }
+ }];
+}
+
#endif
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index 259ae7c1fb..27fe7a7018 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -123,17 +123,10 @@ std::queue<LLFilePickerThread*> LLFilePickerThread::sDeadQ;
void LLFilePickerThread::getFile()
{
#if LL_WINDOWS
+ // Todo: get rid of LLFilePickerThread and make this modeless
start();
#elif LL_DARWIN
- if (!mIsSaveDialog)
- {
- runModeless();
- }
- else
- {
- // Todo: implement Modeless
- run();
- }
+ runModeless();
#else
run();
#endif
@@ -185,22 +178,18 @@ void LLFilePickerThread::runModeless()
if (mIsSaveDialog)
{
- // TODO: not implemented
- /*if (picker.getSaveFile(mSaveFilter, mProposedName, blocking))
- {
- mResponses.push_back(picker.getFirstFile());
- }*/
+ result = picker.getSaveFileModeless(mSaveFilter,
+ mProposedName,
+ modelessStringCallback,
+ this);
+ }
+ else if (mIsGetMultiple)
+ {
+ result = picker.getMultipleOpenFilesModeless(mLoadFilter, modelessVectorCallback, this);
}
else
{
- if (mIsGetMultiple)
- {
- result = picker.getMultipleOpenFilesModeless(mLoadFilter, modelessCallback, this);
- }
- else
- {
- result = picker.getOpenFileModeless(mLoadFilter, modelessCallback, this);
- }
+ result = picker.getOpenFileModeless(mLoadFilter, modelessVectorCallback, this);
}
if (!result)
@@ -210,12 +199,28 @@ void LLFilePickerThread::runModeless()
}
}
-void LLFilePickerThread::modelessCallback(bool result,
+void LLFilePickerThread::modelessStringCallback(bool success,
+ std::string &response,
+ void *user_data)
+{
+ LLFilePickerThread *picker = (LLFilePickerThread*)user_data;
+ if (success)
+ {
+ picker->mResponses.push_back(response);
+ }
+
+ {
+ LLMutexLock lock(sMutex);
+ sDeadQ.push(picker);
+ }
+}
+
+void LLFilePickerThread::modelessVectorCallback(bool success,
std::vector<std::string> &responses,
void *user_data)
{
LLFilePickerThread *picker = (LLFilePickerThread*)user_data;
- if (result)
+ if (success)
{
if (picker->mIsGetMultiple)
{
diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h
index 7cb2cf0d11..61572b9996 100644
--- a/indra/newview/llviewermenufile.h
+++ b/indra/newview/llviewermenufile.h
@@ -106,7 +106,8 @@ public:
virtual void run();
void runModeless();
- static void modelessCallback(bool result, std::vector<std::string> &responses, void *user_data);
+ static void modelessStringCallback(bool success, std::string &response, void *user_data);
+ static void modelessVectorCallback(bool success, std::vector<std::string> &responses, void *user_data);
virtual void notify(const std::vector<std::string>& filenames) = 0;
};