diff options
Diffstat (limited to 'indra/newview/lldirpicker.cpp')
| -rw-r--r-- | indra/newview/lldirpicker.cpp | 778 | 
1 files changed, 389 insertions, 389 deletions
diff --git a/indra/newview/lldirpicker.cpp b/indra/newview/lldirpicker.cpp index 4306185f0a..b33467ca6c 100644 --- a/indra/newview/lldirpicker.cpp +++ b/indra/newview/lldirpicker.cpp @@ -1,389 +1,389 @@ -/**  - * @file lldirpicker.cpp - * @brief OS-specific file picker - * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - *  - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "lldirpicker.h" -#include "llworld.h" -#include "llviewerwindow.h" -#include "llkeyboard.h" -#include "lldir.h" -#include "llframetimer.h" -#include "lltrans.h" -#include "llwindow.h"	// beforeDialog() -#include "llviewercontrol.h" -#include "llwin32headerslean.h" - -#if LL_LINUX || LL_DARWIN -# include "llfilepicker.h" -#endif - -#if LL_WINDOWS -#include <shlobj.h> -#endif - -// -// Implementation -// - -// utility function to check if access to local file system via file browser  -// is enabled and if not, tidy up and indicate we're not allowed to do this. -bool LLDirPicker::check_local_file_access_enabled() -{ -	// if local file browsing is turned off, return without opening dialog -	bool local_file_system_browsing_enabled = gSavedSettings.getBOOL("LocalFileSystemBrowsingEnabled"); -	if ( ! local_file_system_browsing_enabled ) -	{ -		mDir.clear();	// Windows -		mFileName = NULL; // Mac/Linux -		return false; -	} - -	return true; -} - -#if LL_WINDOWS - -LLDirPicker::LLDirPicker() : -	mFileName(NULL), -	mLocked(false), -    pDialog(NULL) -{ -} - -LLDirPicker::~LLDirPicker() -{ -    mEventListener.disconnect(); -} - -void LLDirPicker::reset() -{ -    if (pDialog) -    { -        IFileDialog* p_file_dialog = (IFileDialog*)pDialog; -        p_file_dialog->Close(S_FALSE); -        pDialog = NULL; -    } -} - -bool LLDirPicker::getDir(std::string* filename, bool blocking) -{ -	if (mLocked) -	{ -		return false; -	} - -	// if local file browsing is turned off, return without opening dialog -	if (!check_local_file_access_enabled()) -	{ -		return false; -	} - -	bool success = false; - -	if (blocking) -	{ -		// Modal, so pause agent -		send_agent_pause(); -	} -    else if (!mEventListener.connected()) -    { -        mEventListener = LLEventPumps::instance().obtain("LLApp").listen( -            "DirPicker", -            [this](const LLSD& stat) -            { -                std::string status(stat["status"]); -                if (status != "running") -                { -                    reset(); -                } -                return false; -            }); -    } - -	::OleInitialize(NULL); - -    IFileDialog* p_file_dialog; -    if (SUCCEEDED(CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&p_file_dialog)))) -    { -        DWORD dwOptions; -        if (SUCCEEDED(p_file_dialog->GetOptions(&dwOptions))) -        { -            p_file_dialog->SetOptions(dwOptions | FOS_PICKFOLDERS); -        } -        HWND owner = (HWND)gViewerWindow->getPlatformWindow(); -        pDialog = p_file_dialog; -        if (SUCCEEDED(p_file_dialog->Show(owner))) -        { -            IShellItem* psi; -            if (SUCCEEDED(p_file_dialog->GetResult(&psi))) -            { -                wchar_t* pwstr = NULL; -                if (SUCCEEDED(psi->GetDisplayName(SIGDN_FILESYSPATH, &pwstr))) -                { -                    mDir = ll_convert_wide_to_string(pwstr); -                    CoTaskMemFree(pwstr); -                    success = true; -                } -                psi->Release(); -            } -        } -        pDialog = NULL; -        p_file_dialog->Release(); -    } - -	::OleUninitialize(); - -	if (blocking) -	{ -		send_agent_resume(); -	} - -	// Account for the fact that the app has been stalled. -	LLFrameTimer::updateFrameTime(); -	return success; -} - -std::string LLDirPicker::getDirName() -{ -	return mDir; -} - -/////////////////////////////////////////////DARWIN -#elif LL_DARWIN - -LLDirPicker::LLDirPicker() : -mFileName(NULL), -mLocked(false) -{ -	mFilePicker = new LLFilePicker(); -	reset(); -} - -LLDirPicker::~LLDirPicker() -{ -	delete mFilePicker; -} - -void LLDirPicker::reset() -{ -	if (mFilePicker) -		mFilePicker->reset(); -} - - -//static -bool LLDirPicker::getDir(std::string* filename, bool blocking) -{ -    LLFilePicker::ELoadFilter filter=LLFilePicker::FFLOAD_DIRECTORY; -     -    return mFilePicker->getOpenFile(filter, true); -} - -std::string LLDirPicker::getDirName() -{ -	return mFilePicker->getFirstFile(); -} - -#elif LL_LINUX - -LLDirPicker::LLDirPicker() : -	mFileName(NULL), -	mLocked(false) -{ -	mFilePicker = new LLFilePicker(); -	reset(); -} - -LLDirPicker::~LLDirPicker() -{ -	delete mFilePicker; -} - - -void LLDirPicker::reset() -{ -	if (mFilePicker) -		mFilePicker->reset(); -} - -bool LLDirPicker::getDir(std::string* filename, bool blocking) -{ -	reset(); - -	// if local file browsing is turned off, return without opening dialog -	if (!check_local_file_access_enabled()) -	{ -		return false; -	} - -#if !LL_MESA_HEADLESS - -	if (mFilePicker) -	{ -		GtkWindow* picker = mFilePicker->buildFilePicker(false, true, -								 "dirpicker"); - -		if (picker) -		{		    -		   gtk_window_set_title(GTK_WINDOW(picker), LLTrans::getString("choose_the_directory").c_str()); -		   gtk_widget_show_all(GTK_WIDGET(picker)); -		   gtk_main(); -		   return (!mFilePicker->getFirstFile().empty()); -		} -	} -#endif // !LL_MESA_HEADLESS - -	return false; -} - -std::string LLDirPicker::getDirName() -{ -	if (mFilePicker) -	{ -		return mFilePicker->getFirstFile(); -	} -	return ""; -} - -#else // not implemented - -LLDirPicker::LLDirPicker()  -{ -	reset(); -} - -LLDirPicker::~LLDirPicker() -{ -} - - -void LLDirPicker::reset() -{ -} - -bool LLDirPicker::getDir(std::string* filename, bool blocking) -{ -	return false; -} - -std::string LLDirPicker::getDirName() -{ -	return ""; -} - -#endif - - -LLMutex* LLDirPickerThread::sMutex = NULL; -std::queue<LLDirPickerThread*> LLDirPickerThread::sDeadQ; - -void LLDirPickerThread::getFile() -{ -#if LL_WINDOWS -	start(); -#else -	run(); -#endif -} - -//virtual  -void LLDirPickerThread::run() -{ -#if LL_WINDOWS -	bool blocking = false; -#else -	bool blocking = true; // modal -#endif - -	LLDirPicker picker; - -	if (picker.getDir(&mProposedName, blocking)) -	{ -		mResponses.push_back(picker.getDirName()); -	}	 - -	{ -		LLMutexLock lock(sMutex); -		sDeadQ.push(this); -	} - -} - -//static -void LLDirPickerThread::initClass() -{ -	sMutex = new LLMutex(); -} - -//static -void LLDirPickerThread::cleanupClass() -{ -	clearDead(); - -	delete sMutex; -	sMutex = NULL; -} - -//static -void LLDirPickerThread::clearDead() -{ -	if (!sDeadQ.empty()) -	{ -		LLMutexLock lock(sMutex); -		while (!sDeadQ.empty()) -		{ -			LLDirPickerThread* thread = sDeadQ.front(); -			thread->notify(thread->mResponses); -			delete thread; -			sDeadQ.pop(); -		} -	} -} - -LLDirPickerThread::LLDirPickerThread(const dir_picked_signal_t::slot_type& cb, const std::string &proposed_name) -	: LLThread("dir picker"), -	mFilePickedSignal(NULL) -{ -	mFilePickedSignal = new dir_picked_signal_t(); -	mFilePickedSignal->connect(cb); -} - -LLDirPickerThread::~LLDirPickerThread() -{ -	delete mFilePickedSignal; -} - -void LLDirPickerThread::notify(const std::vector<std::string>& filenames) -{ -	if (!filenames.empty()) -	{ -		if (mFilePickedSignal) -		{ -			(*mFilePickedSignal)(filenames, mProposedName); -		} -	} -} +/**
 + * @file lldirpicker.cpp
 + * @brief OS-specific file picker
 + *
 + * $LicenseInfo:firstyear=2001&license=viewerlgpl$
 + * Second Life Viewer Source Code
 + * Copyright (C) 2010, Linden Research, Inc.
 + *
 + * This library is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU Lesser General Public
 + * License as published by the Free Software Foundation;
 + * version 2.1 of the License only.
 + *
 + * This library is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 + * Lesser General Public License for more details.
 + *
 + * You should have received a copy of the GNU Lesser General Public
 + * License along with this library; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 + *
 + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 + * $/LicenseInfo$
 + */
 +
 +#include "llviewerprecompiledheaders.h"
 +
 +#include "lldirpicker.h"
 +#include "llworld.h"
 +#include "llviewerwindow.h"
 +#include "llkeyboard.h"
 +#include "lldir.h"
 +#include "llframetimer.h"
 +#include "lltrans.h"
 +#include "llwindow.h"   // beforeDialog()
 +#include "llviewercontrol.h"
 +#include "llwin32headerslean.h"
 +
 +#if LL_LINUX || LL_DARWIN
 +# include "llfilepicker.h"
 +#endif
 +
 +#if LL_WINDOWS
 +#include <shlobj.h>
 +#endif
 +
 +//
 +// Implementation
 +//
 +
 +// utility function to check if access to local file system via file browser
 +// is enabled and if not, tidy up and indicate we're not allowed to do this.
 +bool LLDirPicker::check_local_file_access_enabled()
 +{
 +    // if local file browsing is turned off, return without opening dialog
 +    bool local_file_system_browsing_enabled = gSavedSettings.getBOOL("LocalFileSystemBrowsingEnabled");
 +    if ( ! local_file_system_browsing_enabled )
 +    {
 +        mDir.clear();   // Windows
 +        mFileName = NULL; // Mac/Linux
 +        return false;
 +    }
 +
 +    return true;
 +}
 +
 +#if LL_WINDOWS
 +
 +LLDirPicker::LLDirPicker() :
 +    mFileName(NULL),
 +    mLocked(false),
 +    pDialog(NULL)
 +{
 +}
 +
 +LLDirPicker::~LLDirPicker()
 +{
 +    mEventListener.disconnect();
 +}
 +
 +void LLDirPicker::reset()
 +{
 +    if (pDialog)
 +    {
 +        IFileDialog* p_file_dialog = (IFileDialog*)pDialog;
 +        p_file_dialog->Close(S_FALSE);
 +        pDialog = NULL;
 +    }
 +}
 +
 +bool LLDirPicker::getDir(std::string* filename, bool blocking)
 +{
 +    if (mLocked)
 +    {
 +        return false;
 +    }
 +
 +    // if local file browsing is turned off, return without opening dialog
 +    if (!check_local_file_access_enabled())
 +    {
 +        return false;
 +    }
 +
 +    bool success = false;
 +
 +    if (blocking)
 +    {
 +        // Modal, so pause agent
 +        send_agent_pause();
 +    }
 +    else if (!mEventListener.connected())
 +    {
 +        mEventListener = LLEventPumps::instance().obtain("LLApp").listen(
 +            "DirPicker",
 +            [this](const LLSD& stat)
 +            {
 +                std::string status(stat["status"]);
 +                if (status != "running")
 +                {
 +                    reset();
 +                }
 +                return false;
 +            });
 +    }
 +
 +    ::OleInitialize(NULL);
 +
 +    IFileDialog* p_file_dialog;
 +    if (SUCCEEDED(CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&p_file_dialog))))
 +    {
 +        DWORD dwOptions;
 +        if (SUCCEEDED(p_file_dialog->GetOptions(&dwOptions)))
 +        {
 +            p_file_dialog->SetOptions(dwOptions | FOS_PICKFOLDERS);
 +        }
 +        HWND owner = (HWND)gViewerWindow->getPlatformWindow();
 +        pDialog = p_file_dialog;
 +        if (SUCCEEDED(p_file_dialog->Show(owner)))
 +        {
 +            IShellItem* psi;
 +            if (SUCCEEDED(p_file_dialog->GetResult(&psi)))
 +            {
 +                wchar_t* pwstr = NULL;
 +                if (SUCCEEDED(psi->GetDisplayName(SIGDN_FILESYSPATH, &pwstr)))
 +                {
 +                    mDir = ll_convert_wide_to_string(pwstr);
 +                    CoTaskMemFree(pwstr);
 +                    success = true;
 +                }
 +                psi->Release();
 +            }
 +        }
 +        pDialog = NULL;
 +        p_file_dialog->Release();
 +    }
 +
 +    ::OleUninitialize();
 +
 +    if (blocking)
 +    {
 +        send_agent_resume();
 +    }
 +
 +    // Account for the fact that the app has been stalled.
 +    LLFrameTimer::updateFrameTime();
 +    return success;
 +}
 +
 +std::string LLDirPicker::getDirName()
 +{
 +    return mDir;
 +}
 +
 +/////////////////////////////////////////////DARWIN
 +#elif LL_DARWIN
 +
 +LLDirPicker::LLDirPicker() :
 +mFileName(NULL),
 +mLocked(false)
 +{
 +    mFilePicker = new LLFilePicker();
 +    reset();
 +}
 +
 +LLDirPicker::~LLDirPicker()
 +{
 +    delete mFilePicker;
 +}
 +
 +void LLDirPicker::reset()
 +{
 +    if (mFilePicker)
 +        mFilePicker->reset();
 +}
 +
 +
 +//static
 +bool LLDirPicker::getDir(std::string* filename, bool blocking)
 +{
 +    LLFilePicker::ELoadFilter filter=LLFilePicker::FFLOAD_DIRECTORY;
 +
 +    return mFilePicker->getOpenFile(filter, true);
 +}
 +
 +std::string LLDirPicker::getDirName()
 +{
 +    return mFilePicker->getFirstFile();
 +}
 +
 +#elif LL_LINUX
 +
 +LLDirPicker::LLDirPicker() :
 +    mFileName(NULL),
 +    mLocked(false)
 +{
 +    mFilePicker = new LLFilePicker();
 +    reset();
 +}
 +
 +LLDirPicker::~LLDirPicker()
 +{
 +    delete mFilePicker;
 +}
 +
 +
 +void LLDirPicker::reset()
 +{
 +    if (mFilePicker)
 +        mFilePicker->reset();
 +}
 +
 +bool LLDirPicker::getDir(std::string* filename, bool blocking)
 +{
 +    reset();
 +
 +    // if local file browsing is turned off, return without opening dialog
 +    if (!check_local_file_access_enabled())
 +    {
 +        return false;
 +    }
 +
 +#if !LL_MESA_HEADLESS
 +
 +    if (mFilePicker)
 +    {
 +        GtkWindow* picker = mFilePicker->buildFilePicker(false, true,
 +                                 "dirpicker");
 +
 +        if (picker)
 +        {
 +           gtk_window_set_title(GTK_WINDOW(picker), LLTrans::getString("choose_the_directory").c_str());
 +           gtk_widget_show_all(GTK_WIDGET(picker));
 +           gtk_main();
 +           return (!mFilePicker->getFirstFile().empty());
 +        }
 +    }
 +#endif // !LL_MESA_HEADLESS
 +
 +    return false;
 +}
 +
 +std::string LLDirPicker::getDirName()
 +{
 +    if (mFilePicker)
 +    {
 +        return mFilePicker->getFirstFile();
 +    }
 +    return "";
 +}
 +
 +#else // not implemented
 +
 +LLDirPicker::LLDirPicker()
 +{
 +    reset();
 +}
 +
 +LLDirPicker::~LLDirPicker()
 +{
 +}
 +
 +
 +void LLDirPicker::reset()
 +{
 +}
 +
 +bool LLDirPicker::getDir(std::string* filename, bool blocking)
 +{
 +    return false;
 +}
 +
 +std::string LLDirPicker::getDirName()
 +{
 +    return "";
 +}
 +
 +#endif
 +
 +
 +LLMutex* LLDirPickerThread::sMutex = NULL;
 +std::queue<LLDirPickerThread*> LLDirPickerThread::sDeadQ;
 +
 +void LLDirPickerThread::getFile()
 +{
 +#if LL_WINDOWS
 +    start();
 +#else
 +    run();
 +#endif
 +}
 +
 +//virtual
 +void LLDirPickerThread::run()
 +{
 +#if LL_WINDOWS
 +    bool blocking = false;
 +#else
 +    bool blocking = true; // modal
 +#endif
 +
 +    LLDirPicker picker;
 +
 +    if (picker.getDir(&mProposedName, blocking))
 +    {
 +        mResponses.push_back(picker.getDirName());
 +    }
 +
 +    {
 +        LLMutexLock lock(sMutex);
 +        sDeadQ.push(this);
 +    }
 +
 +}
 +
 +//static
 +void LLDirPickerThread::initClass()
 +{
 +    sMutex = new LLMutex();
 +}
 +
 +//static
 +void LLDirPickerThread::cleanupClass()
 +{
 +    clearDead();
 +
 +    delete sMutex;
 +    sMutex = NULL;
 +}
 +
 +//static
 +void LLDirPickerThread::clearDead()
 +{
 +    if (!sDeadQ.empty())
 +    {
 +        LLMutexLock lock(sMutex);
 +        while (!sDeadQ.empty())
 +        {
 +            LLDirPickerThread* thread = sDeadQ.front();
 +            thread->notify(thread->mResponses);
 +            delete thread;
 +            sDeadQ.pop();
 +        }
 +    }
 +}
 +
 +LLDirPickerThread::LLDirPickerThread(const dir_picked_signal_t::slot_type& cb, const std::string &proposed_name)
 +    : LLThread("dir picker"),
 +    mFilePickedSignal(NULL)
 +{
 +    mFilePickedSignal = new dir_picked_signal_t();
 +    mFilePickedSignal->connect(cb);
 +}
 +
 +LLDirPickerThread::~LLDirPickerThread()
 +{
 +    delete mFilePickedSignal;
 +}
 +
 +void LLDirPickerThread::notify(const std::vector<std::string>& filenames)
 +{
 +    if (!filenames.empty())
 +    {
 +        if (mFilePickedSignal)
 +        {
 +            (*mFilePickedSignal)(filenames, mProposedName);
 +        }
 +    }
 +}
  | 
