diff options
| author | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2023-01-26 16:58:00 +0200 | 
|---|---|---|
| committer | akleshchev <117672381+akleshchev@users.noreply.github.com> | 2023-01-27 17:25:18 +0200 | 
| commit | 27080dc7f7f9a733706e0d9120b8ed805e8170c8 (patch) | |
| tree | 9fcc1b583744035a72a1fe784d567ace44c64234 /indra/newview | |
| parent | 2398a28af6f6c225c77b77bef422d1d2dec4a2bb (diff) | |
SL-18996 make MacOS picker dialogs modeless to avoid disconnects #2
Diffstat (limited to 'indra/newview')
| -rw-r--r-- | indra/newview/llfilepicker.cpp | 284 | ||||
| -rw-r--r-- | indra/newview/llfilepicker.h | 12 | ||||
| -rw-r--r-- | indra/newview/llfilepicker_mac.h | 8 | ||||
| -rw-r--r-- | indra/newview/llfilepicker_mac.mm | 50 | ||||
| -rw-r--r-- | indra/newview/llviewermenufile.cpp | 53 | ||||
| -rw-r--r-- | indra/newview/llviewermenufile.h | 3 | 
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;  }; | 
