Split plugin classes and derive AIFilePicker from BasicPluginBase (part 1).

This commit contains all changes, except those in indra/media_plugins
(which was renamed to indra/plugins) and indra/llplugin.

However, it does contain the (new) file
indra/plugins/filepicker/basic_plugin_filepicker.cpp
This commit is contained in:
Aleric Inglewood
2011-05-06 14:39:16 +02:00
parent f6b57d956d
commit e89d6d9d66
26 changed files with 1432 additions and 337 deletions

View File

@@ -113,6 +113,7 @@ Aleric Inglewood
IMP-664
IMP-670
IMP-701
IMP-702
IMP-734
IMP-735
Alissa Sabre

View File

@@ -76,8 +76,8 @@ if (VIEWER)
add_subdirectory(${LIBS_OPEN_PREFIX}llplugin)
add_subdirectory(${LIBS_OPEN_PREFIX}llui)
# viewer media plugins
add_subdirectory(${LIBS_OPEN_PREFIX}media_plugins)
# viewer plugins directory
add_subdirectory(${LIBS_OPEN_PREFIX}plugins)
# llplugin testbed code (is this the right way to include it?)
#if (NOT LINUX)

View File

@@ -0,0 +1,8 @@
# -*- cmake -*-
set(BASIC_PLUGIN_BASE_INCLUDE_DIRS
${LIBS_OPEN_DIR}/plugins/base_basic/
)
set(BASIC_PLUGIN_BASE_LIBRARIES basic_plugin_base)

View File

@@ -1,8 +1,6 @@
# -*- cmake -*-
include(BasicPluginBase)
set(MEDIA_PLUGIN_BASE_INCLUDE_DIRS
${LIBS_OPEN_DIR}/media_plugins/base/
)
set(MEDIA_PLUGIN_BASE_LIBRARIES media_plugin_base)
set(MEDIA_PLUGIN_BASE_INCLUDE_DIRS ${LIBS_OPEN_DIR}/plugins/base_media ${BASIC_PLUGIN_BASE_INCLUDE_DIRS})
set(MEDIA_PLUGIN_BASE_LIBRARIES media_plugin_base ${BASIC_PLUGIN_BASE_LIBRARIES})

View File

@@ -442,6 +442,8 @@ set(viewer_SOURCE_FILES
llviewerkeyboard.cpp
llviewerlayer.cpp
llviewermedia.cpp
llviewermediaeventemitter.cpp
llviewermediaobserver.cpp
llviewermediafocus.cpp
llviewermedia_streamingaudio.cpp
llviewermenu.cpp
@@ -456,6 +458,7 @@ set(viewer_SOURCE_FILES
llviewerparceloverlay.cpp
llviewerpartsim.cpp
llviewerpartsource.cpp
llviewerpluginmanager.cpp
llviewerregion.cpp
llviewershadermgr.cpp
llviewerstats.cpp
@@ -918,6 +921,7 @@ set(viewer_HEADER_FILES
llviewerkeyboard.h
llviewerlayer.h
llviewermedia.h
llviewermediaeventemitter.h
llviewermediaobserver.h
llviewermediafocus.h
llviewermenu.h
@@ -932,6 +936,7 @@ set(viewer_HEADER_FILES
llviewerparceloverlay.h
llviewerpartsim.h
llviewerpartsource.h
llviewerpluginmanager.h
llviewerprecompiledheaders.h
llviewerregion.h
llviewershadermgr.h
@@ -1007,9 +1012,11 @@ source_group("CMake Rules" FILES ViewerInstall.cmake)
set(statemachine_SOURCE_FILES
statemachine/aistatemachine.cpp
statemachine/aifilepicker.cpp
)
set(statemachine_HEADER_FILES
statemachine/aistatemachine.h
statemachine/aifilepicker.h
)
list(APPEND viewer_SOURCE_FILES ${statemachine_SOURCE_FILES})
list(APPEND viewer_HEADER_FILES ${statemachine_HEADER_FILES})

View File

@@ -269,48 +269,36 @@ void LLDirPicker::reset()
LLDirPicker::LLDirPicker()
{
mFilePicker = new LLFilePicker();
reset();
}
LLDirPicker::~LLDirPicker()
{
delete mFilePicker;
}
void LLDirPicker::reset()
{
if (mFilePicker)
mFilePicker->reset();
LLFilePickerBase::reset();
}
BOOL LLDirPicker::getDir(std::string* filename)
{
reset();
if (mFilePicker)
GtkWindow* picker = buildFilePicker(false, true, "dirpicker");
if (picker)
{
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());
}
gtk_window_set_title(GTK_WINDOW(picker), LLTrans::getString("choose_the_directory").c_str());
gtk_widget_show_all(GTK_WIDGET(picker));
gtk_main();
return (!getFirstFile().empty());
}
return FALSE;
}
std::string LLDirPicker::getDirName()
{
if (mFilePicker)
{
return mFilePicker->getFirstFile();
}
return "";
return getFirstFile();
}
#else // not implemented

View File

@@ -57,9 +57,15 @@
#include <commdlg.h>
#endif
class LLFilePicker;
#if LL_LINUX || LL_SOLARIS
#include "llfilepicker.h"
#endif
class LLDirPicker
#if LL_LINUX || LL_SOLARIS
// On Linux we just implement LLDirPicker on top of LLFilePickerBase
: public LLFilePickerBase
#endif
{
public:
// calling this before main() is undefined
@@ -90,19 +96,13 @@ private:
#endif
#if LL_LINUX || LL_SOLARIS
// On Linux we just implement LLDirPicker on top of LLFilePicker
LLFilePicker *mFilePicker;
#endif
std::string* mFileName;
std::string mDir;
BOOL mLocked;
static LLDirPicker sInstance;
public:
// don't call these directly please.
private:
LLDirPicker();
~LLDirPicker();
};

View File

@@ -70,7 +70,7 @@ LLFilePicker LLFilePicker::sInstance;
//
// Implementation
//
LLFilePicker::LLFilePicker()
LLFilePickerBase::LLFilePickerBase()
: mCurrentFile(0),
mLocked(FALSE)
@@ -108,19 +108,13 @@ LLFilePicker::LLFilePicker()
#endif
}
LLFilePicker::~LLFilePicker()
{
// nothing
}
const std::string LLFilePicker::getFirstFile()
const std::string LLFilePickerBase::getFirstFile()
{
mCurrentFile = 0;
return getNextFile();
}
const std::string LLFilePicker::getNextFile()
const std::string LLFilePickerBase::getNextFile()
{
if (mCurrentFile >= getFileCount())
{
@@ -133,7 +127,7 @@ const std::string LLFilePicker::getNextFile()
}
}
const std::string LLFilePicker::getCurFile()
const std::string LLFilePickerBase::getCurFile()
{
if (mCurrentFile >= getFileCount())
{
@@ -146,7 +140,7 @@ const std::string LLFilePicker::getCurFile()
}
}
void LLFilePicker::reset()
void LLFilePickerBase::reset()
{
mLocked = FALSE;
mFiles.clear();
@@ -155,7 +149,7 @@ void LLFilePicker::reset()
#if LL_WINDOWS
BOOL LLFilePicker::setupFilter(ELoadFilter filter)
BOOL LLFilePickerBase::setupFilter(ELoadFilter filter)
{
BOOL res = TRUE;
switch (filter)
@@ -220,7 +214,7 @@ BOOL LLFilePicker::setupFilter(ELoadFilter filter)
return res;
}
BOOL LLFilePicker::getOpenFile(ELoadFilter filter)
BOOL LLFilePickerBase::getOpenFile(ELoadFilter filter)
{
if( mLocked )
{
@@ -258,7 +252,7 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter)
return success;
}
BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter)
BOOL LLFilePickerBase::getMultipleOpenFiles(ELoadFilter filter)
{
if( mLocked )
{
@@ -321,7 +315,7 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter)
return success;
}
BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename)
BOOL LLFilePickerBase::getSaveFile(ESaveFilter filter, const std::string& filename)
{
if( mLocked )
{
@@ -735,7 +729,7 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename)
#elif LL_DARWIN
Boolean LLFilePicker::navOpenFilterProc(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode)
Boolean LLFilePickerBase::navOpenFilterProc(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode)
{
Boolean result = true;
ELoadFilter filter = *((ELoadFilter*) callBackUD);
@@ -832,7 +826,7 @@ Boolean LLFilePicker::navOpenFilterProc(AEDesc *theItem, void *info, void *callB
return result;
}
OSStatus LLFilePicker::doNavChooseDialog(ELoadFilter filter)
OSStatus LLFilePickerBase::doNavChooseDialog(ELoadFilter filter)
{
OSStatus error = noErr;
NavDialogRef navRef = NULL;
@@ -887,7 +881,7 @@ OSStatus LLFilePicker::doNavChooseDialog(ELoadFilter filter)
return error;
}
OSStatus LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filename)
OSStatus LLFilePickerBase::doNavSaveDialog(ESaveFilter filter, const std::string& filename)
{
OSStatus error = noErr;
NavDialogRef navRef = NULL;
@@ -1059,7 +1053,7 @@ OSStatus LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& fi
return error;
}
BOOL LLFilePicker::getOpenFile(ELoadFilter filter)
BOOL LLFilePickerBase::getOpenFile(ELoadFilter filter)
{
if( mLocked )
return FALSE;
@@ -1088,7 +1082,7 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter)
return success;
}
BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter)
BOOL LLFilePickerBase::getMultipleOpenFiles(ELoadFilter filter)
{
if( mLocked )
return FALSE;
@@ -1119,7 +1113,7 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter)
return success;
}
BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename)
BOOL LLFilePickerBase::getSaveFile(ESaveFilter filter, const std::string& filename)
{
if( mLocked )
return FALSE;
@@ -1152,13 +1146,13 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename)
# if LL_GTK
// static
void LLFilePicker::add_to_selectedfiles(gpointer data, gpointer user_data)
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, "");
LLFilePicker* picker = (LLFilePicker*) user_data;
LLFilePickerBase* picker = (LLFilePickerBase*) user_data;
GError *error = NULL;
gchar* filename_utf8 = g_filename_to_utf8((gchar*)data,
-1, NULL, NULL, &error);
@@ -1189,7 +1183,7 @@ void LLFilePicker::add_to_selectedfiles(gpointer data, gpointer user_data)
}
// static
void LLFilePicker::chooser_responder(GtkWidget *widget, gint response, gpointer user_data)
void LLFilePickerBase::chooser_responder(GtkWidget *widget, gint response, gpointer user_data)
{
LLFilePicker* picker = (LLFilePicker*)user_data;
@@ -1212,7 +1206,7 @@ void LLFilePicker::chooser_responder(GtkWidget *widget, gint response, gpointer
}
GtkWindow* LLFilePicker::buildFilePicker(bool is_save, bool is_folder, std::string context)
GtkWindow* LLFilePickerBase::buildFilePicker(bool is_save, bool is_folder, std::string context)
{
if (LLWindowSDL::ll_try_gtk_init())
{
@@ -1270,7 +1264,7 @@ GtkWindow* LLFilePicker::buildFilePicker(bool is_save, bool is_folder, std::stri
g_signal_connect (GTK_FILE_CHOOSER(win),
"response",
G_CALLBACK(LLFilePicker::chooser_responder),
G_CALLBACK(LLFilePickerBase::chooser_responder),
this);
gtk_window_set_modal(GTK_WINDOW(win), TRUE);
@@ -1346,7 +1340,7 @@ static std::string add_imageload_filter_to_gtkchooser(GtkWindow *picker)
}
BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename )
BOOL LLFilePickerBase::getSaveFile( ESaveFilter filter, const std::string& filename )
{
BOOL rtn = FALSE;
@@ -1435,7 +1429,7 @@ BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename
return rtn;
}
BOOL LLFilePicker::getOpenFile( ELoadFilter filter )
BOOL LLFilePickerBase::getOpenFile( ELoadFilter filter )
{
BOOL rtn = FALSE;
@@ -1479,7 +1473,7 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter )
return rtn;
}
BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter )
BOOL LLFilePickerBase::getMultipleOpenFiles( ELoadFilter filter )
{
BOOL rtn = FALSE;
@@ -1511,7 +1505,7 @@ BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter )
// Hacky stubs designed to facilitate fake getSaveFile and getOpenFile with
// static results, when we don't have a real filepicker.
BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename )
BOOL LLFilePickerBase::getSaveFile( ESaveFilter filter, const std::string& filename )
{
reset();
@@ -1525,7 +1519,7 @@ BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename
return FALSE;
}
BOOL LLFilePicker::getOpenFile( ELoadFilter filter )
BOOL LLFilePickerBase::getOpenFile( ELoadFilter filter )
{
reset();
@@ -1543,7 +1537,7 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter )
return TRUE;
}
BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter )
BOOL LLFilePickerBase::getMultipleOpenFiles( ELoadFilter filter )
{
reset();
return FALSE;
@@ -1553,19 +1547,19 @@ BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter )
#else // not implemented
BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename )
BOOL LLFilePickerBase::getSaveFile( ESaveFilter filter, const std::string& filename )
{
reset();
return FALSE;
}
BOOL LLFilePicker::getOpenFile( ELoadFilter filter )
BOOL LLFilePickerBase::getOpenFile( ELoadFilter filter )
{
reset();
return FALSE;
}
BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter )
BOOL LLFilePickerBase::getMultipleOpenFiles( ELoadFilter filter )
{
reset();
return FALSE;

View File

@@ -69,16 +69,11 @@
#include "SDL/SDL_syswm.h"
#endif
class LLFilePicker
// 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
{
#ifdef LL_GTK
friend class LLDirPicker;
friend void chooser_responder(GtkWidget *, gint, gpointer);
#endif // LL_GTK
public:
// calling this before main() is undefined
static LLFilePicker& instance( void ) { return sInstance; }
enum ELoadFilter
{
FFLOAD_ALL = 1,
@@ -212,8 +207,6 @@ private:
S32 mCurrentFile;
BOOL mLocked;
BOOL mMultiFile;
static LLFilePicker sInstance;
protected:
#if LL_GTK
@@ -221,10 +214,21 @@ protected:
std::string context = "generic");
#endif
protected:
LLFilePickerBase();
};
// True singleton, private constructors (and no friends).
class LLFilePicker : public LLFilePickerBase
{
public:
// don't call these directly please.
LLFilePicker();
~LLFilePicker();
// calling this before main() is undefined
static LLFilePicker& instance( void ) { return sInstance; }
private:
static LLFilePicker sInstance;
LLFilePicker() { }
};
#endif

View File

@@ -149,7 +149,7 @@ public:
void updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail = FALSE, F32 delay = 0.f);
LLFloaterPostcard* savePostcard();
void saveTexture();
BOOL saveLocal();
void saveLocal();
BOOL setThumbnailImageSize() ;
void generateThumbnailImage(BOOL force_update = FALSE) ;
@@ -1005,20 +1005,14 @@ void LLSnapshotLivePreview::saveTexture()
mDataSize = 0;
}
BOOL LLSnapshotLivePreview::saveLocal()
void LLSnapshotLivePreview::saveLocal()
{
BOOL success = gViewerWindow->saveImageNumbered(mFormattedImage);
gViewerWindow->saveImageNumbered(mFormattedImage);
// Relinquish image memory. Save button will be disabled as a side-effect.
mFormattedImage = NULL;
mDataSize = 0;
updateSnapshot(FALSE, FALSE);
if(success)
{
gViewerWindow->playSnapshotAnimAndSound();
}
return success;
}
///----------------------------------------------------------------------------

