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);
+ }
+ }
+}
|