Files
SingularityViewer/indra/newview/statemachine/aifilepicker.h
2013-01-07 20:11:18 +01:00

249 lines
10 KiB
C++

/**
* @file aifilepicker.h
* @brief File picker State machine
*
* Copyright (c) 2010, 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 <http://www.gnu.org/licenses/>.
*
* 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.
*
* 02/12/2010
* Initial version, written by Aleric Inglewood @ SL
*/
#ifndef AIFILEPICKER_H
#define AIFILEPICKER_H
#include "aistatemachine.h"
#include "llpluginclassmedia.h"
#include "llviewerpluginmanager.h"
#include <vector>
enum ELoadFilter
{
DF_DIRECTORY,
FFLOAD_ALL,
FFLOAD_WAV,
FFLOAD_IMAGE,
FFLOAD_ANIM,
FFLOAD_XML,
FFLOAD_SLOBJECT,
FFLOAD_RAW,
FFLOAD_MODEL,
FFLOAD_COLLADA,
FFLOAD_SCRIPT,
FFLOAD_DICTIONARY,
FFLOAD_INVGZ,
FFLOAD_AO,
FFLOAD_BLACKLIST
};
enum ESaveFilter
{
FFSAVE_ALL,
FFSAVE_WAV,
FFSAVE_TGA,
FFSAVE_BMP,
FFSAVE_AVI,
FFSAVE_ANIM,
FFSAVE_XML,
FFSAVE_COLLADA,
FFSAVE_RAW,
FFSAVE_J2C,
FFSAVE_PNG,
FFSAVE_JPEG,
FFSAVE_SCRIPT,
FFSAVE_ANIMATN,
FFSAVE_OGG,
FFSAVE_NOTECARD,
FFSAVE_GESTURE,
FFSAVE_SHAPE,
FFSAVE_SKIN,
FFSAVE_HAIR,
FFSAVE_EYES,
FFSAVE_SHIRT,
FFSAVE_PANTS,
FFSAVE_SHOES,
FFSAVE_SOCKS,
FFSAVE_JACKET,
FFSAVE_GLOVES,
FFSAVE_UNDERSHIRT,
FFSAVE_UNDERPANTS,
FFSAVE_SKIRT,
FFSAVE_INVGZ,
FFSAVE_LANDMARK,
FFSAVE_AO,
FFSAVE_BLACKLIST,
FFSAVE_PHYSICS
};
/*
AIFilePicker is an AIStateMachine, that has a LLViewerPluginManager (mPluginManager)
to manage a plugin that runs the actual filepicker in a separate process.
The relationship with the plugin is as follows:
new AIFilePicker
AIFilePicker::mPluginManager = new LLViewerPluginManager
LLPluginProcessParentOwner LLPluginMessagePipeOwner
| | LLPluginMessagePipeOwner::mOwner = LLPluginProcessParentOwner
| | LLPluginMessagePipeOwner::mMessagePipe = LLPluginMessagePipe
| | LLPluginMessagePipeOwner::receiveMessageRaw calls
v | LLPluginProcessParent::receiveMessageRaw
LLPluginClassBasic v
| LLPluginClassBasic::mPlugin = new LLPluginProcessParent ---> new LLPluginMessagePipe
| LLPluginProcessParent::mOwner = (LLPluginProcessParentOwner*)LLPluginClassBasic
| LLPluginProcessParent::sendMessage calls
| LLPluginMessagePipeOwner::writeMessageRaw calls
| mMessagePipe->LLPluginMessagePipe::addMessage
| LLPluginProcessParent::receiveMessageRaw calls
| LLPluginProcessParent::receiveMessage calls
| LLPluginProcessParentOwner::receivePluginMessage == AIPluginFilePicker::receivePluginMessage
|
| LLPluginClassBasic::sendMessage calls mPlugin->LLPluginProcessParent::sendMessage
|
v
LLViewerPluginManager::mPluginBase = new AIPluginFilePicker
AIPluginFilePicker::receivePluginMessage calls
AIFilePicker::receivePluginMessage
AIPluginFilePicker::mStateMachine = AIFilePicker
Where the entry point to send messages to the plugin is LLPluginClassBasic::sendMessage,
and the end point for messages received from the plugin is AIFilePicker::receivePluginMessage.
Termination happens by receiving the "canceled" or "done" message,
which sets the state to AIFilePicker_canceled or AIFilePicker_done
respectively, causing a call to AIStateMachine::finish(), which calls
AIFilePicker::finish_impl which destroys the plugin (mPluginBase),
the plugin manager (mPluginManager) and calls AIStateMachine::kill()
causing the AIFilePicker to be deleted.
*/
// A file picker state machine.
//
// Before calling run(), call open() to pass needed parameters.
//
// When the state machine finishes, call isCanceled to check
// whether or not getFilename and getFolder will be valid.
//
// Objects of this type can be reused multiple times, see
// also the documentation of AIStateMachine.
class AIFilePicker : public AIStateMachine {
public:
AIFilePicker(void);
// Create a dynamically created AIFilePicker object.
static AIFilePicker* create(bool auto_kill = true) { AIFilePicker* filepicker = new AIFilePicker; filepicker->mAutoKill = auto_kill; return filepicker; }
// The starting directory that the user will be in when the file picker opens
// will be the same as the directory used the last time the file picker was
// opened with the same context. If the file 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 filepicker was opened with context "savefile".
void open(std::string const& filename, ESaveFilter filter = FFSAVE_ALL, std::string const& default_path = "", std::string const& context = "savefile");
void open(ELoadFilter filter = FFLOAD_ALL, std::string const& default_path = "", std::string const& context = "openfile", bool multiple = false);
bool isCanceled(void) const { return mCanceled; }
bool hasFilename(void) const { return *this && !mCanceled; }
std::string const& getFilename(void) const;
std::string getFolder(void) const;
std::vector<std::string> const& getFilenames(void) const { return mFilenames; }
// Load the sContextMap from disk.
static bool loadFile(std::string const& filename);
// Save the sContextMap to disk.
static bool saveFile(std::string const& filename);
private:
friend class AIPluginFilePicker;
// This is called from AIPluginFilePicker::receivePluginMessage, see below.
void receivePluginMessage(LLPluginMessage const& message);
public:
enum open_type { save, load, load_multiple };
private:
LLPointer<LLViewerPluginManager> mPluginManager; //!< Pointer to the plugin manager.
typedef std::map<std::string, std::string> context_map_type; //!< Type of mContextMap.
static AIThreadSafeSimpleDC<context_map_type> sContextMap; //!< Map context (ie, "snapshot" or "image") to last used folder.
std::string mContext; //!< Some key to indicate the context (remembers the folder per key).
bool mAutoKill; //!< True if the default behavior is to delete itself after being finished.
// Input variables (cache variable between call to open and run).
open_type mOpenType; //!< Set to whether opening a filepicker to select for saving one file, for loading one file, or loading multiple files.
std::string mFilter; //!< A keyword indicating which file types (extensions) we want to see.
std::string mFilename; //!< When saving: proposed filename.
std::string mFolder; //!< Initial folder to start in.
// Output variables:
bool mCanceled; //!< True if the file picker was canceled or closed.
std::vector<std::string> mFilenames; //!< Filesnames.
// Store a folder for the given context.
static void store_folder(std::string const& context, std::string const& folder);
// Return the last folder stored for 'context', or default_path if none, or context "savefile" if empty, or $HOME if none.
static std::string get_folder(std::string const& default_path, std::string const& context);
protected:
// Call finish() (or abort()), not delete.
/*virtual*/ ~AIFilePicker() { LL_DEBUGS("Plugin") << "Calling AIFilePicker::~AIFilePicker()" << LL_ENDL; }
// Handle initializing the object.
/*virtual*/ void initialize_impl(void);
// Handle mRunState.
/*virtual*/ void multiplex_impl(void);
// Handle aborting from current bs_run state.
/*virtual*/ void abort_impl(void);
// Handle cleaning up from initialization (or post abort) state.
/*virtual*/ void finish_impl(void);
// Implemenation of state_str for run states.
/*virtual*/ char const* state_str_impl(state_type run_state) const;
};
// Viewer-side helper class for objects with a lifetime equal to the
// plugin child process (SLPlugin). Don't use directly.
class AIPluginFilePicker : public LLPluginClassBasic {
LOG_CLASS(AIPluginFilePicker);
public:
AIPluginFilePicker(AIFilePicker* state_machine) : mStateMachine(state_machine) { }
/*virtual*/ ~AIPluginFilePicker() { LL_DEBUGS("Plugin") << "Calling AIPluginFilePicker::~AIPluginFilePicker()" << LL_ENDL; }
static std::string launcher_name(void) { return gDirUtilp->getLLPluginLauncher(); }
static char const* plugin_basename(void) { return "basic_plugin_filepicker"; }
/*virtual*/ void receivePluginMessage(LLPluginMessage const& message) { mStateMachine->receivePluginMessage(message); }
/*virtual*/ void receivedShutdown(void) { /* Nothing -- we terminate on deletion (from AIStateMachine::mainloop) */ }
private:
AIFilePicker* mStateMachine;
};
#endif