View File

@@ -34,7 +34,7 @@
#define LL_LLMediaCtrl_H
#include "llviewermedia.h"
#include "llviewermediaobserver.h"
#include "lluictrl.h"
#include "llframetimer.h"
#include "lldynamictexture.h"

View File

@@ -47,84 +47,12 @@
#include "lluuid.h"
#include "llkeyboard.h"
// Merov: Temporary definitions while porting the new viewer media code to Snowglobe
const int LEFT_BUTTON = 0;
const int RIGHT_BUTTON = 1;
// Move this to its own file.
LLViewerMediaEventEmitter::~LLViewerMediaEventEmitter()
{
observerListType::iterator iter = mObservers.begin();
while( iter != mObservers.end() )
{
LLViewerMediaObserver *self = *iter;
iter++;
remObserver(self);
}
}
///////////////////////////////////////////////////////////////////////////////
//
bool LLViewerMediaEventEmitter::addObserver( LLViewerMediaObserver* observer )
{
if ( ! observer )
return false;
if ( std::find( mObservers.begin(), mObservers.end(), observer ) != mObservers.end() )
return false;
mObservers.push_back( observer );
observer->mEmitters.push_back( this );
return true;
}
///////////////////////////////////////////////////////////////////////////////
//
bool LLViewerMediaEventEmitter::remObserver( LLViewerMediaObserver* observer )
{
if ( ! observer )
return false;
mObservers.remove( observer );
observer->mEmitters.remove(this);
return true;
}
///////////////////////////////////////////////////////////////////////////////
//
void LLViewerMediaEventEmitter::emitEvent( LLPluginClassMedia* media, LLPluginClassMediaOwner::EMediaEvent event )
{
observerListType::iterator iter = mObservers.begin();
while( iter != mObservers.end() )
{
LLViewerMediaObserver *self = *iter;
++iter;
self->handleMediaEvent( media, event );
}
}
// Move this to its own file.
LLViewerMediaObserver::~LLViewerMediaObserver()
{
std::list<LLViewerMediaEventEmitter *>::iterator iter = mEmitters.begin();
while( iter != mEmitters.end() )
{
LLViewerMediaEventEmitter *self = *iter;
iter++;
self->remObserver( this );
}
}
// Move this to its own file.
// helper class that tries to download a URL from a web site and calls a method
// Helper class that tries to download a URL from a web site and calls a method
// on the Panel Land Media and to discover the MIME type
class LLMimeDiscoveryResponder : public LLHTTPClient::Responder
{
@@ -279,9 +207,10 @@ void LLViewerMedia::updateBrowserUserAgent()
for(; iter != end; iter++)
{
LLViewerMediaImpl* pimpl = *iter;
if(pimpl->mMediaSource && pimpl->mMediaSource->pluginSupportsMediaBrowser())
LLPluginClassMedia* plugin = pimpl->getMediaPlugin();
if(plugin && plugin->pluginSupportsMediaBrowser())
{
pimpl->mMediaSource->setBrowserUserAgent(user_agent);
plugin->setBrowserUserAgent(user_agent);
}
}
@@ -366,7 +295,6 @@ LLViewerMediaImpl::LLViewerMediaImpl(const std::string& media_url,
U8 media_loop,
const std::string& mime_type)
:
mMediaSource( NULL ),
mMovieImageHasMips(false),
mTextureId(texture_id),
mMediaWidth(media_width),
@@ -399,7 +327,7 @@ LLViewerMediaImpl::~LLViewerMediaImpl()
//////////////////////////////////////////////////////////////////////////////////////////
bool LLViewerMediaImpl::initializeMedia(const std::string& mime_type)
{
if((mMediaSource == NULL) || (mMimeType != mime_type))
if((mPluginBase == NULL) || (mMimeType != mime_type))
{
if(! initializePlugin(mime_type))
{
@@ -413,7 +341,7 @@ bool LLViewerMediaImpl::initializeMedia(const std::string& mime_type)
}
// play();
return (mMediaSource != NULL);
return (mPluginBase != NULL);
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -434,14 +362,13 @@ void LLViewerMediaImpl::createMediaSource()
void LLViewerMediaImpl::destroyMediaSource()
{
mNeedsNewTexture = true;
if(! mMediaSource)
if (!mPluginBase)
{
return;
}
// Restore the texture
updateMovieImage(LLUUID::null, false);
delete mMediaSource;
mMediaSource = NULL;
destroyPlugin();
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -514,16 +441,17 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
LLNotifications::instance().add("NoPlugin", args);
return NULL;
}
}
//////////////////////////////////////////////////////////////////////////////////////////
bool LLViewerMediaImpl::initializePlugin(const std::string& media_type)
{
if(mMediaSource)
LLPluginClassMedia* plugin = getMediaPlugin();
if (plugin)
{
// Save the previous media source's last set size before destroying it.
mMediaWidth = mMediaSource->getSetWidth();
mMediaHeight = mMediaSource->getSetHeight();
mMediaWidth = plugin->getSetWidth();
mMediaHeight = plugin->getSetHeight();
}
// Always delete the old media impl first.
@@ -541,7 +469,7 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type)
media_source->setAutoScale(mMediaAutoScale);
media_source->setBrowserUserAgent(LLViewerMedia::getCurrentUserAgent());
mMediaSource = media_source;
mPluginBase = media_source;
return true;
}
@@ -550,34 +478,38 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type)
void LLViewerMediaImpl::setSize(int width, int height)
{
LLPluginClassMedia* plugin = getMediaPlugin();
mMediaWidth = width;
mMediaHeight = height;
if(mMediaSource)
if (plugin)
{
mMediaSource->setSize(width, height);
plugin->setSize(width, height);
}
}
//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::play()
{
LLPluginClassMedia* plugin = getMediaPlugin();
// first stop any previously playing media
// stop();
// mMediaSource->addObserver( this );
if(mMediaSource == NULL)
// plugin->addObserver( this );
if (!plugin)
{
if(!initializePlugin(mMimeType))
{
// Plugin failed initialization... should assert or something
return;
}
plugin = getMediaPlugin();
}
// updateMovieImage(mTextureId, true);
mMediaSource->loadURI( mMediaURL );
if(/*mMediaSource->pluginSupportsMediaTime()*/ true)
plugin->loadURI( mMediaURL );
if(/*plugin->pluginSupportsMediaTime()*/ true)
{
start();
}
@@ -586,9 +518,10 @@ void LLViewerMediaImpl::play()
//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::stop()
{
if(mMediaSource)
LLPluginClassMedia* plugin = getMediaPlugin();
if (plugin)
{
mMediaSource->stop();
plugin->stop();
// destroyMediaSource();
}
}
@@ -596,52 +529,57 @@ void LLViewerMediaImpl::stop()
//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::pause()
{
if(mMediaSource)
LLPluginClassMedia* plugin = getMediaPlugin();
if (plugin)
{
mMediaSource->pause();
plugin->pause();
}
}
//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::start()
{
if(mMediaSource)
LLPluginClassMedia* plugin = getMediaPlugin();
if (plugin)
{
mMediaSource->start();
plugin->start();
}
}
//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::seek(F32 time)
{
if(mMediaSource)
LLPluginClassMedia* plugin = getMediaPlugin();
if (plugin)
{
mMediaSource->seek(time);
plugin->seek(time);
}
}
//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::setVolume(F32 volume)
{
if(mMediaSource)
LLPluginClassMedia* plugin = getMediaPlugin();
if (plugin)
{
mMediaSource->setVolume(volume);
plugin->setVolume(volume);
}
}
//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::focus(bool focus)
{
if (mMediaSource)
LLPluginClassMedia* plugin = getMediaPlugin();
if (plugin)
{
// call focus just for the hell of it, even though this apopears to be a nop
mMediaSource->focus(focus);
plugin->focus(focus);
if (focus)
{
// spoof a mouse click to *actually* pass focus
// Don't do this anymore -- it actually clicks through now.
// mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_DOWN, 1, 1, 0);
// mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_UP, 1, 1, 0);
// plugin->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_DOWN, 1, 1, 0);
// plugin->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_UP, 1, 1, 0);
}
}
}
@@ -649,57 +587,62 @@ void LLViewerMediaImpl::focus(bool focus)
//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::mouseDown(S32 x, S32 y)
{
LLPluginClassMedia* plugin = getMediaPlugin();
scaleMouse(&x, &y);
mLastMouseX = x;
mLastMouseY = y;
if (mMediaSource)
if (plugin)
{
mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_DOWN, LEFT_BUTTON, x, y, 0);
plugin->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_DOWN, LEFT_BUTTON, x, y, 0);
}
}
//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::mouseUp(S32 x, S32 y)
{
LLPluginClassMedia* plugin = getMediaPlugin();
scaleMouse(&x, &y);
mLastMouseX = x;
mLastMouseY = y;
if (mMediaSource)
if (plugin)
{
mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_UP, LEFT_BUTTON, x, y, 0);
plugin->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_UP, LEFT_BUTTON, x, y, 0);
}
}
//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::mouseMove(S32 x, S32 y)
{
LLPluginClassMedia* plugin = getMediaPlugin();
scaleMouse(&x, &y);
mLastMouseX = x;
mLastMouseY = y;
if (mMediaSource)
if (plugin)
{
mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_MOVE, LEFT_BUTTON, x, y, 0);
plugin->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_MOVE, LEFT_BUTTON, x, y, 0);
}
}
//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::mouseLeftDoubleClick(S32 x, S32 y)
{
LLPluginClassMedia* plugin = getMediaPlugin();
scaleMouse(&x, &y);
mLastMouseX = x;
mLastMouseY = y;
if (mMediaSource)
if (plugin)
{
mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_DOUBLE_CLICK, LEFT_BUTTON, x, y, 0);
plugin->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_DOUBLE_CLICK, LEFT_BUTTON, x, y, 0);
}
}
//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::onMouseCaptureLost()
{
if (mMediaSource)
LLPluginClassMedia* plugin = getMediaPlugin();
if (plugin)
{
mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_UP, LEFT_BUTTON, mLastMouseX, mLastMouseY, 0);
plugin->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_UP, LEFT_BUTTON, mLastMouseX, mLastMouseY, 0);
}
}
@@ -720,15 +663,17 @@ BOOL LLViewerMediaImpl::handleMouseUp(S32 x, S32 y, MASK mask)
//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::navigateHome()
{
if(mMediaSource)
LLPluginClassMedia* plugin = getMediaPlugin();
if (plugin)
{
mMediaSource->loadURI( mHomeURL );
plugin->loadURI( mHomeURL );
}
}
//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mime_type, bool rediscover_type)
{
LLPluginClassMedia* plugin = getMediaPlugin();
if(rediscover_type)
{
@@ -745,7 +690,7 @@ void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mi
// We use "data" internally for a text/html url for loading the login screen
if(initializeMedia("text/html"))
{
mMediaSource->loadURI( url );
plugin->loadURI( url );
}
}
else
@@ -753,17 +698,17 @@ void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mi
// This catches 'rtsp://' urls
if(initializeMedia(scheme))
{
mMediaSource->loadURI( url );
plugin->loadURI( url );
}
}
}
else if (mMediaSource)
else if (plugin)
{
mMediaSource->loadURI( url );
plugin->loadURI( url );
}
else if(initializeMedia(mime_type) && mMediaSource)
else if(initializeMedia(mime_type) && (plugin = getMediaPlugin()))
{
mMediaSource->loadURI( url );
plugin->loadURI( url );
}
else
{
@@ -777,9 +722,10 @@ void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mi
//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::navigateStop()
{
if(mMediaSource)
LLPluginClassMedia* plugin = getMediaPlugin();
if (plugin)
{
mMediaSource->browse_stop();
plugin->browse_stop();
}
}
@@ -788,8 +734,9 @@ void LLViewerMediaImpl::navigateStop()
bool LLViewerMediaImpl::handleKeyHere(KEY key, MASK mask)
{
bool result = false;
LLPluginClassMedia* plugin = getMediaPlugin();
if (mMediaSource)
if (plugin)
{
// FIXME: THIS IS SO WRONG.
// Menu keys should be handled by the menu system and not passed to UI elements, but this is how LLTextEditor and LLLineEditor do it...
@@ -797,19 +744,19 @@ bool LLViewerMediaImpl::handleKeyHere(KEY key, MASK mask)
{
if( 'C' == key )
{
mMediaSource->copy();
plugin->copy();
result = true;
}
else
if( 'V' == key )
{
mMediaSource->paste();
plugin->paste();
result = true;
}
else
if( 'X' == key )
{
mMediaSource->cut();
plugin->cut();
result = true;
}
}
@@ -819,9 +766,9 @@ bool LLViewerMediaImpl::handleKeyHere(KEY key, MASK mask)
LLSD native_key_data = LLSD::emptyMap();
result = mMediaSource->keyEvent(LLPluginClassMedia::KEY_EVENT_DOWN ,key, mask, native_key_data);
result = plugin->keyEvent(LLPluginClassMedia::KEY_EVENT_DOWN ,key, mask, native_key_data);
// Since the viewer internal event dispatching doesn't give us key-up events, simulate one here.
(void)mMediaSource->keyEvent(LLPluginClassMedia::KEY_EVENT_UP ,key, mask, native_key_data);
(void)plugin->keyEvent(LLPluginClassMedia::KEY_EVENT_UP ,key, mask, native_key_data);
}
}
@@ -832,8 +779,9 @@ bool LLViewerMediaImpl::handleKeyHere(KEY key, MASK mask)
bool LLViewerMediaImpl::handleUnicodeCharHere(llwchar uni_char)
{
bool result = false;
LLPluginClassMedia* plugin = getMediaPlugin();
if (mMediaSource)
if (plugin)
{
// only accept 'printable' characters, sigh...
if (uni_char >= 32 // discard 'control' characters
@@ -841,7 +789,7 @@ bool LLViewerMediaImpl::handleUnicodeCharHere(llwchar uni_char)
{
LLSD native_key_data = LLSD::emptyMap();
mMediaSource->textInput(wstring_to_utf8str(LLWString(1, uni_char)), gKeyboard->currentMask(FALSE), native_key_data);
plugin->textInput(wstring_to_utf8str(LLWString(1, uni_char)), gKeyboard->currentMask(FALSE), native_key_data);
}
}
@@ -851,10 +799,11 @@ bool LLViewerMediaImpl::handleUnicodeCharHere(llwchar uni_char)
//////////////////////////////////////////////////////////////////////////////////////////
bool LLViewerMediaImpl::canNavigateForward()
{
BOOL result = FALSE;
if (mMediaSource)
bool result = false;
LLPluginClassMedia* plugin = getMediaPlugin();
if (plugin)
{
result = mMediaSource->getHistoryForwardAvailable();
result = plugin->getHistoryForwardAvailable();
}
return result;
}
@@ -862,10 +811,11 @@ bool LLViewerMediaImpl::canNavigateForward()
//////////////////////////////////////////////////////////////////////////////////////////
bool LLViewerMediaImpl::canNavigateBack()
{
BOOL result = FALSE;
if (mMediaSource)
bool result = false;
LLPluginClassMedia* plugin = getMediaPlugin();
if (plugin)
{
result = mMediaSource->getHistoryBackAvailable();
result = plugin->getHistoryBackAvailable();
}
return result;
}
@@ -909,20 +859,21 @@ void LLViewerMediaImpl::updateMovieImage(const LLUUID& uuid, BOOL active)
//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::update()
{
if(mMediaSource == NULL)
LLPluginClassMedia* plugin = getMediaPlugin();
if (!plugin)
{
return;
}
mMediaSource->idle();
plugin->idle();
if(mMediaSource->isPluginExited())
if (plugin->isPluginExited())
{
destroyMediaSource();
return;
}
if(!mMediaSource->textureValid())
if (!plugin->textureValid())
{
return;
}
@@ -937,7 +888,7 @@ void LLViewerMediaImpl::update()
if(placeholder_image)
{
LLRect dirty_rect;
if(mMediaSource->getDirty(&dirty_rect))
if (plugin->getDirty(&dirty_rect))
{
// Constrain the dirty rect to be inside the texture
S32 x_pos = llmax(dirty_rect.mLeft, 0);
@@ -948,16 +899,16 @@ void LLViewerMediaImpl::update()
if(width > 0 && height > 0)
{
U8* data = mMediaSource->getBitsData();
U8* data = plugin->getBitsData();
// Offset the pixels pointer to match x_pos and y_pos
data += ( x_pos * mMediaSource->getTextureDepth() * mMediaSource->getBitsWidth() );
data += ( y_pos * mMediaSource->getTextureDepth() );
data += ( x_pos * plugin->getTextureDepth() * plugin->getBitsWidth() );
data += ( y_pos * plugin->getTextureDepth() );
placeholder_image->setSubImage(
data,
mMediaSource->getBitsWidth(),
mMediaSource->getBitsHeight(),
plugin->getBitsWidth(),
plugin->getBitsHeight(),
x_pos,
y_pos,
width,
@@ -966,7 +917,7 @@ void LLViewerMediaImpl::update()
}
mMediaSource->resetDirty();
plugin->resetDirty();
}
}
}
@@ -988,22 +939,23 @@ void LLViewerMediaImpl::updateImagesMediaStreams()
}
LLViewerMediaTexture* placeholder_image = (LLViewerMediaTexture*)LLViewerTextureManager::findTexture( mTextureId );
LLPluginClassMedia* plugin = getMediaPlugin();
if (mNeedsNewTexture
|| placeholder_image->getUseMipMaps()
|| ! placeholder_image->mIsMediaTexture
|| (placeholder_image->getWidth() != mMediaSource->getTextureWidth())
|| (placeholder_image->getHeight() != mMediaSource->getTextureHeight())
|| (mTextureUsedWidth != mMediaSource->getWidth())
|| (mTextureUsedHeight != mMediaSource->getHeight())
|| (placeholder_image->getWidth() != plugin->getTextureWidth())
|| (placeholder_image->getHeight() != plugin->getTextureHeight())
|| (mTextureUsedWidth != plugin->getWidth())
|| (mTextureUsedHeight != plugin->getHeight())
)
{
llinfos << "initializing media placeholder" << llendl;
llinfos << "movie image id " << mTextureId << llendl;
int texture_width = mMediaSource->getTextureWidth();
int texture_height = mMediaSource->getTextureHeight();
int texture_depth = mMediaSource->getTextureDepth();
int texture_width = plugin->getTextureWidth();
int texture_height = plugin->getTextureHeight();
int texture_depth = plugin->getTextureDepth();
// MEDIAOPT: check to see if size actually changed before doing work
placeholder_image->destroyGLTexture();
@@ -1017,10 +969,10 @@ void LLViewerMediaImpl::updateImagesMediaStreams()
int discard_level = 0;
// ask media source for correct GL image format constants
placeholder_image->setExplicitFormat(mMediaSource->getTextureFormatInternal(),
mMediaSource->getTextureFormatPrimary(),
mMediaSource->getTextureFormatType(),
mMediaSource->getTextureFormatSwapBytes());
placeholder_image->setExplicitFormat(plugin->getTextureFormatInternal(),
plugin->getTextureFormatPrimary(),
plugin->getTextureFormatType(),
plugin->getTextureFormatSwapBytes());
placeholder_image->createGLTexture(discard_level, raw);
@@ -1033,8 +985,8 @@ void LLViewerMediaImpl::updateImagesMediaStreams()
// If the amount of the texture being drawn by the media goes down in either width or height,
// recreate the texture to avoid leaving parts of the old image behind.
mTextureUsedWidth = mMediaSource->getWidth();
mTextureUsedHeight = mMediaSource->getHeight();
mTextureUsedWidth = plugin->getWidth();
mTextureUsedHeight = plugin->getHeight();
}
return placeholder_image;
@@ -1050,24 +1002,25 @@ LLUUID LLViewerMediaImpl::getMediaTextureID()
//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::setVisible(bool visible)
{
LLPluginClassMedia* plugin = getMediaPlugin();
mVisible = visible;
if(mVisible)
{
if(mMediaSource && mMediaSource->isPluginExited())
if(plugin && plugin->isPluginExited())
{
destroyMediaSource();
}
if(!mMediaSource)
if(!plugin)
{
createMediaSource();
}
}
if(mMediaSource)
if(plugin)
{
mMediaSource->setPriority(mVisible?LLPluginClassMedia::PRIORITY_NORMAL:LLPluginClassMedia::PRIORITY_HIDDEN);
plugin->setPriority(mVisible?LLPluginClassBasic::PRIORITY_NORMAL:LLPluginClassBasic::PRIORITY_SLEEP);
}
}
@@ -1080,10 +1033,11 @@ void LLViewerMediaImpl::mouseCapture()
//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::getTextureSize(S32 *texture_width, S32 *texture_height)
{
if(mMediaSource && mMediaSource->textureValid())
LLPluginClassMedia* plugin = getMediaPlugin();
if(plugin && plugin->textureValid())
{
S32 real_texture_width = mMediaSource->getBitsWidth();
S32 real_texture_height = mMediaSource->getBitsHeight();
S32 real_texture_width = plugin->getBitsWidth();
S32 real_texture_height = plugin->getBitsHeight();
{
// The "texture width" coming back from the plugin may not be a power of two (thanks to webkit).
@@ -1124,10 +1078,11 @@ void LLViewerMediaImpl::scaleMouse(S32 *mouse_x, S32 *mouse_y)
bool LLViewerMediaImpl::isMediaPlaying()
{
bool result = false;
LLPluginClassMedia* plugin = getMediaPlugin();
if(mMediaSource)
if(plugin)
{
EMediaStatus status = mMediaSource->getStatus();
EMediaStatus status = plugin->getStatus();
if(status == MEDIA_PLAYING || status == MEDIA_LOADING)
result = true;
}
@@ -1138,10 +1093,11 @@ bool LLViewerMediaImpl::isMediaPlaying()
bool LLViewerMediaImpl::isMediaPaused()
{
bool result = false;
LLPluginClassMedia* plugin = getMediaPlugin();
if(mMediaSource)
if(plugin)
{
if(mMediaSource->getStatus() == MEDIA_PAUSED)
if(plugin->getStatus() == MEDIA_PAUSED)
result = true;
}
@@ -1152,7 +1108,7 @@ bool LLViewerMediaImpl::isMediaPaused()
//
bool LLViewerMediaImpl::hasMedia()
{
return mMediaSource != NULL;
return mPluginBase != NULL;
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -1179,8 +1135,9 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* self, LLPluginClass
void
LLViewerMediaImpl::cut()
{
if (mMediaSource)
mMediaSource->cut();
LLPluginClassMedia* plugin = getMediaPlugin();
if (plugin)
plugin->cut();
}
////////////////////////////////////////////////////////////////////////////////
@@ -1188,8 +1145,9 @@ LLViewerMediaImpl::cut()
BOOL
LLViewerMediaImpl::canCut() const
{
if (mMediaSource)
return mMediaSource->canCut();
LLPluginClassMedia* plugin = getMediaPlugin();
if (plugin)
return plugin->canCut();
else
return FALSE;
}
@@ -1199,8 +1157,9 @@ LLViewerMediaImpl::canCut() const
void
LLViewerMediaImpl::copy()
{
if (mMediaSource)
mMediaSource->copy();
LLPluginClassMedia* plugin = getMediaPlugin();
if (plugin)
plugin->copy();
}
////////////////////////////////////////////////////////////////////////////////
@@ -1208,8 +1167,9 @@ LLViewerMediaImpl::copy()
BOOL
LLViewerMediaImpl::canCopy() const
{
if (mMediaSource)
return mMediaSource->canCopy();
LLPluginClassMedia* plugin = getMediaPlugin();
if (plugin)
return plugin->canCopy();
else
return FALSE;
}
@@ -1219,8 +1179,9 @@ LLViewerMediaImpl::canCopy() const
void
LLViewerMediaImpl::paste()
{
if (mMediaSource)
mMediaSource->paste();
LLPluginClassMedia* plugin = getMediaPlugin();
if (plugin)
plugin->paste();
}
////////////////////////////////////////////////////////////////////////////////
@@ -1228,8 +1189,9 @@ LLViewerMediaImpl::paste()
BOOL
LLViewerMediaImpl::canPaste() const
{
if (mMediaSource)
return mMediaSource->canPaste();
LLPluginClassMedia* plugin = getMediaPlugin();
if (plugin)
return plugin->canPaste();
else
return FALSE;
}

View File

@@ -33,34 +33,17 @@
#ifndef LLVIEWERMEDIA_H
#define LLVIEWERMEDIA_H
#include "llviewermediaeventemitter.h"
#include "llviewerpluginmanager.h"
#include "llfocusmgr.h"
#include "llpanel.h"
#include "llpluginclassmediaowner.h"
#include "llviewermediaobserver.h"
class LLViewerMediaImpl;
class LLUUID;
//class LLViewerMediaTexture;
class LLSD;
class LLViewerTexture;
typedef LLPointer<LLViewerMediaImpl> viewer_media_t;
///////////////////////////////////////////////////////////////////////////////
//
class LLViewerMediaEventEmitter
{
public:
virtual ~LLViewerMediaEventEmitter();
bool addObserver( LLViewerMediaObserver* subject );
bool remObserver( LLViewerMediaObserver* subject );
void emitEvent(LLPluginClassMedia* self, LLPluginClassMediaOwner::EMediaEvent event);
private:
typedef std::list< LLViewerMediaObserver* > observerListType;
observerListType mObservers;
};
class LLViewerMedia
{
@@ -93,7 +76,7 @@ class LLViewerMedia
// Implementation functions not exported into header file
class LLViewerMediaImpl
: public LLMouseHandler, public LLRefCount, public LLPluginClassMediaOwner, public LLViewerMediaEventEmitter, public LLEditMenuHandler
: public LLViewerPluginManager, public LLMouseHandler, public LLPluginClassMediaOwner, public LLViewerMediaEventEmitter, public LLEditMenuHandler
{
LOG_CLASS(LLViewerMediaImpl);
public:
@@ -112,9 +95,12 @@ public:
void setMediaType(const std::string& media_type);
bool initializeMedia(const std::string& mime_type);
bool initializePlugin(const std::string& media_type);
LLPluginClassMedia* getMediaPlugin() { return mMediaSource; }
LLPluginClassMedia* getMediaPlugin() const { return (LLPluginClassMedia*)mPluginBase; }
void setSize(int width, int height);
// Inherited from LLViewerPluginManager.
/*virtual*/ void update();
void play();
void stop();
void pause();
@@ -141,7 +127,6 @@ public:
void getTextureSize(S32 *texture_width, S32 *texture_height);
void scaleMouse(S32 *mouse_x, S32 *mouse_y);
void update();
void updateMovieImage(const LLUUID& image_id, BOOL active);
void updateImagesMediaStreams();
LLUUID getMediaTextureID();
@@ -201,7 +186,6 @@ public:
public:
// a single media url with some data and an impl.
LLPluginClassMedia* mMediaSource;
LLUUID mTextureId;
bool mMovieImageHasMips;
std::string mMediaURL;
@@ -219,7 +203,6 @@ public:
bool mSuspendUpdates;
bool mVisible;
private:
/*LLViewerMediaTexture*/LLViewerTexture *updatePlaceholderImage();
};

View File

@@ -0,0 +1,85 @@
/**
* @file llviewermediaeventemitter.cpp
* @brief Implementation of LLViewerMediaEventEmitter
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2010, 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 "llviewermediaeventemitter.h"
#include "llviewermediaobserver.h"
#include <algorithm>
LLViewerMediaEventEmitter::~LLViewerMediaEventEmitter()
{
observerListType::iterator iter = mObservers.begin();
while (iter != mObservers.end())
{
LLViewerMediaObserver* self = *iter;
++iter;
remObserver(self);
}
}
bool LLViewerMediaEventEmitter::addObserver(LLViewerMediaObserver* observer)
{
if (!observer)
return false;
if (std::find(mObservers.begin(), mObservers.end(), observer) != mObservers.end())
return false;
mObservers.push_back(observer);
observer->mEmitters.push_back(this);
return true;
}
bool LLViewerMediaEventEmitter::remObserver(LLViewerMediaObserver* observer)
{
if (!observer)
return false;
mObservers.remove(observer);
observer->mEmitters.remove(this);
return true;
}
void LLViewerMediaEventEmitter::emitEvent(LLPluginClassMedia* media, LLPluginClassMediaOwner::EMediaEvent event)
{
observerListType::iterator iter = mObservers.begin();
while (iter != mObservers.end())
{
LLViewerMediaObserver* self = *iter;
++iter;
self->handleMediaEvent(media, event);
}
}

View File

@@ -0,0 +1,56 @@
/**
* @file llviewermediaeventemitter.h
* @brief Helper class
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2010, 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$
*/
#ifndef LLVIEWERMEDIAEVENTEMITTER_H
#define LLVIEWERMEDIAEVENTEMITTER_H
#include "llpluginclassmediaowner.h"
#include <list>
class LLViewerMediaObserver;
class LLPluginClassMedia;
class LLViewerMediaEventEmitter
{
public:
virtual ~LLViewerMediaEventEmitter();
bool addObserver(LLViewerMediaObserver* subject);
bool remObserver(LLViewerMediaObserver* subject);
void emitEvent(LLPluginClassMedia* self, LLPluginClassMediaOwner::EMediaEvent event);
private:
typedef std::list< LLViewerMediaObserver*> observerListType;
observerListType mObservers;
};
#endif // LLVIEWERMEDIAEVENTEMITTER_H

View File

@@ -0,0 +1,47 @@
/**
* @file llviewermediaobserver.cpp
* @brief Implementation of class LLViewerMediaObserver.
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2010, 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 "llviewermediaeventemitter.h"
#include "llviewermediaobserver.h"
LLViewerMediaObserver::~LLViewerMediaObserver()
{
std::list<LLViewerMediaEventEmitter*>::iterator iter = mEmitters.begin();
while (iter != mEmitters.end())
{
LLViewerMediaEventEmitter* self = *iter;
++iter;
self->remObserver(this);
}
}

View File

@@ -552,8 +552,6 @@ class LLFileTakeSnapshotToDisk : public view_listener_t
6144,
supersample))
{
gViewerWindow->playSnapshotAnimAndSound();
LLPointer<LLImageFormatted> formatted;
switch(LLFloaterSnapshot::ESnapshotFormat(gSavedSettings.getS32("SnapshotFormat")))
{

View File

@@ -34,6 +34,7 @@
#define LLVIEWERPARCELMEDIA_H
#include "llviewermedia.h"
#include "llviewermediaobserver.h"
// For use by other patches so they know that media filtering is implemented.
#define MEDIA_FILTERING 1
@@ -42,7 +43,6 @@ class LLMessageSystem;
class LLParcel;
class LLViewerParcelMediaNavigationObserver;
// This class understands land parcels, network traffic, LSL media
// transport commands, and talks to the LLViewerMedia class to actually
// do playback. It allows us to remove code from LLViewerParcelMgr.

View File

@@ -0,0 +1,56 @@
/**
* @file llviewerpluginmanager.cpp
* @brief Client interface to the plugin engine
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2010, 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 "llviewerpluginmanager.h"
void LLViewerPluginManager::destroyPlugin()
{
delete mPluginBase;
mPluginBase = NULL;
}
void LLViewerPluginManager::update()
{
if (!mPluginBase)
{
return;
}
mPluginBase->idle();
if (mPluginBase->isPluginExited())
{
destroyPlugin();
return;
}
}

View File

@@ -0,0 +1,115 @@
/**
* @file llviewerpluginmanager.h
* @brief Client interface to the plugin engine
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2010, 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$
*/
#ifndef LLVIEWERPLUGINMANAGER_H
#define LLVIEWERPLUGINMANAGER_H
#include <string>
#include "llmemory.h"
#include "llerror.h"
#include "lldir.h"
#include "llfile.h"
#include "llviewercontrol.h"
#include "llnotifications.h"
#include "llpluginclassbasic.h"
class LLViewerPluginManager : public LLRefCount
{
LOG_CLASS(LLViewerPluginManager);
public:
// Construct an uninitialized LLViewerPluginManager object.
LLViewerPluginManager(void) : mPluginBase(NULL) { }
// Create a PLUGIN_TYPE (must be derived from LLPluginClassBasic).
// This uses PLUGIN_TYPE::launcher_name() and PLUGIN_TYPE::plugin_basename().
// If successful, returns the created LLPluginClassBasic, NULL otherwise.
template<class PLUGIN_TYPE, typename T>
LLPluginClassBasic* createPlugin(T* user_data);
// Delete the plugin.
void destroyPlugin();
// Handle plugin messages.
virtual void update();
// Return pointer to plugin.
LLPluginClassBasic* getPlugin(void) const { return mPluginBase; }
protected:
LLPluginClassBasic* mPluginBase; //!< Pointer to the base class of the underlaying plugin.
};
template<class PLUGIN_TYPE, typename T>
LLPluginClassBasic* LLViewerPluginManager::createPlugin(T* user_data)
{
// Always delete the old plugin first.
destroyPlugin();
std::string plugin_name = gDirUtilp->getLLPluginFilename(PLUGIN_TYPE::plugin_basename());
// See if the plugin executable exists.
llstat s;
if (LLFile::stat(PLUGIN_TYPE::launcher_name(), &s))
{
LL_WARNS("Plugin") << "Couldn't find launcher at " << PLUGIN_TYPE::launcher_name() << LL_ENDL;
}
else if (LLFile::stat(plugin_name, &s))
{
LL_WARNS("Plugin") << "Couldn't find plugin at " << plugin_name << LL_ENDL;
}
else
{
LLPluginClassBasic* plugin = new PLUGIN_TYPE(user_data);
if (plugin->init(PLUGIN_TYPE::launcher_name(), plugin_name, gSavedSettings.getBOOL("PluginAttachDebuggerToPlugins")))
{
mPluginBase = plugin;
}
else
{
LL_WARNS("Plugin") << "Failed to init plugin. Destroying." << LL_ENDL;
delete plugin;
}
}
if (mPluginBase)
return mPluginBase;
LL_WARNS("Plugin") << "plugin intialization failed for plugin: " << PLUGIN_TYPE::plugin_basename() << LL_ENDL;
LLSD args;
args["MIME_TYPE"] = PLUGIN_TYPE::plugin_basename(); // FIXME: Use different notification.
LLNotifications::instance().add("NoPlugin", args);
return NULL;
}
#endif // LLVIEWERPLUGINMANAGER_H

View File

@@ -89,7 +89,7 @@
#include "llmaniptranslate.h"
#include "llface.h"
#include "llfeaturemanager.h"
#include "llfilepicker.h"
#include "statemachine/aifilepicker.h"
#include "llfloater.h"
#include "llfloateractivespeakers.h"
#include "llfloaterbuildoptions.h"
@@ -3988,27 +3988,27 @@ BOOL LLViewerWindow::mousePointOnLandGlobal(const S32 x, const S32 y, LLVector3d
}
// Saves an image to the harddrive as "SnapshotX" where X >= 1.
BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image)
void LLViewerWindow::saveImageNumbered(LLPointer<LLImageFormatted> image)
{
if (!image)
{
return FALSE;
return;
}
LLFilePicker::ESaveFilter pick_type;
ESaveFilter pick_type;
std::string extension("." + image->getExtension());
if (extension == ".j2c")
pick_type = LLFilePicker::FFSAVE_J2C;
pick_type = FFSAVE_J2C;
else if (extension == ".bmp")
pick_type = LLFilePicker::FFSAVE_BMP;
pick_type = FFSAVE_BMP;
else if (extension == ".jpg")
pick_type = LLFilePicker::FFSAVE_JPEG;
pick_type = FFSAVE_JPEG;
else if (extension == ".png")
pick_type = LLFilePicker::FFSAVE_PNG;
pick_type = FFSAVE_PNG;
else if (extension == ".tga")
pick_type = LLFilePicker::FFSAVE_TGA;
pick_type = FFSAVE_TGA;
else
pick_type = LLFilePicker::FFSAVE_ALL; // ???
pick_type = FFSAVE_ALL; // ???
// Get a base file location if needed.
if ( ! isSnapshotLocSet())
@@ -4018,20 +4018,34 @@ BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image)
// getSaveFile will append an appropriate extension to the proposed name, based on the ESaveFilter constant passed in.
// pick a directory in which to save
LLFilePicker& picker = LLFilePicker::instance();
if (!picker.getSaveFile(pick_type, proposed_name))
{
// Clicked cancel
return FALSE;
}
AIFilePicker* filepicker = new AIFilePicker; // Deleted in LLViewerWindow::saveImageNumbered_filepicker_callback
filepicker->open(proposed_name, pick_type, "", "snapshot");
filepicker->run(boost::bind(&LLViewerWindow::saveImageNumbered_filepicker_callback, this, image, extension, filepicker, _1));
return;
}
// LLViewerWindow::sSnapshotBaseName and LLViewerWindow::sSnapshotDir already known. Go straight to saveImageNumbered_continued.
saveImageNumbered_continued(image, extension);
}
void LLViewerWindow::saveImageNumbered_filepicker_callback(LLPointer<LLImageFormatted> image, std::string const& extension, AIFilePicker* filepicker, bool success)
{
llassert((bool)*filepicker == success);
if (success)
{
// Copy the directory + file name
std::string filepath = picker.getFirstFile();
std::string filepath = filepicker->getFilename();
LLViewerWindow::sSnapshotBaseName = gDirUtilp->getBaseFileName(filepath, true);
LLViewerWindow::sSnapshotDir = gDirUtilp->getDirName(filepath);
}
saveImageNumbered_continued(image, extension);
}
delete filepicker;
}
void LLViewerWindow::saveImageNumbered_continued(LLPointer<LLImageFormatted> image, std::string const& extension)
{
// Look for an unused file name
std::string filepath;
S32 i = 1;
@@ -4051,7 +4065,10 @@ BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image)
}
while( -1 != err ); // search until the file is not found (i.e., stat() gives an error).
return image->save(filepath);
if (image->save(filepath))
{
playSnapshotAnimAndSound();
}
}
void LLViewerWindow::resetSnapshotLoc()

View File

@@ -60,6 +60,7 @@ class LLTextBox;
class LLImageRaw;
class LLHUDIcon;
class LLMouseHandler;
class AIFilePicker;
#define PICK_HALF_WIDTH 5
#define PICK_DIAMETER (2 * PICK_HALF_WIDTH + 1)
@@ -282,19 +283,21 @@ public:
// snapshot functionality.
// perhaps some of this should move to llfloatershapshot? -MG
typedef enum e_snapshot_type
enum ESnapshotType
{
SNAPSHOT_TYPE_COLOR,
SNAPSHOT_TYPE_DEPTH,
SNAPSHOT_TYPE_OBJECT_ID
} ESnapshotType;
};
BOOL saveSnapshot(const std::string& filename, S32 image_width, S32 image_height, BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, ESnapshotType type = SNAPSHOT_TYPE_COLOR);
BOOL rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, BOOL keep_window_aspect = TRUE, BOOL is_texture = FALSE,
BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, ESnapshotType type = SNAPSHOT_TYPE_COLOR, S32 max_size = MAX_SNAPSHOT_IMAGE_SIZE, F32 supersample = 1.f );
BOOL thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type) ;
BOOL isSnapshotLocSet() const { return ! sSnapshotDir.empty(); }
void resetSnapshotLoc() const { sSnapshotDir.clear(); }
BOOL saveImageNumbered(LLImageFormatted *image);
void saveImageNumbered(LLPointer<LLImageFormatted> image);
void saveImageNumbered_filepicker_callback(LLPointer<LLImageFormatted> image, std::string const& extension, AIFilePicker* filepicker, bool success);
void saveImageNumbered_continued(LLPointer<LLImageFormatted> image, std::string const& extension);
// Reset the directory where snapshots are saved.
// Client will open directory picker on next snapshot save.

View File

@@ -0,0 +1,369 @@
/**
* @file aifilepicker.cpp
* @brief Implementation of AIFilePicker
*
* 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.
*
* 04/12/2010
* Initial version, written by Aleric Inglewood @ SL
*/
#include "../llviewerprecompiledheaders.h"
#include "../llviewermedia.h"
#include "../lltrans.h"
#include "llpluginclassmedia.h"
#include "llpluginmessageclasses.h"
#include "aifilepicker.h"
#if LL_WINDOWS
#include "../llviewerwindow.h"
#endif
#if LL_GTK && LL_X11
#include "llwindowsdl.h"
#endif
enum filepicker_state_type {
AIFilePicker_initialize_plugin = AIStateMachine::max_state,
AIFilePicker_plugin_running,
AIFilePicker_canceled,
AIFilePicker_done
};
char const* AIFilePicker::state_str_impl(state_type run_state) const
{
switch(run_state)
{
AI_CASE_RETURN(AIFilePicker_initialize_plugin);
AI_CASE_RETURN(AIFilePicker_plugin_running);
AI_CASE_RETURN(AIFilePicker_canceled);
AI_CASE_RETURN(AIFilePicker_done);
}
return "UNKNOWN STATE";
}
AIFilePicker::AIFilePicker(void) : mPluginManager(NULL), mCanceled(false)
{
}
void AIFilePicker::store_folder(std::string const& context, std::string const& folder)
{
if (!folder.empty())
{
mContextMap[context] = folder;
}
}
std::string AIFilePicker::get_folder(std::string const& default_path, std::string const& context)
{
context_map_type::iterator iter = mContextMap.find(context);
if (iter != mContextMap.end())
{
return iter->second;
}
else if (!default_path.empty())
{
return default_path;
}
else if ((iter = mContextMap.find("savefile")) != mContextMap.end())
{
return iter->second;
}
else
{
// This is the last resort when all else failed. Open the file chooser in directory 'home'.
char const* home = NULL;
#if LL_WINDOWS
#warning "Attention WINDOWS DEVELOPER: Set 'home' to a sensible default directory (users Desktop?)"
#else
home = getenv("HOME");
#endif
return home ? home : "";
}
}
void AIFilePicker::open(ELoadFilter filter, std::string const& default_path, std::string const& context, bool multiple)
{
mContext = context;
mFolder = get_folder(default_path, context);
mOpenType = multiple ? load_multiple : load;
switch(filter)
{
case FFLOAD_ALL:
mFilter = "all";
break;
case FFLOAD_WAV:
mFilter = "wav";
break;
case FFLOAD_IMAGE:
mFilter = "image";
break;
case FFLOAD_ANIM:
mFilter = "anim";
break;
#ifdef _CORY_TESTING
case FFLOAD_GEOMETRY:
mFilter = "geometry";
break;
#endif
case FFLOAD_XML:
mFilter = "xml";
break;
case FFLOAD_SLOBJECT:
mFilter = "slobject";
break;
case FFLOAD_RAW:
mFilter = "raw";
break;
case FFLOAD_TEXT:
mFilter = "text";
break;
}
}
void AIFilePicker::open(std::string const& filename, ESaveFilter filter, std::string const& default_path, std::string const& context)
{
mFilename = filename;
mContext = context;
mFolder = get_folder(default_path, context);
mOpenType = save;
switch(filter)
{
case FFSAVE_ALL:
mFilter = "all";
break;
case FFSAVE_WAV:
mFilter = "wav";
break;
case FFSAVE_TGA:
mFilter = "tga";
break;
case FFSAVE_BMP:
mFilter = "bmp";
break;
case FFSAVE_AVI:
mFilter = "avi";
break;
case FFSAVE_ANIM:
mFilter = "anim";
break;
#ifdef _CORY_TESTING
case FFSAVE_GEOMETRY:
mFilter = "geometry";
break;
#endif
case FFSAVE_XML:
mFilter = "xml";
break;
case FFSAVE_COLLADA:
mFilter = "collada";
break;
case FFSAVE_RAW:
mFilter = "raw";
break;
case FFSAVE_J2C:
mFilter = "j2c";
break;
case FFSAVE_PNG:
mFilter = "png";
break;
case FFSAVE_JPEG:
mFilter = "jpeg";
break;
case FFSAVE_HPA:
mFilter = "hpa";
break;
case FFSAVE_TEXT:
mFilter = "text";
break;
case FFSAVE_LSL:
mFilter = "lsl";
break;
}
}
void AIFilePicker::initialize_impl(void)
{
mCanceled = false;
if (mFilter.empty())
{
llwarns << "Calling AIFilePicker::initialize_impl() with empty mFilter. Call open before calling run!" << llendl;
abort();
return;
}
mPluginManager = new LLViewerPluginManager;
if (!mPluginManager)
{
abort();
return;
}
LLPluginClassBasic* plugin = mPluginManager->createPlugin<AIPluginFilePicker>(this);
if (!plugin)
{
abort();
return;
}
set_state(AIFilePicker_initialize_plugin);
}
void AIFilePicker::multiplex_impl(void)
{
mPluginManager->update(); // Give the plugin some CPU for it's messages.
LLPluginClassBasic* plugin = mPluginManager->getPlugin();
if (!plugin || plugin->isPluginExited())
{
// This happens when there was a problem with the plugin (ie, it crashed).
abort();
return;
}
switch (mRunState)
{
case AIFilePicker_initialize_plugin:
{
if (!plugin->isPluginRunning())
{
break; // Still initializing.
}
// Send initialization message.
LLPluginMessage initialization_message(LLPLUGIN_MESSAGE_CLASS_BASIC, "initialization");
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"
};
LLSD dictionary;
for (int key = 0; key < sizeof(key_str) / sizeof(key_str[0]); ++key)
{
dictionary[key_str[key]] = LLTrans::getString(key_str[key]);
}
initialization_message.setValueLLSD("dictionary", dictionary);
#if LL_WINDOWS || (LL_GTK && LL_X11)
std::ostringstream window_id_str;
#if LL_WINDOWS
unsigned long window_id = gViewerWindow->getPlatformWindow();
#else
unsigned long window_id = LLWindowSDL::get_SDL_XWindowID();
#endif
if (window_id != None)
{
window_id_str << std::hex << "0x" << window_id;
initialization_message.setValue("window_id", window_id_str.str());
}
else
{
LL_WARNS("Plugin") << "Couldn't get xwid to use for transient." << LL_ENDL;
}
#endif // LL_WINDOWS || (LL_GTK && LL_X11)
plugin->sendMessage(initialization_message);
// Send open message.
LLPluginMessage open_message(LLPLUGIN_MESSAGE_CLASS_BASIC, "open");
open_message.setValue("type", (mOpenType == save) ? "save" : (mOpenType == load) ? "load" : "load_multiple");
open_message.setValue("filter", mFilter);
if (mOpenType == save) open_message.setValue("default", mFilename);
open_message.setValue("folder", mFolder);
open_message.setValue("gorgon", "block"); // Don't expect HeartBeat messages after an "open".
plugin->sendMessage(open_message);
set_state(AIFilePicker_plugin_running);
break;
}
case AIFilePicker_plugin_running:
{
// Users are slow, no need to look for new messages from the plugin all too often.
yield_ms(250);
break;
}
case AIFilePicker_canceled:
{
mCanceled = true;
finish();
break;
}
case AIFilePicker_done:
{
// Store folder of first filename as context.
store_folder(mContext, getFolder());
finish();
}
}
}
void AIFilePicker::abort_impl(void)
{
}
void AIFilePicker::finish_impl(void)
{
mPluginManager = NULL; // This deletes the plugin, since mPluginManager is a LLPointer.
mFilter.clear(); // Check that open is called before calling run (again).
}
// This function is called when a new message is received from the plugin.
// We get here when calling mPluginManager->update() in the first line of
// AIFilePicker::multiplex_impl.
//
// Note that we can't call finish() or abort() directly in this function,
// as that deletes mPluginManager and we're using the plugin manager
// right now (to receive this message)!
void AIFilePicker::receivePluginMessage(const LLPluginMessage &message)
{
std::string message_class = message.getClass();
if (message_class == LLPLUGIN_MESSAGE_CLASS_BASIC)
{
std::string message_name = message.getName();
if (message_name == "canceled")
{
set_state(AIFilePicker_canceled);
}
else if (message_name == "done")
{
LLSD filenames = message.getValueLLSD("filenames");
mFilenames.clear();
for(LLSD::array_iterator filename = filenames.beginArray(); filename != filenames.endArray(); ++filename)
{
mFilenames.push_back(*filename);
}
set_state(AIFilePicker_done);
}
else
{
LL_WARNS("Plugin") << "Unknown " << message_class << " class message: " << message_name << LL_ENDL;
}
}
}
std::string const& AIFilePicker::getFilename(void) const
{
// Only call this function after the AIFilePicker finished successfully without being canceled.
llassert_always(!mFilenames.empty());
// This function returns the first filename in the case that more than one was selected.
return mFilenames[0];
}
std::string AIFilePicker::getFolder(void) const
{
// Return the folder of the first filename.
return gDirUtilp->getDirName(getFilename());
}

