diff options
| -rw-r--r-- | indra/newview/llfilepicker.cpp | 83 | ||||
| -rw-r--r-- | indra/newview/llfilepicker.h | 5 | ||||
| -rw-r--r-- | indra/newview/llfilepicker_mac.h | 6 | ||||
| -rw-r--r-- | indra/newview/llfilepicker_mac.mm | 68 | ||||
| -rw-r--r-- | indra/newview/llviewermenufile.cpp | 73 | ||||
| -rw-r--r-- | indra/newview/llviewermenufile.h | 2 | 
6 files changed, 220 insertions, 17 deletions
| diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index 3669fb1eeb..06cb78741e 100644 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -678,6 +678,30 @@ bool	LLFilePicker::doNavChooseDialog(ELoadFilter filter)  	return false;  } +bool    LLFilePicker::doNavChooseDialogModeless(ELoadFilter filter, +                                                void (*callback)(bool, std::vector<std::string> &,void*), +                                                void *userdata) +{ +    // if local file browsing is turned off, return without opening dialog +    if ( check_local_file_access_enabled() == false ) +    { +        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)  { @@ -852,18 +876,52 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking)  	return success;  } + +BOOL LLFilePicker::getOpenFileModeless(ELoadFilter filter, +                                       void (*callback)(bool, std::vector<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; +    mPickOptions |= F_FILE; +  +    if (filter == FFLOAD_DIRECTORY) //This should only be called from lldirpicker. +    { + +        mPickOptions |= ( F_NAV_SUPPORT | F_DIRECTORY ); +        mPickOptions &= ~F_FILE; +    } + +    if (filter == FFLOAD_ALL)    // allow application bundles etc. to be traversed; important for DEV-16869, but generally useful +    { +        mPickOptions |= F_NAV_SUPPORT; +    } + +    return doNavChooseDialogModeless(filter, callback, userdata); +} +  BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter, bool blocking)  {  	if( mLocked )  		return FALSE; -	BOOL success = FALSE; -  	// if local file browsing is turned off, return without opening dialog  	if ( check_local_file_access_enabled() == false )  	{  		return FALSE;  	} +     +    BOOL success = FALSE;  	reset(); @@ -897,6 +955,27 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter, bool blocking)  	return success;  } + +BOOL LLFilePicker::getMultipleOpenFilesModeless( ELoadFilter filter, void (*callback)(bool, std::vector<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_FILE; + +    mPickOptions |= F_MULTIPLE; + +    return doNavChooseDialogModeless(filter, callback, userdata); +} +  BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename, bool blocking)  { diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h index 04ba4416d7..04adeb8526 100644 --- a/indra/newview/llfilepicker.h +++ b/indra/newview/llfilepicker.h @@ -115,7 +115,11 @@ 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 getOpenFile( ELoadFilter filter = FFLOAD_ALL, bool blocking = true  ); +    // Todo: implement getOpenFileModeless and getMultipleOpenFilesModeless +    // for windows and use directly instead of ugly LLFilePickerThread +    BOOL getOpenFileModeless( ELoadFilter filter, void (*callback)(bool, std::vector<std::string> &, void*), void *userdata); // MAC only.  	BOOL getMultipleOpenFiles( ELoadFilter filter = FFLOAD_ALL, bool blocking = true ); +    BOOL getMultipleOpenFilesModeless( ELoadFilter filter, void (*callback)(bool, std::vector<std::string> &, void*), void *userdata ); // MAC only  	// Get the filename(s) found. getFirstFile() sets the pointer to  	// the start of the structure and allows the start of iteration. @@ -166,6 +170,7 @@ 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 doNavSaveDialog(ESaveFilter filter, const std::string& filename);      std::vector<std::string>* navOpenFilterProc(ELoadFilter filter);  #endif diff --git a/indra/newview/llfilepicker_mac.h b/indra/newview/llfilepicker_mac.h index e0b7e2e8ce..d6b69bb856 100644 --- a/indra/newview/llfilepicker_mac.h +++ b/indra/newview/llfilepicker_mac.h @@ -41,6 +41,12 @@  //void modelessPicker();  std::vector<std::string>* doLoadDialog(const std::vector<std::string>* allowed_types,                    unsigned int flags); + +void doLoadDialogModeless(const std::vector<std::string>* allowed_types, +                unsigned int flags, +                void (*callback)(bool, std::vector<std::string>&, void*), +                void *userdata); +  std::string* doSaveDialog(const std::string* file,                     const std::string* type,                    const std::string* creator, diff --git a/indra/newview/llfilepicker_mac.mm b/indra/newview/llfilepicker_mac.mm index 1438e4dc0a..f6892f40fa 100644 --- a/indra/newview/llfilepicker_mac.mm +++ b/indra/newview/llfilepicker_mac.mm @@ -29,27 +29,22 @@  #include <iostream>  #include "llfilepicker_mac.h" -std::vector<std::string>* doLoadDialog(const std::vector<std::string>* allowed_types,  -                 unsigned int flags) +NSOpenPanel *init_panel(const std::vector<std::string>* allowed_types, unsigned int flags)  { -    int i, result; -     -    //Aura TODO:  We could init a small window and release it at the end of this routine -    //for a modeless interface. +    int i;      NSOpenPanel *panel = [NSOpenPanel openPanel]; -    //NSString *fileName = nil;      NSMutableArray *fileTypes = nil; -    if ( allowed_types && !allowed_types->empty())  +    if ( allowed_types && !allowed_types->empty())      {          fileTypes = [[NSMutableArray alloc] init];          for (i=0;i<allowed_types->size();++i)          { -            [fileTypes addObject:  -             [NSString stringWithCString:(*allowed_types)[i].c_str()  +            [fileTypes addObject: +             [NSString stringWithCString:(*allowed_types)[i].c_str()                                  encoding:[NSString defaultCStringEncoding]]];          }      } @@ -62,21 +57,30 @@ std::vector<std::string>* doLoadDialog(const std::vector<std::string>* allowed_t      [panel setCanChooseFiles: ( (flags & F_FILE)?true:false )];      [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ]; -    std::vector<std::string>* outfiles = NULL;  -          if (fileTypes)      {          [panel setAllowedFileTypes:fileTypes]; -        result = [panel runModal];      } -    else  +    else      {          // I suggest it's better to open the last path and let this default to home dir as necessary          // for consistency with other OS X apps          //          //[panel setDirectoryURL: fileURLWithPath(NSHomeDirectory()) ]; -        result = [panel runModal];      } +    return panel; +} + +std::vector<std::string>* doLoadDialog(const std::vector<std::string>* allowed_types,  +                 unsigned int flags) +{ +    int result; +     +    NSOpenPanel *panel = init_panel(allowed_types,flags); +     +    result = [panel runModal]; +     +    std::vector<std::string>* outfiles = NULL;      if (result == NSOKButton)       { @@ -97,6 +101,40 @@ std::vector<std::string>* doLoadDialog(const std::vector<std::string>* allowed_t      return outfiles;  } +void doLoadDialogModeless(const std::vector<std::string>* allowed_types, +                 unsigned int flags, +                 void (*callback)(bool, std::vector<std::string> &, void*), +                 void *userdata) +{ +    // Note: might need to return and save this panel +    // so that it does not close immediately +    NSOpenPanel *panel = init_panel(allowed_types,flags); +     +    [panel beginWithCompletionHandler:^(NSModalResponse result) +        { +            if (result == NSOKButton) +            { +                std::vector<std::string> outfiles; +                NSArray *filesToOpen = [panel URLs]; +                int i, count = [filesToOpen count]; +                 +                if (count > 0) +                { +                     +                    for (i=0; i<count; i++) { +                        NSString *aFile = [[filesToOpen objectAtIndex:i] path]; +                        std::string *afilestr = new std::string([aFile UTF8String]); +                        outfiles.push_back(*afilestr); +                    } +                    callback(true, outfiles, userdata); +                } +                else +                { +                    callback(false, outfiles, userdata); +                } +            } +        }]; +}  std::string* doSaveDialog(const std::string* file,                     const std::string* type, diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index fdf1d04c09..259ae7c1fb 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -124,6 +124,16 @@ void LLFilePickerThread::getFile()  {  #if LL_WINDOWS  	start(); +#elif LL_DARWIN +    if (!mIsSaveDialog) +    { +        runModeless(); +    } +    else +    { +        // Todo: implement Modeless +        run(); +    }  #else  	run();  #endif @@ -166,7 +176,70 @@ void LLFilePickerThread::run()  		LLMutexLock lock(sMutex);  		sDeadQ.push(this);  	} +} + +void LLFilePickerThread::runModeless() +{ +    BOOL result = FALSE; +    LLFilePicker picker; +    if (mIsSaveDialog) +    { +        // TODO: not implemented +        /*if (picker.getSaveFile(mSaveFilter, mProposedName, blocking)) +        { +            mResponses.push_back(picker.getFirstFile()); +        }*/ +    } +    else +    { +        if (mIsGetMultiple) +        { +            result = picker.getMultipleOpenFilesModeless(mLoadFilter, modelessCallback, this); +        } +        else +        { +            result = picker.getOpenFileModeless(mLoadFilter, modelessCallback, this); +        } +    } +     +    if (!result) +    { +        LLMutexLock lock(sMutex); +        sDeadQ.push(this); +    } +} + +void LLFilePickerThread::modelessCallback(bool result, +                                          std::vector<std::string> &responses, +                                          void *user_data) +{ +    LLFilePickerThread *picker = (LLFilePickerThread*)user_data; +    if (result) +    { +        if (picker->mIsGetMultiple) +        { +            picker->mResponses = responses; +        } +        else +        { +            std::vector<std::string>::iterator iter = responses.begin(); +            while (iter != responses.end()) +            { +                if (!iter->empty()) +                { +                    picker->mResponses.push_back(*iter); +                    break; +                } +                iter++; +            } +        } +    } +     +    { +        LLMutexLock lock(sMutex); +        sDeadQ.push(picker); +    }  }  //static diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h index beeac418d9..7cb2cf0d11 100644 --- a/indra/newview/llviewermenufile.h +++ b/indra/newview/llviewermenufile.h @@ -105,6 +105,8 @@ public:  	void getFile();  	virtual void run(); +    void runModeless(); +    static void modelessCallback(bool result, std::vector<std::string> &responses, void *user_data);  	virtual void notify(const std::vector<std::string>& filenames) = 0;  }; | 
