diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 3599a1d3d..340989a05 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -132,7 +132,6 @@ set(viewer_SOURCE_FILES lldebugmessagebox.cpp lldebugview.cpp lldelayedgestureerror.cpp - lldirpicker.cpp lldrawable.cpp lldrawpoolalpha.cpp lldrawpoolavatar.cpp @@ -154,7 +153,6 @@ set(viewer_SOURCE_FILES llface.cpp llfasttimerview.cpp llfeaturemanager.cpp - llfilepicker.cpp llfirstuse.cpp llflexibleobject.cpp llfloaterabout.cpp @@ -609,7 +607,6 @@ set(viewer_HEADER_FILES lldebugmessagebox.h lldebugview.h lldelayedgestureerror.h - lldirpicker.h lldrawable.h lldrawpool.h lldrawpoolalpha.h @@ -632,7 +629,6 @@ set(viewer_HEADER_FILES llface.h llfasttimerview.h llfeaturemanager.h - llfilepicker.h llfirstuse.h llflexibleobject.h llfloaterabout.h @@ -1017,6 +1013,7 @@ set(statemachine_SOURCE_FILES set(statemachine_HEADER_FILES statemachine/aistatemachine.h statemachine/aifilepicker.h + statemachine/aidirpicker.h ) list(APPEND viewer_SOURCE_FILES ${statemachine_SOURCE_FILES}) list(APPEND viewer_HEADER_FILES ${statemachine_HEADER_FILES}) diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp index 2992e60bd..d910ab4b2 100644 --- a/indra/newview/llassetuploadresponders.cpp +++ b/indra/newview/llassetuploadresponders.cpp @@ -38,7 +38,6 @@ #include "llagent.h" #include "llcompilequeue.h" #include "llfloaterbuycurrency.h" -#include "llfilepicker.h" #include "llnotify.h" #include "llinventorymodel.h" #include "llinventoryview.h" @@ -129,7 +128,7 @@ void LLAssetUploadResponder::error(U32 statusNum, const std::string& reason) break; } LLUploadDialog::modalUploadFinished(); - LLFilePicker::instance().reset(); // unlock file picker when bulk upload fails + //AIFIXME? LLFilePicker::instance().reset(); // unlock file picker when bulk upload fails } //virtual @@ -293,7 +292,7 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content) view->getPanel()->setSelection(content["new_inventory_item"].asUUID(), TAKE_FOCUS_NO); if((LLAssetType::AT_TEXTURE == asset_type || LLAssetType::AT_SOUND == asset_type) - /* FIXME: && LLFilePicker::instance().getFileCount() <= FILE_COUNT_DISPLAY_THRESHOLD */) + /* AIFIXME: && LLFilePicker::instance().getFileCount() <= FILE_COUNT_DISPLAY_THRESHOLD */) { view->getPanel()->openSelected(); } @@ -310,7 +309,7 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content) // remove the "Uploading..." message LLUploadDialog::modalUploadFinished(); -#if 0 // FIXME: This needs to be done in some other way. +#if 0 // AIFIXME: This needs to be done in some other way. // *FIX: This is a pretty big hack. What this does is check the // file picker if there are any more pending uploads. If so, // upload that file. diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp deleted file mode 100644 index 2a325c0bb..000000000 --- a/indra/newview/llfilepicker.cpp +++ /dev/null @@ -1,1587 +0,0 @@ -/** - * @file llfilepicker.cpp - * @brief OS-specific file picker - * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llfilepicker.h" -#include "llworld.h" -#include "llviewerwindow.h" -#include "llkeyboard.h" -#include "lldir.h" -#include "llframetimer.h" -#include "lltrans.h" - -#if LL_SDL -#include "llwindowsdl.h" // for some X/GTK utils to help with filepickers -#endif // LL_SDL - -// -// Globals -// - -LLFilePicker LLFilePicker::sInstance; - -#if LL_WINDOWS -// -#define SOUND_FILTER L"Sounds (*.wav; *.ogg)\0*.wav;*.ogg\0" -#define IMAGE_FILTER L"Images (*.tga; *.bmp; *.jpg; *.jpeg; *.png; *.jp2; *.j2k; *.j2c)\0*.tga;*.bmp;*.jpg;*.jpeg;*.png;*.jp2;*.j2k;*.j2c\0" -#define INVGZ_FILTER L"Inv cache (*.inv; *.inv.gz)\0*.inv;*.inv.gz\0" -#define AO_FILTER L"Animation Override (*.ao)\0*.ao\0" -#define BLACKLIST_FILTER L"Asset Blacklist (*.blacklist)\0*.blacklist\0" -// -#define ANIM_FILTER L"Animations (*.bvh)\0*.bvh\0" -#ifdef _CORY_TESTING -#define GEOMETRY_FILTER L"SL Geometry (*.slg)\0*.slg\0" -#endif -#define XML_FILTER L"XML files (*.xml)\0*.xml\0" -#define SLOBJECT_FILTER L"Objects (*.slobject)\0*.slobject\0" -#define RAW_FILTER L"RAW files (*.raw)\0*.raw\0" -#endif - -// -// Implementation -// -LLFilePickerBase::LLFilePickerBase() - : mCurrentFile(0), - mLocked(FALSE) - -{ - reset(); - -#if LL_WINDOWS - mOFN.lStructSize = sizeof(OPENFILENAMEW); - mOFN.hwndOwner = NULL; // Set later - mOFN.hInstance = NULL; - mOFN.lpstrCustomFilter = NULL; - mOFN.nMaxCustFilter = 0; - mOFN.lpstrFile = NULL; // set in open and close - mOFN.nMaxFile = LL_MAX_PATH; - mOFN.lpstrFileTitle = NULL; - mOFN.nMaxFileTitle = 0; - mOFN.lpstrInitialDir = NULL; - mOFN.lpstrTitle = NULL; - mOFN.Flags = 0; // set in open and close - mOFN.nFileOffset = 0; - mOFN.nFileExtension = 0; - mOFN.lpstrDefExt = NULL; - mOFN.lCustData = 0L; - mOFN.lpfnHook = NULL; - mOFN.lpTemplateName = NULL; -#endif - -#if LL_DARWIN - memset(&mNavOptions, 0, sizeof(mNavOptions)); - OSStatus error = NavGetDefaultDialogCreationOptions(&mNavOptions); - if (error == noErr) - { - mNavOptions.modality = kWindowModalityAppModal; - } -#endif -} - -const std::string LLFilePickerBase::getFirstFile() -{ - mCurrentFile = 0; - return getNextFile(); -} - -const std::string LLFilePickerBase::getNextFile() -{ - if (mCurrentFile >= getFileCount()) - { - mLocked = FALSE; - return std::string(); - } - else - { - return mFiles[mCurrentFile++]; - } -} - -const std::string LLFilePickerBase::getCurFile() -{ - if (mCurrentFile >= getFileCount()) - { - mLocked = FALSE; - return std::string(); - } - else - { - return mFiles[mCurrentFile]; - } -} - -void LLFilePickerBase::reset() -{ - mLocked = FALSE; - mFiles.clear(); - mCurrentFile = 0; -} - -#if LL_WINDOWS - -BOOL LLFilePickerBase::setupFilter(ELoadFilter filter) -{ - BOOL res = TRUE; - switch (filter) - { - case FFLOAD_ALL: - mOFN.lpstrFilter = L"All Files (*.*)\0*.*\0" \ - SOUND_FILTER \ - IMAGE_FILTER \ - ANIM_FILTER \ - L"\0"; - break; - case FFLOAD_WAV: - mOFN.lpstrFilter = SOUND_FILTER \ - L"\0"; - break; - case FFLOAD_IMAGE: - mOFN.lpstrFilter = IMAGE_FILTER \ - L"\0"; - break; - case FFLOAD_ANIM: - mOFN.lpstrFilter = ANIM_FILTER \ - L"\0"; - break; -#ifdef _CORY_TESTING - case FFLOAD_GEOMETRY: - mOFN.lpstrFilter = GEOMETRY_FILTER \ - L"\0"; - break; -#endif - case FFLOAD_XML: - mOFN.lpstrFilter = XML_FILTER \ - L"\0"; - break; - case FFLOAD_SLOBJECT: - mOFN.lpstrFilter = SLOBJECT_FILTER \ - L"\0"; - break; - case FFLOAD_RAW: - mOFN.lpstrFilter = RAW_FILTER \ - L"\0"; - break; - // - case FFLOAD_INVGZ: - mOFN.lpstrFilter = INVGZ_FILTER \ - L"\0"; - break; - - case FFLOAD_AO: - mOFN.lpstrFilter = AO_FILTER \ - L"\0"; - break; - - case FFLOAD_BLACKLIST: - mOFN.lpstrFilter = BLACKLIST_FILTER \ - L"\0"; - break; - // - default: - res = FALSE; - break; - } - return res; -} - -BOOL LLFilePickerBase::getOpenFile(ELoadFilter filter) -{ - if( mLocked ) - { - return FALSE; - } - BOOL success = FALSE; - - // don't provide default file selection - mFilesW[0] = '\0'; - - mOFN.hwndOwner = (HWND)gViewerWindow->getPlatformWindow(); - mOFN.lpstrFile = mFilesW; - mOFN.nMaxFile = SINGLE_FILENAME_BUFFER_SIZE; - mOFN.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR ; - mOFN.nFilterIndex = 1; - - setupFilter(filter); - - // Modal, so pause agent - send_agent_pause(); - - reset(); - - // NOTA BENE: hitting the file dialog triggers a window focus event, destroying the selection manager!! - success = GetOpenFileName(&mOFN); - if (success) - { - std::string filename = utf16str_to_utf8str(llutf16string(mFilesW)); - mFiles.push_back(filename); - } - send_agent_resume(); - - // Account for the fact that the app has been stalled. - LLFrameTimer::updateFrameTime(); - return success; -} - -BOOL LLFilePickerBase::getMultipleOpenFiles(ELoadFilter filter) -{ - if( mLocked ) - { - return FALSE; - } - BOOL success = FALSE; - - // don't provide default file selection - mFilesW[0] = '\0'; - - mOFN.hwndOwner = (HWND)gViewerWindow->getPlatformWindow(); - mOFN.lpstrFile = mFilesW; - mOFN.nFilterIndex = 1; - mOFN.nMaxFile = FILENAME_BUFFER_SIZE; - mOFN.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR | - OFN_EXPLORER | OFN_ALLOWMULTISELECT; - - setupFilter(filter); - - reset(); - - // Modal, so pause agent - send_agent_pause(); - // NOTA BENE: hitting the file dialog triggers a window focus event, destroying the selection manager!! - success = GetOpenFileName(&mOFN); // pauses until ok or cancel. - if( success ) - { - // The getopenfilename api doesn't tell us if we got more than - // one file, so we have to test manually by checking string - // lengths. - if( wcslen(mOFN.lpstrFile) > mOFN.nFileOffset ) /*Flawfinder: ignore*/ - { - std::string filename = utf16str_to_utf8str(llutf16string(mFilesW)); - mFiles.push_back(filename); - } - else - { - mLocked = TRUE; - WCHAR* tptrw = mFilesW; - std::string dirname; - while(1) - { - if (*tptrw == 0 && *(tptrw+1) == 0) // double '\0' - break; - if (*tptrw == 0) - tptrw++; // shouldn't happen? - std::string filename = utf16str_to_utf8str(llutf16string(tptrw)); - if (dirname.empty()) - dirname = filename + "\\"; - else - mFiles.push_back(dirname + filename); - tptrw += filename.size(); - } - } - } - send_agent_resume(); - - // Account for the fact that the app has been stalled. - LLFrameTimer::updateFrameTime(); - return success; -} - -BOOL LLFilePickerBase::getSaveFile(ESaveFilter filter, const std::string& filename) -{ - if( mLocked ) - { - return FALSE; - } - BOOL success = FALSE; - - mOFN.lpstrFile = mFilesW; - if (!filename.empty()) - { - llutf16string tstring = utf8str_to_utf16str(filename); - wcsncpy(mFilesW, tstring.c_str(), FILENAME_BUFFER_SIZE); } /*Flawfinder: ignore*/ - else - { - mFilesW[0] = '\0'; - } - mOFN.hwndOwner = (HWND)gViewerWindow->getPlatformWindow(); - - switch( filter ) - { - case FFSAVE_ALL: - mOFN.lpstrDefExt = NULL; - mOFN.lpstrFilter = - L"All Files (*.*)\0*.*\0" \ - L"WAV Sounds (*.wav)\0*.wav\0" \ - L"Targa, Bitmap Images (*.tga; *.bmp)\0*.tga;*.bmp\0" \ - L"\0"; - break; - case FFSAVE_WAV: - if (filename.empty()) - { - wcsncpy( mFilesW,L"untitled.wav", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ - } - mOFN.lpstrDefExt = L"wav"; - mOFN.lpstrFilter = - L"WAV Sounds (*.wav)\0*.wav\0" \ - L"\0"; - break; - case FFSAVE_TGA: - if (filename.empty()) - { - wcsncpy( mFilesW,L"untitled.tga", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ - } - mOFN.lpstrDefExt = L"tga"; - mOFN.lpstrFilter = - L"Targa Images (*.tga)\0*.tga\0" \ - L"\0"; - break; - case FFSAVE_BMP: - if (filename.empty()) - { - wcsncpy( mFilesW,L"untitled.bmp", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ - } - mOFN.lpstrDefExt = L"bmp"; - mOFN.lpstrFilter = - L"Bitmap Images (*.bmp)\0*.bmp\0" \ - L"\0"; - break; - case FFSAVE_PNG: - if (filename.empty()) - { - wcsncpy( mFilesW,L"untitled.png", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ - } - mOFN.lpstrDefExt = L"png"; - mOFN.lpstrFilter = - L"PNG Images (*.png)\0*.png\0" \ - L"\0"; - break; - case FFSAVE_JPEG: - if (filename.empty()) - { - wcsncpy( mFilesW,L"untitled.jpeg", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ - } - mOFN.lpstrDefExt = L"jpg"; - mOFN.lpstrFilter = - L"JPEG Images (*.jpg *.jpeg)\0*.jpg;*.jpeg\0" \ - L"\0"; - break; - case FFSAVE_AVI: - if (filename.empty()) - { - wcsncpy( mFilesW,L"untitled.avi", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ - } - mOFN.lpstrDefExt = L"avi"; - mOFN.lpstrFilter = - L"AVI Movie File (*.avi)\0*.avi\0" \ - L"\0"; - break; - case FFSAVE_ANIM: - if (filename.empty()) - { - wcsncpy( mFilesW,L"untitled.xaf", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ - } - mOFN.lpstrDefExt = L"xaf"; - mOFN.lpstrFilter = - L"XAF Anim File (*.xaf)\0*.xaf\0" \ - L"\0"; - break; -#ifdef _CORY_TESTING - case FFSAVE_GEOMETRY: - if (filename.empty()) - { - wcsncpy( mFilesW,L"untitled.slg", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ - } - mOFN.lpstrDefExt = L"slg"; - mOFN.lpstrFilter = - L"SLG SL Geometry File (*.slg)\0*.slg\0" \ - L"\0"; - break; -#endif - case FFSAVE_XML: - if (filename.empty()) - { - wcsncpy( mFilesW,L"untitled.xml", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ - } - - mOFN.lpstrDefExt = L"xml"; - mOFN.lpstrFilter = - L"XML File (*.xml)\0*.xml\0" \ - L"\0"; - break; - case FFSAVE_COLLADA: - if (filename.empty()) - { - wcsncpy( mFilesW,L"untitled.collada", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ - } - mOFN.lpstrDefExt = L"collada"; - mOFN.lpstrFilter = - L"COLLADA File (*.collada)\0*.collada\0" \ - L"\0"; - break; - case FFSAVE_RAW: - if (filename.empty()) - { - wcsncpy( mFilesW,L"untitled.raw", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ - } - mOFN.lpstrDefExt = L"raw"; - mOFN.lpstrFilter = RAW_FILTER \ - L"\0"; - break; - case FFSAVE_J2C: - if (filename.empty()) - { - wcsncpy( mFilesW,L"untitled.j2c", FILENAME_BUFFER_SIZE); - } - mOFN.lpstrDefExt = L"j2c"; - mOFN.lpstrFilter = - L"Compressed Images (*.j2c)\0*.j2c\0" \ - L"\0"; - break; - // - case FFSAVE_ANIMATN: - if(filename.empty()) - { - wcsncpy( mFilesW,L"untitled.animatn", FILENAME_BUFFER_SIZE); - } - mOFN.lpstrDefExt = L"animatn"; - mOFN.lpstrFilter = - L"SL Animations (*.animatn)\0*.animatn\0" \ - L"\0"; - break; - case FFSAVE_OGG: - if(filename.empty()) - { - wcsncpy( mFilesW,L"untitled.ogg", FILENAME_BUFFER_SIZE); - } - mOFN.lpstrDefExt = L"ogg"; - mOFN.lpstrFilter = - L"Ogg (*.ogg)\0*.ogg\0" \ - L"\0"; - break; - case FFSAVE_NOTECARD: - if(filename.empty()) - { - wcsncpy( mFilesW,L"untitled.notecard", FILENAME_BUFFER_SIZE); - } - mOFN.lpstrDefExt = L"notecard"; - mOFN.lpstrFilter = - L"Notecards (*.notecard)\0*.notecard\0" \ - L"\0"; - break; - case FFSAVE_GESTURE: - if(filename.empty()) - { - wcsncpy( mFilesW,L"untitled.gesture", FILENAME_BUFFER_SIZE); - } - mOFN.lpstrDefExt = L"gesture"; - mOFN.lpstrFilter = - L"Gestures (*.gesture)\0*.gesture\0" \ - L"\0"; - break; - case FFSAVE_LSL: - if(filename.empty()) - { - wcsncpy( mFilesW,L"untitled.lsl", FILENAME_BUFFER_SIZE); - } - mOFN.lpstrDefExt = L"lsl"; - mOFN.lpstrFilter = - L"LSL (*.lsl)\0*.lsl\0" \ - L"\0"; - break; - case FFSAVE_SHAPE: - if(filename.empty()) - { - wcsncpy( mFilesW,L"untitled.shape", FILENAME_BUFFER_SIZE); - } - mOFN.lpstrDefExt = L"shape"; - mOFN.lpstrFilter = - L"Shapes (*.shape)\0*.shape\0" \ - L"\0"; - break; - case FFSAVE_SKIN: - if(filename.empty()) - { - wcsncpy( mFilesW,L"untitled.skin", FILENAME_BUFFER_SIZE); - } - mOFN.lpstrDefExt = L"skin"; - mOFN.lpstrFilter = - L"Skins (*.skin)\0*.skin\0" \ - L"\0"; - break; - case FFSAVE_HAIR: - if(filename.empty()) - { - wcsncpy( mFilesW,L"untitled.hair", FILENAME_BUFFER_SIZE); - } - mOFN.lpstrDefExt = L"hair"; - mOFN.lpstrFilter = - L"Hair (*.hair)\0*.hair\0" \ - L"\0"; - break; - case FFSAVE_EYES: - if(filename.empty()) - { - wcsncpy( mFilesW,L"untitled.eyes", FILENAME_BUFFER_SIZE); - } - mOFN.lpstrDefExt = L"eyes"; - mOFN.lpstrFilter = - L"Eyes (*.eyes)\0*.eyes\0" \ - L"\0"; - break; - case FFSAVE_SHIRT: - if(filename.empty()) - { - wcsncpy( mFilesW,L"untitled.shirt", FILENAME_BUFFER_SIZE); - } - mOFN.lpstrDefExt = L"shirt"; - mOFN.lpstrFilter = - L"Shirts (*.shirt)\0*.shirt\0" \ - L"\0"; - break; - case FFSAVE_PANTS: - if(filename.empty()) - { - wcsncpy( mFilesW,L"untitled.pants", FILENAME_BUFFER_SIZE); - } - mOFN.lpstrDefExt = L"pants"; - mOFN.lpstrFilter = - L"Pants (*.pants)\0*.pants\0" \ - L"\0"; - break; - case FFSAVE_SHOES: - if(filename.empty()) - { - wcsncpy( mFilesW,L"untitled.shoes", FILENAME_BUFFER_SIZE); - } - mOFN.lpstrDefExt = L"shoes"; - mOFN.lpstrFilter = - L"Shoes (*.shoes)\0*.shoes\0" \ - L"\0"; - break; - case FFSAVE_SOCKS: - if(filename.empty()) - { - wcsncpy( mFilesW,L"untitled.socks", FILENAME_BUFFER_SIZE); - } - mOFN.lpstrDefExt = L"socks"; - mOFN.lpstrFilter = - L"Socks (*.socks)\0*.socks\0" \ - L"\0"; - break; - case FFSAVE_JACKET: - if(filename.empty()) - { - wcsncpy( mFilesW,L"untitled.jacket", FILENAME_BUFFER_SIZE); - } - mOFN.lpstrDefExt = L"jacket"; - mOFN.lpstrFilter = - L"Jackets (*.jacket)\0*.jacket\0" \ - L"\0"; - break; - case FFSAVE_GLOVES: - if(filename.empty()) - { - wcsncpy( mFilesW,L"untitled.gloves", FILENAME_BUFFER_SIZE); - } - mOFN.lpstrDefExt = L"gloves"; - mOFN.lpstrFilter = - L"Gloves (*.gloves)\0*.gloves\0" \ - L"\0"; - break; - case FFSAVE_UNDERSHIRT: - if(filename.empty()) - { - wcsncpy( mFilesW,L"untitled.undershirt", FILENAME_BUFFER_SIZE); - } - mOFN.lpstrDefExt = L"undershirt"; - mOFN.lpstrFilter = - L"Undershirts (*.undershirt)\0*.undershirt\0" \ - L"\0"; - break; - case FFSAVE_UNDERPANTS: - if(filename.empty()) - { - wcsncpy( mFilesW,L"untitled.underpants", FILENAME_BUFFER_SIZE); - } - mOFN.lpstrDefExt = L"underpants"; - mOFN.lpstrFilter = - L"Underpants (*.underpants)\0*.underpants\0" \ - L"\0"; - break; - case FFSAVE_SKIRT: - if(filename.empty()) - { - wcsncpy( mFilesW,L"untitled.skirt", FILENAME_BUFFER_SIZE); - } - mOFN.lpstrDefExt = L"skirt"; - mOFN.lpstrFilter = - L"Skirts (*.skirt)\0*.skirt\0" \ - L"\0"; - break; - case FFSAVE_LANDMARK: - if(filename.empty()) - { - wcsncpy( mFilesW,L"untitled.landmark", FILENAME_BUFFER_SIZE); - } - mOFN.lpstrDefExt = L"landmark"; - mOFN.lpstrFilter = - L"Landmarks (*.landmark)\0*.landmark\0" \ - L"\0"; - break; - case FFSAVE_AO: - if(filename.empty()) - { - wcsncpy( mFilesW,L"untitled.ao", FILENAME_BUFFER_SIZE); - } - mOFN.lpstrDefExt = L"ao"; - mOFN.lpstrFilter = - L"Animation overrides (*.ao)\0*.ao\0" \ - L"\0"; - break; - case FFSAVE_INVGZ: - if(filename.empty()) - { - wcsncpy( mFilesW,L"untitled.inv", FILENAME_BUFFER_SIZE); - } - mOFN.lpstrDefExt = L".inv"; - mOFN.lpstrFilter = - L"InvCache (*.inv)\0*.inv\0" \ - L"\0"; - break; - case FFSAVE_BLACKLIST: - if(filename.empty()) - { - wcsncpy( mFilesW,L"untitled.blacklist", FILENAME_BUFFER_SIZE); - } - mOFN.lpstrDefExt = L".blacklist"; - mOFN.lpstrFilter = - L"Asset Blacklists (*.blacklist)\0*.blacklist\0" \ - L"\0"; - break; - case FFSAVE_PHYSICS: - if(filename.empty()) - { - wcsncpy( mFilesW,L"untitled.phy", FILENAME_BUFFER_SIZE); - } - mOFN.lpstrDefExt = L"phy"; - mOFN.lpstrFilter = - L"Landmarks (*.phy)\0*.phy\0" \ - L"\0"; - break; - // - default: - return FALSE; - } - - - mOFN.nMaxFile = SINGLE_FILENAME_BUFFER_SIZE; - mOFN.Flags = OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST; - - reset(); - - // Modal, so pause agent - send_agent_pause(); - { - // NOTA BENE: hitting the file dialog triggers a window focus event, destroying the selection manager!! - success = GetSaveFileName(&mOFN); - if (success) - { - std::string filename = utf16str_to_utf8str(llutf16string(mFilesW)); - mFiles.push_back(filename); - } - gKeyboard->resetKeys(); - } - send_agent_resume(); - - // Account for the fact that the app has been stalled. - LLFrameTimer::updateFrameTime(); - return success; -} - -#elif LL_DARWIN - -Boolean LLFilePickerBase::navOpenFilterProc(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode) -{ - Boolean result = true; - ELoadFilter filter = *((ELoadFilter*) callBackUD); - OSStatus error = noErr; - - if (filterMode == kNavFilteringBrowserList && filter != FFLOAD_ALL && (theItem->descriptorType == typeFSRef || theItem->descriptorType == typeFSS)) - { - // navInfo is only valid for typeFSRef and typeFSS - NavFileOrFolderInfo *navInfo = (NavFileOrFolderInfo*) info; - if (!navInfo->isFolder) - { - AEDesc desc; - error = AECoerceDesc(theItem, typeFSRef, &desc); - if (error == noErr) - { - FSRef fileRef; - error = AEGetDescData(&desc, &fileRef, sizeof(fileRef)); - if (error == noErr) - { - LSItemInfoRecord fileInfo; - error = LSCopyItemInfoForRef(&fileRef, kLSRequestExtension | kLSRequestTypeCreator, &fileInfo); - if (error == noErr) - { - if (filter == FFLOAD_IMAGE) - { - if (fileInfo.filetype != 'JPEG' && fileInfo.filetype != 'JPG ' && - fileInfo.filetype != 'BMP ' && fileInfo.filetype != 'TGA ' && - fileInfo.filetype != 'BMPf' && fileInfo.filetype != 'TPIC' && - fileInfo.filetype != 'PNG ' && - (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("jpeg"), kCFCompareCaseInsensitive) != kCFCompareEqualTo && - CFStringCompare(fileInfo.extension, CFSTR("jpg"), kCFCompareCaseInsensitive) != kCFCompareEqualTo && - CFStringCompare(fileInfo.extension, CFSTR("bmp"), kCFCompareCaseInsensitive) != kCFCompareEqualTo && - CFStringCompare(fileInfo.extension, CFSTR("tga"), kCFCompareCaseInsensitive) != kCFCompareEqualTo && - CFStringCompare(fileInfo.extension, CFSTR("png"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) - ) - { - result = false; - } - } - else if (filter == FFLOAD_WAV) - { - if (fileInfo.filetype != 'WAVE' && fileInfo.filetype != 'WAV ' && - (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("wave"), kCFCompareCaseInsensitive) != kCFCompareEqualTo && - CFStringCompare(fileInfo.extension, CFSTR("wav"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) - ) - { - result = false; - } - } - else if (filter == FFLOAD_ANIM) - { - if (fileInfo.filetype != 'BVH ' && - (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("bvh"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) - ) - { - result = false; - } - } - else if (filter == FFLOAD_XML) - { - if (fileInfo.filetype != 'XML ' && - (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("xml"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) - ) - { - result = false; - } - } -#ifdef _CORY_TESTING - else if (filter == FFLOAD_GEOMETRY) - { - if (fileInfo.filetype != 'SLG ' && - (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("slg"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) - ) - { - result = false; - } - } -#endif - else if (filter == FFLOAD_SLOBJECT) - { - llwarns << "*** navOpenFilterProc: FFLOAD_SLOBJECT NOT IMPLEMENTED ***" << llendl; - } - else if (filter == FFLOAD_RAW) - { - if (fileInfo.filetype != '\?\?\?\?' && - (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("raw"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) - ) - { - result = false; - } - } - - if (fileInfo.extension) - { - CFRelease(fileInfo.extension); - } - } - } - AEDisposeDesc(&desc); - } - } - } - return result; -} - -OSStatus LLFilePickerBase::doNavChooseDialog(ELoadFilter filter) -{ - OSStatus error = noErr; - NavDialogRef navRef = NULL; - NavReplyRecord navReply; - - memset(&navReply, 0, sizeof(navReply)); - - // NOTE: we are passing the address of a local variable here. - // This is fine, because the object this call creates will exist for less than the lifetime of this function. - // (It is destroyed by NavDialogDispose() below.) - error = NavCreateChooseFileDialog(&mNavOptions, NULL, NULL, NULL, navOpenFilterProc, (void*)(&filter), &navRef); - - gViewerWindow->mWindow->beforeDialog(); - - if (error == noErr) - error = NavDialogRun(navRef); - - gViewerWindow->mWindow->afterDialog(); - - if (error == noErr) - error = NavDialogGetReply(navRef, &navReply); - - if (navRef) - NavDialogDispose(navRef); - - if (error == noErr && navReply.validRecord) - { - SInt32 count = 0; - SInt32 index; - - // AE indexes are 1 based... - error = AECountItems(&navReply.selection, &count); - for (index = 1; index <= count; index++) - { - FSRef fsRef; - AEKeyword theAEKeyword; - DescType typeCode; - Size actualSize = 0; - char path[MAX_PATH]; /*Flawfinder: ignore*/ - - memset(&fsRef, 0, sizeof(fsRef)); - error = AEGetNthPtr(&navReply.selection, index, typeFSRef, &theAEKeyword, &typeCode, &fsRef, sizeof(fsRef), &actualSize); - - if (error == noErr) - error = FSRefMakePath(&fsRef, (UInt8*) path, sizeof(path)); - - if (error == noErr) - mFiles.push_back(std::string(path)); - } - } - - return error; -} - -OSStatus LLFilePickerBase::doNavSaveDialog(ESaveFilter filter, const std::string& filename) -{ - OSStatus error = noErr; - NavDialogRef navRef = NULL; - NavReplyRecord navReply; - - memset(&navReply, 0, sizeof(navReply)); - - // Setup the type, creator, and extension - OSType type, creator; - CFStringRef extension = NULL; - switch (filter) - { - case FFSAVE_WAV: - type = 'WAVE'; - creator = 'TVOD'; - extension = CFSTR(".wav"); - break; - - case FFSAVE_TGA: - type = 'TPIC'; - creator = 'prvw'; - extension = CFSTR(".tga"); - break; - - case FFSAVE_BMP: - type = 'BMPf'; - creator = 'prvw'; - extension = CFSTR(".bmp"); - break; - case FFSAVE_JPEG: - type = 'JPEG'; - creator = 'prvw'; - extension = CFSTR(".jpeg"); - break; - case FFSAVE_PNG: - type = 'PNG '; - creator = 'prvw'; - extension = CFSTR(".png"); - break; - case FFSAVE_AVI: - type = '\?\?\?\?'; - creator = '\?\?\?\?'; - extension = CFSTR(".mov"); - break; - - case FFSAVE_ANIM: - type = '\?\?\?\?'; - creator = '\?\?\?\?'; - extension = CFSTR(".xaf"); - break; - -#ifdef _CORY_TESTING - case FFSAVE_GEOMETRY: - type = '\?\?\?\?'; - creator = '\?\?\?\?'; - extension = CFSTR(".slg"); - break; -#endif - case FFSAVE_RAW: - type = '\?\?\?\?'; - creator = '\?\?\?\?'; - extension = CFSTR(".raw"); - break; - - case FFSAVE_J2C: - type = '\?\?\?\?'; - creator = 'prvw'; - extension = CFSTR(".j2c"); - break; - - case FFSAVE_ALL: - default: - type = '\?\?\?\?'; - creator = '\?\?\?\?'; - extension = CFSTR(""); - break; - } - - // Create the dialog - error = NavCreatePutFileDialog(&mNavOptions, type, creator, NULL, NULL, &navRef); - if (error == noErr) - { - CFStringRef nameString = NULL; - bool hasExtension = true; - - // Create a CFString of the initial file name - if (!filename.empty()) - nameString = CFStringCreateWithCString(NULL, filename.c_str(), kCFStringEncodingUTF8); - else - nameString = CFSTR("Untitled"); - - // Add the extension if one was not provided - if (nameString && !CFStringHasSuffix(nameString, extension)) - { - CFStringRef tempString = nameString; - hasExtension = false; - nameString = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), tempString, extension); - CFRelease(tempString); - } - - // Set the name in the dialog - if (nameString) - { - error = NavDialogSetSaveFileName(navRef, nameString); - CFRelease(nameString); - } - else - { - error = paramErr; - } - } - - gViewerWindow->mWindow->beforeDialog(); - - // Run the dialog - if (error == noErr) - error = NavDialogRun(navRef); - - gViewerWindow->mWindow->afterDialog(); - - if (error == noErr) - error = NavDialogGetReply(navRef, &navReply); - - if (navRef) - NavDialogDispose(navRef); - - if (error == noErr && navReply.validRecord) - { - SInt32 count = 0; - - // AE indexes are 1 based... - error = AECountItems(&navReply.selection, &count); - if (count > 0) - { - // Get the FSRef to the containing folder - FSRef fsRef; - AEKeyword theAEKeyword; - DescType typeCode; - Size actualSize = 0; - - memset(&fsRef, 0, sizeof(fsRef)); - error = AEGetNthPtr(&navReply.selection, 1, typeFSRef, &theAEKeyword, &typeCode, &fsRef, sizeof(fsRef), &actualSize); - - if (error == noErr) - { - char path[PATH_MAX]; /*Flawfinder: ignore*/ - char newFileName[SINGLE_FILENAME_BUFFER_SIZE]; /*Flawfinder: ignore*/ - - error = FSRefMakePath(&fsRef, (UInt8*)path, PATH_MAX); - if (error == noErr) - { - if (CFStringGetCString(navReply.saveFileName, newFileName, sizeof(newFileName), kCFStringEncodingUTF8)) - { - mFiles.push_back(std::string(path) + "/" + std::string(newFileName)); - } - else - { - error = paramErr; - } - } - else - { - error = paramErr; - } - } - } - } - - return error; -} - -BOOL LLFilePickerBase::getOpenFile(ELoadFilter filter) -{ - if( mLocked ) - return FALSE; - - BOOL success = FALSE; - - OSStatus error = noErr; - - reset(); - - mNavOptions.optionFlags &= ~kNavAllowMultipleFiles; - // Modal, so pause agent - send_agent_pause(); - { - error = doNavChooseDialog(filter); - } - send_agent_resume(); - if (error == noErr) - { - if (getFileCount()) - success = true; - } - - // Account for the fact that the app has been stalled. - LLFrameTimer::updateFrameTime(); - return success; -} - -BOOL LLFilePickerBase::getMultipleOpenFiles(ELoadFilter filter) -{ - if( mLocked ) - return FALSE; - - BOOL success = FALSE; - - OSStatus error = noErr; - - reset(); - - mNavOptions.optionFlags |= kNavAllowMultipleFiles; - // Modal, so pause agent - send_agent_pause(); - { - error = doNavChooseDialog(filter); - } - send_agent_resume(); - if (error == noErr) - { - if (getFileCount()) - success = true; - if (getFileCount() > 1) - mLocked = TRUE; - } - - // Account for the fact that the app has been stalled. - LLFrameTimer::updateFrameTime(); - return success; -} - -BOOL LLFilePickerBase::getSaveFile(ESaveFilter filter, const std::string& filename) -{ - if( mLocked ) - return FALSE; - BOOL success = FALSE; - OSStatus error = noErr; - - reset(); - - mNavOptions.optionFlags &= ~kNavAllowMultipleFiles; - - // Modal, so pause agent - send_agent_pause(); - { - error = doNavSaveDialog(filter, filename); - } - send_agent_resume(); - if (error == noErr) - { - if (getFileCount()) - success = true; - } - - // Account for the fact that the app has been stalled. - LLFrameTimer::updateFrameTime(); - return success; -} - -#elif LL_LINUX || LL_SOLARIS - -# if LL_GTK - -// static -void LLFilePickerBase::add_to_selectedfiles(gpointer data, gpointer user_data) -{ - // We need to run g_filename_to_utf8 in the user's locale - std::string saved_locale(setlocale(LC_ALL, NULL)); - setlocale(LC_ALL, ""); - - LLFilePickerBase* picker = (LLFilePickerBase*) user_data; - GError *error = NULL; - gchar* filename_utf8 = g_filename_to_utf8((gchar*)data, - -1, NULL, NULL, &error); - if (error) - { - // *FIXME. - // This condition should really be notified to the user, e.g. - // through a message box. Just logging it is inappropriate. - - // g_filename_display_name is ideal, but >= glib 2.6, so: - // a hand-rolled hacky makeASCII which disallows control chars - std::string display_name; - for (const gchar *str = (const gchar *)data; *str; str++) - { - display_name += (char)((*str >= 0x20 && *str <= 0x7E) ? *str : '?'); - } - llwarns << "g_filename_to_utf8 failed on \"" << display_name << "\": " << error->message << llendl; - } - - if (filename_utf8) - { - picker->mFiles.push_back(std::string(filename_utf8)); - lldebugs << "ADDED FILE " << filename_utf8 << llendl; - g_free(filename_utf8); - } - - setlocale(LC_ALL, saved_locale.c_str()); -} - -// static -void LLFilePickerBase::chooser_responder(GtkWidget *widget, gint response, gpointer user_data) -{ - LLFilePicker* picker = (LLFilePicker*)user_data; - - lldebugs << "GTK DIALOG RESPONSE " << response << llendl; - - if (response == GTK_RESPONSE_ACCEPT) - { - GSList *file_list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(widget)); - g_slist_foreach(file_list, (GFunc)add_to_selectedfiles, user_data); - g_slist_foreach(file_list, (GFunc)g_free, NULL); - g_slist_free (file_list); - } - - // set the default path for this usage context. - picker->mContextToPathMap[picker->mCurContextName] = - gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(widget)); - - gtk_widget_destroy(widget); - gtk_main_quit(); -} - - -GtkWindow* LLFilePickerBase::buildFilePicker(bool is_save, bool is_folder, std::string context) -{ - if (LLWindowSDL::ll_try_gtk_init()) - { - GtkWidget *win = NULL; - GtkFileChooserAction pickertype = - is_save? - (is_folder? - GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER : - GTK_FILE_CHOOSER_ACTION_SAVE) : - (is_folder? - GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER : - GTK_FILE_CHOOSER_ACTION_OPEN); - - win = gtk_file_chooser_dialog_new(NULL, NULL, - pickertype, - GTK_STOCK_CANCEL, - GTK_RESPONSE_CANCEL, - is_folder ? - GTK_STOCK_APPLY : - (is_save ? - GTK_STOCK_SAVE : - GTK_STOCK_OPEN), - GTK_RESPONSE_ACCEPT, - (gchar *)NULL); - mCurContextName = context; - - // get the default path for this usage context if it's been - // seen before. - std::map::iterator - this_path = mContextToPathMap.find(context); - if (this_path != mContextToPathMap.end()) - { - gtk_file_chooser_set_current_folder - (GTK_FILE_CHOOSER(win), - this_path->second.c_str()); - } - -# if LL_X11 - // Make GTK tell the window manager to associate this - // dialog with our non-GTK raw X11 window, which should try - // to keep it on top etc. - Window XWindowID = LLWindowSDL::get_SDL_XWindowID(); - if (None != XWindowID) - { - gtk_widget_realize(GTK_WIDGET(win)); // so we can get its gdkwin - GdkWindow *gdkwin = gdk_window_foreign_new(XWindowID); - gdk_window_set_transient_for(GTK_WIDGET(win)->window, - gdkwin); - } - else - { - llwarns << "Hmm, couldn't get xwid to use for transient." << llendl; - } -# endif //LL_X11 - - g_signal_connect (GTK_FILE_CHOOSER(win), - "response", - G_CALLBACK(LLFilePickerBase::chooser_responder), - this); - - gtk_window_set_modal(GTK_WINDOW(win), TRUE); - - /* GTK 2.6: if (is_folder) - gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(win), - TRUE); */ - - return GTK_WINDOW(win); - } - else - { - return NULL; - } -} - -static void add_common_filters_to_gtkchooser(GtkFileFilter *gfilter, - GtkWindow *picker, - std::string filtername) -{ - gtk_file_filter_set_name(gfilter, filtername.c_str()); - gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker), - gfilter); - GtkFileFilter *allfilter = gtk_file_filter_new(); - gtk_file_filter_add_pattern(allfilter, "*"); - gtk_file_filter_set_name(allfilter, LLTrans::getString("all_files").c_str()); - gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker), allfilter); - gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(picker), gfilter); -} - -static std::string add_simple_pattern_filter_to_gtkchooser(GtkWindow *picker, - std::string pattern, - std::string filtername) -{ - GtkFileFilter *gfilter = gtk_file_filter_new(); - gtk_file_filter_add_pattern(gfilter, pattern.c_str()); - add_common_filters_to_gtkchooser(gfilter, picker, filtername); - return filtername; -} - -static std::string add_simple_mime_filter_to_gtkchooser(GtkWindow *picker, - std::string mime, - std::string filtername) -{ - GtkFileFilter *gfilter = gtk_file_filter_new(); - gtk_file_filter_add_mime_type(gfilter, mime.c_str()); - add_common_filters_to_gtkchooser(gfilter, picker, filtername); - return filtername; -} - -static std::string add_wav_filter_to_gtkchooser(GtkWindow *picker) -{ - return add_simple_mime_filter_to_gtkchooser(picker, "audio/x-wav", - LLTrans::getString("sound_files") + " (*.wav)"); -} - -static std::string add_bvh_filter_to_gtkchooser(GtkWindow *picker) -{ - return add_simple_pattern_filter_to_gtkchooser(picker, "*.bvh", - LLTrans::getString("animation_files") + " (*.bvh)"); -} - -static std::string add_xml_filter_to_gtkchooser(GtkWindow *picker) -{ - return add_simple_mime_filter_to_gtkchooser(picker, "text/xml", - LLTrans::getString("xml_file") + " (*.xml)"); -} - -static std::string add_imageload_filter_to_gtkchooser(GtkWindow *picker) -{ - GtkFileFilter *gfilter = gtk_file_filter_new(); - gtk_file_filter_add_pattern(gfilter, "*.tga"); - gtk_file_filter_add_mime_type(gfilter, "image/jpeg"); - gtk_file_filter_add_mime_type(gfilter, "image/png"); - gtk_file_filter_add_mime_type(gfilter, "image/bmp"); - std::string filtername = LLTrans::getString("image_files") + " (*.tga; *.bmp; *.jpg; *.png)"; - add_common_filters_to_gtkchooser(gfilter, picker, filtername); - return filtername; -} - - -BOOL LLFilePickerBase::getSaveFile( ESaveFilter filter, const std::string& filename ) -{ - BOOL rtn = FALSE; - - gViewerWindow->mWindow->beforeDialog(); - - reset(); - - GtkWindow* picker = buildFilePicker(true, false, "savefile"); - - if (picker) - { - std::string suggest_name = "untitled"; - std::string suggest_ext = ""; - std::string caption = LLTrans::getString("save_file_verb") + " "; - switch (filter) - { - case FFSAVE_WAV: - caption += add_wav_filter_to_gtkchooser(picker); - suggest_ext = ".wav"; - break; - case FFSAVE_TGA: - caption += add_simple_pattern_filter_to_gtkchooser - (picker, "*.tga", LLTrans::getString("targa_image_files") + " (*.tga)"); - suggest_ext = ".tga"; - break; - case FFSAVE_BMP: - caption += add_simple_mime_filter_to_gtkchooser - (picker, "image/bmp", LLTrans::getString("bitmap_image_files") + " (*.bmp)"); - suggest_ext = ".bmp"; - break; - case FFSAVE_AVI: - caption += add_simple_mime_filter_to_gtkchooser - (picker, "video/x-msvideo", - LLTrans::getString("avi_movie_file") + " (*.avi)"); - suggest_ext = ".avi"; - break; - case FFSAVE_ANIM: - caption += add_simple_pattern_filter_to_gtkchooser - (picker, "*.xaf", LLTrans::getString("xaf_animation_file") + " (*.xaf)"); - suggest_ext = ".xaf"; - break; - case FFSAVE_XML: - caption += add_simple_pattern_filter_to_gtkchooser - (picker, "*.xml", LLTrans::getString("xml_file") + " (*.xml)"); - suggest_ext = ".xml"; - break; - case FFSAVE_RAW: - caption += add_simple_pattern_filter_to_gtkchooser - (picker, "*.raw", LLTrans::getString("raw_file") + " (*.raw)"); - suggest_ext = ".raw"; - break; - case FFSAVE_J2C: - caption += add_simple_mime_filter_to_gtkchooser - (picker, "images/jp2", - LLTrans::getString("compressed_image_files") + " (*.j2c)"); - suggest_ext = ".j2c"; - break; - default:; - break; - } - - gtk_window_set_title(GTK_WINDOW(picker), caption.c_str()); - - if (filename.empty()) - { - suggest_name += suggest_ext; - - gtk_file_chooser_set_current_name - (GTK_FILE_CHOOSER(picker), - suggest_name.c_str()); - } - else - { - gtk_file_chooser_set_current_name - (GTK_FILE_CHOOSER(picker), filename.c_str()); - } - - gtk_widget_show_all(GTK_WIDGET(picker)); - gtk_main(); - - rtn = (getFileCount() == 1); - } - - gViewerWindow->mWindow->afterDialog(); - - return rtn; -} - -BOOL LLFilePickerBase::getOpenFile( ELoadFilter filter ) -{ - BOOL rtn = FALSE; - - gViewerWindow->mWindow->beforeDialog(); - - reset(); - - GtkWindow* picker = buildFilePicker(false, false, "openfile"); - - if (picker) - { - std::string caption = LLTrans::getString("load_file_verb") + " "; - std::string filtername = ""; - switch (filter) - { - case FFLOAD_WAV: - filtername = add_wav_filter_to_gtkchooser(picker); - break; - case FFLOAD_ANIM: - filtername = add_bvh_filter_to_gtkchooser(picker); - break; - case FFLOAD_IMAGE: - filtername = add_imageload_filter_to_gtkchooser(picker); - break; - case FFLOAD_XML: - filtername = add_xml_filter_to_gtkchooser(picker); - break; - default:; - break; - } - - caption += filtername; - - gtk_window_set_title(GTK_WINDOW(picker), caption.c_str()); - - gtk_widget_show_all(GTK_WIDGET(picker)); - gtk_main(); - - rtn = (getFileCount() == 1); - } - - gViewerWindow->mWindow->afterDialog(); - - return rtn; -} - -BOOL LLFilePickerBase::getMultipleOpenFiles( ELoadFilter filter ) -{ - BOOL rtn = FALSE; - - gViewerWindow->mWindow->beforeDialog(); - - reset(); - - GtkWindow* picker = buildFilePicker(false, false, "openfile"); - - if (picker) - { - gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER(picker), - TRUE); - - gtk_window_set_title(GTK_WINDOW(picker), LLTrans::getString("load_files").c_str()); - - gtk_widget_show_all(GTK_WIDGET(picker)); - gtk_main(); - rtn = !mFiles.empty(); - } - - gViewerWindow->mWindow->afterDialog(); - - return rtn; -} - -# else // LL_GTK - -// Hacky stubs designed to facilitate fake getSaveFile and getOpenFile with -// static results, when we don't have a real filepicker. - -BOOL LLFilePickerBase::getSaveFile( ESaveFilter filter, const std::string& filename ) -{ - reset(); - - llinfos << "getSaveFile suggested filename is [" << filename - << "]" << llendl; - if (!filename.empty()) - { - mFiles.push_back(gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter() + filename); - return TRUE; - } - return FALSE; -} - -BOOL LLFilePickerBase::getOpenFile( ELoadFilter filter ) -{ - reset(); - - // HACK: Static filenames for 'open' until we implement filepicker - std::string filename = gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter() + "upload"; - switch (filter) - { - case FFLOAD_WAV: filename += ".wav"; break; - case FFLOAD_IMAGE: filename += ".tga"; break; - case FFLOAD_ANIM: filename += ".bvh"; break; - case FFLOAD_XML: filename += ".xml"; break; - default: break; - } - mFiles.push_back(filename); - llinfos << "getOpenFile: Will try to open file: " << hackyfilename << llendl; - return TRUE; -} - -BOOL LLFilePickerBase::getMultipleOpenFiles( ELoadFilter filter ) -{ - reset(); - return FALSE; -} - -#endif // LL_GTK - -#else // not implemented - -BOOL LLFilePickerBase::getSaveFile( ESaveFilter filter, const std::string& filename ) -{ - reset(); - return FALSE; -} - -BOOL LLFilePickerBase::getOpenFile( ELoadFilter filter ) -{ - reset(); - return FALSE; -} - -BOOL LLFilePickerBase::getMultipleOpenFiles( ELoadFilter filter ) -{ - reset(); - return FALSE; -} - -#endif diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h deleted file mode 100644 index 3be94f8e0..000000000 --- a/indra/newview/llfilepicker.h +++ /dev/null @@ -1,230 +0,0 @@ -/** - * @file llfilepicker.h - * @brief OS-specific file picker - * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -// OS specific file selection dialog. This is implemented as a -// singleton class, so call the instance() method to get the working -// instance. When you call getMultipleOpenFile(), it locks the picker -// until you iterate to the end of the list of selected files with -// getNextFile() or call reset(). - -#ifndef LL_LLFILEPICKER_H -#define LL_LLFILEPICKER_H - -#include "stdtypes.h" - -#if LL_DARWIN -#include - -// AssertMacros.h does bad things. -#undef verify -#undef check -#undef require - -#include -#include "llstring.h" - -#endif - -// Need commdlg.h for OPENFILENAMEA -#ifdef LL_WINDOWS -#include -#endif - -// mostly for Linux, possible on others -#if LL_GTK -# include "gtk/gtk.h" -#endif // LL_GTK - -// also mostly for Linux, for some X11-specific filepicker usability tweaks -#if LL_X11 -#include "SDL/SDL_syswm.h" -#endif - -// This class is used as base class of a singleton and is therefore not -// allowed to have any static members or static local variables! -class LLFilePickerBase -{ -public: - enum ELoadFilter - { - FFLOAD_ALL = 1, - FFLOAD_WAV = 2, - FFLOAD_IMAGE = 3, - FFLOAD_ANIM = 4, -#ifdef _CORY_TESTING - FFLOAD_GEOMETRY = 5, -#endif - FFLOAD_XML = 6, - FFLOAD_SLOBJECT = 7, - FFLOAD_RAW = 8, - // - FFLOAD_INVGZ = 9, - FFLOAD_AO = 10, - FFLOAD_BLACKLIST = 11 - // - }; - - enum ESaveFilter - { - FFSAVE_ALL = 1, - FFSAVE_WAV = 3, - FFSAVE_TGA = 4, - FFSAVE_BMP = 5, - FFSAVE_AVI = 6, - FFSAVE_ANIM = 7, -#ifdef _CORY_TESTING - FFSAVE_GEOMETRY = 8, -#endif - FFSAVE_XML = 9, - FFSAVE_COLLADA = 10, - FFSAVE_RAW = 11, - FFSAVE_J2C = 12, - FFSAVE_PNG = 13, - FFSAVE_JPEG = 14, - // - FFSAVE_ANIMATN = 15, - FFSAVE_OGG = 16, - FFSAVE_NOTECARD = 17, - FFSAVE_GESTURE = 18, - FFSAVE_LSL = 19, - // good grief - FFSAVE_SHAPE = 20, - FFSAVE_SKIN = 21, - FFSAVE_HAIR = 22, - FFSAVE_EYES = 23, - FFSAVE_SHIRT = 24, - FFSAVE_PANTS = 25, - FFSAVE_SHOES = 26, - FFSAVE_SOCKS = 27, - FFSAVE_JACKET = 28, - FFSAVE_GLOVES = 29, - FFSAVE_UNDERSHIRT = 30, - FFSAVE_UNDERPANTS = 31, - FFSAVE_SKIRT = 32, - FFSAVE_INVGZ = 33, - FFSAVE_LANDMARK = 34, - FFSAVE_AO = 35, - FFSAVE_BLACKLIST = 36, - FFSAVE_PHYSICS = 37, - // - }; - - // open the dialog. This is a modal operation - BOOL getSaveFile( ESaveFilter filter = FFSAVE_ALL, const std::string& filename = LLStringUtil::null ); - BOOL getOpenFile( ELoadFilter filter = FFLOAD_ALL ); - BOOL getMultipleOpenFiles( ELoadFilter filter = FFLOAD_ALL ); - - // Get the filename(s) found. getFirstFile() sets the pointer to - // the start of the structure and allows the start of iteration. - const std::string getFirstFile(); - - // getNextFile() increments the internal representation and - // returns the next file specified by the user. Returns NULL when - // no more files are left. Further calls to getNextFile() are - // undefined. - const std::string getNextFile(); - - // This utility function extracts the current file name without - // doing any incrementing. - const std::string getCurFile(); - - // Returns the index of the current file. - S32 getCurFileNum() const { return mCurrentFile; } - - S32 getFileCount() const { return (S32)mFiles.size(); } - - // See llvfs/lldir.h : getBaseFileName and getDirName to extract base or directory names - - // clear any lists of buffers or whatever, and make sure the file - // picker isn't locked. - void reset(); - -private: - enum - { - SINGLE_FILENAME_BUFFER_SIZE = 1024, - //FILENAME_BUFFER_SIZE = 65536 - FILENAME_BUFFER_SIZE = 65000 - }; - -#if LL_WINDOWS - OPENFILENAMEW mOFN; // for open and save dialogs - WCHAR mFilesW[FILENAME_BUFFER_SIZE]; - - BOOL setupFilter(ELoadFilter filter); -#endif - -#if LL_DARWIN - NavDialogCreationOptions mNavOptions; - - OSStatus doNavChooseDialog(ELoadFilter filter); - OSStatus doNavSaveDialog(ESaveFilter filter, const std::string& filename); - static Boolean navOpenFilterProc(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode); -#endif - -#if LL_GTK - static void add_to_selectedfiles(gpointer data, gpointer user_data); - static void chooser_responder(GtkWidget *widget, gint response, gpointer user_data); - // we remember the last path that was accessed for a particular usage - std::map mContextToPathMap; - std::string mCurContextName; -#endif - - std::vector mFiles; - S32 mCurrentFile; - BOOL mLocked; - BOOL mMultiFile; - -protected: -#if LL_GTK - GtkWindow* buildFilePicker(bool is_save, bool is_folder, - std::string context = "generic"); -#endif - -protected: - LLFilePickerBase(); -}; - -// True singleton, private constructors (and no friends). -class LLFilePicker : public LLFilePickerBase -{ -public: - // calling this before main() is undefined - static LLFilePicker& instance( void ) { return sInstance; } - -private: - static LLFilePicker sInstance; - - LLFilePicker() { } -}; - -#endif diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index 6e524a05f..72720692f 100644 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -76,7 +76,6 @@ #include "llviewerwindow.h" #include "llviewertexturelist.h" #include "llworldmap.h" -#include "llfilepicker.h" #include "llfloateravatarpicker.h" #include "lldir.h" #include "llselectmgr.h" diff --git a/indra/newview/llfloatervfsexplorer.cpp b/indra/newview/llfloatervfsexplorer.cpp index 6f6384a37..99662b9d9 100644 --- a/indra/newview/llfloatervfsexplorer.cpp +++ b/indra/newview/llfloatervfsexplorer.cpp @@ -5,7 +5,6 @@ #include "lluictrlfactory.h" #include "llscrolllistctrl.h" #include "llcheckboxctrl.h" -#include "llfilepicker.h" #include "llvfs.h" #include "lllocalinventory.h" #include "llviewerwindow.h" diff --git a/indra/newview/llinventorybackup.cpp b/indra/newview/llinventorybackup.cpp index c6f687272..416c82065 100644 --- a/indra/newview/llinventorybackup.cpp +++ b/indra/newview/llinventorybackup.cpp @@ -5,7 +5,7 @@ #include "llinventorymodel.h" #include "llviewerinventory.h" #include "statemachine/aifilepicker.h" -#include "lldirpicker.h" +#include "statemachine/aidirpicker.h" #include "llviewertexturelist.h" // gTextureList #include "llagent.h" // gAgent #include "llviewerwindow.h" // gViewerWindow @@ -120,36 +120,41 @@ void LLFloaterInventoryBackupSettings::onClickNext(void* userdata) } // Get dir name - LLDirPicker& picker = LLDirPicker::instance(); - std::string filename = "New Folder"; - if (!picker.getDir(&filename)) + AIDirPicker* dirpicker = new AIDirPicker("New Folder"); + dirpicker->run(boost::bind(&LLFloaterInventoryBackupSettings::onClickNext_continued, userdata, dirpicker)); +} + +// static +void LLFloaterInventoryBackupSettings::onClickNext_continued(void* userdata, AIDirPicker* dirpicker) +{ + LLFloaterInventoryBackupSettings* floater = (LLFloaterInventoryBackupSettings*)userdata; + LLInventoryBackupOrder* order = floater->mOrder; + + if (!dirpicker->hasDirname()) { floater->close(); return; } - filename = picker.getDirName(); + std::string dirname = dirpicker->getDirname(); // Make local directory tree - LLFile::mkdir(filename); + LLFile::mkdir(dirname); std::vector::iterator _cat_iter = order->mCats.begin(); std::vector::iterator _cat_end = order->mCats.end(); for( ; _cat_iter != _cat_end; ++_cat_iter) { - std::string path = filename + OS_SEP + LLInventoryBackup::getPath(*_cat_iter, order->mCats); + std::string path = dirname + OS_SEP + LLInventoryBackup::getPath(*_cat_iter, order->mCats); LLFile::mkdir(path); } // Go go backup floater - LLFloaterInventoryBackup* backup_floater = new LLFloaterInventoryBackup(filename, order->mCats, order->mItems); + LLFloaterInventoryBackup* backup_floater = new LLFloaterInventoryBackup(dirname, order->mCats, order->mItems); backup_floater->center(); // Close myself floater->close(); } - - - // static bool LLInventoryBackup::itemIsFolder(LLInventoryItem* item) { diff --git a/indra/newview/llinventorybackup.h b/indra/newview/llinventorybackup.h index 16d9a3ad1..2ee0c197c 100644 --- a/indra/newview/llinventorybackup.h +++ b/indra/newview/llinventorybackup.h @@ -15,6 +15,8 @@ #include "llviewertexture.h" #include "llfloater.h" +class AIDirPicker; + class LLInventoryBackupOrder { public: @@ -44,6 +46,7 @@ public: LLFloaterInventoryBackupSettings(LLInventoryBackupOrder* order); BOOL postBuild(void); static void onClickNext(void* userdata); + static void onClickNext_continued(void* userdata, AIDirPicker* dirpicker); LLInventoryBackupOrder* mOrder; virtual ~LLFloaterInventoryBackupSettings(); diff --git a/indra/newview/llpanelnetwork.cpp b/indra/newview/llpanelnetwork.cpp index 6e66628eb..6bc34989a 100644 --- a/indra/newview/llpanelnetwork.cpp +++ b/indra/newview/llpanelnetwork.cpp @@ -39,7 +39,7 @@ // project includes #include "llcheckboxctrl.h" #include "llradiogroup.h" -#include "lldirpicker.h" +#include "statemachine/aidirpicker.h" #include "lluictrlfactory.h" #include "llviewercontrol.h" #include "llviewerwindow.h" @@ -151,18 +151,24 @@ void LLPanelNetwork::onClickClearCache(void*) // static void LLPanelNetwork::onClickSetCache(void* user_data) { - LLPanelNetwork* self = (LLPanelNetwork*)user_data; - std::string cur_name(gSavedSettings.getString("CacheLocation")); std::string proposed_name(cur_name); - LLDirPicker& picker = LLDirPicker::instance(); - if (! picker.getDir(&proposed_name ) ) + AIDirPicker* dirpicker = new AIDirPicker(proposed_name, "cachelocation"); + dirpicker->run(boost::bind(&LLPanelNetwork::onClickSetCache_continued, user_data, dirpicker)); +} + +// static +void LLPanelNetwork::onClickSetCache_continued(void* user_data, AIDirPicker* dirpicker) +{ + if (!dirpicker->hasDirname()) { return; //Canceled! } - std::string dir_name = picker.getDirName(); + LLPanelNetwork* self = (LLPanelNetwork*)user_data; + std::string cur_name(gSavedSettings.getString("CacheLocation")); + std::string dir_name = dirpicker->getDirname(); if (!dir_name.empty() && dir_name != cur_name) { self->childSetText("cache_location", dir_name); diff --git a/indra/newview/llpanelnetwork.h b/indra/newview/llpanelnetwork.h index a5e2269a4..30dc471e6 100644 --- a/indra/newview/llpanelnetwork.h +++ b/indra/newview/llpanelnetwork.h @@ -35,6 +35,8 @@ #include "llpanel.h" +class AIDirPicker; + class LLPanelNetwork : public LLPanel { public: @@ -49,6 +51,7 @@ public: private: static void onClickClearCache(void*); static void onClickSetCache(void*); + static void onClickSetCache_continued(void* user_data, AIDirPicker* dirpicker); static void onClickResetCache(void*); static void onCommitPort(LLUICtrl* ctrl, void*); static void onCommitSocks5ProxyEnabled(LLUICtrl* ctrl, void* data); diff --git a/indra/newview/llprefsim.cpp b/indra/newview/llprefsim.cpp index 8c1f71b4b..62dc37726 100644 --- a/indra/newview/llprefsim.cpp +++ b/indra/newview/llprefsim.cpp @@ -45,7 +45,7 @@ #include "llviewernetwork.h" #include "lluictrlfactory.h" -#include "lldirpicker.h" +#include "statemachine/aidirpicker.h" #include "hippogridmanager.h" @@ -53,6 +53,8 @@ #include "rlvhandler.h" // [/RLVa:KB] +class AIDirPicker; + class LLPrefsIMImpl : public LLPanel { public: @@ -67,6 +69,7 @@ public: void enableHistory(); static void onClickLogPath(void* user_data); + static void onClickLogPath_continued(void* user_data, AIDirPicker* dirpicker); static void onCommitLogging(LLUICtrl* ctrl, void* user_data); protected: @@ -301,13 +304,20 @@ void LLPrefsIMImpl::onClickLogPath(void* user_data) std::string proposed_name(self->childGetText("log_path_string")); - LLDirPicker& picker = LLDirPicker::instance(); - if (!picker.getDir(&proposed_name ) ) + AIDirPicker* dirpicker = new AIDirPicker(proposed_name); + dirpicker->run(boost::bind(&LLPrefsIMImpl::onClickLogPath_continued, user_data, dirpicker)); +} + +// static +void LLPrefsIMImpl::onClickLogPath_continued(void* user_data, AIDirPicker* dirpicker) +{ + if (!dirpicker->hasDirname()) { return; //Canceled! } - self->childSetText("log_path_string", picker.getDirName()); + LLPrefsIMImpl* self=(LLPrefsIMImpl*)user_data; + self->childSetText("log_path_string", dirpicker->getDirname()); } diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 319f1cb57..e92a5185c 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -74,7 +74,6 @@ // tag: vaa emerald local_asset_browser [begin] #include "floaterlocalassetbrowse.h" #include "llscrolllistctrl.h" -#include "llfilepicker.h" #define LOCALLIST_COL_ID 1 // tag: vaa emerald local_asset_browser [end] diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h index e9fedf37d..a6d96c08c 100644 --- a/indra/newview/llviewermenu.h +++ b/indra/newview/llviewermenu.h @@ -35,9 +35,6 @@ #include "llmenugl.h" -//newview includes -#include "llfilepicker.h" - class LLUICtrl; class LLView; class LLParcelSelection; diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index a8d78cd8d..0a3254ea0 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -420,7 +420,7 @@ void upload_error(const std::string& error_message, const std::string& label, co { lldebugs << "unable to remove temp file" << llendl; } - LLFilePicker::instance().reset(); + //AIFIXME? LLFilePicker::instance().reset(); } class LLFileEnableCloseWindow : public view_listener_t @@ -965,7 +965,7 @@ void upload_new_resource(const std::string& src_filename, std::string name, { lldebugs << "unable to remove temp file" << llendl; } - LLFilePicker::instance().reset(); + //AIFIXME? LLFilePicker::instance().reset(); } } // diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 99844508f..60a2be5a3 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -49,7 +49,6 @@ #include "llchat.h" #include "lldbstrings.h" #include "lleconomy.h" -#include "llfilepicker.h" #include "llfocusmgr.h" #include "llfollowcamparams.h" #include "llinstantmessage.h" diff --git a/indra/newview/statemachine/aidirpicker.h b/indra/newview/statemachine/aidirpicker.h new file mode 100644 index 000000000..452f42b3e --- /dev/null +++ b/indra/newview/statemachine/aidirpicker.h @@ -0,0 +1,77 @@ +/** + * @file aidirpicker.h + * @brief Directory picker State machine + * + * Copyright (c) 2011, Aleric Inglewood. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution. + * + * CHANGELOG + * and additional copyright holders. + * + * 10/05/2011 + * Initial version, written by Aleric Inglewood @ SL + */ + +#ifndef AIDIRPICKER_H +#define AIDIRPICKER_H + +#include "aifilepicker.h" + +// A directory picker state machine. +// +// Before calling run(), call open() to pass needed parameters. +// +// When the state machine finishes, call hasDirname to check +// whether or not getDirname will be valid. +// +// Objects of this type can be reused multiple times, see +// also the documentation of AIStateMachine. +class AIDirPicker : protected AIFilePicker { +public: + // Allow to pass the arguments to open upon creation. + // + // The starting directory that the user will be in when the directory picker opens + // will be the same as the directory used the last time the directory picker was + // opened with the same context. If the directory picker was never opened before + // with the given context, the starting directory will be set to default_path + // unless that is the empty string, in which case it will be equal to the + // directory used the last time the file- or dirpicker was opened with context + // "openfile". + AIDirPicker(std::string const& default_path = "", std::string const& context = "openfile") { open(default_path, context); } + + // This should only be called if you want to re-use the AIDirPicker after it finished + // (from the callback function, followed by a call to 'run'). Normally it is not used. + void open(std::string const& default_path = "", std::string const& context = "openfile") { AIFilePicker::open(DF_DIRECTORY, default_path, context); } + + bool hasDirname(void) const { return hasFilename(); } + std::string const& getDirname(void) const { return getFilename(); } + +public: + // Basically all public members of AIStateMachine could made accessible here, + // but I don't think others will ever be needed (not even these, actually). + using AIStateMachine::state_type; + using AIFilePicker::isCanceled; + using AIStateMachine::run; + +protected: + // Call finish() (or abort()), not delete. + /*virtual*/ ~AIDirPicker() { LL_DEBUGS("Plugin") << "Calling AIDirPicker::~AIDirPicker()" << LL_ENDL; } +}; + +#endif diff --git a/indra/newview/statemachine/aifilepicker.cpp b/indra/newview/statemachine/aifilepicker.cpp index e0588a990..e3a09009d 100644 --- a/indra/newview/statemachine/aifilepicker.cpp +++ b/indra/newview/statemachine/aifilepicker.cpp @@ -107,6 +107,9 @@ void AIFilePicker::open(ELoadFilter filter, std::string const& default_path, std mOpenType = multiple ? load_multiple : load; switch(filter) { + case DF_DIRECTORY: + mFilter = "directory"; + break; case FFLOAD_ALL: mFilter = "all"; break; @@ -314,7 +317,8 @@ void AIFilePicker::multiplex_impl(void) static char const* key_str[] = { "all_files", "sound_files", "animation_files", "image_files", "save_file_verb", "targa_image_files", "bitmap_image_files", "avi_movie_file", "xaf_animation_file", - "xml_file", "raw_file", "compressed_image_files", "load_file_verb", "load_files" + "xml_file", "raw_file", "compressed_image_files", "load_file_verb", "load_files", + "choose_the_directory" }; LLSD dictionary; for (int key = 0; key < sizeof(key_str) / sizeof(key_str[0]); ++key) diff --git a/indra/newview/statemachine/aifilepicker.h b/indra/newview/statemachine/aifilepicker.h index d916055fe..a1709eeb8 100644 --- a/indra/newview/statemachine/aifilepicker.h +++ b/indra/newview/statemachine/aifilepicker.h @@ -38,6 +38,7 @@ enum ELoadFilter { + DF_DIRECTORY, FFLOAD_ALL, FFLOAD_WAV, FFLOAD_IMAGE, @@ -175,7 +176,7 @@ public: private: LLPointer mPluginManager; //!< Pointer to the plugin manager. - // FIXME: this should be a separate, thread-safe singleton. + // AIFIXME: this should be a separate, thread-safe singleton. typedef std::map context_map_type; //!< Type of mContextMap. context_map_type mContextMap; //!< Map context (ie, "snapshot" or "image") to last used folder. std::string mContext; //!< Some key to indicate the context (remembers the folder per key). diff --git a/indra/plugins/filepicker/CMakeLists.txt b/indra/plugins/filepicker/CMakeLists.txt index d3b233e01..13714e89f 100644 --- a/indra/plugins/filepicker/CMakeLists.txt +++ b/indra/plugins/filepicker/CMakeLists.txt @@ -28,12 +28,16 @@ if(NOT WORD_SIZE EQUAL 32) endif (NOT WORD_SIZE EQUAL 32) set(basic_plugin_filepicker_SOURCE_FILES - basic_plugin_filepicker.cpp + basic_plugin_filepicker.cpp + legacy.cpp llfilepicker.cpp + lldirpicker.cpp ) set(basic_plugin_filepicker_HEADER_FILES + legacy.h llfilepicker.h + lldirpicker.h ) set_source_files_properties(${basic_plugin_filepicker_HEADER_FILES} diff --git a/indra/plugins/filepicker/basic_plugin_filepicker.cpp b/indra/plugins/filepicker/basic_plugin_filepicker.cpp index b954e27b4..1201c3f71 100644 --- a/indra/plugins/filepicker/basic_plugin_filepicker.cpp +++ b/indra/plugins/filepicker/basic_plugin_filepicker.cpp @@ -36,6 +36,7 @@ #include "linden_common.h" #include "basic_plugin_base.h" #include "llfilepicker.h" +#include "lldirpicker.h" class FilepickerPlugin : public BasicPluginBase { @@ -229,9 +230,14 @@ void FilepickerPlugin::receiveMessage(char const* message_string) std::string type = message_in.getValue("type"); std::string filter = message_in.getValue("filter"); std::string folder = message_in.getValue("folder"); + bool get_directory = (filter == "directory"); bool canceled; - if (type == "save") + if (get_directory) + { + canceled = !LLDirPicker::instance().getDir(&folder); + } + else if (type == "save") { canceled = !LLFilePicker::instance().getSaveFile(str2savefilter(filter), message_in.getValue("default"), folder); } @@ -254,9 +260,16 @@ void FilepickerPlugin::receiveMessage(char const* message_string) LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_BASIC, "done"); message.setValue("perseus", "unblock"); LLSD filenames; - for (std::string filename = LLFilePicker::instance().getFirstFile(); !filename.empty(); filename = LLFilePicker::instance().getNextFile()) + if (get_directory) { - filenames.append(filename); + filenames.append(LLDirPicker::instance().getDirName()); + } + else + { + for (std::string filename = LLFilePicker::instance().getFirstFile(); !filename.empty(); filename = LLFilePicker::instance().getNextFile()) + { + filenames.append(filename); + } } message.setValueLLSD("filenames", filenames); sendMessage(message); diff --git a/indra/plugins/filepicker/legacy.cpp b/indra/plugins/filepicker/legacy.cpp new file mode 100644 index 000000000..f89862061 --- /dev/null +++ b/indra/plugins/filepicker/legacy.cpp @@ -0,0 +1,112 @@ +/** + * @file legacy.cpp + * @brief Helper stubs to keep the picker files as much as possible equal to their original. + * + * Copyright (c) 2011, Aleric Inglewood. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution. + * + * CHANGELOG + * and additional copyright holders. + * + * 11/05/2011 + * - Initial version, written by Aleric Inglewood @ SL + */ + +#include "legacy.h" +#include "basic_plugin_base.h" // For PLS_INFOS etc. + +// Translation map. +translation_map_type translation_map; + +namespace translation +{ + std::string getString(char const* key) + { + translation_map_type::iterator iter = translation_map.find(key); + return (iter != translation_map.end()) ? iter->second : key; + } + + void add(std::string const& key, std::string const& translation) + { + PLS_DEBUGS << "Adding translation \"" << key << "\" --> \"" << translation << "\"" << PLS_ENDL; + translation_map[key] = translation; + } +} + +#if LL_GTK +namespace LLWindowSDL { + bool ll_try_gtk_init(void) + { + static BOOL done_gtk_diag = FALSE; + static BOOL gtk_is_good = FALSE; + static BOOL done_setlocale = FALSE; + static BOOL tried_gtk_init = FALSE; + + if (!done_setlocale) + { + PLS_INFOS << "Starting GTK Initialization." << PLS_ENDL; + //maybe_lock_display(); + gtk_disable_setlocale(); + //maybe_unlock_display(); + done_setlocale = TRUE; + } + + if (!tried_gtk_init) + { + tried_gtk_init = TRUE; + if (!g_thread_supported ()) g_thread_init (NULL); + //maybe_lock_display(); + gtk_is_good = gtk_init_check(NULL, NULL); + //maybe_unlock_display(); + if (!gtk_is_good) + PLS_WARNS << "GTK Initialization failed." << PLS_ENDL; + } + if (gtk_is_good && !done_gtk_diag) + { + PLS_INFOS << "GTK Initialized." << PLS_ENDL; + PLS_INFOS << "- Compiled against GTK version " + << GTK_MAJOR_VERSION << "." + << GTK_MINOR_VERSION << "." + << GTK_MICRO_VERSION << PLS_ENDL; + PLS_INFOS << "- Running against GTK version " + << gtk_major_version << "." + << gtk_minor_version << "." + << gtk_micro_version << PLS_ENDL; + //maybe_lock_display(); + const gchar* gtk_warning = gtk_check_version( + GTK_MAJOR_VERSION, + GTK_MINOR_VERSION, + GTK_MICRO_VERSION); + //maybe_unlock_display(); + if (gtk_warning) + { + PLS_WARNS << "- GTK COMPATIBILITY WARNING: " << gtk_warning << PLS_ENDL; + gtk_is_good = FALSE; + } + else + { + PLS_INFOS << "- GTK version is good." << PLS_ENDL; + } + done_gtk_diag = TRUE; + } + return gtk_is_good; + } +} +#endif + diff --git a/indra/plugins/filepicker/legacy.h b/indra/plugins/filepicker/legacy.h new file mode 100644 index 000000000..253a99280 --- /dev/null +++ b/indra/plugins/filepicker/legacy.h @@ -0,0 +1,79 @@ +/** + * @file legacy.h + * @brief Declarations of legacy.cpp. + * + * Copyright (c) 2011, Aleric Inglewood. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution. + * + * CHANGELOG + * and additional copyright holders. + * + * 11/05/2011 + * - Initial version, written by Aleric Inglewood @ SL + */ + +#include +#include +#include "stdtypes.h" // BOOL + +// Translation map. +typedef std::map translation_map_type; +extern translation_map_type translation_map; + +namespace translation +{ + std::string getString(char const* key); + void add(std::string const& key, std::string const& translation); +} + +#if LL_GTK +namespace LLWindowSDL { + bool ll_try_gtk_init(void); +} +#endif + +// A temporary hack to minimize the number of changes from the original llfilepicker.cpp. +#define LLTrans translation + +#if LL_DARWIN +#include + +// AssertMacros.h does bad things. +#undef verify +#undef check +#undef require + +#include "llstring.h" +#endif + +// Need commdlg.h for OPENFILENAMEA +#ifdef LL_WINDOWS +#include +#endif + +// mostly for Linux, possible on others +#if LL_GTK +# include "gtk/gtk.h" +#endif // LL_GTK + +// also mostly for Linux, for some X11-specific filepicker usability tweaks +#if LL_X11 +#include "SDL/SDL_syswm.h" +#endif + diff --git a/indra/newview/lldirpicker.cpp b/indra/plugins/filepicker/lldirpicker.cpp similarity index 92% rename from indra/newview/lldirpicker.cpp rename to indra/plugins/filepicker/lldirpicker.cpp index 3840b52bd..39dff05e9 100644 --- a/indra/newview/lldirpicker.cpp +++ b/indra/plugins/filepicker/lldirpicker.cpp @@ -30,16 +30,12 @@ * $/LicenseInfo$ */ -#include "llviewerprecompiledheaders.h" - +#include "linden_common.h" #include "lldirpicker.h" -//#include "llviewermessage.h" -#include "llworld.h" -#include "llviewerwindow.h" -#include "llkeyboard.h" -#include "lldir.h" -#include "llframetimer.h" -#include "lltrans.h" +#include "llpreprocessor.h" +#include "llerror.h" +#include "basic_plugin_base.h" // For PLS_INFOS etc. +#include "legacy.h" #if LL_LINUX || LL_SOLARIS # include "llfilepicker.h" @@ -77,9 +73,6 @@ BOOL LLDirPicker::getDir(std::string* filename) } BOOL success = FALSE; - // Modal, so pause agent - send_agent_pause(); - BROWSEINFO bi; memset(&bi, 0, sizeof(bi)); @@ -109,10 +102,6 @@ BOOL LLDirPicker::getDir(std::string* filename) ::OleUninitialize(); - send_agent_resume(); - - // Account for the fact that the app has been stalled. - LLFrameTimer::updateFrameTime(); return success; } @@ -237,20 +226,15 @@ BOOL LLDirPicker::getDir(std::string* filename) // mNavOptions.saveFileName - // Modal, so pause agent - send_agent_pause(); { error = doNavChooseDialog(); } - send_agent_resume(); if (error == noErr) { if (mDir.length() > 0) success = true; } - // Account for the fact that the app has been stalled. - LLFrameTimer::updateFrameTime(); return success; } diff --git a/indra/newview/lldirpicker.h b/indra/plugins/filepicker/lldirpicker.h similarity index 100% rename from indra/newview/lldirpicker.h rename to indra/plugins/filepicker/lldirpicker.h diff --git a/indra/plugins/filepicker/llfilepicker.cpp b/indra/plugins/filepicker/llfilepicker.cpp index 8028665e3..48069e88c 100644 --- a/indra/plugins/filepicker/llfilepicker.cpp +++ b/indra/plugins/filepicker/llfilepicker.cpp @@ -35,92 +35,7 @@ #include "llpreprocessor.h" #include "llerror.h" #include "basic_plugin_base.h" // For PLS_INFOS etc. - -#if LL_SDL -#include "llwindowsdl.h" // for some X/GTK utils to help with filepickers -#endif // LL_SDL - -// Translation map. -typedef std::map translation_map_type; -translation_map_type translation_map; - -// A temporary hack to minimize the number of changes from the original llfilepicker.cpp. -#define LLTrans translation -namespace translation -{ - std::string getString(char const* key) - { - translation_map_type::iterator iter = translation_map.find(key); - return (iter != translation_map.end()) ? iter->second : key; - } - - void add(std::string const& key, std::string const& translation) - { - PLS_DEBUGS << "Adding translation \"" << key << "\" --> \"" << translation << "\"" << PLS_ENDL; - translation_map[key] = translation; - } -} - -#if LL_GTK -namespace LLWindowSDL { - bool ll_try_gtk_init(void) - { - static BOOL done_gtk_diag = FALSE; - static BOOL gtk_is_good = FALSE; - static BOOL done_setlocale = FALSE; - static BOOL tried_gtk_init = FALSE; - - if (!done_setlocale) - { - PLS_INFOS << "Starting GTK Initialization." << PLS_ENDL; - //maybe_lock_display(); - gtk_disable_setlocale(); - //maybe_unlock_display(); - done_setlocale = TRUE; - } - - if (!tried_gtk_init) - { - tried_gtk_init = TRUE; - if (!g_thread_supported ()) g_thread_init (NULL); - //maybe_lock_display(); - gtk_is_good = gtk_init_check(NULL, NULL); - //maybe_unlock_display(); - if (!gtk_is_good) - PLS_WARNS << "GTK Initialization failed." << PLS_ENDL; - } - if (gtk_is_good && !done_gtk_diag) - { - PLS_INFOS << "GTK Initialized." << PLS_ENDL; - PLS_INFOS << "- Compiled against GTK version " - << GTK_MAJOR_VERSION << "." - << GTK_MINOR_VERSION << "." - << GTK_MICRO_VERSION << PLS_ENDL; - PLS_INFOS << "- Running against GTK version " - << gtk_major_version << "." - << gtk_minor_version << "." - << gtk_micro_version << PLS_ENDL; - //maybe_lock_display(); - const gchar* gtk_warning = gtk_check_version( - GTK_MAJOR_VERSION, - GTK_MINOR_VERSION, - GTK_MICRO_VERSION); - //maybe_unlock_display(); - if (gtk_warning) - { - PLS_WARNS << "- GTK COMPATIBILITY WARNING: " << gtk_warning << PLS_ENDL; - gtk_is_good = FALSE; - } - else - { - PLS_INFOS << "- GTK version is good." << PLS_ENDL; - } - done_gtk_diag = TRUE; - } - return gtk_is_good; - } -} -#endif +#include "legacy.h" // // Globals @@ -290,7 +205,7 @@ bool LLFilePickerBase::setupFilter(ELoadFilter filter) return res; } -// FIXME: Use folder +// AIFIXME: Use folder bool LLFilePickerBase::getLoadFile(ELoadFilter filter, std::string const& folder) { if( mLocked ) @@ -309,9 +224,6 @@ bool LLFilePickerBase::getLoadFile(ELoadFilter filter, std::string const& folder setupFilter(filter); - // Modal, so pause agent - send_agent_pause(); - reset(); // NOTA BENE: hitting the file dialog triggers a window focus event, destroying the selection manager!! @@ -321,14 +233,11 @@ bool LLFilePickerBase::getLoadFile(ELoadFilter filter, std::string const& folder std::string filename = utf16str_to_utf8str(llutf16string(mFilesW)); mFiles.push_back(filename); } - send_agent_resume(); - // Account for the fact that the app has been stalled. - LLFrameTimer::updateFrameTime(); return success; } -// FIXME: Use folder +// AIFIXME: Use folder bool LLFilePickerBase::getMultipleLoadFiles(ELoadFilter filter, std::string const& folder) { if( mLocked ) @@ -350,8 +259,6 @@ bool LLFilePickerBase::getMultipleLoadFiles(ELoadFilter filter, std::string cons reset(); - // Modal, so pause agent - send_agent_pause(); // NOTA BENE: hitting the file dialog triggers a window focus event, destroying the selection manager!! success = GetOpenFileName(&mOFN); // pauses until ok or cancel. if( success ) @@ -384,14 +291,11 @@ bool LLFilePickerBase::getMultipleLoadFiles(ELoadFilter filter, std::string cons } } } - send_agent_resume(); - // Account for the fact that the app has been stalled. - LLFrameTimer::updateFrameTime(); return success; } -// FIXME: Use folder +// AIFIXME: Use folder bool LLFilePickerBase::getSaveFile(ESaveFilter filter, std::string const& filename, std::string const& folder) { if( mLocked ) @@ -783,8 +687,6 @@ bool LLFilePickerBase::getSaveFile(ESaveFilter filter, std::string const& filena reset(); - // Modal, so pause agent - send_agent_pause(); { // NOTA BENE: hitting the file dialog triggers a window focus event, destroying the selection manager!! success = GetSaveFileName(&mOFN); @@ -795,10 +697,7 @@ bool LLFilePickerBase::getSaveFile(ESaveFilter filter, std::string const& filena } gKeyboard->resetKeys(); } - send_agent_resume(); - // Account for the fact that the app has been stalled. - LLFrameTimer::updateFrameTime(); return success; } @@ -1137,7 +1036,7 @@ OSStatus LLFilePickerBase::doNavSaveDialog(ESaveFilter filter, const std::string return error; } -// FIXME: Use folder +// AIFIXME: Use folder bool LLFilePickerBase::getLoadFile(ELoadFilter filter, std::string const& folder) { if( mLocked ) @@ -1150,24 +1049,19 @@ bool LLFilePickerBase::getLoadFile(ELoadFilter filter, std::string const& folder reset(); mNavOptions.optionFlags &= ~kNavAllowMultipleFiles; - // Modal, so pause agent - send_agent_pause(); { error = doNavChooseDialog(filter); } - send_agent_resume(); if (error == noErr) { if (getFileCount()) success = true; } - // Account for the fact that the app has been stalled. - LLFrameTimer::updateFrameTime(); return success; } -// FIXME: Use folder +// AIFIXME: Use folder bool LLFilePickerBase::getMultipleLoadFiles(ELoadFilter filter, std::string const& folder) { if( mLocked ) @@ -1180,12 +1074,9 @@ bool LLFilePickerBase::getMultipleLoadFiles(ELoadFilter filter, std::string cons reset(); mNavOptions.optionFlags |= kNavAllowMultipleFiles; - // Modal, so pause agent - send_agent_pause(); { error = doNavChooseDialog(filter); } - send_agent_resume(); if (error == noErr) { if (getFileCount()) @@ -1194,12 +1085,10 @@ bool LLFilePickerBase::getMultipleLoadFiles(ELoadFilter filter, std::string cons mLocked = TRUE; } - // Account for the fact that the app has been stalled. - LLFrameTimer::updateFrameTime(); return success; } -// FIXME: Use folder +// AIFIXME: Use folder bool LLFilePickerBase::getSaveFile(ESaveFilter filter, std::string const& filename, std::string const& folder) { if( mLocked ) @@ -1211,20 +1100,15 @@ bool LLFilePickerBase::getSaveFile(ESaveFilter filter, std::string const& filena mNavOptions.optionFlags &= ~kNavAllowMultipleFiles; - // Modal, so pause agent - send_agent_pause(); { error = doNavSaveDialog(filter, filename); } - send_agent_resume(); if (error == noErr) { if (getFileCount()) success = true; } - // Account for the fact that the app has been stalled. - LLFrameTimer::updateFrameTime(); return success; } @@ -1601,7 +1485,7 @@ bool LLFilePickerBase::getSaveFile(ESaveFilter filter, std::string const& filena return FALSE; } -// FIXME: Use folder +// AIFIXME: Use folder bool LLFilePickerBase::getLoadFile(ELoadFilter filter, std::string const& folder) { reset(); diff --git a/indra/plugins/filepicker/llfilepicker.h b/indra/plugins/filepicker/llfilepicker.h index 4e1a52a7e..f8e17719e 100644 --- a/indra/plugins/filepicker/llfilepicker.h +++ b/indra/plugins/filepicker/llfilepicker.h @@ -39,37 +39,8 @@ #ifndef LL_LLFILEPICKER_H #define LL_LLFILEPICKER_H -#include "stdtypes.h" -#include +#include "legacy.h" #include -#include - -#if LL_DARWIN -#include - -// AssertMacros.h does bad things. -#undef verify -#undef check -#undef require - -#include "llstring.h" - -#endif - -// Need commdlg.h for OPENFILENAMEA -#ifdef LL_WINDOWS -#include -#endif - -// mostly for Linux, possible on others -#if LL_GTK -# include "gtk/gtk.h" -#endif // LL_GTK - -// also mostly for Linux, for some X11-specific filepicker usability tweaks -#if LL_X11 -#include "SDL/SDL_syswm.h" -#endif // This class is used as base class of a singleton and is therefore not // allowed to have any static members or static local variables! @@ -246,9 +217,4 @@ private: LLFilePicker() { } }; -namespace translation -{ - void add(std::string const& key, std::string const& translation); -} - #endif