View File

@@ -0,0 +1,160 @@
/**
* @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 "../llviewermedia.h"
#include <vector>
enum ELoadFilter
{
FFLOAD_ALL,
FFLOAD_WAV,
FFLOAD_IMAGE,
FFLOAD_ANIM,
FFLOAD_XML,
FFLOAD_SLOBJECT,
FFLOAD_RAW,
FFLOAD_TEXT
};
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_HPA,
FFSAVE_TEXT,
FFSAVE_LSL
};
// 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);
// 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; }
std::string const& getFilename(void) const;
std::string getFolder(void) const;
std::vector<std::string> const& getFilenames(void) const { return mFilenames; }
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.
// FIXME: this should be a separate, thread-safe singleton.
typedef std::map<std::string, std::string> 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).
// 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.
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.
std::string get_folder(std::string const& default_path, std::string const& context);
protected:
// 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) { }
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); }
private:
AIFilePicker* mStateMachine;
};
#endif

View File

@@ -220,13 +220,18 @@ class WindowsManifest(ViewerManifest):
# self.path("openjpeg.dll")
# self.end_prefix()
# Plugins - FilePicker
if self.prefix(src='../plugins/filepicker/%s' % self.args['configuration'], dst="llplugin"):
self.path("basic_plugin_filepicker.dll")
self.end_prefix()
# Media plugins - QuickTime
if self.prefix(src='../media_plugins/quicktime/%s' % self.args['configuration'], dst="llplugin"):
if self.prefix(src='../plugins/quicktime/%s' % self.args['configuration'], dst="llplugin"):
self.path("media_plugin_quicktime.dll")
self.end_prefix()
# Media plugins - WebKit/Qt
if self.prefix(src='../media_plugins/webkit/%s' % self.args['configuration'], dst="llplugin"):
if self.prefix(src='../plugins/webkit/%s' % self.args['configuration'], dst="llplugin"):
self.path("media_plugin_webkit.dll")
self.end_prefix()
@@ -533,8 +538,9 @@ class DarwinManifest(ViewerManifest):
# plugins
if self.prefix(src="", dst="llplugin"):
self.path("../media_plugins/quicktime/" + self.args['configuration'] + "/media_plugin_quicktime.dylib", "media_plugin_quicktime.dylib")
self.path("../media_plugins/webkit/" + self.args['configuration'] + "/media_plugin_webkit.dylib", "media_plugin_webkit.dylib")
self.path("../plugins/filepicker/" + self.args['configuration'] + "/basic_plugin_filepicker.dylib", "basic_plugin_filepicker.dylib")
self.path("../plugins/quicktime/" + self.args['configuration'] + "/media_plugin_quicktime.dylib", "media_plugin_quicktime.dylib")
self.path("../plugins/webkit/" + self.args['configuration'] + "/media_plugin_webkit.dylib", "media_plugin_webkit.dylib")
self.path("../../libraries/universal-darwin/lib_release/libllqtwebkit.dylib", "libllqtwebkit.dylib")
self.end_prefix("llplugin")
@@ -689,8 +695,9 @@ class LinuxManifest(ViewerManifest):
# plugins
if self.prefix(src="", dst="bin/llplugin"):
self.path("../media_plugins/webkit/libmedia_plugin_webkit.so", "libmedia_plugin_webkit.so")
self.path("../media_plugins/gstreamer010/libmedia_plugin_gstreamer010.so", "libmedia_plugin_gstreamer.so")
self.path("../plugins/filepicker/libbasic_plugin_filepicker.so", "libbasic_plugin_filepicker.so")
self.path("../plugins/webkit/libmedia_plugin_webkit.so", "libmedia_plugin_webkit.so")
self.path("../plugins/gstreamer010/libmedia_plugin_gstreamer010.so", "libmedia_plugin_gstreamer.so")
self.end_prefix("bin/llplugin")
# Per platform MIME config on the cheap. See SNOW-307 / DEV-41388

View File

@@ -0,0 +1,243 @@
/**
* @file plugin_filepicker.cpp
* @brief Plugin that runs a file picker.
*
* @cond
* $LicenseInfo:firstyear=2010&license=viewergpl$
*
* Copyright (c) 2010, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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$
*
* @endcond
*/
#include "linden_common.h"
#include "basic_plugin_base.h"
#include "llfilepicker.h"
class FilepickerPlugin : public BasicPluginBase
{
public:
FilepickerPlugin(LLPluginInstance::sendMessageFunction send_message_function, LLPluginInstance* plugin_instance);
~FilepickerPlugin();
/*virtual*/ void receiveMessage(char const* message_string);
private:
bool init();
};
FilepickerPlugin::FilepickerPlugin(LLPluginInstance::sendMessageFunction send_message_function, LLPluginInstance* plugin_instance) :
BasicPluginBase(send_message_function, plugin_instance)
{
}
FilepickerPlugin::~FilepickerPlugin()
{
}
static LLFilePicker::ESaveFilter str2savefilter(std::string const& filter)
{
// Complement of AIFilePicker::open(std::string const& filename, ESaveFilter filter, std::string const& folder)
if (filter == "wav")
return LLFilePicker::FFSAVE_WAV;
else if (filter == "tga")
return LLFilePicker::FFSAVE_TGA;
else if (filter == "bmp")
return LLFilePicker::FFSAVE_BMP;
else if (filter == "avi")
return LLFilePicker::FFSAVE_AVI;
else if (filter == "anim")
return LLFilePicker::FFSAVE_ANIM;
#ifdef _CORY_TESTING
else if (filter == "geometry")
return LLFilePicker::FFSAVE_GEOMETRY;
#endif
else if (filter == "xml")
return LLFilePicker::FFSAVE_XML;
else if (filter == "collada")
return LLFilePicker::FFSAVE_COLLADA;
else if (filter == "raw")
return LLFilePicker::FFSAVE_RAW;
else if (filter == "j2c")
return LLFilePicker::FFSAVE_J2C;
else if (filter == "png")
return LLFilePicker::FFSAVE_PNG;
else if (filter == "jpeg")
return LLFilePicker::FFSAVE_JPEG;
else if (filter == "hpa")
return LLFilePicker::FFSAVE_HPA;
else if (filter == "text")
return LLFilePicker::FFSAVE_TEXT;
else if (filter == "lsl")
return LLFilePicker::FFSAVE_LSL;
else
return LLFilePicker::FFSAVE_ALL;
}
static LLFilePicker::ELoadFilter str2loadfilter(std::string const& filter)
{
// Complement of AIFilePicker::open(ELoadFilter filter, std::string const& folder)
if (filter == "wav")
return LLFilePicker::FFLOAD_WAV;
else if (filter == "image")
return LLFilePicker::FFLOAD_IMAGE;
else if (filter == "anim")
return LLFilePicker::FFLOAD_ANIM;
#ifdef _CORY_TESTING
else if (filter == "geometry")
return LLFilePicker::FFLOAD_GEOMETRY;
#endif
else if (filter == "xml")
return LLFilePicker::FFLOAD_XML;
else if (filter == "slobject")
return LLFilePicker::FFLOAD_SLOBJECT;
else if (filter == "raw")
return LLFilePicker::FFLOAD_RAW;
else if (filter == "text")
return LLFilePicker::FFLOAD_TEXT;
else
return LLFilePicker::FFLOAD_ALL;
}
// This is the SLPlugin process.
// This is part of the loaded DSO.
//
// This function is called from LLPluginInstance::sendMessage
// for messages received from the viewer (that are not 'internal').
void FilepickerPlugin::receiveMessage(char const* message_string)
{
LLPluginMessage message_in;
if (message_in.parse(message_string) >= 0)
{
std::string message_class = message_in.getClass();
std::string message_name = message_in.getName();
if (message_class == LLPLUGIN_MESSAGE_CLASS_BASE)
{
if (message_name == "init")
{
LLPluginMessage message("base", "init_response");
LLSD versions = LLSD::emptyMap();
versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION;
versions[LLPLUGIN_MESSAGE_CLASS_BASIC] = LLPLUGIN_MESSAGE_CLASS_BASIC_VERSION;
message.setValueLLSD("versions", versions);
std::string plugin_version = "Filepicker Plugin, version 1.0.0.0";
message.setValue("plugin_version", plugin_version);
sendMessage(message);
}
else if (message_name == "idle")
{
// This whole message should not have existed imho -- Aleric
}
else
{
std::cerr << "FilepickerPlugin::receiveMessage: unknown base message: " << message_name << std::endl;
}
}
else if (message_class == LLPLUGIN_MESSAGE_CLASS_BASIC)
{
// This message should be sent at most once per SLPlugin invokation.
if (message_name == "initialization")
{
LLSD dictionary = message_in.getValueLLSD("dictionary");
for (LLSD::map_iterator iter = dictionary.beginMap(); iter != dictionary.endMap(); ++iter)
{
translation::add(iter->first, iter->second.asString());
}
if (message_in.hasValue("window_id"))
{
unsigned long window_id = strtoul(message_in.getValue("window_id").c_str(), NULL, 16);
LLFilePicker::instance().setWindowID(window_id);
}
}
// This message may theoretically be repeated (though currently the plugin is terminated after returning).
else if (message_name == "open")
{
std::string type = message_in.getValue("type");
std::string filter = message_in.getValue("filter");
std::string folder = message_in.getValue("folder");
bool canceled;
if (type == "save")
{
canceled = !LLFilePicker::instance().getSaveFile(str2savefilter(filter), message_in.getValue("default"), folder);
}
else if (type == "load")
{
canceled = !LLFilePicker::instance().getLoadFile(str2loadfilter(filter), folder);
}
else // type == "load_multiple"
{
canceled = !LLFilePicker::instance().getMultipleLoadFiles(str2loadfilter(filter), folder);
}
if (canceled)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_BASIC, "canceled");
message.setValue("perseus", "unblock");
sendMessage(message);
}
else
{
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())
{
filenames.append(filename);
}
message.setValueLLSD("filenames", filenames);
sendMessage(message);
}
}
else
{
std::cerr << "FilepickerPlugin::receiveMessage: unknown basic message: " << message_name << std::endl;
}
}
else
{
std::cerr << "FilepickerPlugin::receiveMessage: unknown message class: " << message_class << std::endl;
}
}
}
bool FilepickerPlugin::init(void)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_BASIC, "name_text");
message.setValue("name", "Filepicker Plugin");
sendMessage(message);
return true;
}
int create_plugin(LLPluginInstance::sendMessageFunction send_message_function, LLPluginInstance* plugin_instance, BasicPluginBase** plugin_object)
{
*plugin_object = new FilepickerPlugin(send_message_function, plugin_instance);
return 0;
}