diff options
author | Josh Bell <josh@lindenlab.com> | 2008-02-14 01:45:59 +0000 |
---|---|---|
committer | Josh Bell <josh@lindenlab.com> | 2008-02-14 01:45:59 +0000 |
commit | 98fd90ddd6595f2ee7e626c14117f51def621ec5 (patch) | |
tree | 9a9caf8bffa53b753fe850f445bd133195e9bb03 /indra/newview | |
parent | 89d938efe371645756240da72f4c359c36985060 (diff) |
svn merge -r 79730:79944 svn+ssh://svn.lindenlab.com/svn/linden/branches/parcel_media/sl-parcelmedia-6 --> release
QAR-275 Parcel Media
Sam made me do it.
Diffstat (limited to 'indra/newview')
62 files changed, 3169 insertions, 1079 deletions
diff --git a/indra/newview/app_settings/keywords.ini b/indra/newview/app_settings/keywords.ini index 5a68c5b163..0800647068 100644 --- a/indra/newview/app_settings/keywords.ini +++ b/indra/newview/app_settings/keywords.ini @@ -422,7 +422,10 @@ PARCEL_MEDIA_COMMAND_PLAY Play media stream PARCEL_MEDIA_COMMAND_LOOP Loop media stream PARCEL_MEDIA_COMMAND_TEXTURE Get or set the parcel's media texture PARCEL_MEDIA_COMMAND_URL Get or set the parcel's media url +PARCEL_MEDIA_COMMAND_TYPE Get or set the parcel's media mimetype +PARCEL_MEDIA_COMMAND_DESC Get or set the parcel's media description PARCEL_MEDIA_COMMAND_TIME Set media stream to specific time +PARCEL_MEDIA_COMMAND_SIZE Get or set the parcel's media pixel resolution PARCEL_MEDIA_COMMAND_AGENT Allows media stream commands to apply to only one agent PARCEL_MEDIA_COMMAND_UNLOAD Unloads the media stream PARCEL_MEDIA_COMMAND_AUTO_ALIGN Auto aligns the media stream to the texture size. May cause a performance hit and loss of some visual quality. @@ -492,6 +495,15 @@ STRING_TRIM_HEAD Used with llStringTrim to trim leading spaces from a string. STRING_TRIM_TAIL Used with llStringTrim to trim trailing spaces from a string. STRING_TRIM Used with llStringTrim to trim both leading and trailing spaces from a string. +CLICK_ACTION_NONE Used with llSetClickAction to disable the click action +CLICK_ACTION_TOUCH Used with llSetClickAction to set touch as the default action when object is clicked +CLICK_ACTION_SIT Used with llSetClickAction to set sit as the default action when object is clicked +CLICK_ACTION_BUY Used with llSetClickAction to set buy as the default action when object is clicked +CLICK_ACTION_PAY Used with llSetClickAction to set pay as the default action when object is clicked +CLICK_ACTION_OPEN Used with llSetClickAction to set open as the default action when object is clicked +CLICK_ACTION_PLAY Used with llSetClickAction to set play as the default action when object is clicked +CLICK_ACTION_OPEN_MEDIA Used with llSetClickAction to set open-media as the default action when object is clicked + # string constants [word .1, .3, .5] NULL_KEY Indicates an empty key diff --git a/indra/newview/cursors_mac/UI_CURSOR_TOOLMEDIAOPEN.tif b/indra/newview/cursors_mac/UI_CURSOR_TOOLMEDIAOPEN.tif Binary files differnew file mode 100644 index 0000000000..7c0bcfcbc5 --- /dev/null +++ b/indra/newview/cursors_mac/UI_CURSOR_TOOLMEDIAOPEN.tif diff --git a/indra/newview/cursors_mac/UI_CURSOR_TOOLPAUSE.tif b/indra/newview/cursors_mac/UI_CURSOR_TOOLPAUSE.tif Binary files differnew file mode 100644 index 0000000000..3431887aff --- /dev/null +++ b/indra/newview/cursors_mac/UI_CURSOR_TOOLPAUSE.tif diff --git a/indra/newview/cursors_mac/UI_CURSOR_TOOLPLAY.tif b/indra/newview/cursors_mac/UI_CURSOR_TOOLPLAY.tif Binary files differnew file mode 100644 index 0000000000..796bbb78e3 --- /dev/null +++ b/indra/newview/cursors_mac/UI_CURSOR_TOOLPLAY.tif diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index fe9b90ae60..075a7089de 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -47,6 +47,7 @@ #include "llpumpio.h" #include "llfloateractivespeakers.h" #include "llimpanel.h" +#include "llmimetypes.h" #include "llstartup.h" #include "llfocusmgr.h" #include "llviewerjoystick.h" @@ -59,6 +60,7 @@ #include "llworldmap.h" #include "llmutelist.h" #include "llurldispatcher.h" +#include "llurlhistory.h" #include "llweb.h" #include "llsecondlifeurls.h" @@ -76,7 +78,6 @@ #include "llnotify.h" -#include "llmediaengine.h" #include "llviewerkeyboard.h" #include "lllfsthread.h" #include "llworkerthread.h" @@ -97,7 +98,6 @@ #include "llviewermenu.h" #include "llselectmgr.h" #include "lltracker.h" -#include "llmozlib.h" #include "llviewerparcelmgr.h" #include "llworldmapview.h" @@ -169,21 +169,6 @@ static char** gTempArgV; #if LL_WINDOWS && LL_LCD_COMPILE #include "lllcd.h" #endif -// -#if LL_QUICKTIME_ENABLED - #if LL_DARWIN - #include <QuickTime/QuickTime.h> - #else - // quicktime specific includes - #include "MacTypes.h" - #include "QTML.h" - #include "Movies.h" - #include "FixMath.h" - #endif -#endif -// -////// - //---------------------------------------------------------------------------- // viewer.cpp - these are only used in viewer, should be easily moved. @@ -228,10 +213,6 @@ extern BOOL gbCapturing; extern BOOL gRandomizeFramerate; extern BOOL gPeriodicSlowFrame; -#if LL_GSTREAMER_ENABLED -void UnloadGStreamer(); -#endif - //////////////////////////////////////////////////////////// // All from the last globals push... bool gVerifySSLCert = true; @@ -257,6 +238,7 @@ BOOL gShowObjectUpdates = FALSE; BOOL gLogMessages = FALSE; std::string gChannelName = LL_CHANNEL; BOOL gUseAudio = TRUE; +BOOL gUseQuickTime = TRUE; LLString gCmdLineFirstName; LLString gCmdLineLastName; LLString gCmdLinePassword; @@ -1174,6 +1156,9 @@ bool LLAppViewer::init() LLAgent::parseTeleportMessages("teleport_strings.xml"); + // load MIME type -> media impl mappings + LLMIMETypes::parseMIMETypes( "mime_types.xml" ); + mCrashBehavior = gCrashSettings.getS32(CRASH_BEHAVIOR_SETTING); LLVectorPerformanceOptions::initClass(); @@ -1574,32 +1559,6 @@ bool LLAppViewer::cleanup() llwarns << "Hack, skipping audio engine cleanup" << llendflush; #endif - - // moved to main application shutdown for now because it's non-trivial and only needs to be done once - // (even though it goes against the media framework design) - - LLMediaEngine::cleanupClass(); - -#if LL_QUICKTIME_ENABLED - if (gQuickTimeInitialized) - { - // clean up media stuff - llinfos << "Cleaning up QuickTime" << llendl; - ExitMovies (); - #if LL_WINDOWS - // Only necessary/available on Windows. - TerminateQTML (); - #endif - } - llinfos << "Quicktime cleaned up" << llendflush; -#endif - -#if LL_GSTREAMER_ENABLED - llinfos << "Cleaning up GStreamer" << llendl; - UnloadGStreamer(); - llinfos << "GStreamer cleaned up" << llendflush; -#endif - llinfos << "Cleaning up feature manager" << llendflush; delete gFeatureManagerp; gFeatureManagerp = NULL; @@ -1661,18 +1620,12 @@ bool LLAppViewer::cleanup() LLTracker::cleanupInstance(); -#if LL_LIBXUL_ENABLED - // this must be done after floater cleanup (delete gViewerWindow) since - // floaters potentially need the manager to destroy their contents. - LLMozLib::getInstance()->reset(); -#endif - // *FIX: This is handled in LLAppViewerWin32::cleanup(). // I'm keeping the comment to remember its order in cleanup, // in case of unforseen dependency. -//#if LL_WINDOWS -// gDXHardware.cleanup(); -//#endif // LL_WINDOWS + //#if LL_WINDOWS + // gDXHardware.cleanup(); + //#endif // LL_WINDOWS #if LL_WINDOWS && LL_LCD_COMPILE // shut down the LCD window on a logitech keyboard, if there is one @@ -1729,6 +1682,9 @@ bool LLAppViewer::cleanup() gColors.cleanup(); gCrashSettings.cleanup(); + // Save URL history file + LLURLHistory::saveFile("url_history.xml"); + if (gMuteListp) { // save mute list @@ -2368,8 +2324,6 @@ bool LLAppViewer::initWindow() LLAlertDialog::parseAlerts("alerts.xml"); LLNotifyBox::parseNotify("notify.xml"); - LLMediaEngine::initClass(); - // // Clean up the feature manager lookup table - settings were updated // in the LLViewerWindow constructor diff --git a/indra/newview/llfirstuse.cpp b/indra/newview/llfirstuse.cpp index 2772a13416..97ebc02ba1 100644 --- a/indra/newview/llfirstuse.cpp +++ b/indra/newview/llfirstuse.cpp @@ -264,3 +264,14 @@ void LLFirstUse::useVoice() LLFloaterVoiceWizard::showInstance(); } } + +// static +void LLFirstUse::useMedia() +{ + if (gSavedSettings.getWarning("FirstMedia")) + { + gSavedSettings.setWarning("FirstMedia", FALSE); + + LLNotifyBox::showXml("FirstMedia"); + } +} diff --git a/indra/newview/llfirstuse.h b/indra/newview/llfirstuse.h index b5cf148285..5510ce02b9 100644 --- a/indra/newview/llfirstuse.h +++ b/indra/newview/llfirstuse.h @@ -105,7 +105,8 @@ public: static void useDebugMenus(); static void useSculptedPrim(); static void useVoice(); - + static void useMedia(); + protected: static std::set<LLString> sConfigVariables; }; diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index 01e529078f..7da2ac79b1 100644 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -48,12 +48,9 @@ #include "llviewerbuild.h" #include "llvieweruictrlfactory.h" #include "llappviewer.h" - -#if LL_LIBXUL_ENABLED -#include "llmozlib.h" -#endif // LL_LIBXUL_ENABLED - #include "llglheaders.h" +#include "llmediamanager.h" + extern LLCPUInfo gSysCPU; extern LLMemoryInfo gSysMemory; @@ -147,11 +144,18 @@ LLFloaterAbout::LLFloaterAbout() support.append( (const char*) glGetString(GL_VERSION) ); support.append("\n"); -#if LL_LIBXUL_ENABLED - support.append("LLMozLib Version: "); - support.append( (const char*) LLMozLib::getInstance()->getVersion().c_str() ); - support.append("\n"); -#endif // LL_LIBXUL_ENABLED + LLMediaManager *mgr = LLMediaManager::getInstance(); + if (mgr) + { + LLMediaBase *media_source = mgr->createSourceFromMimeType("http", "text/html"); + if (media_source) + { + support.append("LLMozLib Version: "); + support.append((const char*) media_source->getVersion().c_str()); + support.append("\n"); + mgr->destroySource(media_source); + } + } if (gViewerStats && gPacketsIn > 0) diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 6dd55c169b..f340ff2569 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -31,8 +31,6 @@ #include "llviewerprecompiledheaders.h" -#include <sstream> - #include "llfloaterland.h" #include "llcachename.h" @@ -53,6 +51,7 @@ #include "lllineeditor.h" #include "llnamelistctrl.h" #include "llnotify.h" +#include "llpanellandmedia.h" #include "llradiogroup.h" #include "llscrolllistctrl.h" #include "llselectmgr.h" @@ -68,10 +67,39 @@ #include "llviewerstats.h" #include "llviewertexteditor.h" #include "llviewerwindow.h" -#include "llmediaengine.h" #include "llviewercontrol.h" #include "roles_constants.h" +#include <sstream> +#include <time.h> + +static const S32 EDIT_HEIGHT = 16; +static const S32 LEFT = HPAD; +static const S32 BOTTOM = VPAD; +static const S32 RULER0 = LEFT; +static const S32 RULER05 = RULER0 + 24; +static const S32 RULER1 = RULER05 + 16; +static const S32 RULER15 = RULER1 + 20; +static const S32 RULER2 = RULER1 + 32; +static const S32 RULER205= RULER2 + 32; +static const S32 RULER20 = RULER2 + 64; +static const S32 RULER21 = RULER20 + 16; +static const S32 RULER22 = RULER21 + 32; +static const S32 RULER225 = RULER20 + 64; +static const S32 RULER23 = RULER22 + 64; +static const S32 RULER24 = RULER23 + 26; +static const S32 RULER3 = RULER2 + 102; +static const S32 RULER4 = RULER3 + 8; +static const S32 RULER5 = RULER4 + 50; +static const S32 RULER6 = RULER5 + 52; +static const S32 RULER7 = RULER6 + 24; +static const S32 RIGHT = LEFT + 278; +static const S32 FAR_RIGHT = LEFT + 324 + 40; + +static const char PRICE[] = "Price:"; +static const char NO_PRICE[] = ""; +static const char AREA[] = "Area:"; + static const char OWNER_ONLINE[] = "0"; static const char OWNER_OFFLINE[] = "1"; static const char OWNER_GROUP[] = "2"; @@ -80,16 +108,7 @@ static const char OWNER_GROUP[] = "2"; static const BOOL BUY_GROUP_LAND = TRUE; static const BOOL BUY_PERSONAL_LAND = FALSE; -// Values for the parcel voice settings radio group -enum -{ - kRadioVoiceChatEstate = 0, - kRadioVoiceChatPrivate = 1, - kRadioVoiceChatDisable = 2 -}; - // Statics -LLFloaterLand* LLFloaterLand::sInstance = NULL; LLParcelSelectionObserver* LLFloaterLand::sObserver = NULL; S32 LLFloaterLand::sLastTab = 0; @@ -150,64 +169,42 @@ void send_parcel_select_objects(S32 parcel_local_id, S32 return_type, } -// static -void LLFloaterLand::show() -{ - if (!sInstance) - { - sInstance = new LLFloaterLand(); - - // Select tab from last view - sInstance->mTabLand->selectTab(sLastTab); - - sObserver = new LLParcelSelectionObserver(); - gParcelMgr->addObserver( sObserver ); - } - - sInstance->open(); /*Flawfinder: ignore*/ - - // Done automatically when the selected parcel's properties arrive - // (and hence we have the local id). - // gParcelMgr->sendParcelAccessListRequest(AL_ACCESS | AL_BAN | AL_RENTER); - - sInstance->mParcel = gParcelMgr->getFloatingParcelSelection(); - - // Refresh even if not over a region so we don't get an - // uninitialized dialog. The dialog is 0-region aware. - sInstance->refresh(); -} - //static LLPanelLandObjects* LLFloaterLand::getCurrentPanelLandObjects() { - if (!sInstance) - { - return NULL; - } - - return sInstance->mPanelObjects; + return LLFloaterLand::getInstance()->mPanelObjects; } //static LLPanelLandCovenant* LLFloaterLand::getCurrentPanelLandCovenant() { - if (!sInstance) - { - return NULL; - } - - return sInstance->mPanelCovenant; + return LLFloaterLand::getInstance()->mPanelCovenant; } // static void LLFloaterLand::refreshAll() { - if (sInstance) - { - sInstance->refresh(); - } + LLFloaterLand::getInstance()->refresh(); +} + +void LLFloaterLand::onOpen() +{ + // Select tab from last view + mTabLand->selectTab(sLastTab); + + + // Done automatically when the selected parcel's properties arrive + // (and hence we have the local id). + // gParcelMgr->sendParcelAccessListRequest(AL_ACCESS | AL_BAN | AL_RENTER); + + mParcel = gParcelMgr->getFloatingParcelSelection(); + + // Refresh even if not over a region so we don't get an + // uninitialized dialog. The dialog is 0-region aware. + refresh(); } + // virtual void LLFloaterLand::onClose(bool app_quitting) { @@ -225,7 +222,7 @@ void LLFloaterLand::onClose(bool app_quitting) } -LLFloaterLand::LLFloaterLand() +LLFloaterLand::LLFloaterLand(const LLSD& seed) : LLFloater("floaterland", "FloaterLandRect5", "About Land") { @@ -242,7 +239,12 @@ LLFloaterLand::LLFloaterLand() gUICtrlFactory->buildFloater(this, "floater_about_land.xml", &factory_map); + sObserver = new LLParcelSelectionObserver(); + gParcelMgr->addObserver( sObserver ); +} +BOOL LLFloaterLand::postBuild() +{ LLTabContainerCommon* tab = LLUICtrlFactory::getTabContainerByName(this, "landtab"); mTabLand = (LLTabContainer*) tab; @@ -252,16 +254,16 @@ LLFloaterLand::LLFloaterLand() { tab->selectTab(sLastTab); } + + return TRUE; } // virtual LLFloaterLand::~LLFloaterLand() { - sInstance = NULL; } - // public void LLFloaterLand::refresh() { @@ -2214,239 +2216,7 @@ void LLPanelLandOptions::onClickPublishHelp(void*) } } -//--------------------------------------------------------------------------- -// LLPanelLandMedia -//--------------------------------------------------------------------------- - -LLPanelLandMedia::LLPanelLandMedia(LLParcelSelectionHandle& parcel) -: LLPanel("land_media_panel"), mParcel(parcel) -{ -} - - - -BOOL LLPanelLandMedia::postBuild() -{ - - mCheckSoundLocal = LLUICtrlFactory::getCheckBoxByName(this, "check sound local"); - childSetCommitCallback("check sound local", onCommitAny, this); - - mRadioVoiceChat = LLUICtrlFactory::getRadioGroupByName(this, "parcel_voice_channel"); - childSetCommitCallback("parcel_voice_channel", onCommitAny, this); - - mMusicURLEdit = LLUICtrlFactory::getLineEditorByName(this, "music_url"); - childSetCommitCallback("music_url", onCommitAny, this); - - - mMediaTextureCtrl = LLUICtrlFactory::getTexturePickerByName(this, "media texture"); - if (mMediaTextureCtrl) - { - mMediaTextureCtrl->setCommitCallback( onCommitAny ); - mMediaTextureCtrl->setCallbackUserData( this ); - mMediaTextureCtrl->setAllowNoTexture ( TRUE ); - mMediaTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); - mMediaTextureCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); - } - else - { - llwarns << "LLUICtrlFactory::getTexturePickerByName() returned NULL for 'media texure'" << llendl; - } - - mMediaAutoScaleCheck = LLUICtrlFactory::getCheckBoxByName(this, "media_auto_scale"); - childSetCommitCallback("media_auto_scale", onCommitAny, this); - - mMediaURLEdit = LLUICtrlFactory::getLineEditorByName(this, "media_url"); - childSetCommitCallback("media_url", onCommitAny, this); - - return TRUE; -} - - -// virtual -LLPanelLandMedia::~LLPanelLandMedia() -{ } - - -// public -void LLPanelLandMedia::refresh() -{ - LLParcel *parcel = mParcel->getParcel(); - - if (!parcel) - { - mCheckSoundLocal->set(FALSE); - mCheckSoundLocal->setEnabled(FALSE); - - mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatEstate); - mRadioVoiceChat->setEnabled(FALSE); - - mMusicURLEdit->setText(LLString::null); - mMusicURLEdit->setEnabled(FALSE); - - mMediaURLEdit->setText(LLString::null); - mMediaURLEdit->setEnabled(FALSE); - - mMediaAutoScaleCheck->set ( FALSE ); - mMediaAutoScaleCheck->setEnabled(FALSE); - - mMediaTextureCtrl->clear(); - mMediaTextureCtrl->setEnabled(FALSE); - - #if 0 - mMediaStopButton->setEnabled ( FALSE ); - mMediaStartButton->setEnabled ( FALSE ); - #endif - } - else - { - // something selected, hooray! - - // Display options - BOOL can_change_media = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_CHANGE_MEDIA); - - mCheckSoundLocal->set( parcel->getSoundLocal() ); - mCheckSoundLocal->setEnabled( can_change_media ); - - LLViewerRegion* selection_region = gParcelMgr->getSelectionRegion(); - BOOL region_allows_voice = FALSE; - if (selection_region) - { - region_allows_voice = selection_region->isVoiceEnabled(); - } - - if(parcel->getVoiceEnabled()) - { - if(parcel->getVoiceUseEstateChannel()) - mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatEstate); - else - mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatPrivate); - } - else - { - mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatDisable); - } - - mRadioVoiceChat->setEnabled( can_change_media && region_allows_voice ); - - // don't display urls if you're not able to change it - // much requested change in forums so people can't 'steal' urls - // NOTE: bug#2009 means this is still vunerable - however, bug - // should be closed since this bug opens up major security issues elsewhere. - if ( can_change_media ) - { - mMusicURLEdit->setDrawAsterixes ( FALSE ); - mMediaURLEdit->setDrawAsterixes ( FALSE ); - } - else - { - mMusicURLEdit->setDrawAsterixes ( TRUE ); - mMediaURLEdit->setDrawAsterixes ( TRUE ); - } - - mMusicURLEdit->setText(parcel->getMusicURL()); - mMusicURLEdit->setEnabled( can_change_media ); - - mMediaURLEdit->setText(parcel->getMediaURL()); - mMediaURLEdit->setEnabled( can_change_media ); - - mMediaAutoScaleCheck->set ( parcel->getMediaAutoScale () ); - mMediaAutoScaleCheck->setEnabled ( can_change_media ); - - LLUUID tmp = parcel->getMediaID(); - mMediaTextureCtrl->setImageAssetID ( parcel->getMediaID() ); - mMediaTextureCtrl->setEnabled( can_change_media ); - - #if 0 - // there is a media url and a media texture selected - if ( ( ! ( std::string ( parcel->getMediaURL() ).empty () ) ) && ( ! ( parcel->getMediaID ().isNull () ) ) ) - { - // turn on transport controls if allowed for this parcel - mMediaStopButton->setEnabled ( editable ); - mMediaStartButton->setEnabled ( editable ); - } - else - { - // no media url or no media texture - mMediaStopButton->setEnabled ( FALSE ); - mMediaStartButton->setEnabled ( FALSE ); - }; - #endif - } -} - -// static -void LLPanelLandMedia::onCommitAny(LLUICtrl *ctrl, void *userdata) -{ - LLPanelLandMedia *self = (LLPanelLandMedia *)userdata; - - LLParcel* parcel = self->mParcel->getParcel(); - if (!parcel) - { - return; - } - - // Extract data from UI - BOOL sound_local = self->mCheckSoundLocal->get(); - int voice_setting = self->mRadioVoiceChat->getSelectedIndex(); - std::string music_url = self->mMusicURLEdit->getText(); - std::string media_url = self->mMediaURLEdit->getText(); - U8 media_auto_scale = self->mMediaAutoScaleCheck->get(); - LLUUID media_id = self->mMediaTextureCtrl->getImageAssetID(); - - BOOL voice_enabled; - BOOL voice_estate_chan; - - switch(voice_setting) - { - default: - case kRadioVoiceChatEstate: - voice_enabled = TRUE; - voice_estate_chan = TRUE; - break; - case kRadioVoiceChatPrivate: - voice_enabled = TRUE; - voice_estate_chan = FALSE; - break; - case kRadioVoiceChatDisable: - voice_enabled = FALSE; - voice_estate_chan = FALSE; - break; - } - - // Remove leading/trailing whitespace (common when copying/pasting) - LLString::trim(music_url); - LLString::trim(media_url); - - // Push data into current parcel - parcel->setParcelFlag(PF_ALLOW_VOICE_CHAT, voice_enabled); - parcel->setParcelFlag(PF_USE_ESTATE_VOICE_CHAN, voice_estate_chan); - parcel->setParcelFlag(PF_SOUND_LOCAL, sound_local); - parcel->setMusicURL(music_url.c_str()); - parcel->setMediaURL(media_url.c_str()); - parcel->setMediaID(media_id); - parcel->setMediaAutoScale ( media_auto_scale ); - - // Send current parcel data upstream to server - gParcelMgr->sendParcelPropertiesUpdate( parcel ); - - // Might have changed properties, so let's redraw! - self->refresh(); -} - -void LLPanelLandMedia::onClickStopMedia ( void* data ) -{ - LLMediaEngine::getInstance ()->stop (); -} - -void LLPanelLandMedia::onClickStartMedia ( void* data ) -{ - // force a commit - gFocusMgr.setKeyboardFocus ( NULL ); - - // force a reload - LLMediaEngine::getInstance ()->convertImageAndLoadUrl ( true, false, std::string()); -} //--------------------------------------------------------------------------- // LLPanelLandAccess diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h index 8b77bb990a..e504e27f21 100644 --- a/indra/newview/llfloaterland.h +++ b/indra/newview/llfloaterland.h @@ -68,13 +68,9 @@ class LLPanelLandRenters; class LLPanelLandCovenant; class LLFloaterLand -: public LLFloater +: public LLFloater, public LLUISingleton<LLFloaterLand> { public: - // Call show() to open a land floater. - // Will query the viewer parcel manager to see what is selected. - static void show(); - static BOOL floaterVisible() { return sInstance && sInstance->getVisible(); } static void refreshAll(); static LLPanelLandObjects* getCurrentPanelLandObjects(); @@ -82,11 +78,15 @@ public: // Destroys itself on close. virtual void onClose(bool app_quitting); + virtual void onOpen(); + virtual BOOL postBuild(); protected: + friend class LLUISingleton<LLFloaterLand>; + // Does its own instance management, so clients not allowed // to allocate or destroy. - LLFloaterLand(); + LLFloaterLand(const LLSD& seed); virtual ~LLFloaterLand(); void refresh(); @@ -102,7 +102,6 @@ protected: protected: - static LLFloaterLand* sInstance; static LLParcelSelectionObserver* sObserver; static S32 sLastTab; @@ -344,35 +343,6 @@ protected: }; -class LLPanelLandMedia -: public LLPanel -{ -public: - LLPanelLandMedia(LLHandle<LLParcelSelection>& parcelp); - virtual ~LLPanelLandMedia(); - void refresh(); - - static void onCommitAny(LLUICtrl* ctrl, void *userdata); - static void onClickStopMedia ( void* data ); - static void onClickStartMedia ( void* data ); - - virtual BOOL postBuild(); - -protected: - LLCheckBoxCtrl* mCheckSoundLocal; - LLRadioGroup* mRadioVoiceChat; - LLLineEditor* mMusicURLEdit; - LLLineEditor* mMediaURLEdit; - LLTextureCtrl* mMediaTextureCtrl; - LLCheckBoxCtrl* mMediaAutoScaleCheck; - //LLButton* mMediaStopButton; - //LLButton* mMediaStartButton; - - LLHandle<LLParcelSelection>& mParcel; -}; - - - class LLPanelLandAccess : public LLPanel { diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 8d77d79d83..060952667b 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -150,11 +150,9 @@ LLPreferenceCore::LLPreferenceCore(LLTabContainerCommon* tab_container, LLButton mTabContainer->addTabPanel(mNetworkPanel, mNetworkPanel->getLabel(), FALSE, onTabChanged, mTabContainer); mNetworkPanel->setDefaultBtn(default_btn); - #if LL_LIBXUL_ENABLED mWebPanel = new LLPanelWeb(); mTabContainer->addTabPanel(mWebPanel, mWebPanel->getLabel(), FALSE, onTabChanged, mTabContainer); mWebPanel->setDefaultBtn(default_btn); - #endif mDisplayPanel = new LLPanelDisplay(); mTabContainer->addTabPanel(mDisplayPanel, mDisplayPanel->getLabel(), FALSE, onTabChanged, mTabContainer); @@ -257,13 +255,11 @@ LLPreferenceCore::~LLPreferenceCore() delete mMsgPanel; mMsgPanel = NULL; } - #if LL_LIBXUL_ENABLED if (mWebPanel) { delete mWebPanel; mWebPanel = NULL; } - #endif } @@ -279,9 +275,7 @@ void LLPreferenceCore::apply() mPrefsVoice->apply(); mPrefsIM->apply(); mMsgPanel->apply(); - #if LL_LIBXUL_ENABLED mWebPanel->apply(); - #endif #if LL_WINDOWS && LL_LCD_COMPILE // only add this option if we actually have a logitech keyboard / speaker set if (gLcdScreen->Enabled()) @@ -306,9 +300,7 @@ void LLPreferenceCore::cancel() mPrefsVoice->cancel(); mPrefsIM->cancel(); mMsgPanel->cancel(); - #if LL_LIBXUL_ENABLED mWebPanel->cancel(); - #endif #if LL_WINDOWS && LL_LCD_COMPILE // only add this option if we actually have a logitech keyboard / speaker set if (gLcdScreen->Enabled()) diff --git a/indra/newview/llfloatertos.cpp b/indra/newview/llfloatertos.cpp index 20f9e1ecd4..bdf583126f 100644 --- a/indra/newview/llfloatertos.cpp +++ b/indra/newview/llfloatertos.cpp @@ -145,7 +145,6 @@ BOOL LLFloaterTOS::postBuild() return TRUE; } -#if LL_LIBXUL_ENABLED // disable Agree to TOS radio button until the page has fully loaded LLRadioGroup* tos_agreement = LLUICtrlFactory::getRadioGroupByName(this, "tos_agreement"); if ( tos_agreement ) @@ -172,18 +171,6 @@ BOOL LLFloaterTOS::postBuild() gResponsePtr = LLIamHere::build( this ); LLHTTPClient::get( childGetValue( "real_url" ).asString(), gResponsePtr ); }; -#else - LLTextEditor *Editor = LLUICtrlFactory::getTextEditorByName(this, "tos_text"); - if (Editor) - { - Editor->setHandleEditKeysDirectly( TRUE ); - Editor->setEnabled( FALSE ); - Editor->setReadOnlyFgColor(LLColor4::white); - Editor->setWordWrap(TRUE); - Editor->setFocus(TRUE); - } - childSetValue("tos_text", LLSD(mMessage)); -#endif return TRUE; } @@ -193,7 +180,6 @@ void LLFloaterTOS::setSiteIsAlive( bool alive ) // only do this for TOS pages if ( mType == TOS_TOS ) { -#if LL_LIBXUL_ENABLED LLWebBrowserCtrl* web_browser = LLUICtrlFactory::getWebBrowserCtrlByName(this, "tos_html"); // if the contents of the site was retrieved if ( alive ) @@ -220,20 +206,17 @@ void LLFloaterTOS::setSiteIsAlive( bool alive ) web_browser->setVisible( FALSE ); }; }; -#endif // LL_LIBXUL_ENABLED }; } LLFloaterTOS::~LLFloaterTOS() { -#if LL_LIBXUL_ENABLED // stop obsaerving events LLWebBrowserCtrl* web_browser = LLUICtrlFactory::getWebBrowserCtrlByName(this, "tos_html"); if ( web_browser ) { web_browser->addObserver( this ); }; -#endif // LL_LIBXUL_ENABLED // tell the responder we're not here anymore if ( gResponsePtr ) diff --git a/indra/newview/llfloaterurlentry.cpp b/indra/newview/llfloaterurlentry.cpp new file mode 100644 index 0000000000..1ad9e0577c --- /dev/null +++ b/indra/newview/llfloaterurlentry.cpp @@ -0,0 +1,268 @@ +/** + * @file llfloaterurlentry.cpp + * @brief LLFloaterURLEntry class implementation + * + * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterurlentry.h" + +#include "llpanellandmedia.h" + +// project includes +#include "llcombobox.h" +#include "llurlhistory.h" +#include "llvieweruictrlfactory.h" +#include "llwindow.h" +#include "llviewerwindow.h" + +static LLFloaterURLEntry* sInstance = NULL; + +// Move this to its own file. +// 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 LLMediaTypeResponder : public LLHTTPClient::Responder +{ +public: + LLMediaTypeResponder( LLViewHandle parent ) : + mParent( parent ) + {} + + LLViewHandle mParent; + + + virtual void completedHeader(U32 status, const std::string& reason, const LLSD& content) + { + std::string media_type = content["content-type"].asString(); + std::string::size_type idx1 = media_type.find_first_of(";"); + std::string mime_type = media_type.substr(0, idx1); + completeAny(status, mime_type); + } + + virtual void error( U32 status, const std::string& reason ) + { + completeAny(status, "none/none"); + } + + void completeAny(U32 status, const std::string& mime_type) + { + LLFloaterURLEntry* floater_url_entry = + (LLFloaterURLEntry*)LLFloater::getFloaterByHandle(mParent); + if ( floater_url_entry ) + floater_url_entry->headerFetchComplete( status, mime_type ); + } +}; + +//----------------------------------------------------------------------------- +// LLFloaterURLEntry() +//----------------------------------------------------------------------------- +LLFloaterURLEntry::LLFloaterURLEntry(LLViewHandle parent) + : + LLFloater(), + mPanelLandMediaHandle(parent) +{ + gUICtrlFactory->buildFloater(this, "floater_url_entry.xml"); + + mMediaURLEdit = LLUICtrlFactory::getComboBoxByName(this, "media_entry"); + + // Cancel button + childSetAction("cancel_btn", onBtnCancel, this); + + // Cancel button + childSetAction("clear_btn", onBtnClear, this); + + // clear media list button + LLSD parcel_history = LLURLHistory::getURLHistory("parcel"); + bool enable_clear_button = parcel_history.size() > 0 ? true : false; + childSetEnabled( "clear_btn", enable_clear_button ); + + // OK button + childSetAction("ok_btn", onBtnOK, this); + + setDefaultBtn("ok_btn"); + buildURLHistory(); + + sInstance = this; +} + +//----------------------------------------------------------------------------- +// ~LLFloaterURLEntry() +//----------------------------------------------------------------------------- +LLFloaterURLEntry::~LLFloaterURLEntry() +{ + sInstance = NULL; +} + +void LLFloaterURLEntry::buildURLHistory() +{ + LLCtrlListInterface* url_list = childGetListInterface("media_entry"); + if (url_list) + { + url_list->operateOnAll(LLCtrlListInterface::OP_DELETE); + } + + // Get all of the entries in the "parcel" collection + LLSD parcel_history = LLURLHistory::getURLHistory("parcel"); + + LLSD::array_iterator iter_history = + parcel_history.beginArray(); + LLSD::array_iterator end_history = + parcel_history.endArray(); + for(; iter_history != end_history; ++iter_history) + { + url_list->addSimpleElement((*iter_history).asString()); + } +} + +void LLFloaterURLEntry::headerFetchComplete(U32 status, const std::string& mime_type) +{ + LLPanelLandMedia* panel_media = (LLPanelLandMedia*)LLPanel::getPanelByHandle(mPanelLandMediaHandle); + if (panel_media) + { + // status is ignored for now -- error = "none/none" + panel_media->setMediaType(mime_type); + panel_media->setMediaURL(mMediaURLEdit->getValue().asString()); + } + // Decrement the cursor + getWindow()->decBusyCount(); + childSetVisible("loading_label", false); + close(); +} + +// static +LLViewHandle LLFloaterURLEntry::show(LLViewHandle parent) +{ + if (sInstance) + { + sInstance->open(); + } + else + { + sInstance = new LLFloaterURLEntry(parent); + } + sInstance->updateFromLandMediaPanel(); + return sInstance->getHandle(); +} + +void LLFloaterURLEntry::updateFromLandMediaPanel() +{ + LLPanelLandMedia* panel_media = (LLPanelLandMedia*)LLPanel::getPanelByHandle(mPanelLandMediaHandle); + if (panel_media) + { + std::string media_url = panel_media->getMediaURL(); + addURLToCombobox(media_url); + } +} + +bool LLFloaterURLEntry::addURLToCombobox(const std::string& media_url) +{ + if(! mMediaURLEdit->setSimple( media_url ) && ! media_url.empty()) + { + mMediaURLEdit->add( media_url ); + mMediaURLEdit->setSimple( media_url ); + return true; + } + + // URL was not added for whatever reason (either it was empty or already existed) + return false; +} + +// static +//----------------------------------------------------------------------------- +// onBtnOK() +//----------------------------------------------------------------------------- +void LLFloaterURLEntry::onBtnOK( void* userdata ) +{ + LLFloaterURLEntry *self =(LLFloaterURLEntry *)userdata; + + std::string media_url = self->mMediaURLEdit->getValue().asString(); + self->mMediaURLEdit->remove(media_url); + LLURLHistory::removeURL("parcel", media_url); + if(self->addURLToCombobox(media_url)) + { + // Add this url to the parcel collection + LLURLHistory::addURL("parcel", media_url); + } + + // leading whitespace causes problems with the MIME-type detection so strip it + LLString::trim( media_url ); + + // First check the URL scheme + LLURI url(media_url); + std::string scheme = url.scheme(); + + // We assume that an empty scheme is an http url, as this is how we will treat it. + if(scheme == "") + { + scheme = "http"; + } + + // Discover the MIME type only for "http" scheme. + if(scheme == "http") + { + LLHTTPClient::getHeaderOnly( media_url, + new LLMediaTypeResponder(self->getHandle())); + } + else + { + self->headerFetchComplete(0, scheme); + } + + // Grey the buttons until we get the header response + self->childSetEnabled("ok_btn", false); + self->childSetEnabled("cancel_btn", false); + self->childSetEnabled("media_entry", false); + + // show progress bar here? + getWindow()->incBusyCount(); + self->childSetVisible("loading_label", true); +} + +// static +//----------------------------------------------------------------------------- +// onBtnCancel() +//----------------------------------------------------------------------------- +void LLFloaterURLEntry::onBtnCancel( void* userdata ) +{ + LLFloaterURLEntry *self =(LLFloaterURLEntry *)userdata; + self->close(); +} + +// static +//----------------------------------------------------------------------------- +// onBtnClear() +//----------------------------------------------------------------------------- +void LLFloaterURLEntry::onBtnClear( void* userdata ) +{ + gViewerWindow->alertXml( "ConfirmClearMediaUrlList", callback_clear_url_list, userdata ); +} + +void LLFloaterURLEntry::callback_clear_url_list(S32 option, void* userdata) +{ + if ( option == 0 ) // YES + { + LLFloaterURLEntry *self =(LLFloaterURLEntry *)userdata; + + if ( self ) + { + // clear saved list + LLCtrlListInterface* url_list = self->childGetListInterface("media_entry"); + if ( url_list ) + { + url_list->operateOnAll( LLCtrlListInterface::OP_DELETE ); + } + + // clear current contents of combo box + self->mMediaURLEdit->clear(); + + // clear stored version of list + LLURLHistory::clear("parcel"); + + // cleared the list so disable Clear button + self->childSetEnabled( "clear_btn", false ); + } + } +} diff --git a/indra/newview/llfloaterurlentry.h b/indra/newview/llfloaterurlentry.h new file mode 100644 index 0000000000..022c1eddd7 --- /dev/null +++ b/indra/newview/llfloaterurlentry.h @@ -0,0 +1,44 @@ +/** + * @file llfloaternamedesc.h + * @brief LLFloaterNameDesc class definition + * + * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#ifndef LL_LLFLOATERURLENTRY_H +#define LL_LLFLOATERURLENTRY_H + +#include "llfloater.h" + +class LLLineEditor; + +class LLFloaterURLEntry : public LLFloater +{ +public: + // Can only be shown by LLPanelLandMedia, and pushes data back into + // that panel via the handle. + static LLViewHandle show(LLViewHandle panel_land_media_handle); + + void updateFromLandMediaPanel(); + + void headerFetchComplete(U32 status, const std::string& mime_type); + + bool addURLToCombobox(const std::string& media_url); + +private: + LLFloaterURLEntry(LLViewHandle parent); + /*virtual*/ ~LLFloaterURLEntry(); + void buildURLHistory(); + +private: + LLComboBox* mMediaURLEdit; + LLViewHandle mPanelLandMediaHandle; + + static void onBtnOK(void*); + static void onBtnCancel(void*); + static void onBtnClear(void*); + static void callback_clear_url_list(S32 option, void* userdata); +}; + +#endif // LL_LLFLOATERURLENTRY_H diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index ba56d70c0a..29b739bca3 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -851,11 +851,11 @@ void LLViewerParcelMgr::renderCollisionSegments(U8* segments, BOOL use_pass, LLV if (use_pass && (mCollisionBanned == BA_NOT_ON_LIST)) { - LLViewerImage::bindTexture(mPassImage); + LLViewerImage::bindTexture( getPassImage() ); } else { - LLViewerImage::bindTexture(mBlockedImage); + LLViewerImage::bindTexture( getBlockedImage() ); } glBegin(GL_QUADS); diff --git a/indra/newview/llmimetypes.cpp b/indra/newview/llmimetypes.cpp new file mode 100644 index 0000000000..3c4dab8e04 --- /dev/null +++ b/indra/newview/llmimetypes.cpp @@ -0,0 +1,241 @@ +/** + * @file llmimetypes.cpp + * @author James Cook + * @brief Translates a MIME type like "video/quicktime" into a + * localizable user-friendly string like "QuickTime Movie" + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +#include "llviewerprecompiledheaders.h" + +#include "llmimetypes.h" + +#include "llvieweruictrlfactory.h" + +LLMIMETypes::mime_info_map_t LLMIMETypes::sMap; +LLMIMETypes::mime_widget_set_map_t LLMIMETypes::sWidgetMap; + +LLString sDefaultLabel; + // Returned when we don't know what to do with the mime type +LLString sDefaultWidgetType; + // Returned when we don't know what widget set to use +LLString sDefaultImpl; + // Returned when we don't know what impl to use + +///////////////////////////////////////////////////////////////////////////// + +// static +bool LLMIMETypes::parseMIMETypes(const LLString& xml_filename) +{ + LLXMLNodePtr root; + bool success = LLViewerUICtrlFactory::getLayeredXMLNode(xml_filename, root); + if (!success || !root || !root->hasName("mimetypes")) + { + llwarns << "Unable to read MIME type file: " + << xml_filename << llendl; + return false; + } + + for (LLXMLNode* node = root->getFirstChild(); + node != NULL; + node = node->getNextSibling()) + { + if (node->hasName("defaultlabel")) + { + sDefaultLabel = node->getTextContents(); + } + else if (node->hasName("defaultwidget")) + { + sDefaultWidgetType = node->getTextContents(); + } + else if (node->hasName("defaultimpl")) + { + sDefaultImpl = node->getTextContents(); + } + else if (node->hasName("mimetype") || node->hasName("scheme")) + { + LLString mime_type; + node->getAttributeString("name", mime_type); + LLMIMEInfo info; + for (LLXMLNode* child = node->getFirstChild(); + child != NULL; + child = child->getNextSibling()) + { + if (child->hasName("label")) + { + info.mLabel = child->getTextContents(); + } + else if (child->hasName("widgettype")) + { + info.mWidgetType = child->getTextContents(); + } + else if (child->hasName("impl")) + { + info.mImpl = child->getTextContents(); + } + } + sMap[mime_type] = info; + } + else if (node->hasName("widgetset")) + { + LLString set_name; + node->getAttributeString("name", set_name); + LLMIMEWidgetSet info; + for (LLXMLNode* child = node->getFirstChild(); + child != NULL; + child = child->getNextSibling()) + { + if (child->hasName("label")) + { + info.mLabel = child->getTextContents(); + } + if (child->hasName("icon")) + { + info.mIcon = child->getTextContents(); + } + if (child->hasName("default_type")) + { + info.mDefaultMimeType = child->getTextContents(); + } + if (child->hasName("tooltip")) + { + info.mToolTip = child->getTextContents(); + } + if (child->hasName("playtip")) + { + info.mPlayTip = child->getTextContents(); + } + if (child->hasName("allow_resize")) + { + child->getBoolValue( 1, (BOOL*)&( info.mAllowResize ) ); + } + if (child->hasName("allow_looping")) + { + child->getBoolValue( 1, (BOOL*)&( info.mAllowLooping ) ); + } + } + sWidgetMap[set_name] = info; + } + } + return true; +} + +// static +LLString LLMIMETypes::translate(const LLString& mime_type) +{ + mime_info_map_t::const_iterator it = sMap.find(mime_type); + if (it != sMap.end()) + { + return it->second.mLabel; + } + else + { + return sDefaultLabel; + } +} + +// static +LLString LLMIMETypes::widgetType(const LLString& mime_type) +{ + mime_info_map_t::const_iterator it = sMap.find(mime_type); + if (it != sMap.end()) + { + return it->second.mWidgetType; + } + else + { + return sDefaultWidgetType; + } +} + +// static +LLString LLMIMETypes::implType(const LLString& mime_type) +{ + mime_info_map_t::const_iterator it = sMap.find(mime_type); + if (it != sMap.end()) + { + return it->second.mImpl; + } + else + { + return sDefaultImpl; + } +} + +// static +LLString LLMIMETypes::findIcon(const LLString& mime_type) +{ + LLString icon = ""; + LLString widget_type = LLMIMETypes::widgetType(mime_type); + mime_widget_set_map_t::iterator it = sWidgetMap.find(widget_type); + if(it != sWidgetMap.end()) + { + icon = it->second.mIcon; + } + return icon; +} + +// static +LLString LLMIMETypes::findDefaultMimeType(const LLString& widget_type) +{ + LLString mime_type = "none/none"; + mime_widget_set_map_t::iterator it = sWidgetMap.find(widget_type); + if(it != sWidgetMap.end()) + { + mime_type = it->second.mDefaultMimeType; + } + return mime_type; +} + +// static +LLString LLMIMETypes::findToolTip(const LLString& mime_type) +{ + LLString tool_tip = ""; + LLString widget_type = LLMIMETypes::widgetType(mime_type); + mime_widget_set_map_t::iterator it = sWidgetMap.find(widget_type); + if(it != sWidgetMap.end()) + { + tool_tip = it->second.mToolTip; + } + return tool_tip; +} + +// static +LLString LLMIMETypes::findPlayTip(const LLString& mime_type) +{ + LLString play_tip = ""; + LLString widget_type = LLMIMETypes::widgetType(mime_type); + mime_widget_set_map_t::iterator it = sWidgetMap.find(widget_type); + if(it != sWidgetMap.end()) + { + play_tip = it->second.mPlayTip; + } + return play_tip; +} + +// static +bool LLMIMETypes::findAllowResize(const LLString& mime_type) +{ + bool allow_resize = false; + LLString widget_type = LLMIMETypes::widgetType(mime_type); + mime_widget_set_map_t::iterator it = sWidgetMap.find(widget_type); + if(it != sWidgetMap.end()) + { + allow_resize = it->second.mAllowResize; + } + return allow_resize; +} + +// static +bool LLMIMETypes::findAllowLooping(const LLString& mime_type) +{ + bool allow_looping = false; + LLString widget_type = LLMIMETypes::widgetType(mime_type); + mime_widget_set_map_t::iterator it = sWidgetMap.find(widget_type); + if(it != sWidgetMap.end()) + { + allow_looping = it->second.mAllowLooping; + } + return allow_looping; +} diff --git a/indra/newview/llmimetypes.h b/indra/newview/llmimetypes.h new file mode 100644 index 0000000000..1c309477a2 --- /dev/null +++ b/indra/newview/llmimetypes.h @@ -0,0 +1,95 @@ +/** + * @file llmimetypes.h + * @author James Cook + * @brief Translates a MIME type like "video/quicktime" into a + * localizable user-friendly string like "QuickTime Movie" + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +#ifndef LLMIMETYPES_H +#define LLMIMETYPES_H + +#include "llstring.h" // because XML parsing lib uses LLString, ugh +#include <map> + +class LLMIMETypes +{ +public: + static bool parseMIMETypes(const LLString& xml_file_path); + // Loads the MIME string definition XML file, usually + // from the application skins directory + + static LLString translate(const LLString& mime_type); + // Returns "QuickTime Movie" from "video/quicktime" + + static LLString widgetType(const LLString& mime_type); + // Type of control widgets for this MIME type + // Returns "movie" from "video/quicktime" + + static LLString implType(const LLString& mime_type); + // Type of Impl to use for decoding media. + + static LLString findIcon(const LLString& mime_type); + // Icon from control widget type for this MIME type + + static LLString findToolTip(const LLString& mime_type); + // Tool tip from control widget type for this MIME type + + static LLString findPlayTip(const LLString& mime_type); + // Play button tool tip from control widget type for this MIME type + + static LLString findDefaultMimeType(const LLString& widget_type); + // Canonical mime type associated with this widget set + + static bool findAllowResize(const LLString& mime_type); + // accessor for flag to enable/disable media size edit fields + + static bool LLMIMETypes::findAllowLooping(const LLString& mime_type); + // accessor for flag to enable/disable media looping checkbox + +public: + struct LLMIMEInfo + { + LLString mLabel; + // friendly label like "QuickTime Movie" + + LLString mWidgetType; + // "web" means use web media UI widgets + + LLString mImpl; + // which impl to use with this mime type + }; + struct LLMIMEWidgetSet + { + LLString mLabel; + // friendly label like "QuickTime Movie" + + LLString mIcon; + // Name of icon asset to display in toolbar + + LLString mDefaultMimeType; + // Mime type string to use in absence of a specific one + + LLString mToolTip; + // custom tool tip for this mime type + + LLString mPlayTip; + // custom tool tip to display for Play button + + bool mAllowResize; + // enable/disable media size edit fields + + bool mAllowLooping; + // enable/disable media looping checkbox + }; + typedef std::map< LLString, LLMIMEInfo > mime_info_map_t; + typedef std::map< LLString, LLMIMEWidgetSet > mime_widget_set_map_t; + + // Public so users can iterate over it + static mime_info_map_t sMap; + static mime_widget_set_map_t sWidgetMap; +private: +}; + +#endif diff --git a/indra/newview/lloverlaybar.cpp b/indra/newview/lloverlaybar.cpp index 15195d8f02..2c33cccf71 100644 --- a/indra/newview/lloverlaybar.cpp +++ b/indra/newview/lloverlaybar.cpp @@ -42,7 +42,6 @@ #include "llchatbar.h" #include "llfocusmgr.h" #include "llimview.h" -#include "llmediaengine.h" #include "llmediaremotectrl.h" #include "llpanelaudiovolume.h" #include "llparcel.h" @@ -50,7 +49,10 @@ #include "llui.h" #include "llviewercontrol.h" #include "llviewerimagelist.h" +#include "llviewermedia.h" #include "llviewermenu.h" // handle_reset_view() +#include "llviewermedia.h" +#include "llviewerparcelmedia.h" #include "llviewerparcelmgr.h" #include "llvieweruictrlfactory.h" #include "llviewerwindow.h" @@ -97,7 +99,6 @@ LLOverlayBar::LLOverlayBar() : LLPanel(), mMediaRemote(NULL), mVoiceRemote(NULL), - mMediaState(STOPPED), mMusicState(STOPPED) { setMouseOpaque(FALSE); @@ -220,7 +221,7 @@ void LLOverlayBar::refresh() BOOL controls_grabbed = gAgent.anyControlGrabbed(); button = LLUICtrlFactory::getButtonByName(this, "Release Keys"); - + if (button && button->getVisible() != controls_grabbed) { button->setVisible(controls_grabbed); @@ -231,7 +232,7 @@ void LLOverlayBar::refresh() BOOL mouselook_grabbed; mouselook_grabbed = gAgent.isControlGrabbed(CONTROL_ML_LBUTTON_DOWN_INDEX) - || gAgent.isControlGrabbed(CONTROL_ML_LBUTTON_UP_INDEX); + || gAgent.isControlGrabbed(CONTROL_ML_LBUTTON_UP_INDEX); button = LLUICtrlFactory::getButtonByName(this, "Mouselook"); if (button && button->getVisible() != mouselook_grabbed) @@ -257,7 +258,6 @@ void LLOverlayBar::refresh() buttons_changed = TRUE; } - enableMediaButtons(); moveChildToBackOfTabGroup(mMediaRemote); moveChildToBackOfTabGroup(mVoiceRemote); @@ -340,24 +340,40 @@ void LLOverlayBar::mediaPlay(void*) return; } - if (gOverlayBar->mMediaState != PLAYING) + + if (LLViewerMedia::isMediaPaused()) + { + LLViewerParcelMedia::start(); + } + else if(LLViewerMedia::isMediaPlaying()) + { + LLViewerParcelMedia::pause(); + } + else { - gOverlayBar->mMediaState = PLAYING; // desired state LLParcel* parcel = gParcelMgr->getAgentParcel(); if (parcel) { - LLString path(""); - LLMediaEngine::getInstance()->convertImageAndLoadUrl( true, false, path ); + LLViewerParcelMedia::play(parcel); } } - else +} + +//static +void LLOverlayBar::mediaPause(void*) +{ + + LLViewerParcelMedia::pause(); +} + +//static +void LLOverlayBar::mediaStop(void*) +{ + if (!gOverlayBar) { - gOverlayBar->mMediaState = PAUSED; // desired state - LLMediaEngine::getInstance()->pause(); + return; } - - //gOverlayBar->mMediaState = STOPPED; // desired state - //LLMediaEngine::getInstance()->stop(); + LLViewerParcelMedia::stop(); } //static @@ -403,39 +419,3 @@ void LLOverlayBar::musicPlay(void*) } } -void LLOverlayBar::enableMediaButtons() -{ - if (mMediaRemote) - { - // Music - LLParcel* parcel = gParcelMgr->getAgentParcel(); - if (parcel - && gAudiop - && !parcel->getMusicURL().empty() - && gSavedSettings.getBOOL("AudioStreamingMusic")) - { - mMediaRemote->childSetEnabled("music_play", TRUE); - } - else - { - mMediaRemote->childSetEnabled("music_play", FALSE); - } - - // Media - // if there is a url and a texture and media is enabled and available and media streaming is on... (phew!) - if (LLMediaEngine::getInstance() - && LLMediaEngine::getInstance()->getUrl ().length () - && LLMediaEngine::getInstance()->getImageUUID ().notNull () - && LLMediaEngine::getInstance()->isEnabled () - && LLMediaEngine::getInstance()->isAvailable () - && gSavedSettings.getBOOL ( "AudioStreamingVideo" ) ) - { - mMediaRemote->childSetEnabled("media_play", TRUE); - } - else - { - mMediaRemote->childSetEnabled("media_play", FALSE); - } - } -} - diff --git a/indra/newview/lloverlaybar.h b/indra/newview/lloverlaybar.h index 90886e1c72..90ab8d057a 100644 --- a/indra/newview/lloverlaybar.h +++ b/indra/newview/lloverlaybar.h @@ -67,7 +67,6 @@ public: void layoutButtons(); // helpers for returning desired state - BOOL mediaPlaying() { return mMediaState == PLAYING; } BOOL musicPlaying() { return mMusicState == PLAYING; } static void onClickIMReceived(void* data); @@ -79,7 +78,14 @@ public: //static media helper functions static void mediaPlay(void*); + static void mediaPause(void*); + static void mediaStop(void*); + static void musicPlay(void*); + static void musicPause(void*); + static void musicStop(void*); + + static void toggleAudioVolumeFloater(void*); protected: static void* createMediaRemote(void* userdata); @@ -93,8 +99,7 @@ protected: LLVoiceRemoteCtrl* mVoiceRemote; bool mBuilt; // dialog constructed yet? enum { STOPPED=0, PLAYING=1, PAUSED=2 }; - BOOL mMediaState; - BOOL mMusicState; + S32 mMusicState; }; extern LLOverlayBar* gOverlayBar; diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index 0146214c4b..d9416bbf37 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -495,7 +495,6 @@ BOOL LLPanelAvatarWeb::postBuild(void) childSetControlName("auto_load","AutoLoadWebProfiles"); -#if LL_LIBXUL_ENABLED mWebBrowser = (LLWebBrowserCtrl*)getChildByName("profile_html"); // links open in internally @@ -503,7 +502,6 @@ BOOL LLPanelAvatarWeb::postBuild(void) // observe browser events mWebBrowser->addObserver( this ); -#endif // LL_LIBXUL_ENABLED return TRUE; } @@ -563,13 +561,11 @@ LLPanelAvatarWeb::LLPanelAvatarWeb(const std::string& name, const LLRect& rect, LLPanelAvatarWeb::~LLPanelAvatarWeb() { -#if LL_LIBXUL_ENABLED // stop observing browser events if ( mWebBrowser ) { mWebBrowser->remObserver( this ); }; -#endif } void LLPanelAvatarWeb::enableControls(BOOL self) @@ -606,12 +602,6 @@ void LLPanelAvatarWeb::setWebURL(std::string url) childSetVisible("profile_html",false); } -#if !LL_LIBXUL_ENABLED - childSetVisible("load",false); - childSetVisible("profile_html",false); - childSetVisible("status_text",false); -#endif - } // static @@ -627,18 +617,13 @@ void LLPanelAvatarWeb::onCommitURL(LLUICtrl* ctrl, void* data) // static void LLPanelAvatarWeb::onClickWebProfileHelp(void *) { -#if LL_LIBXUL_ENABLED gViewerWindow->alertXml("ClickWebProfileHelpAvatar"); -#else - gViewerWindow->alertXml("ClickWebProfileNoWebHelpAvatar"); -#endif } void LLPanelAvatarWeb::load(std::string url) { bool have_url = (!url.empty()); -#if LL_LIBXUL_ENABLED if (have_url) { llinfos << "Loading " << url << llendl; @@ -658,9 +643,6 @@ void LLPanelAvatarWeb::load(std::string url) childSetEnabled("home",use_home); childSetEnabled("open",have_url); -#else - childSetEnabled("open",have_url); -#endif } void LLPanelAvatarWeb::load() @@ -692,7 +674,6 @@ void LLPanelAvatarWeb::onClickOpen(void* data) } } -#if LL_LIBXUL_ENABLED void LLPanelAvatarWeb::onStatusTextChange( const EventType& eventIn ) { childSetText("status_text", eventIn.getStringValue() ); @@ -702,7 +683,6 @@ void LLPanelAvatarWeb::onLocationChange( const EventType& eventIn ) { childSetText("url_edit", eventIn.getStringValue() ); } -#endif //----------------------------------------------------------------------------- diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h index 7d491c6143..d992c29304 100644 --- a/indra/newview/llpanelavatar.h +++ b/indra/newview/llpanelavatar.h @@ -137,9 +137,7 @@ private: // WARNING! The order of the inheritance here matters!! Do not change. - KLW class LLPanelAvatarWeb : public LLPanelAvatarTab -#if LL_LIBXUL_ENABLED , public LLWebBrowserCtrlObserver -#endif { public: LLPanelAvatarWeb(const std::string& name, const LLRect& rect, LLPanelAvatar* panel_avatar); @@ -157,11 +155,9 @@ public: static void onCommitURL(LLUICtrl* ctrl, void* data); static void onClickWebProfileHelp(void *); -#if LL_LIBXUL_ENABLED // browser observer impls virtual void onStatusTextChange( const EventType& eventIn ); virtual void onLocationChange( const EventType& eventIn ); -#endif private: std::string mURL; diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 8ce2ae5d9c..83fc991ae0 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -57,10 +57,9 @@ #include "lltooldraganddrop.h" #include "llui.h" #include "llviewercontrol.h" +#include "llviewermedia.h" #include "llviewerobject.h" #include "llviewerstats.h" -#include "llmediaengine.h" - #include "llvieweruictrlfactory.h" // @@ -374,14 +373,19 @@ void LLPanelFace::getState() childSetEnabled("button align",FALSE); //mBtnAutoFix->setEnabled ( FALSE ); - if ( LLMediaEngine::getInstance()->getMediaRenderer () ) - if ( LLMediaEngine::getInstance()->getMediaRenderer ()->isLoaded () ) - { - childSetEnabled("textbox autofix",editable); - //mLabelTexAutoFix->setEnabled ( editable ); - childSetEnabled("button align",editable); - //mBtnAutoFix->setEnabled ( editable ); - } + if(LLViewerMedia::hasMedia()) + { + childSetEnabled("textbox autofix",editable); + childSetEnabled("button align",editable); + } + //if ( LLMediaEngine::getInstance()->getMediaRenderer () ) + // if ( LLMediaEngine::getInstance()->getMediaRenderer ()->isLoaded () ) + // { + // + // //mLabelTexAutoFix->setEnabled ( editable ); + // + // //mBtnAutoFix->setEnabled ( editable ); + // } childSetEnabled("button apply",editable); bool identical; @@ -884,27 +888,25 @@ struct LLPanelFaceSetMediaFunctor : public LLSelectedTEFunctor virtual bool apply(LLViewerObject* object, S32 te) { // only do this if it's a media texture - if ( object->getTE ( te )->getID() == LLMediaEngine::getInstance()->getImageUUID () ) + if ( object->getTE ( te )->getID() == LLViewerMedia::getMediaTextureID() ) { - // make sure we're valid - if ( LLMediaEngine::getInstance()->getMediaRenderer() ) + S32 media_width, media_height; + S32 texture_width, texture_height; + if ( LLViewerMedia::getMediaSize( &media_width, &media_height ) + && LLViewerMedia::getTextureSize( &texture_width, &texture_height ) ) { - // calculate correct scaling based on media dimensions and next-power-of-2 texture dimensions - F32 scaleS = (F32)LLMediaEngine::getInstance()->getMediaRenderer()->getMediaWidth() / - (F32)LLMediaEngine::getInstance()->getMediaRenderer()->getTextureWidth(); - - F32 scaleT = (F32)LLMediaEngine::getInstance()->getMediaRenderer()->getMediaHeight() / - (F32)LLMediaEngine::getInstance()->getMediaRenderer()->getTextureHeight(); + F32 scale_s = (F32)media_width / (F32)texture_width; + F32 scale_t = (F32)media_height / (F32)texture_height; // set scale and adjust offset - object->setTEScaleS( te, scaleS ); - object->setTEScaleT( te, scaleT ); // don't need to flip Y anymore since QT does this for us now. - object->setTEOffsetS( te, -( 1.0f - scaleS ) / 2.0f ); - object->setTEOffsetT( te, -( 1.0f - scaleT ) / 2.0f ); + object->setTEScaleS( te, scale_s ); + object->setTEScaleT( te, scale_t ); // don't need to flip Y anymore since QT does this for us now. + object->setTEOffsetS( te, -( 1.0f - scale_s ) / 2.0f ); + object->setTEOffsetT( te, -( 1.0f - scale_t ) / 2.0f ); } } return true; - } + }; }; void LLPanelFace::onClickAutoFix(void* userdata) diff --git a/indra/newview/llpanelland.cpp b/indra/newview/llpanelland.cpp index d86f81d21d..45e78f257f 100644 --- a/indra/newview/llpanelland.cpp +++ b/indra/newview/llpanelland.cpp @@ -253,5 +253,5 @@ void LLPanelLandInfo::onClickAbout(void*) gParcelMgr->selectParcelInRectangle(); } - LLFloaterLand::show(); + LLFloaterLand::showInstance(); } diff --git a/indra/newview/llpanellandmedia.cpp b/indra/newview/llpanellandmedia.cpp new file mode 100644 index 0000000000..1ac95c9a82 --- /dev/null +++ b/indra/newview/llpanellandmedia.cpp @@ -0,0 +1,378 @@ +/** + * @file llpanellandmedia.cpp + * @author Callum Prentice, Sam Kolb, James Cook + * @brief Allows configuration of "media" for a land parcel, + * for example movies, web pages, and audio. + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +#include "llviewerprecompiledheaders.h" + +#include "llpanellandmedia.h" + +// viewer includes +#include "llmimetypes.h" +#include "llviewerparcelmgr.h" +#include "llvieweruictrlfactory.h" + +// library includes +#include "llcheckboxctrl.h" +#include "llcombobox.h" +#include "llfloaterurlentry.h" +#include "llfocusmgr.h" +#include "lllineeditor.h" +#include "llparcel.h" +#include "lltextbox.h" +#include "llradiogroup.h" +#include "llspinctrl.h" +#include "llsdutil.h" +#include "lltexturectrl.h" +#include "roles_constants.h" + +// Values for the parcel voice settings radio group +enum +{ + kRadioVoiceChatEstate = 0, + kRadioVoiceChatPrivate = 1, + kRadioVoiceChatDisable = 2 +}; + +//--------------------------------------------------------------------------- +// LLPanelLandMedia +//--------------------------------------------------------------------------- + +LLPanelLandMedia::LLPanelLandMedia(LLParcelSelectionHandle& parcel) +: LLPanel("land_media_panel"), mParcel(parcel) +{ +} + + +// virtual +LLPanelLandMedia::~LLPanelLandMedia() +{ + // close LLFloaterURLEntry? +} + + +BOOL LLPanelLandMedia::postBuild() +{ + mCheckSoundLocal = LLUICtrlFactory::getCheckBoxByName(this, "check sound local"); + childSetCommitCallback("check sound local", onCommitAny, this); + + mRadioVoiceChat = LLUICtrlFactory::getRadioGroupByName(this, "parcel_voice_channel"); + childSetCommitCallback("parcel_voice_channel", onCommitAny, this); + + mMusicURLEdit = LLUICtrlFactory::getLineEditorByName(this, "music_url"); + childSetCommitCallback("music_url", onCommitAny, this); + + mMediaTextureCtrl = LLUICtrlFactory::getTexturePickerByName(this, "media texture"); + if (mMediaTextureCtrl) + { + mMediaTextureCtrl->setCommitCallback( onCommitAny ); + mMediaTextureCtrl->setCallbackUserData( this ); + mMediaTextureCtrl->setAllowNoTexture ( TRUE ); + mMediaTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); + mMediaTextureCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); + } + else + { + llwarns << "LLUICtrlFactory::getTexturePickerByName() returned NULL for 'media texure'" << llendl; + } + + mMediaAutoScaleCheck = LLUICtrlFactory::getCheckBoxByName(this, "media_auto_scale"); + childSetCommitCallback("media_auto_scale", onCommitAny, this); + + mMediaLoopCheck = LLUICtrlFactory::getCheckBoxByName(this, "media_loop"); + childSetCommitCallback("media_loop", onCommitAny, this); + + mMediaUrlCheck = LLUICtrlFactory::getCheckBoxByName(this, "hide_media_url"); + childSetCommitCallback("hide_media_url", onCommitAny, this); + + mMusicUrlCheck = LLUICtrlFactory::getCheckBoxByName(this, "hide_music_url"); + childSetCommitCallback("hide_music_url", onCommitAny, this); + + mMediaURLEdit = LLUICtrlFactory::getLineEditorByName(this, "media_url"); + childSetCommitCallback("media_url", onCommitAny, this); + + mMediaDescEdit = LLUICtrlFactory::getLineEditorByName(this, "url_description"); + childSetCommitCallback("url_description", onCommitAny, this); + + mMediaTypeCombo = LLUICtrlFactory::getComboBoxByName(this, "media type"); + childSetCommitCallback("media type", onCommitType, this); + populateMIMECombo(); + mMediaTypeCombo->sortByName(); + + mMediaWidthCtrl = LLUICtrlFactory::getSpinnerByName(this, "media_size_width"); + childSetCommitCallback("media_size_width", onCommitAny, this); + mMediaHeightCtrl = LLUICtrlFactory::getSpinnerByName(this, "media_size_height"); + childSetCommitCallback("media_size_height", onCommitAny, this); + mMediaSizeCtrlLabel = LLUICtrlFactory::getTextBoxByName(this, "media_size"); + + mSetURLButton = LLUICtrlFactory::getButtonByName(this, "set_media_url"); + childSetAction("set_media_url", onSetBtn, this); + + return TRUE; +} + + +// public +void LLPanelLandMedia::refresh() +{ + LLParcel *parcel = mParcel->getParcel(); + + if (!parcel) + { + clearCtrls(); + } + else + { + // something selected, hooray! + + // Display options + BOOL can_change_media = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_CHANGE_MEDIA); + + mCheckSoundLocal->set( parcel->getSoundLocal() ); + mCheckSoundLocal->setEnabled( can_change_media ); + + if(parcel->getVoiceEnabled()) + { + if(parcel->getVoiceUseEstateChannel()) + mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatEstate); + else + mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatPrivate); + } + else + { + mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatDisable); + } + + mRadioVoiceChat->setEnabled( can_change_media ); + + mMusicURLEdit->setText(parcel->getMusicURL()); + mMusicURLEdit->setEnabled( can_change_media ); + + mMediaURLEdit->setText(parcel->getMediaURL()); + mMediaURLEdit->setEnabled( FALSE ); + + mMediaDescEdit->setText(LLString(parcel->getMediaDesc())); + mMediaDescEdit->setEnabled( can_change_media ); + + std::string mime_type = parcel->getMediaType(); + if (mime_type.empty()) + { + mime_type = "none/none"; + } + setMediaType(mime_type); + mMediaTypeCombo->setEnabled( can_change_media ); + childSetText("mime_type", mime_type); + + mMediaUrlCheck->set( parcel->getObscureMedia() ); + mMediaUrlCheck->setEnabled( can_change_media ); + + mMusicUrlCheck->set( parcel->getObscureMusic() ); + mMusicUrlCheck->setEnabled( can_change_media ); + + // don't display urls if you're not able to change it + // much requested change in forums so people can't 'steal' urls + // NOTE: bug#2009 means this is still vunerable - however, bug + // should be closed since this bug opens up major security issues elsewhere. + bool obscure_media = ! can_change_media && parcel->getObscureMedia(); + bool obscure_music = ! can_change_media && parcel->getObscureMusic(); + + // Special code to disable asterixes for html type + if(mime_type == "text/html") + { + obscure_media = false; + mMediaUrlCheck->set( 0 ); + mMediaUrlCheck->setEnabled( false ); + } + + mMusicURLEdit->setDrawAsterixes( obscure_music ); + mMediaURLEdit->setDrawAsterixes( obscure_media ); + + mMediaAutoScaleCheck->set( parcel->getMediaAutoScale () ); + mMediaAutoScaleCheck->setEnabled ( can_change_media ); + + // Special code to disable looping checkbox for HTML MIME type + // (DEV-10042 -- Parcel Media: "Loop Media" should be disabled for static media types) + bool allow_looping = LLMIMETypes::findAllowLooping( mime_type ); + if ( allow_looping ) + mMediaLoopCheck->set( parcel->getMediaLoop () ); + else + mMediaLoopCheck->set( false ); + mMediaLoopCheck->setEnabled ( can_change_media && allow_looping ); + + // disallow media size change for mime types that don't allow it + bool allow_resize = LLMIMETypes::findAllowResize( mime_type ); + if ( allow_resize ) + mMediaWidthCtrl->setValue( parcel->getMediaWidth() ); + else + mMediaWidthCtrl->setValue( 0 ); + mMediaWidthCtrl->setEnabled ( can_change_media && allow_resize ); + + if ( allow_resize ) + mMediaHeightCtrl->setValue( parcel->getMediaHeight() ); + else + mMediaHeightCtrl->setValue( 0 ); + mMediaHeightCtrl->setEnabled ( can_change_media && allow_resize ); + + // enable/disable for text label for completeness + mMediaSizeCtrlLabel->setEnabled( can_change_media && allow_resize ); + + LLUUID tmp = parcel->getMediaID(); + mMediaTextureCtrl->setImageAssetID ( parcel->getMediaID() ); + mMediaTextureCtrl->setEnabled( can_change_media ); + + mSetURLButton->setEnabled( can_change_media ); + + #if 0 + // there is a media url and a media texture selected + if ( ( ! ( std::string ( parcel->getMediaURL() ).empty () ) ) && ( ! ( parcel->getMediaID ().isNull () ) ) ) + { + // turn on transport controls if allowed for this parcel + mMediaStopButton->setEnabled ( editable ); + mMediaStartButton->setEnabled ( editable ); + } + else + { + // no media url or no media texture + mMediaStopButton->setEnabled ( FALSE ); + mMediaStartButton->setEnabled ( FALSE ); + }; + #endif + + LLFloaterURLEntry* floater_url_entry = (LLFloaterURLEntry*)LLFloater::getFloaterByHandle(mURLEntryFloater); + if (floater_url_entry) + { + floater_url_entry->updateFromLandMediaPanel(); + } + } +} + +void LLPanelLandMedia::populateMIMECombo() +{ + LLMIMETypes::mime_widget_set_map_t::const_iterator it; + for (it = LLMIMETypes::sWidgetMap.begin(); it != LLMIMETypes::sWidgetMap.end(); ++it) + { + const LLString& mime_type = it->first; + const LLMIMETypes::LLMIMEWidgetSet& info = it->second; + mMediaTypeCombo->add(info.mLabel, mime_type); + } +} +void LLPanelLandMedia::setMediaType(const LLString& mime_type) +{ + LLParcel *parcel = mParcel->getParcel(); + if(parcel) + parcel->setMediaType(mime_type.c_str()); + + LLString media_key = LLMIMETypes::widgetType(mime_type); + mMediaTypeCombo->setValue(media_key); + childSetText("mime_type", mime_type); +} + +void LLPanelLandMedia::setMediaURL(const LLString& media_url) +{ + mMediaURLEdit->setText(media_url); + mMediaURLEdit->onCommit(); + +} + +// static +void LLPanelLandMedia::onCommitType(LLUICtrl *ctrl, void *userdata) +{ + LLPanelLandMedia *self = (LLPanelLandMedia *)userdata; + std::string current_type = LLMIMETypes::widgetType(self->childGetText("mime_type")); + std::string new_type = self->mMediaTypeCombo->getValue(); + if(current_type != new_type) + { + self->childSetText("mime_type", LLMIMETypes::findDefaultMimeType(new_type)); + } + onCommitAny(ctrl, userdata); + +} +// static +void LLPanelLandMedia::onCommitAny(LLUICtrl *ctrl, void *userdata) +{ + LLPanelLandMedia *self = (LLPanelLandMedia *)userdata; + + LLParcel* parcel = self->mParcel->getParcel(); + if (!parcel) + { + return; + } + + // Extract data from UI + BOOL sound_local = self->mCheckSoundLocal->get(); + int voice_setting = self->mRadioVoiceChat->getSelectedIndex(); + std::string music_url = self->mMusicURLEdit->getText(); + std::string media_url = self->mMediaURLEdit->getText(); + std::string media_desc = self->mMediaDescEdit->getText(); + std::string mime_type = self->childGetText("mime_type"); + U8 media_auto_scale = self->mMediaAutoScaleCheck->get(); + U8 media_loop = self->mMediaLoopCheck->get(); + U8 obscure_media = self->mMediaUrlCheck->get(); + U8 obscure_music = self->mMusicUrlCheck->get(); + S32 media_width = (S32)self->mMediaWidthCtrl->get(); + S32 media_height = (S32)self->mMediaHeightCtrl->get(); + LLUUID media_id = self->mMediaTextureCtrl->getImageAssetID(); + + self->childSetText("mime_type", mime_type); + + BOOL voice_enabled; + BOOL voice_estate_chan; + + switch(voice_setting) + { + default: + case kRadioVoiceChatEstate: + voice_enabled = TRUE; + voice_estate_chan = TRUE; + break; + case kRadioVoiceChatPrivate: + voice_enabled = TRUE; + voice_estate_chan = FALSE; + break; + case kRadioVoiceChatDisable: + voice_enabled = FALSE; + voice_estate_chan = FALSE; + break; + } + + // Remove leading/trailing whitespace (common when copying/pasting) + LLString::trim(music_url); + LLString::trim(media_url); + + // Push data into current parcel + parcel->setParcelFlag(PF_ALLOW_VOICE_CHAT, voice_enabled); + parcel->setParcelFlag(PF_USE_ESTATE_VOICE_CHAN, voice_estate_chan); + parcel->setParcelFlag(PF_SOUND_LOCAL, sound_local); + parcel->setMusicURL(music_url.c_str()); + parcel->setMediaURL(media_url.c_str()); + parcel->setMediaType(mime_type.c_str()); + parcel->setMediaDesc(media_desc.c_str()); + parcel->setMediaWidth(media_width); + parcel->setMediaHeight(media_height); + parcel->setMediaID(media_id); + parcel->setMediaAutoScale ( media_auto_scale ); + parcel->setMediaLoop ( media_loop ); + parcel->setObscureMedia( obscure_media ); + parcel->setObscureMusic( obscure_music ); + + // Send current parcel data upstream to server + gParcelMgr->sendParcelPropertiesUpdate( parcel ); + + // Might have changed properties, so let's redraw! + self->refresh(); +} +// static +void LLPanelLandMedia::onSetBtn(void *userdata) +{ + LLPanelLandMedia *self = (LLPanelLandMedia *)userdata; + self->mURLEntryFloater = LLFloaterURLEntry::show( self->getHandle() ); + LLFloater* parent_floater = gFloaterView->getParentFloater(self); + if (parent_floater) + { + parent_floater->addDependentFloater(LLFloater::getFloaterByHandle(self->mURLEntryFloater)); + } +} diff --git a/indra/newview/llpanellandmedia.h b/indra/newview/llpanellandmedia.h new file mode 100644 index 0000000000..aa84b245e2 --- /dev/null +++ b/indra/newview/llpanellandmedia.h @@ -0,0 +1,58 @@ +/** + * @file llpanellandmedia.h + * @author Callum Prentice, Sam Kolb, James Cook + * @brief Allows configuration of "media" for a land parcel, + * for example movies, web pages, and audio. + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +#ifndef LLPANELLANDMEDIA_H +#define LLPANELLANDMEDIA_H + +#include "lllineeditor.h" +#include "llmemory.h" // LLHandle<> +#include "llpanel.h" +#include "llparcelselection.h" +#include "lluifwd.h" // widget pointer types + +class LLPanelLandMedia +: public LLPanel +{ +public: + LLPanelLandMedia(LLHandle<LLParcelSelection>& parcelp); + /*virtual*/ ~LLPanelLandMedia(); + /*virtual*/ BOOL postBuild(); + void refresh(); + void setMediaType(const LLString& media_type); + void setMediaURL(const LLString& media_type); + const LLString& getMediaURL() { return mMediaURLEdit->getText(); } + +private: + void populateMIMECombo(); + static void onCommitAny(LLUICtrl* ctrl, void *userdata); + static void onCommitType(LLUICtrl* ctrl, void *userdata); + static void onSetBtn(void* userdata); + +private: + LLCheckBoxCtrl* mCheckSoundLocal; + LLRadioGroup* mRadioVoiceChat; + LLLineEditor* mMusicURLEdit; + LLLineEditor* mMediaURLEdit; + LLLineEditor* mMediaDescEdit; + LLComboBox* mMediaTypeCombo; + LLButton* mSetURLButton; + LLSpinCtrl* mMediaHeightCtrl; + LLSpinCtrl* mMediaWidthCtrl; + LLTextBox* mMediaSizeCtrlLabel; + LLTextureCtrl* mMediaTextureCtrl; + LLCheckBoxCtrl* mMediaAutoScaleCheck; + LLCheckBoxCtrl* mMediaLoopCheck; + LLCheckBoxCtrl* mMediaUrlCheck; + LLCheckBoxCtrl* mMusicUrlCheck; + LLViewHandle mURLEntryFloater; + + LLHandle<LLParcelSelection>& mParcel; +}; + +#endif diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index bc6f6fedd8..a80765c805 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -71,7 +71,8 @@ #include "llwebbrowserctrl.h" #include "llfloaterhtml.h" -//#include "llfloaterhtmlhelp.h" + +#include "llfloaterhtmlhelp.h" #include "llfloatertos.h" #include "llglheaders.h" @@ -95,12 +96,10 @@ public: LLLoginRefreshHandler() : LLCommandHandler("login_refresh", false) { } bool handle(const LLSD& tokens, const LLSD& queryMap) { -#if LL_LIBXUL_ENABLED if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP) { LLPanelLogin::loadLoginPage(); } -#endif return true; } }; @@ -438,7 +437,6 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, #endif // get the web browser control - #if LL_LIBXUL_ENABLED LLWebBrowserCtrl* web_browser = LLUICtrlFactory::getWebBrowserCtrlByName(this, "login_html"); if ( web_browser ) { @@ -475,9 +473,6 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, } LLHTTPClient::head( login_page, gResponsePtr ); }; - #else - mHtmlAvailable = FALSE; - #endif #if !USE_VIEWER_AUTH // Initialize visibility (and don't force visibility - use prefs) @@ -487,7 +482,6 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, void LLPanelLogin::setSiteIsAlive( bool alive ) { -#if LL_LIBXUL_ENABLED LLWebBrowserCtrl* web_browser = LLUICtrlFactory::getWebBrowserCtrlByName(this, "login_html"); // if the contents of the site was retrieved if ( alive ) @@ -523,10 +517,6 @@ void LLPanelLogin::setSiteIsAlive( bool alive ) } #endif } - -#else - mHtmlAvailable = FALSE; -#endif } void LLPanelLogin::mungePassword(LLUICtrl* caller, void* user_data) @@ -620,7 +610,6 @@ BOOL LLPanelLogin::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) return TRUE; } -#if LL_LIBXUL_ENABLED if ( KEY_F1 == key ) { llinfos << "Spawning HTML help window" << llendl; @@ -636,7 +625,6 @@ BOOL LLPanelLogin::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) tos_dialog->startModal(); return TRUE; } -# endif #endif if (!called_from_parent) @@ -917,14 +905,12 @@ void LLPanelLogin::setAlwaysRefresh(bool refresh) { if (LLStartUp::getStartupState() >= STATE_LOGIN_CLEANUP) return; -#if LL_LIBXUL_ENABLED LLWebBrowserCtrl* web_browser = LLUICtrlFactory::getWebBrowserCtrlByName(sInstance, "login_html"); if (web_browser) { web_browser->setAlwaysRefresh(refresh); } -#endif } @@ -1050,15 +1036,12 @@ void LLPanelLogin::loadLoginPage() #endif #endif -#if LL_LIBXUL_ENABLED LLWebBrowserCtrl* web_browser = LLUICtrlFactory::getWebBrowserCtrlByName(sInstance, "login_html"); // navigate to the "real" page web_browser->navigateTo( oStr.str() ); -#endif } -#if LL_LIBXUL_ENABLED void LLPanelLogin::onNavigateComplete( const EventType& eventIn ) { LLWebBrowserCtrl* web_browser = LLUICtrlFactory::getWebBrowserCtrlByName(sInstance, "login_html"); @@ -1074,7 +1057,6 @@ void LLPanelLogin::onNavigateComplete( const EventType& eventIn ) //web_browser->handleKey(KEY_TAB, MASK_NONE, false); } } -#endif //--------------------------------------------------------------------------- // Protected methods diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h index 3deb6fee51..76a16528cb 100644 --- a/indra/newview/llpanellogin.h +++ b/indra/newview/llpanellogin.h @@ -64,11 +64,9 @@ class LLLoginHandler : public LLCommandHandler extern LLLoginHandler gLoginHandler; -class LLPanelLogin -: public LLPanel -#if LL_LIBXUL_ENABLED - , public LLWebBrowserCtrlObserver -#endif +class LLPanelLogin: + public LLPanel, + public LLWebBrowserCtrlObserver { public: LLPanelLogin(const LLRect &rect, BOOL show_server, @@ -111,11 +109,7 @@ private: static void newAccountAlertCallback(S32 option, void*); static void onClickQuit(void*); static void onClickVersion(void*); - -#if LL_LIBXUL_ENABLED - // browser observer impls virtual void onNavigateComplete( const EventType& eventIn ); -#endif static void onClickForgotPassword(void*); static void onPassKey(LLLineEditor* caller, void* user_data); diff --git a/indra/newview/llparcelselection.cpp b/indra/newview/llparcelselection.cpp new file mode 100644 index 0000000000..5478a96b97 --- /dev/null +++ b/indra/newview/llparcelselection.cpp @@ -0,0 +1,83 @@ +/** + * @file llparcelselection.cpp + * @brief Information about the currently selected parcel + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llparcelselection.h" + +#include "llparcel.h" + + +// static +LLPointer<LLParcelSelection> LLParcelSelection::sNullSelection; + +template<> + const LLHandle<LLParcelSelection>::NullFunc + LLHandle<LLParcelSelection>::sNullFunc = + LLParcelSelection::getNullParcelSelection; + +// +// LLParcelSelection +// +LLParcelSelection::LLParcelSelection() : + mParcel(NULL), + mSelectedMultipleOwners(FALSE), + mWholeParcelSelected(FALSE), + mSelectedSelfCount(0), + mSelectedOtherCount(0), + mSelectedPublicCount(0) +{ +} + +LLParcelSelection::LLParcelSelection(LLParcel* parcel) : + mParcel(parcel), + mSelectedMultipleOwners(FALSE), + mWholeParcelSelected(FALSE), + mSelectedSelfCount(0), + mSelectedOtherCount(0), + mSelectedPublicCount(0) +{ +} + +LLParcelSelection::~LLParcelSelection() +{ +} + +BOOL LLParcelSelection::getMultipleOwners() const +{ + return mSelectedMultipleOwners; +} + + +BOOL LLParcelSelection::getWholeParcelSelected() const +{ + return mWholeParcelSelected; +} + + +S32 LLParcelSelection::getClaimableArea() const +{ + const S32 UNIT_AREA = S32( PARCEL_GRID_STEP_METERS * PARCEL_GRID_STEP_METERS ); + return mSelectedPublicCount * UNIT_AREA; +} + +bool LLParcelSelection::hasOthersSelected() const +{ + return mSelectedOtherCount != 0; +} + +// static +LLParcelSelection* LLParcelSelection::getNullParcelSelection() +{ + if (sNullSelection.isNull()) + { + sNullSelection = new LLParcelSelection; + } + + return sNullSelection; +} diff --git a/indra/newview/llparcelselection.h b/indra/newview/llparcelselection.h new file mode 100644 index 0000000000..579a0f2549 --- /dev/null +++ b/indra/newview/llparcelselection.h @@ -0,0 +1,63 @@ +/** + * @file llparcelselection.h + * @brief Information about the currently selected parcel + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#ifndef LLPARCELSELECTION_H +#define LLPARCELSELECTION_H + +#include "llmemory.h" + +class LLParcel; + +class LLParcelSelection : public LLRefCount +{ + friend class LLViewerParcelMgr; + +protected: + ~LLParcelSelection(); + +public: + LLParcelSelection(LLParcel* parcel); + LLParcelSelection(); + + // this can return NULL at any time, as parcel selection + // might have been invalidated. + LLParcel* getParcel() { return mParcel; } + + // Return the number of grid units that are owned by you within + // the selection (computed by server). + S32 getSelfCount() const { return mSelectedSelfCount; } + + // Returns area that will actually be claimed in meters squared. + S32 getClaimableArea() const; + bool hasOthersSelected() const; + + // Does the selection have multiple land owners in it? + BOOL getMultipleOwners() const; + + // Is the entire parcel selected, or just a part? + BOOL getWholeParcelSelected() const; + + static LLParcelSelection* getNullParcelSelection(); + +private: + void setParcel(LLParcel* parcel) { mParcel = parcel; } + +private: + LLParcel* mParcel; + BOOL mSelectedMultipleOwners; + BOOL mWholeParcelSelected; + S32 mSelectedSelfCount; + S32 mSelectedOtherCount; + S32 mSelectedPublicCount; + + static LLPointer<LLParcelSelection> sNullSelection; +}; + +typedef LLHandle<LLParcelSelection> LLParcelSelectionHandle; + +#endif diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index c6d721faeb..d3afd65cbe 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -471,14 +471,12 @@ void LLScriptEdCore::updateDynamicHelp(BOOL immediate) LLFloater* help_floater = LLFloater::getFloaterByHandle(mLiveHelpHandle); if (!help_floater) return; -#if LL_LIBXUL_ENABLED // update back and forward buttons LLButton* fwd_button = LLUICtrlFactory::getButtonByName(help_floater, "fwd_btn"); LLButton* back_button = LLUICtrlFactory::getButtonByName(help_floater, "back_btn"); LLWebBrowserCtrl* browser = LLUICtrlFactory::getWebBrowserCtrlByName(help_floater, "lsl_guide_html"); back_button->setEnabled(browser->canNavigateBack()); fwd_button->setEnabled(browser->canNavigateForward()); -#endif // LL_LIBXUL_ENABLED if (!immediate && !gSavedSettings.getBOOL("ScriptHelpFollowsCursor")) { @@ -546,9 +544,9 @@ void LLScriptEdCore::setHelpPage(const LLString& help_string) url_string.setArg("[LSL_STRING]", help_string); addHelpItemToHistory(help_string); -#if LL_LIBXUL_ENABLED + web_browser->navigateTo(url_string); -#endif // LL_LIBXUL_ENABLED + } void LLScriptEdCore::addHelpItemToHistory(const LLString& help_string) @@ -680,10 +678,8 @@ void LLScriptEdCore::onBtnDynamicHelp(void* userdata) live_help_floater->childSetAction("back_btn", onClickBack, userdata); live_help_floater->childSetAction("fwd_btn", onClickForward, userdata); -#if LL_LIBXUL_ENABLED LLWebBrowserCtrl* browser = LLUICtrlFactory::getWebBrowserCtrlByName(live_help_floater, "lsl_guide_html"); browser->setAlwaysRefresh(TRUE); -#endif // LL_LIBXUL_ENABLED LLComboBox* help_combo = LLUICtrlFactory::getComboBoxByName(live_help_floater, "history_combo"); LLKeywordToken *token; @@ -707,7 +703,6 @@ void LLScriptEdCore::onBtnDynamicHelp(void* userdata) //static void LLScriptEdCore::onClickBack(void* userdata) { -#if LL_LIBXUL_ENABLED LLScriptEdCore* corep = (LLScriptEdCore*)userdata; LLFloater* live_help_floater = LLFloater::getFloaterByHandle(corep->mLiveHelpHandle); if (live_help_floater) @@ -718,13 +713,11 @@ void LLScriptEdCore::onClickBack(void* userdata) browserp->navigateBack(); } } -#endif // LL_LIBXUL_ENABLED } //static void LLScriptEdCore::onClickForward(void* userdata) { -#if LL_LIBXUL_ENABLED LLScriptEdCore* corep = (LLScriptEdCore*)userdata; LLFloater* live_help_floater = LLFloater::getFloaterByHandle(corep->mLiveHelpHandle); if (live_help_floater) @@ -735,7 +728,6 @@ void LLScriptEdCore::onClickForward(void* userdata) browserp->navigateForward(); } } -#endif // LL_LIBXUL_ENABLED } // static @@ -772,13 +764,11 @@ void LLScriptEdCore::onHelpComboCommit(LLUICtrl* ctrl, void* userdata) corep->addHelpItemToHistory(help_string); -#if LL_LIBXUL_ENABLED LLWebBrowserCtrl* web_browser = gUICtrlFactory->getWebBrowserCtrlByName(live_help_floater, "lsl_guide_html"); LLUIString url_string = gSavedSettings.getString("LSLHelpURL"); url_string.setArg("[APP_DIRECTORY]", gDirUtilp->getWorkingDir()); url_string.setArg("[LSL_STRING]", help_string); web_browser->navigateTo(url_string); -#endif // LL_LIBXUL_ENABLED } } diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 8df34d39c6..423954800f 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -134,6 +134,7 @@ #include "llui.h" #include "llurldispatcher.h" #include "llurlsimstring.h" +#include "llurlhistory.h" #include "llurlwhitelist.h" #include "lluserauth.h" #include "llvieweraudio.h" @@ -143,10 +144,12 @@ #include "llviewergenericmessage.h" #include "llviewergesture.h" #include "llviewerimagelist.h" +#include "llviewermedia.h" #include "llviewermenu.h" #include "llviewermessage.h" #include "llviewernetwork.h" #include "llviewerobjectlist.h" +#include "llviewerparcelmedia.h" #include "llviewerparcelmgr.h" #include "llviewerregion.h" #include "llviewerstats.h" @@ -160,7 +163,6 @@ #include "llxfermanager.h" #include "pipeline.h" #include "llappviewer.h" -#include "llmediaengine.h" #include "llfasttimerview.h" #include "llfloatermap.h" #include "llweb.h" @@ -169,27 +171,11 @@ #include "llnamebox.h" #include "llnameeditor.h" -#if LL_LIBXUL_ENABLED -#include "llmozlib.h" -#endif // LL_LIBXUL_ENABLED - #if LL_WINDOWS #include "llwindebug.h" #include "lldxhardware.h" #endif -#if LL_QUICKTIME_ENABLED -#if LL_DARWIN -#include <QuickTime/QuickTime.h> -#else -// quicktime specific includes -#include "MacTypes.h" -#include "QTML.h" -#include "Movies.h" -#include "FixMath.h" -#endif -#endif - // // exported globals // @@ -213,8 +199,6 @@ LLPointer<LLImageGL> gStartImageGL; static LLHost gAgentSimHost; static BOOL gSkipOptionalUpdate = FALSE; -bool gUseQuickTime = true; -bool gQuickTimeInitialized = false; static bool gGotUseCircuitCodeAck = false; LLString gInitialOutfit; LLString gInitialOutfitGender; // "male" or "female" @@ -545,59 +529,7 @@ BOOL idle_startup() // initialize the economy gGlobalEconomy = new LLGlobalEconomy(); - //--------------------------------------------------------------------- - // LibXUL (Mozilla) initialization - //--------------------------------------------------------------------- - #if LL_LIBXUL_ENABLED - set_startup_status(0.58f, "Initializing embedded web browser...", gAgent.mMOTD.c_str()); - display_startup(); - llinfos << "Initializing embedded web browser..." << llendl; - - #if LL_DARWIN - // For Mac OS, we store both the shared libraries and the runtime files (chrome/, plugins/, etc) in - // Second Life.app/Contents/MacOS/. This matches the way Firefox is distributed on the Mac. - std::string componentDir(gDirUtilp->getExecutableDir()); - #elif LL_WINDOWS - std::string componentDir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) ); - componentDir += gDirUtilp->getDirDelimiter(); - #ifdef LL_DEBUG - componentDir += "mozilla_debug"; - #else - componentDir += "mozilla"; - #endif - #elif LL_LINUX - std::string componentDir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) ); - componentDir += gDirUtilp->getDirDelimiter(); - componentDir += "mozilla-runtime-linux-i686"; - #else - std::string componentDir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) ); - componentDir += gDirUtilp->getDirDelimiter(); - componentDir += "mozilla"; - #endif -#if LL_LINUX - // Yuck, Mozilla init plays with the locale - push/pop - // the locale to protect it, as exotic/non-C locales - // causes our code lots of general critical weirdness - // and crashness. (SL-35450) - std::string saved_locale = setlocale(LC_ALL, NULL); -#endif // LL_LINUX - - // initialize Mozilla - pass in executable dir, location of extra dirs (chrome/, greprefs/, plugins/ etc.) and path to profile dir) - LLMozLib::getInstance()->init( gDirUtilp->getExecutableDir(), componentDir, gDirUtilp->getExpandedFilename( LL_PATH_MOZILLA_PROFILE, "" ) ); - -#if LL_LINUX - setlocale(LC_ALL, saved_locale.c_str() ); -#endif // LL_LINUX - - std::ostringstream codec; - codec << "[Second Life "; - codec << "(" << gChannelName << ")"; - codec << " - " << LL_VERSION_MAJOR << "." << LL_VERSION_MINOR << "." << LL_VERSION_PATCH << "." << LL_VERSION_BUILD; - codec << "]"; - LLMozLib::getInstance()->setBrowserAgentId( codec.str() ); - LLMozLib::getInstance()->enableProxy( gSavedSettings.getBOOL("BrowserProxyEnabled"), gSavedSettings.getString("BrowserProxyAddress"), gSavedSettings.getS32("BrowserProxyPort") ); - #endif //------------------------------------------------- // Init audio, which may be needed for prefs dialog @@ -694,7 +626,29 @@ BOOL idle_startup() show_connect_box = TRUE; } + // Go to the next startup state + LLStartUp::setStartupState( STATE_MEDIA_INIT ); + return do_normal_idle; + } + + + //--------------------------------------------------------------------- + // LLMediaEngine Init + //--------------------------------------------------------------------- + if (STATE_MEDIA_INIT == LLStartUp::getStartupState()) + { + llinfos << "Initializing Multimedia...." << llendl; + set_startup_status(0.03f, "Initializing Multimedia...", gAgent.mMOTD.c_str()); + display_startup(); + LLViewerMedia::initClass(); + LLViewerParcelMedia::initClass(); + + if (gViewerWindow) + { + audio_update_volume(true); + } + LLStartUp::setStartupState( STATE_LOGIN_SHOW ); return do_normal_idle; } @@ -892,6 +846,9 @@ BOOL idle_startup() &LLURLDispatcher::dispatchFromTextEditor, &LLURLDispatcher::dispatchFromTextEditor ); + // Load URL History File + LLURLHistory::loadFile("url_history.xml"); + //------------------------------------------------- // Handle startup progress screen //------------------------------------------------- @@ -934,7 +891,7 @@ BOOL idle_startup() // Poke the VFS, which could potentially block for a while if // Windows XP is acting up - set_startup_status(0.05f, "Verifying cache files (can take 60-90 seconds)...", NULL); + set_startup_status(0.07f, "Verifying cache files (can take 60-90 seconds)...", NULL); display_startup(); gVFS->pokeFiles(); @@ -1774,7 +1731,7 @@ BOOL idle_startup() display_startup(); gImageList.decodeAllImages(1.f); } - LLStartUp::setStartupState( STATE_QUICKTIME_INIT ); + LLStartUp::setStartupState( STATE_WORLD_WAIT ); // JC - Do this as late as possible to increase likelihood Purify // will run. @@ -1808,79 +1765,8 @@ BOOL idle_startup() } //--------------------------------------------------------------------- - // LLMediaEngine Init - //--------------------------------------------------------------------- - if (STATE_QUICKTIME_INIT == LLStartUp::getStartupState()) - { - if (gViewerWindow) - { - audio_update_volume(true); - } - - #if LL_QUICKTIME_ENABLED // windows only right now but will be ported to mac - if (gUseQuickTime) - { - if(!gQuickTimeInitialized) - { - // initialize quicktime libraries (fails gracefully if quicktime not installed ($QUICKTIME) - llinfos << "Initializing QuickTime...." << llendl; - set_startup_status(0.57f, "Initializing QuickTime...", gAgent.mMOTD.c_str()); - display_startup(); - #if LL_WINDOWS - // Only necessary/available on Windows. - if ( InitializeQTML ( 0L ) != noErr ) - { - // quicktime init failed - turn off media engine support - LLMediaEngine::getInstance ()->setAvailable ( FALSE ); - llinfos << "...not found - unable to initialize." << llendl; - set_startup_status(0.57f, "QuickTime not found - unable to initialize.", gAgent.mMOTD.c_str()); - } - else - { - llinfos << "QUICKTIME> QuickTime version (hex) is " << std::hex << LLMediaEngine::getInstance()->getQuickTimeVersion() << llendl; - llinfos << "QUICKTIME> QuickTime version is " << std::dec << LLMediaEngine::getInstance()->getQuickTimeVersion() << llendl; - if ( LLMediaEngine::getInstance()->getQuickTimeVersion() < LL_MIN_QUICKTIME_VERSION ) - { - // turn off QuickTime if version is less than required - LLMediaEngine::getInstance ()->setAvailable ( FALSE ); - - // display a message here explaining why we disabled QuickTime - gViewerWindow->alertXml("QuickTimeOutOfDate"); - } - else - { - llinfos << ".. initialized successfully." << llendl; - set_startup_status(0.57f, "QuickTime initialized successfully.", gAgent.mMOTD.c_str()); - }; - }; - #elif LL_DARWIN - llinfos << "QUICKTIME> QuickTime version (hex) is " << std::hex << LLMediaEngine::getInstance()->getQuickTimeVersion() << llendl; - llinfos << "QUICKTIME> QuickTime version is " << std::dec << LLMediaEngine::getInstance()->getQuickTimeVersion() << llendl; - if ( LLMediaEngine::getInstance()->getQuickTimeVersion() < LL_MIN_QUICKTIME_VERSION ) - { - // turn off QuickTime if version is less than required - LLMediaEngine::getInstance ()->setAvailable ( FALSE ); - - // display a message here explaining why we disabled QuickTime - gViewerWindow->alertXml("QuickTimeOutOfDate"); - } - #endif - - EnterMovies (); - gQuickTimeInitialized = true; - } - } - else - { - LLMediaEngine::getInstance()->setAvailable( FALSE ); - } - #endif - LLStartUp::setStartupState( STATE_WORLD_WAIT ); - return do_normal_idle; - } - //--------------------------------------------------------------------- // Agent Send //--------------------------------------------------------------------- if(STATE_WORLD_WAIT == LLStartUp::getStartupState()) @@ -3126,18 +3012,6 @@ void register_viewer_callbacks(LLMessageSystem* msg) msg->setHandlerFunc("ParcelObjectOwnersReply", LLPanelLandObjects::processParcelObjectOwnersReply); - // Reponse to the "Refresh" button on land objects floater. - if (gSavedSettings.getBOOL("AudioStreamingVideo")) - { - msg->setHandlerFunc("ParcelMediaCommandMessage", LLMediaEngine::process_parcel_media); - msg->setHandlerFunc ( "ParcelMediaUpdate", LLMediaEngine::process_parcel_media_update ); - } - else - { - msg->setHandlerFunc("ParcelMediaCommandMessage", null_message_callback); - gMessageSystem->setHandlerFunc ( "ParcelMediaUpdate", null_message_callback ); - } - msg->setHandlerFunc("InitiateDownload", process_initiate_download); msg->setHandlerFunc("LandStatReply", LLFloaterTopObjects::handle_land_reply); msg->setHandlerFunc("GenericMessage", process_generic_message); diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h index 08f2f6002c..351d4b1a21 100644 --- a/indra/newview/llstartup.h +++ b/indra/newview/llstartup.h @@ -46,6 +46,7 @@ extern const char* SCREEN_LAST_FILENAME; enum EStartupState{ STATE_FIRST, // Initial startup + STATE_MEDIA_INIT, // Initialzie media library STATE_LOGIN_SHOW, // Show login screen STATE_LOGIN_WAIT, // Wait for user input at login screen STATE_LOGIN_CLEANUP, // Get rid of login screen and start login @@ -58,7 +59,6 @@ enum EStartupState{ STATE_WORLD_INIT, // Start building the world STATE_SEED_GRANTED_WAIT, // Wait for seed cap grant STATE_SEED_CAP_GRANTED, // Have seed cap grant - STATE_QUICKTIME_INIT, // Initialzie QT STATE_WORLD_WAIT, // Waiting for simulator STATE_AGENT_SEND, // Connect to a region STATE_AGENT_WAIT, // Wait for region @@ -72,8 +72,6 @@ enum EStartupState{ // exported symbols extern BOOL gAgentMovementCompleted; -extern bool gUseQuickTime; -extern bool gQuickTimeInitialized; extern LLPointer<LLImageGL> gStartImageGL; class LLStartUp diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index 8c4fc833db..58039bf878 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -49,6 +49,7 @@ #include "llfloaterbuycurrency.h" #include "llfloaterchat.h" #include "llfloaterdirectory.h" // to spawn search +#include "llfloaterlagmeter.h" #include "llfloaterland.h" #include "llfloaterregioninfo.h" #include "llfloaterscriptdebug.h" @@ -163,8 +164,49 @@ LLStatusBar::LLStatusBar(const std::string& name, const LLRect& rect) childSetCommitCallback("search_editor", onCommitSearch, this); childSetAction("search_btn", onClickSearch, this); + childSetVisible("search_editor", gSavedSettings.getBOOL("ShowSearchBar")); + childSetVisible("search_btn", gSavedSettings.getBOOL("ShowSearchBar")); + childSetActionTextbox("ParcelNameText", onClickParcelInfo ); childSetActionTextbox("BalanceText", onClickBalance ); + + // Adding Net Stat Graph + S32 x = mRect.getWidth() - 2; + S32 y = 0; + LLRect r; + r.set( x-SIM_STAT_WIDTH, y+MENU_BAR_HEIGHT-1, x, y+1); + mSGBandwidth = new LLStatGraph("BandwidthGraph", r); + mSGBandwidth->setFollows(FOLLOWS_BOTTOM | FOLLOWS_RIGHT); + mSGBandwidth->setStat(&gViewerStats->mKBitStat); + LLString text = childGetText("bandwidth_tooltip") + " "; + LLUIString bandwidth_tooltip = text; // get the text from XML until this widget is XML driven + mSGBandwidth->setLabel(bandwidth_tooltip.getString().c_str()); + mSGBandwidth->setUnits("Kbps"); + mSGBandwidth->setPrecision(0); + mSGBandwidth->setMouseOpaque(FALSE); + addChild(mSGBandwidth); + x -= SIM_STAT_WIDTH + 2; + + r.set( x-SIM_STAT_WIDTH, y+MENU_BAR_HEIGHT-1, x, y+1); + mSGPacketLoss = new LLStatGraph("PacketLossPercent", r); + mSGPacketLoss->setFollows(FOLLOWS_BOTTOM | FOLLOWS_RIGHT); + mSGPacketLoss->setStat(&gViewerStats->mPacketsLostPercentStat); + text = childGetText("packet_loss_tooltip") + " "; + LLUIString packet_loss_tooltip = text; // get the text from XML until this widget is XML driven + mSGPacketLoss->setLabel(packet_loss_tooltip.getString().c_str()); + mSGPacketLoss->setUnits("%"); + mSGPacketLoss->setMin(0.f); + mSGPacketLoss->setMax(5.f); + mSGPacketLoss->setThreshold(0, 0.5f); + mSGPacketLoss->setThreshold(1, 1.f); + mSGPacketLoss->setThreshold(2, 3.f); + mSGPacketLoss->setPrecision(1); + mSGPacketLoss->setMouseOpaque(FALSE); + mSGPacketLoss->mPerSec = FALSE; + addChild(mSGPacketLoss); + + childSetActionTextbox("stat_btn", onClickStatGraph); + } LLStatusBar::~LLStatusBar() @@ -212,6 +254,14 @@ void LLStatusBar::draw() // Per-frame updates of visibility void LLStatusBar::refresh() { + // Adding Net Stat Meter back in + F32 bwtotal = gViewerThrottle.getMaxBandwidth() / 1000.f; + mSGBandwidth->setMin(0.f); + mSGBandwidth->setMax(bwtotal*1.25f); + mSGBandwidth->setThreshold(0, bwtotal*0.75f); + mSGBandwidth->setThreshold(1, bwtotal); + mSGBandwidth->setThreshold(2, bwtotal); + // *TODO: Localize / translate time // Get current UTC time, adjusted for the user's clock @@ -262,6 +312,8 @@ void LLStatusBar::refresh() S32 x = MENU_RIGHT + MENU_PARCEL_SPACING; S32 y = 0; + bool search_visible = gSavedSettings.getBOOL("ShowSearchBar"); + // reshape menu bar to its content's width if (MENU_RIGHT != gMenuBarView->getRect().getWidth()) { @@ -534,14 +586,69 @@ void LLStatusBar::refresh() snprintf(mRegionDetails.mOwner, MAX_STRING, "Unknown"); mRegionDetails.mTraffic = 0.0f; } + mTextParcelName->setText(location_name); + + + // x = right edge + // loop through: stat graphs, search btn, search text editor, money, buy money, clock + // adjust rect + // finally adjust parcel name rect + + S32 new_right = getRect().getWidth(); + if (search_visible) + { + childGetRect("search_btn", r); + r.translate( new_right - r.mRight, 0); + childSetRect("search_btn", r); + new_right -= r.getWidth(); + + childGetRect("search_editor", r); + r.translate( new_right - r.mRight, 0); + childSetRect("search_editor", r); + new_right -= r.getWidth() + 6; + + } + else + { + childGetRect("stat_btn", r); + r.translate( new_right - r.mRight, 0); + childSetRect("stat_btn", r); + new_right -= r.getWidth() + 6; + } + + // Set rects of money, buy money, time + childGetRect("BalanceText", r); + r.translate( new_right - r.mRight, 0); + childSetRect("BalanceText", r); + new_right -= r.getWidth() - 18; + + childGetRect("buycurrency", r); + r.translate( new_right - r.mRight, 0); + childSetRect("buycurrency", r); + new_right -= r.getWidth() + 6; + + childGetRect("TimeText", r); + // mTextTime->getTextPixelWidth(); + r.translate( new_right - r.mRight, 0); + childSetRect("TimeText", r); + // new_right -= r.getWidth() + MENU_PARCEL_SPACING; + + // Adjust region name and parcel name x += 8; const S32 PARCEL_RIGHT = llmin(mTextTime->getRect().mLeft, mTextParcelName->getTextPixelWidth() + x + 5); r.set(x+4, mRect.getHeight() - 2, PARCEL_RIGHT, 0); mTextParcelName->setRect(r); + + // Set search bar visibility + childSetVisible("search_editor", search_visible); + childSetVisible("search_btn", search_visible); + mSGBandwidth->setVisible(! search_visible); + mSGPacketLoss->setVisible(! search_visible); + childSetEnabled("stat_btn", ! search_visible); } void LLStatusBar::setVisibleForMouselook(bool visible) @@ -551,6 +658,8 @@ void LLStatusBar::setVisibleForMouselook(bool visible) childSetVisible("buycurrency", visible); childSetVisible("search_editor", visible); childSetVisible("search_btn", visible); + mSGBandwidth->setVisible(visible); + mSGPacketLoss->setVisible(visible); setBackgroundVisible(visible); } @@ -662,7 +771,7 @@ static void onClickParcelInfo(void* data) { gParcelMgr->selectParcelAt(gAgent.getPositionGlobal()); - LLFloaterLand::show(); + LLFloaterLand::showInstance(); } static void onClickBalance(void* data) @@ -806,6 +915,12 @@ void LLStatusBar::onClickSearch(void* data) LLFloaterDirectory::showFindAll(search_text); } +// static +void LLStatusBar::onClickStatGraph(void* data) +{ + LLFloaterLagMeter::show(data); +} + BOOL can_afford_transaction(S32 cost) { return((cost <= 0)||((gStatusBar) && (gStatusBar->getBalance() >=cost))); diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h index d0f3e66fa9..78f744c4b5 100644 --- a/indra/newview/llstatusbar.h +++ b/indra/newview/llstatusbar.h @@ -120,6 +120,7 @@ private: static void onCommitSearch(LLUICtrl*, void* data); static void onClickSearch(void* data); + static void onClickStatGraph(void* data); private: LLTextBox *mTextBalance; @@ -128,6 +129,9 @@ private: LLTextBox* mTextParcelName; + LLStatGraph *mSGBandwidth; + LLStatGraph *mSGPacketLoss; + LLButton *mBtnBuyCurrency; S32 mBalance; diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index fa8213d662..0c88442fd2 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -35,6 +35,7 @@ #include "indra_constants.h" #include "llclickaction.h" +#include "llmediabase.h" // for status codes #include "llparcel.h" #include "llagent.h" @@ -54,14 +55,17 @@ #include "lltoolmgr.h" #include "lltoolselect.h" #include "llviewercamera.h" +#include "llviewerparcelmedia.h" #include "llviewermenu.h" -#include "llviewerobject.h" #include "llviewerobjectlist.h" +#include "llviewerobject.h" #include "llviewerparcelmgr.h" #include "llviewerwindow.h" +#include "llviewermedia.h" #include "llvoavatar.h" #include "llworld.h" #include "llui.h" +#include "llweb.h" LLToolPie *gToolPie = NULL; @@ -73,6 +77,11 @@ extern void handle_buy(void*); extern BOOL gDebugClicks; +static void handle_click_action_play(); +static void handle_click_action_open_media(LLPointer<LLViewerObject> objectp); +static ECursorType cursor_from_parcel_media(U8 click_action); + + LLToolPie::LLToolPie() : LLTool("Select"), mPieMouseButtonDown( FALSE ), @@ -87,6 +96,7 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask) { if (!gCamera) return FALSE; + gPickFaces = TRUE; //left mouse down always picks transparent gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, leftMouseCallback, TRUE, TRUE); @@ -137,7 +147,7 @@ BOOL LLToolPie::pickAndShowMenu(S32 x, S32 y, MASK mask, BOOL always_show) else { // not selling passes, get info - LLFloaterLand::show(); + LLFloaterLand::showInstance(); } } @@ -211,6 +221,13 @@ BOOL LLToolPie::pickAndShowMenu(S32 x, S32 y, MASK mask, BOOL always_show) sLeftClickSelection = LLToolSelect::handleObjectSelection(parent, MASK_NONE, FALSE, TRUE); } return TRUE; + case CLICK_ACTION_PLAY: + handle_click_action_play(); + return TRUE; + case CLICK_ACTION_OPEN_MEDIA: + // sClickActionObject = object; + handle_click_action_open_media(object); + return TRUE; } } @@ -411,6 +428,47 @@ U8 final_click_action(LLViewerObject* obj) return click_action; } +ECursorType cursor_from_object(LLViewerObject* object) +{ + LLViewerObject* parent = NULL; + if (object) + { + parent = object->getRootEdit(); + } + U8 click_action = final_click_action(object); + ECursorType cursor = UI_CURSOR_ARROW; + switch(click_action) + { + case CLICK_ACTION_SIT: + cursor = UI_CURSOR_TOOLSIT; + break; + case CLICK_ACTION_BUY: + cursor = UI_CURSOR_TOOLBUY; + break; + case CLICK_ACTION_OPEN: + // Open always opens the parent. + if (parent && parent->allowOpen()) + { + cursor = UI_CURSOR_TOOLOPEN; + } + break; + case CLICK_ACTION_PAY: + if ((object && object->flagTakesMoney()) + || (parent && parent->flagTakesMoney())) + { + cursor = UI_CURSOR_TOOLPAY; + } + break; + case CLICK_ACTION_PLAY: + case CLICK_ACTION_OPEN_MEDIA: + cursor = cursor_from_parcel_media(click_action); + break; + default: + break; + } + return cursor; +} + // When we get object properties after left-clicking on an object // with left-click = buy, if it's the same object, do the buy. // static @@ -486,28 +544,7 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask) if (object && useClickAction(FALSE, mask, object, parent)) { - U8 click_action = final_click_action(object); - ECursorType cursor = UI_CURSOR_ARROW; - switch(click_action) - { - default: break; - case CLICK_ACTION_SIT: cursor = UI_CURSOR_TOOLSIT; break; - case CLICK_ACTION_BUY: cursor = UI_CURSOR_TOOLBUY; break; - case CLICK_ACTION_OPEN: - // Open always opens the parent. - if (parent && parent->allowOpen()) - { - cursor = UI_CURSOR_TOOLOPEN; - } - break; - case CLICK_ACTION_PAY: - if ((object && object->flagTakesMoney()) - || (parent && parent->flagTakesMoney())) - { - cursor = UI_CURSOR_TOOLPAY; - } - break; - } + ECursorType cursor = cursor_from_object(object); gViewerWindow->getWindow()->setCursor(cursor); lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl; } @@ -677,4 +714,95 @@ void LLToolPie::render() return; } +static void handle_click_action_play() +{ + LLParcel* parcel = gParcelMgr->getAgentParcel(); + if (!parcel) return; + + LLMediaBase::EStatus status = LLViewerParcelMedia::getStatus(); + switch(status) + { + case LLMediaBase::STATUS_STARTED: + LLViewerParcelMedia::pause(); + break; + + case LLMediaBase::STATUS_PAUSED: + LLViewerParcelMedia::start(); + break; + + default: + LLViewerParcelMedia::play(parcel); + break; + } +} + +static void handle_click_action_open_media(LLPointer<LLViewerObject> objectp) +{ + //FIXME: how do we handle object in different parcel than us? + LLParcel* parcel = gParcelMgr->getAgentParcel(); + if (!parcel) return; + + // did we hit an object? + if (objectp.isNull()) return; + + // did we hit a valid face on the object? + if( gLastHitObjectFace < 0 || gLastHitObjectFace >= objectp->getNumTEs() ) return; + + // is media playing on this face? + if (!LLViewerMedia::isActiveMediaTexture(objectp->getTE(gLastHitObjectFace)->getID())) + { + handle_click_action_play(); + return; + } + + std::string media_url = std::string ( parcel->getMediaURL () ); + std::string media_type = std::string ( parcel->getMediaType() ); + LLString::trim(media_url); + + // Get the scheme, see if that is handled as well. + LLURI uri(media_url); + std::string media_scheme = uri.scheme() != "" ? uri.scheme() : "http"; + + // HACK: This is directly referencing an impl name. BAD! + // This can be removed when we have a truly generic media browser that only + // builds an impl based on the type of url it is passed. + if( LLMediaManager::getInstance()->supportsMediaType( "LLMediaImplLLMozLib", media_scheme, media_type ) ) + { + LLWeb::loadURL(media_url); + } +} + +static ECursorType cursor_from_parcel_media(U8 click_action) +{ + // HACK: This is directly referencing an impl name. BAD! + // This can be removed when we have a truly generic media browser that only + // builds an impl based on the type of url it is passed. + + //FIXME: how do we handle object in different parcel than us? + ECursorType open_cursor = UI_CURSOR_ARROW; + LLParcel* parcel = gParcelMgr->getAgentParcel(); + if (!parcel) return open_cursor; + + std::string media_url = std::string ( parcel->getMediaURL () ); + std::string media_type = std::string ( parcel->getMediaType() ); + LLString::trim(media_url); + + // Get the scheme, see if that is handled as well. + LLURI uri(media_url); + std::string media_scheme = uri.scheme() != "" ? uri.scheme() : "http"; + + if( LLMediaManager::getInstance()->supportsMediaType( "LLMediaImplLLMozLib", media_scheme, media_type ) ) + { + open_cursor = UI_CURSOR_TOOLMEDIAOPEN; + } + + LLMediaBase::EStatus status = LLViewerParcelMedia::getStatus(); + switch(status) + { + case LLMediaBase::STATUS_STARTED: + return click_action == CLICK_ACTION_PLAY ? UI_CURSOR_TOOLPAUSE : open_cursor; + default: + return UI_CURSOR_TOOLPLAY; + } +} diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp index 82b2b597ca..9e4f196601 100644 --- a/indra/newview/llurldispatcher.cpp +++ b/indra/newview/llurldispatcher.cpp @@ -39,6 +39,7 @@ #include "llfloaterdirectory.h" #include "llfloaterhtml.h" #include "llfloaterworldmap.h" +#include "llfloaterhtmlhelp.h" #include "llpanellogin.h" #include "llstartup.h" // gStartupState #include "llurlsimstring.h" @@ -159,9 +160,7 @@ bool LLURLDispatcherImpl::dispatchHelp(const std::string& url, BOOL right_mouse) { if (matchPrefix(url, SLURL_SL_HELP_PREFIX)) { -#if LL_LIBXUL_ENABLED gViewerHtmlHelp.show(); -#endif // LL_LIBXUL_ENABLED return true; } return false; diff --git a/indra/newview/llurlhistory.cpp b/indra/newview/llurlhistory.cpp new file mode 100644 index 0000000000..86a12a73fa --- /dev/null +++ b/indra/newview/llurlhistory.cpp @@ -0,0 +1,110 @@ +/** + * @file llurlhistory.cpp + * @author Sam Kolb + * @brief Manages a list of recent URLs + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +#include "llviewerprecompiledheaders.h" + +#include "llurlhistory.h" + +#include "lldir.h" +#include "llsdserialize.h" + +LLSD LLURLHistory::sHistorySD; + +const int MAX_URL_COUNT = 10; + +///////////////////////////////////////////////////////////////////////////// + +// static +bool LLURLHistory::loadFile(const LLString& filename) +{ + LLSD data; + { + LLString temp_str = gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter(); + + llifstream file((temp_str + filename).c_str()); + + if (file.is_open()) + { + llinfos << "Loading history.xml file at " << filename << llendl; + LLSDSerialize::fromXML(data, file); + } + + if (data.isUndefined()) + { + llinfos << "file missing, ill-formed, " + "or simply undefined; not changing the" + " file" << llendl; + return false; + } + } + sHistorySD = data; + return true; +} + +// static +bool LLURLHistory::saveFile(const LLString& filename) +{ + LLString temp_str = gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter(); + llofstream out((temp_str + filename).c_str()); + if (!out.good()) + { + llwarns << "Unable to open " << filename << " for output." << llendl; + return false; + } + + LLSDSerialize::toXML(sHistorySD, out); + + out.close(); + return true; +} +// static +// This function returns a portion of the history llsd that contains the collected +// url history +LLSD LLURLHistory::getURLHistory(const std::string& collection) +{ + if(sHistorySD.has(collection)) + { + return sHistorySD[collection]; + } + return LLSD(); +} + +// static +void LLURLHistory::addURL(const std::string& collection, const std::string& url) +{ + sHistorySD[collection].insert(0, url); + LLURLHistory::limitSize(collection); +} +// static +void LLURLHistory::removeURL(const std::string& collection, const std::string& url) +{ + LLSD::array_iterator iter = sHistorySD[collection].beginArray(); + LLSD::array_iterator end = sHistorySD[collection].endArray(); + for(int index = 0; index < sHistorySD[collection].size(); index++) + { + if(sHistorySD[collection].get(index).asString() == url) + { + sHistorySD[collection].erase(index); + } + } +} + +// static +void LLURLHistory::clear(const std::string& collection) +{ + sHistorySD[ collection ] = LLSD(); +} + +void LLURLHistory::limitSize(const std::string& collection) +{ + while(sHistorySD[collection].size() > MAX_URL_COUNT) + { + sHistorySD[collection].erase(MAX_URL_COUNT); + } +} + diff --git a/indra/newview/llurlhistory.h b/indra/newview/llurlhistory.h new file mode 100644 index 0000000000..210057f746 --- /dev/null +++ b/indra/newview/llurlhistory.h @@ -0,0 +1,37 @@ +/** + * @file llurlhistory.h + * @author Sam Kolb + * @brief Manages a list of recent URLs + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +#ifndef LLURLHISTORY_H +#define LLURLHISTORY_H + +#include "llstring.h" + +class LLSD; + +class LLURLHistory +{ +public: + // Loads an xml file of URLs. Currently only supports Parcel URL history + static bool loadFile(const LLString& filename); + + // Saves the current history to XML + static bool saveFile(const LLString& filename); + + static LLSD getURLHistory(const std::string& collection); + + static void addURL(const std::string& collection, const std::string& url); + static void removeURL(const std::string& collection, const std::string& url); + static void clear(const std::string& collection); + + static void limitSize(const std::string& collection); + +private: + static LLSD sHistorySD; +}; + +#endif // LLURLHISTORY_H diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp index b8c8e62c4b..affce91b79 100644 --- a/indra/newview/llvieweraudio.cpp +++ b/indra/newview/llvieweraudio.cpp @@ -35,12 +35,12 @@ #include "audiosettings.h" #include "llagent.h" #include "llappviewer.h" -#include "llmediaengine.h" #include "llvieweraudio.h" #include "llviewercamera.h" #include "llviewercontrol.h" #include "llviewerwindow.h" #include "llvoiceclient.h" +#include "llviewermedia.h" ///////////////////////////////////////////////////////// @@ -153,13 +153,10 @@ void audio_update_volume(bool force_update) } // Streaming Media - if(LLMediaEngine::getInstance()) - { - F32 media_volume = gSavedSettings.getF32("AudioLevelMedia"); - media_volume = mute_volume * master_volume * (media_volume*media_volume); - BOOL media_muted = gSavedSettings.getBOOL("MuteMedia"); - LLMediaEngine::getInstance()->setVolume(media_muted ? 0.f : media_volume); - } + F32 media_volume = gSavedSettings.getF32("AudioLevelMedia"); + BOOL media_muted = gSavedSettings.getBOOL("MuteMedia"); + media_volume = mute_volume * master_volume * (media_volume*media_volume); + LLViewerMedia::setVolume( media_muted ? 0.0f : media_volume ); // Voice if (gVoiceClient) diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 250b250a7a..7180683a86 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -261,7 +261,6 @@ void LLFloaterSettingsDebug::updateControl(LLControlBase* controlp) spinner4->setVisible(FALSE); color_swatch->setVisible(FALSE); childSetVisible("val_text", FALSE); - childSetVisible("boolean_combo", FALSE); mComment->setText(LLString::null); if (controlp) @@ -299,6 +298,7 @@ void LLFloaterSettingsDebug::updateControl(LLControlBase* controlp) case TYPE_U32: spinner1->setVisible(TRUE); spinner1->setLabel(LLString("value")); // Debug, don't translate + childSetVisible("boolean_combo", FALSE); if (!spinner1->hasFocus()) { spinner1->setValue(sd); @@ -311,6 +311,7 @@ void LLFloaterSettingsDebug::updateControl(LLControlBase* controlp) case TYPE_S32: spinner1->setVisible(TRUE); spinner1->setLabel(LLString("value")); // Debug, don't translate + childSetVisible("boolean_combo", FALSE); if (!spinner1->hasFocus()) { spinner1->setValue(sd); @@ -323,6 +324,7 @@ void LLFloaterSettingsDebug::updateControl(LLControlBase* controlp) case TYPE_F32: spinner1->setVisible(TRUE); spinner1->setLabel(LLString("value")); // Debug, don't translate + childSetVisible("boolean_combo", FALSE); if (!spinner1->hasFocus()) { spinner1->setPrecision(3); @@ -346,6 +348,7 @@ void LLFloaterSettingsDebug::updateControl(LLControlBase* controlp) break; case TYPE_STRING: childSetVisible("val_text", TRUE); + childSetVisible("boolean_combo", FALSE); if (!childHasFocus("val_text")) { childSetValue("val_text", sd); @@ -353,6 +356,7 @@ void LLFloaterSettingsDebug::updateControl(LLControlBase* controlp) break; case TYPE_VEC3: { + childSetVisible("boolean_combo", FALSE); LLVector3 v; v.setValue(sd); spinner1->setVisible(TRUE); @@ -380,6 +384,7 @@ void LLFloaterSettingsDebug::updateControl(LLControlBase* controlp) } case TYPE_VEC3D: { + childSetVisible("boolean_combo", FALSE); LLVector3d v; v.setValue(sd); spinner1->setVisible(TRUE); @@ -407,6 +412,7 @@ void LLFloaterSettingsDebug::updateControl(LLControlBase* controlp) } case TYPE_RECT: { + childSetVisible("boolean_combo", FALSE); LLRect r; r.setValue(sd); spinner1->setVisible(TRUE); @@ -457,6 +463,7 @@ void LLFloaterSettingsDebug::updateControl(LLControlBase* controlp) } case TYPE_COL4: { + childSetVisible("boolean_combo", FALSE); LLColor4 clr; clr.setValue(sd); color_swatch->setVisible(TRUE); @@ -478,6 +485,7 @@ void LLFloaterSettingsDebug::updateControl(LLControlBase* controlp) } case TYPE_COL3: { + childSetVisible("boolean_combo", FALSE); LLColor3 clr; clr.setValue(sd); color_swatch->setVisible(TRUE); @@ -486,6 +494,7 @@ void LLFloaterSettingsDebug::updateControl(LLControlBase* controlp) } case TYPE_COL4U: { + childSetVisible("boolean_combo", FALSE); LLColor4U clr; clr.setValue(sd); color_swatch->setVisible(TRUE); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp new file mode 100644 index 0000000000..7a86b1d67c --- /dev/null +++ b/indra/newview/llviewermedia.cpp @@ -0,0 +1,608 @@ +/** + * @file llviewermedia.cpp + * @author Callum Prentice & James Cook + * @brief Client interface to the media engine + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +#include "llviewerprecompiledheaders.h" + +#include "llviewermedia.h" + +#include "llmimetypes.h" +#include "llviewercontrol.h" +#include "llviewerimage.h" +#include "llviewerwindow.h" +#include "llversionviewer.h" +#include "llviewerimagelist.h" + +#include "llevent.h" // LLSimpleListener +#include "llmediamanager.h" +#include "lluuid.h" + +// don't want to include llappviewer.h +extern std::string gChannelName; + +// Implementation functions not exported into header file +class LLViewerMediaImpl + : public LLMediaObserver +{ + public: + LLViewerMediaImpl() + : mMediaSource( NULL ), + mMovieImageID(), + mMovieImageHasMips(false) + { } + + void initControlListeners(); + + void destroyMediaSource(); + + void play(const std::string& media_url, + const std::string& mime_type, + const LLUUID& placeholder_texture_id, + S32 media_width, S32 media_height, U8 media_auto_scale, + U8 media_loop); + + void stop(); + void pause(); + void start(); + void seek(F32 time); + void setVolume(F32 volume); + LLMediaBase::EStatus getStatus(); + + /*virtual*/ void onMediaSizeChange(const EventType& event_in); + /*virtual*/ void onMediaContentsChange(const EventType& event_in); + + void updateMovieImage(const LLUUID& image_id, BOOL active); + void updateImagesMediaStreams(); + LLUUID getMediaTextureID(); + + public: + + // a single media url with some data and an impl. + LLMediaBase* mMediaSource; + LLUUID mMovieImageID; + bool mMovieImageHasMips; + std::string mMediaURL; + std::string mMimeType; + private: + void initializePlaceholderImage(LLViewerImage *placeholder_image, LLMediaBase *media_source); +}; + +static LLViewerMediaImpl sViewerMediaImpl; + +void LLViewerMediaImpl::destroyMediaSource() +{ + LLMediaManager* mgr = LLMediaManager::getInstance(); + if ( mMediaSource ) + { + bool was_playing = LLViewerMedia::isMediaPlaying(); + mMediaSource->remObserver(this); + mgr->destroySource( mMediaSource ); + + // Restore the texture + updateMovieImage(LLUUID::null, was_playing); + + } + mMediaSource = NULL; +} + +void LLViewerMediaImpl::play(const std::string& media_url, + const std::string& mime_type, + const LLUUID& placeholder_texture_id, + S32 media_width, S32 media_height, U8 media_auto_scale, + U8 media_loop) +{ + // first stop any previously playing media + stop(); + + // Save this first, as init/load below may fire events + mMovieImageID = placeholder_texture_id; + + // If the mime_type passed in is different than the cached one, and + // Auto-discovery is turned OFF, replace the cached mime_type with the new one. + if(mime_type != mMimeType && + ! gSavedSettings.getBOOL("AutoMimeDiscovery")) + { + mMimeType = mime_type; + } + LLURI url(media_url); + std::string scheme = url.scheme() != "" ? url.scheme() : "http"; + + LLMediaManager* mgr = LLMediaManager::getInstance(); + mMediaSource = mgr->createSourceFromMimeType(scheme, mMimeType ); + if ( !mMediaSource ) + { + llwarns << "media source create failed " << media_url + << " type " << mMimeType + << llendl; + return; + } + + if ((media_width != 0) && (media_height != 0)) + { + mMediaSource->setRequestedMediaSize(media_width, media_height); + } + + mMediaSource->setLooping(media_loop); + mMediaSource->setAutoScaled(media_auto_scale); + mMediaSource->addObserver( this ); + mMediaSource->navigateTo( media_url ); + mMediaSource->addCommand(LLMediaBase::COMMAND_START); + + // Store the URL and Mime Type + mMediaURL = media_url; + +} + +void LLViewerMediaImpl::stop() +{ + destroyMediaSource(); +} + +void LLViewerMediaImpl::pause() +{ + if(mMediaSource) + { + mMediaSource->addCommand(LLMediaBase::COMMAND_PAUSE); + } +} + +void LLViewerMediaImpl::start() +{ + if(mMediaSource) + { + mMediaSource->addCommand(LLMediaBase::COMMAND_START); + } +} + +void LLViewerMediaImpl::seek(F32 time) +{ + if(mMediaSource) + { + mMediaSource->seek(time); + } +} + +void LLViewerMediaImpl::setVolume(F32 volume) +{ + if(mMediaSource) + { + mMediaSource->setVolume( volume); + } +} + +LLMediaBase::EStatus LLViewerMediaImpl::getStatus() +{ + if (mMediaSource) + { + return mMediaSource->getStatus(); + } + else + { + return LLMediaBase::STATUS_UNKNOWN; + } +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMediaImpl::updateMovieImage(const LLUUID& uuid, BOOL active) +{ + // IF the media image hasn't changed, do nothing + if (mMovieImageID == uuid) + { + return; + } + // If we have changed media uuid, restore the old one + if (!mMovieImageID.isNull()) + { + LLViewerImage* oldImage = LLViewerImage::getImage( mMovieImageID ); + if (oldImage) + { + oldImage->reinit(mMovieImageHasMips); + oldImage->mIsMediaTexture = FALSE; + } + mMovieImageID.setNull(); + } + // If the movie is playing, set the new media image + if (active && !uuid.isNull()) + { + LLViewerImage* viewerImage = LLViewerImage::getImage( uuid ); + if( viewerImage ) + { + mMovieImageID = uuid; + // Can't use mipmaps for movies because they don't update the full image + mMovieImageHasMips = viewerImage->getUseMipMaps(); + viewerImage->reinit(FALSE); + viewerImage->mIsMediaTexture = TRUE; + } + } +} + + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMediaImpl::updateImagesMediaStreams() +{ + LLMediaManager::updateClass(); +} + +void LLViewerMediaImpl::initializePlaceholderImage(LLViewerImage *placeholder_image, LLMediaBase *media_source) +{ + int media_width = media_source->getMediaWidth(); + int media_height = media_source->getMediaHeight(); + //int media_rowspan = media_source->getMediaRowSpan(); + + // if width & height are invalid, don't bother doing anything + if ( media_width < 1 || media_height < 1 ) + return; + + llinfos << "initializing media placeholder" << llendl; + llinfos << "movie image id " << mMovieImageID << llendl; + + int texture_width = LLMediaManager::textureWidthFromMediaWidth( media_width ); + int texture_height = LLMediaManager::textureHeightFromMediaHeight( media_height ); + int texture_depth = media_source->getMediaDepth(); + + // MEDIAOPT: check to see if size actually changed before doing work + placeholder_image->destroyGLTexture(); + // MEDIAOPT: apparently just calling setUseMipMaps(FALSE) doesn't work? + placeholder_image->reinit(FALSE); // probably not needed + + // MEDIAOPT: seems insane that we actually have to make an imageraw then + // immediately discard it + LLPointer<LLImageRaw> raw = new LLImageRaw(texture_width, texture_height, texture_depth); + raw->clear(0x0f, 0x0f, 0x0f, 0xff); + int discard_level = 0; + + // ask media source for correct GL image format constants + placeholder_image->setExplicitFormat(media_source->getTextureFormatInternal(), + media_source->getTextureFormatPrimary(), + media_source->getTextureFormatType()); + + placeholder_image->createGLTexture(discard_level, raw); + + // placeholder_image->setExplicitFormat() + placeholder_image->setUseMipMaps(FALSE); + + // MEDIAOPT: set this dynamically on play/stop + placeholder_image->mIsMediaTexture = true; +} + + + +// virtual +void LLViewerMediaImpl::onMediaContentsChange(const EventType& event_in) +{ + LLMediaBase* media_source = event_in.getSubject(); + LLViewerImage* placeholder_image = gImageList.getImage( mMovieImageID ); + if ((placeholder_image) && (placeholder_image->getHasGLTexture())) + { + if (placeholder_image->getUseMipMaps()) + { + // bad image! NO MIPMAPS! + initializePlaceholderImage(placeholder_image, media_source); + } + + U8* data = media_source->getMediaData(); + S32 x_pos = 0; + S32 y_pos = 0; + S32 width = media_source->getMediaWidth(); + S32 height = media_source->getMediaHeight(); + S32 data_width = media_source->getMediaDataWidth(); + S32 data_height = media_source->getMediaDataHeight(); + placeholder_image->setSubImage(data, data_width, data_height, + x_pos, y_pos, width, height); + } +} + + +// virtual +void LLViewerMediaImpl::onMediaSizeChange(const EventType& event_in) +{ + LLMediaBase* media_source = event_in.getSubject(); + LLViewerImage* placeholder_image = gImageList.getImage( mMovieImageID ); + if (placeholder_image) + { + initializePlaceholderImage(placeholder_image, media_source); + } + else + { + llinfos << "no placeholder image" << llendl; + } +} + + + // Get the image we're using + + /* + // update media stream if required + LLMediaEngine* media_engine = LLMediaEngine::getInstance(); + if (media_engine) + { + if ( media_engine->update() ) + { + LLUUID media_uuid = media_engine->getImageUUID(); + updateMovieImage(media_uuid, TRUE); + if (!media_uuid.isNull()) + { + LLViewerImage* viewerImage = getImage( media_uuid ); + if( viewerImage ) + { + LLMediaBase* renderer = media_engine->getMediaRenderer(); + if ((renderer->getTextureWidth() != viewerImage->getWidth()) || + (renderer->getTextureHeight() != viewerImage->getHeight()) || + (renderer->getTextureDepth() != viewerImage->getComponents()) || + (viewerImage->getHasGLTexture() == FALSE)) + { + // destroy existing GL image + viewerImage->destroyGLTexture(); + + // set new size + viewerImage->setSize( renderer->getTextureWidth(), + renderer->getTextureHeight(), + renderer->getTextureDepth() ); + + LLPointer<LLImageRaw> raw = new LLImageRaw(renderer->getTextureWidth(), + renderer->getTextureHeight(), + renderer->getTextureDepth()); + raw->clear(0x7f,0x7f,0x7f,0xff); + viewerImage->createGLTexture(0, raw); + } + + // Set the explicit format the instance wants + viewerImage->setExplicitFormat(renderer->getTextureFormatInternal(), + renderer->getTextureFormatPrimary(), + renderer->getTextureFormatType(), + renderer->getTextureFormatSwapBytes()); + // This should be redundant, but just in case: + viewerImage->setUseMipMaps(FALSE); + + LLImageRaw* rawImage = media_engine->getImageRaw(); + if ( rawImage ) + { + viewerImage->setSubImage(rawImage, 0, 0, + renderer->getMediaWidth(), + renderer->getMediaHeight()); + } + } + else + { + llwarns << "MediaEngine update unable to get viewer image for GL texture" << llendl; + } + } + } + else + { + LLUUID media_uuid = media_engine->getImageUUID(); + updateMovieImage(media_uuid, FALSE); + } + } + */ + + +////////////////////////////////////////////////////////////////////////////////////////// +LLUUID LLViewerMediaImpl::getMediaTextureID() +{ + return mMovieImageID; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// Wrapper class +////////////////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::initClass() +{ + LLMediaManagerData* init_data = new LLMediaManagerData; + +// std::string executable_dir = std::string( arg0 ).substr( 0, std::string( arg0 ).find_last_of("\\/") ); +// std::string component_dir = std::string( executable_dir ).substr( 0, std::string( executable_dir ).find_last_of("\\/") ); +// component_dir = std::string( component_dir ).substr( 0, std::string( component_dir ).find_last_of("\\/") ); +// component_dir = std::string( component_dir ).substr( 0, std::string( component_dir ).find_last_of("\\/") ); +// component_dir += "\\newview\\app_settings\\mozilla"; + + +#if LL_DARWIN + // For Mac OS, we store both the shared libraries and the runtime files (chrome/, plugins/, etc) in + // Second Life.app/Contents/MacOS/. This matches the way Firefox is distributed on the Mac. + std::string component_dir(gDirUtilp->getExecutableDir()); +#elif LL_WINDOWS + std::string component_dir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) ); + component_dir += gDirUtilp->getDirDelimiter(); + #ifdef LL_DEBUG + component_dir += "mozilla_debug"; + #else // LL_DEBUG + component_dir += "mozilla"; + #endif // LL_DEBUG +#elif LL_LINUX + std::string component_dir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) ); + component_dir += gDirUtilp->getDirDelimiter(); + component_dir += "mozilla-runtime-linux-i686"; +#else + std::string component_dir( gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "" ) ); + component_dir += gDirUtilp->getDirDelimiter(); + component_dir += "mozilla"; +#endif + + // append our magic version number string to the browser user agent id + std::ostringstream codec; + codec << "[Second Life "; + codec << "(" << gChannelName << ")"; + codec << " - " << LL_VERSION_MAJOR << "." << LL_VERSION_MINOR << "." << LL_VERSION_PATCH << "." << LL_VERSION_BUILD; + codec << "]"; + init_data->setBrowserUserAgentId( codec.str() ); + + std::string application_dir = gDirUtilp->getExecutableDir(); + + init_data->setBrowserApplicationDir( application_dir ); + std::string profile_dir = gDirUtilp->getExpandedFilename( LL_PATH_MOZILLA_PROFILE, "" ); + init_data->setBrowserProfileDir( profile_dir ); + init_data->setBrowserComponentDir( component_dir ); + std::string profile_name("Second Life"); + init_data->setBrowserProfileName( profile_name ); + init_data->setBrowserParentWindow( gViewerWindow->getPlatformWindow() ); + + LLMediaManager::initClass( init_data ); + + LLMediaManager* mm = LLMediaManager::getInstance(); + LLMIMETypes::mime_info_map_t::const_iterator it; + for (it = LLMIMETypes::sMap.begin(); it != LLMIMETypes::sMap.end(); ++it) + { + const LLString& mime_type = it->first; + const LLMIMETypes::LLMIMEInfo& info = it->second; + mm->addMimeTypeImplNameMap( mime_type, info.mImpl ); + } +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::cleanupClass() +{ + LLMediaManager::cleanupClass(); +} + +// static +void LLViewerMedia::play(const std::string& media_url, + const std::string& mime_type, + const LLUUID& placeholder_texture_id, + S32 media_width, S32 media_height, U8 media_auto_scale, + U8 media_loop) +{ + sViewerMediaImpl.play(media_url, mime_type, placeholder_texture_id, + media_width, media_height, media_auto_scale, media_loop); +} + +// static +void LLViewerMedia::stop() +{ + sViewerMediaImpl.stop(); +} + +// static +void LLViewerMedia::pause() +{ + sViewerMediaImpl.pause(); +} + +// static +void LLViewerMedia::start() +{ + sViewerMediaImpl.start(); +} + +// static +void LLViewerMedia::seek(F32 time) +{ + sViewerMediaImpl.seek(time); +} + +// static +void LLViewerMedia::setVolume(F32 volume) +{ + sViewerMediaImpl.setVolume(volume); +} + +// static +LLMediaBase::EStatus LLViewerMedia::getStatus() +{ + return sViewerMediaImpl.getStatus(); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +LLUUID LLViewerMedia::getMediaTextureID() +{ + return sViewerMediaImpl.getMediaTextureID(); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::getMediaSize(S32 *media_width, S32 *media_height) +{ + // make sure we're valid + + if ( sViewerMediaImpl.mMediaSource != NULL ) + { + *media_width = sViewerMediaImpl.mMediaSource->getMediaWidth(); + *media_height = sViewerMediaImpl.mMediaSource->getMediaHeight(); + return true; + } + return false; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::getTextureSize(S32 *texture_width, S32 *texture_height) +{ + if ( sViewerMediaImpl.mMediaSource != NULL ) + { + S32 media_width = sViewerMediaImpl.mMediaSource->getMediaWidth(); + S32 media_height = sViewerMediaImpl.mMediaSource->getMediaHeight(); + *texture_width = LLMediaManager::textureWidthFromMediaWidth( media_width ); + *texture_height = LLMediaManager::textureHeightFromMediaHeight( media_height ); + return true; + } + return false; +} + + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::updateImagesMediaStreams() +{ + sViewerMediaImpl.updateImagesMediaStreams(); +} +////////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::isMediaPlaying() +{ + LLMediaBase::EStatus status = sViewerMediaImpl.getStatus(); + return (status == LLMediaBase::STATUS_STARTED ); +} +////////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::isMediaPaused() +{ + LLMediaBase::EStatus status = sViewerMediaImpl.getStatus(); + return (status == LLMediaBase::STATUS_PAUSED); +} +////////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::hasMedia() +{ + return sViewerMediaImpl.mMediaSource != NULL; +} + +////////////////////////////////////////////////////////////////////////////////////////// +//static +bool LLViewerMedia::isActiveMediaTexture(const LLUUID& id) +{ + return (id.notNull() + && id == getMediaTextureID() + && isMediaPlaying()); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +std::string LLViewerMedia::getMediaURL() +{ + return sViewerMediaImpl.mMediaURL; +} +////////////////////////////////////////////////////////////////////////////////////////// +// static +std::string LLViewerMedia::getMimeType() +{ + return sViewerMediaImpl.mMimeType; +} +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::setMimeType(std::string mime_type) +{ + sViewerMediaImpl.mMimeType = mime_type; +} + + diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h new file mode 100644 index 0000000000..6ecaea54ce --- /dev/null +++ b/indra/newview/llviewermedia.h @@ -0,0 +1,49 @@ +/** + * @file llviewermedia.h + * @author Callum Prentice & James Cook + * @brief Client interface to the media engine + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +#ifndef LLVIEWERMEDIA_H +#define LLVIEWERMEDIA_H + +#include "llmediabase.h" // for status codes + +class LLUUID; + +class LLViewerMedia +{ + public: + static void initClass(); + static void cleanupClass(); + + static void play(const std::string& media_url, + const std::string& mime_type, + const LLUUID& placeholder_texture_id, + S32 media_width, S32 media_height, U8 media_auto_scale, + U8 media_loop); + static void stop(); + static void pause(); + static void start(); + static void seek(F32 time); + static void setVolume(F32 volume); + static LLMediaBase::EStatus getStatus(); + + static LLUUID getMediaTextureID(); + static bool getMediaSize(S32 *media_width, S32 *media_height); + static bool getTextureSize(S32 *texture_width, S32 *texture_height); + static bool isMediaPlaying(); + static bool isMediaPaused(); + static bool hasMedia(); + static bool isActiveMediaTexture(const LLUUID& id); + + static std::string getMediaURL(); + static std::string getMimeType(); + static void setMimeType(std::string mime_type); + + static void updateImagesMediaStreams(); +}; + +#endif // LLVIEWERMEDIA_H diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index f732b0fda0..9c94306fb7 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -104,6 +104,7 @@ #include "llfloatergroupinvite.h" #include "llfloatergroups.h" #include "llfloaterhtml.h" +#include "llfloaterhtmlhelp.h" #include "llfloaterinspect.h" #include "llfloaterlagmeter.h" #include "llfloaterland.h" @@ -5340,7 +5341,7 @@ class LLShowFloater : public view_listener_t gParcelMgr->selectParcelAt(gAgent.getPositionGlobal()); } - LLFloaterLand::show(); + LLFloaterLand::showInstance(); } else if (floater_name == "buy land") { @@ -5365,25 +5366,19 @@ class LLShowFloater : public view_listener_t } else if (floater_name == "help f1") { -#if LL_LIBXUL_ENABLED gViewerHtmlHelp.show( gSavedSettings.getString("HelpHomeURL") ); -#endif } else if (floater_name == "help in-world") { -#if LL_LIBXUL_ENABLED const bool open_app_slurls = true; LLFloaterHtml::getInstance()->show( "in-world_help", open_app_slurls ); -#endif } else if (floater_name == "help additional") { -#if LL_LIBXUL_ENABLED const bool open_app_slurls = true; LLFloaterHtml::getInstance()->show( "additional_help", open_app_slurls ); -#endif } else if (floater_name == "complaint reporter") { diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 6b18fb46be..5e3ffb5e04 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -5039,7 +5039,7 @@ void callback_load_url(S32 option, void* data) if (0 == option) { - LLWeb::loadURL(infop->mUrl); + LLWeb::loadURL(infop->mUrl); } delete infop; diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index f2ddc173a0..42124610eb 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -156,8 +156,6 @@ public: // Return codes for processUpdateMessage enum { MEDIA_URL_REMOVED = 0x1, MEDIA_URL_ADDED = 0x2, MEDIA_URL_UPDATED = 0x4 }; - enum { CLICK_ACTION_TOUCH = 0, CLICK_ACTION_SIT = 1, CLICK_ACTION_BUY = 2 }; - virtual U32 processUpdateMessage(LLMessageSystem *mesgsys, void **user_data, U32 block_num, diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp new file mode 100644 index 0000000000..33c8ed919c --- /dev/null +++ b/indra/newview/llviewerparcelmedia.cpp @@ -0,0 +1,340 @@ +/** + * @file llviewerparcelmedia.cpp + * @author Callum Prentice & James Cook + * @brief Handlers for multimedia on a per-parcel basis + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +#include "llviewerprecompiledheaders.h" +#include "llviewerparcelmedia.h" + +#include "llagent.h" +#include "llviewercontrol.h" +#include "llviewermedia.h" +#include "llviewerregion.h" +#include "llparcel.h" +#include "llviewerparcelmgr.h" +#include "lluuid.h" +#include "message.h" +#include "llviewerparcelmediaautoplay.h" +#include "llfirstuse.h" + +// Static Variables + +S32 LLViewerParcelMedia::sMediaParcelLocalID = 0; +LLUUID LLViewerParcelMedia::sMediaRegionID; + +// Move this to its own file. +// 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 +{ +public: + LLMimeDiscoveryResponder( ) + {} + + + + virtual void completedHeader(U32 status, const std::string& reason, const LLSD& content) + { + std::string media_type = content["content-type"].asString(); + std::string::size_type idx1 = media_type.find_first_of(";"); + std::string mime_type = media_type.substr(0, idx1); + completeAny(status, mime_type); + } + + virtual void error( U32 status, const std::string& reason ) + { + completeAny(status, "none/none"); + } + + void completeAny(U32 status, const std::string& mime_type) + { + LLViewerMedia::setMimeType(mime_type); + } +}; + +// static +void LLViewerParcelMedia::initClass() +{ + LLMessageSystem* msg = gMessageSystem; + msg->setHandlerFunc("ParcelMediaCommandMessage", processParcelMediaCommandMessage ); + msg->setHandlerFunc("ParcelMediaUpdate", processParcelMediaUpdate ); + LLViewerParcelMediaAutoPlay::initClass(); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerParcelMedia::update(LLParcel* parcel) +{ + if (/*LLViewerMedia::hasMedia()*/ true) + { + // we have a player + if (parcel) + { + // we're in a parcel + bool new_parcel = false; + S32 parcelid = parcel->getLocalID(); + LLUUID regionid = gAgent.getRegion()->getRegionID(); + if (parcelid != sMediaParcelLocalID || regionid != sMediaRegionID) + { + sMediaParcelLocalID = parcelid; + sMediaRegionID = regionid; + new_parcel = true; + } + + std::string mediaUrl = std::string ( parcel->getMediaURL () ); + LLString::trim(mediaUrl); + + // has something changed? + if ( ( LLViewerMedia::getMediaURL() != mediaUrl ) + || ( LLViewerMedia::getMediaTextureID() != parcel->getMediaID () ) ) + { + bool video_was_playing = FALSE; + bool same_media_id = LLViewerMedia::getMediaTextureID() == parcel->getMediaID (); + + if (LLViewerMedia::isMediaPlaying()) + { + video_was_playing = TRUE; + } + + if ( !mediaUrl.empty() && same_media_id && ! new_parcel) + { + // Someone has "changed the channel", changing the URL of a video + // you were already watching. Automatically play provided the texture ID is the same + if (video_was_playing) + { + // Poke the mime type in before calling play. + // This is necessary because in this instance we are not waiting + // for the results of a header curl. In order to change the channel + // a mime type MUST be provided. + LLViewerMedia::setMimeType(parcel->getMediaType()); + play(parcel); + } + } + else + { + stop(); + } + + // Discover the MIME type + // Disabled for the time being. Get the mime type from the parcel. + if(gSavedSettings.getBOOL("AutoMimeDiscovery")) + { + LLHTTPClient::getHeaderOnly( mediaUrl, new LLMimeDiscoveryResponder()); + } + else + { + LLViewerMedia::setMimeType(parcel->getMediaType()); + } + + } + } + else + { + stop(); + } + } + /* + else + { + // no audio player, do a first use dialog if their is media here + if (parcel) + { + std::string mediaUrl = std::string ( parcel->getMediaURL () ); + if (!mediaUrl.empty ()) + { + if (gSavedSettings.getWarning("QuickTimeInstalled")) + { + gSavedSettings.setWarning("QuickTimeInstalled", FALSE); + + LLNotifyBox::showXml("NoQuickTime" ); + }; + } + } + } + */ +} + +// static +void LLViewerParcelMedia::play(LLParcel* parcel) +{ + llinfos << "play" << llendl; + + if (!parcel) return; + + if (!gSavedSettings.getBOOL("AudioStreamingVideo")) + return; + + std::string media_url = parcel->getMediaURL(); + std::string mime_type = parcel->getMediaType(); + LLUUID placeholder_texture_id = parcel->getMediaID(); + U8 media_auto_scale = parcel->getMediaAutoScale(); + U8 media_loop = parcel->getMediaLoop(); + S32 media_width = parcel->getMediaWidth(); + S32 media_height = parcel->getMediaHeight(); + LLViewerMedia::play(media_url, mime_type, placeholder_texture_id, + media_width, media_height, media_auto_scale, + media_loop); + LLFirstUse::useMedia(); + + LLViewerParcelMediaAutoPlay::playStarted(); +} + +// static +void LLViewerParcelMedia::stop() +{ + + LLViewerMedia::stop(); +} + +// static +void LLViewerParcelMedia::pause() +{ + LLViewerMedia::pause(); +} + +// static +void LLViewerParcelMedia::start() +{ + LLViewerMedia::start(); + LLFirstUse::useMedia(); + + LLViewerParcelMediaAutoPlay::playStarted(); +} + +// static +void LLViewerParcelMedia::seek(F32 time) +{ + LLViewerMedia::seek(time); +} + + +// static +LLMediaBase::EStatus LLViewerParcelMedia::getStatus() +{ + return LLViewerMedia::getStatus(); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerParcelMedia::processParcelMediaCommandMessage( LLMessageSystem *msg, void ** ) +{ + // extract the agent id + // LLUUID agent_id; + // msg->getUUID( agent_id ); + + U32 flags; + U32 command; + F32 time; + msg->getU32( "CommandBlock", "Flags", flags ); + msg->getU32( "CommandBlock", "Command", command); + msg->getF32( "CommandBlock", "Time", time ); + + if (flags &( (1<<PARCEL_MEDIA_COMMAND_STOP) + | (1<<PARCEL_MEDIA_COMMAND_PAUSE) + | (1<<PARCEL_MEDIA_COMMAND_PLAY) + | (1<<PARCEL_MEDIA_COMMAND_LOOP) + | (1<<PARCEL_MEDIA_COMMAND_UNLOAD) )) + { + // stop + if( command == PARCEL_MEDIA_COMMAND_STOP ) + { + stop(); + } + else + // pause + if( command == PARCEL_MEDIA_COMMAND_PAUSE ) + { + pause(); + } + else + // play + if( command == PARCEL_MEDIA_COMMAND_PLAY ) + { + if (LLViewerMedia::isMediaPaused()) + { + start(); + } + else + { + LLParcel *parcel = gParcelMgr->getAgentParcel(); + play(parcel); + } + } + else + // loop + if( command == PARCEL_MEDIA_COMMAND_LOOP ) + { + //llinfos << ">>> LLMediaEngine::process_parcel_media with command = " <<( '0' + command ) << llendl; + + // huh? what is play? + //convertImageAndLoadUrl( play ); + //convertImageAndLoadUrl( true, false, std::string() ); + } + else + // unload + if( command == PARCEL_MEDIA_COMMAND_UNLOAD ) + { + stop(); + } + } + + if (flags & (1<<PARCEL_MEDIA_COMMAND_TIME)) + { + if(! LLViewerMedia::hasMedia()) + { + LLParcel *parcel = gParcelMgr->getAgentParcel(); + play(parcel); + } + seek(time); + } +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerParcelMedia::processParcelMediaUpdate( LLMessageSystem *msg, void ** ) +{ + LLUUID media_id; + std::string media_url; + std::string media_type; + S32 media_width = 0; + S32 media_height = 0; + U8 media_auto_scale = FALSE; + U8 media_loop = FALSE; + + msg->getUUID( "DataBlock", "MediaID", media_id ); + char media_url_buffer[257]; + msg->getString( "DataBlock", "MediaURL", 255, media_url_buffer ); + media_url = media_url_buffer; + msg->getU8("DataBlock", "MediaAutoScale", media_auto_scale); + + if (msg->getNumberOfBlocks("DataBlockExtended")) // do we have the extended data? + { + char media_type_buffer[257]; + msg->getString("DataBlockExtended", "MediaType", 255, media_type_buffer); + media_type = media_type_buffer; + msg->getU8("DataBlockExtended", "MediaLoop", media_loop); + msg->getS32("DataBlockExtended", "MediaWidth", media_width); + msg->getS32("DataBlockExtended", "MediaHeight", media_height); + } + + LLParcel *parcel = gParcelMgr->getAgentParcel(); + BOOL same = FALSE; + if (parcel) + { + same = ((parcel->getMediaURL() == media_url) && + (parcel->getMediaType() == media_type) && + (parcel->getMediaID() == media_id) && + (parcel->getMediaWidth() == media_width) && + (parcel->getMediaHeight() == media_height) && + (parcel->getMediaAutoScale() == media_auto_scale) && + (parcel->getMediaLoop() == media_loop)); + } + + if (!same) + LLViewerMedia::play(media_url, media_type, media_id, + media_auto_scale, media_width, media_height, + media_loop); +} diff --git a/indra/newview/llviewerparcelmedia.h b/indra/newview/llviewerparcelmedia.h new file mode 100644 index 0000000000..bf391a83cb --- /dev/null +++ b/indra/newview/llviewerparcelmedia.h @@ -0,0 +1,52 @@ +/** + * @file llviewerparcelmedia.h + * @author Callum Prentice & James Cook + * @brief Handlers for multimedia on a per-parcel basis + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +#ifndef LLVIEWERPARCELMEDIA_H +#define LLVIEWERPARCELMEDIA_H + +#include "llmediabase.h" + +class LLMessageSystem; +class LLParcel; + +// 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. +class LLViewerParcelMedia +{ + public: + static void initClass(); + + static void update(LLParcel* parcel); + // called when the agent's parcel has a new URL, or the agent has + // walked on to a new parcel with media + + static void play(LLParcel* parcel); + // user clicked play button in media transport controls + + static void stop(); + // user clicked stop button in media transport controls + + static void pause(); + static void start(); + // restart after pause - no need for all the setup + + static void seek(F32 time); + // jump to timecode time + + static LLMediaBase::EStatus getStatus(); + + static void processParcelMediaCommandMessage( LLMessageSystem *msg, void ** ); + static void processParcelMediaUpdate( LLMessageSystem *msg, void ** ); + + public: + static S32 sMediaParcelLocalID; + static LLUUID sMediaRegionID; +}; + +#endif diff --git a/indra/newview/llviewerparcelmediaautoplay.cpp b/indra/newview/llviewerparcelmediaautoplay.cpp new file mode 100644 index 0000000000..112c6dfcea --- /dev/null +++ b/indra/newview/llviewerparcelmediaautoplay.cpp @@ -0,0 +1,129 @@ +/** + * @file llviewerparcelmediaautoplay.cpp + * @author Karl Stiefvater + * @brief timer to automatically play media in a parcel + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llviewerparcelmediaautoplay.h" +#include "llviewerparcelmedia.h" +#include "llviewercontrol.h" +#include "llviewermedia.h" +#include "llparcel.h" +#include "llviewerparcelmgr.h" +#include "lluuid.h" +#include "message.h" +#include "llviewerimagelist.h" // for texture stats +#include "llagent.h" + +const F32 AUTOPLAY_TIME = 5; // how many seconds before we autoplay +const F32 AUTOPLAY_SIZE = 24*24; // how big the texture must be (pixel area) before we autoplay +const F32 AUTOPLAY_SPEED = 0.1f; // how slow should the agent be moving to autoplay + +LLViewerParcelMediaAutoPlay::LLViewerParcelMediaAutoPlay() : + LLEventTimer(1), + mPlayed(FALSE), + mTimeInParcel(0) +{ +} + +static LLViewerParcelMediaAutoPlay *sAutoPlay = NULL; + +// static +void LLViewerParcelMediaAutoPlay::initClass() +{ + if (!sAutoPlay) + sAutoPlay = new LLViewerParcelMediaAutoPlay; +} + +// static +void LLViewerParcelMediaAutoPlay::cleanupClass() +{ + if (sAutoPlay) + delete sAutoPlay; +} + +// static +void LLViewerParcelMediaAutoPlay::playStarted() +{ + if (sAutoPlay) + { + sAutoPlay->mPlayed = TRUE; + } +} + +BOOL LLViewerParcelMediaAutoPlay::tick() +{ + LLParcel *this_parcel = NULL; + std::string this_media_url; + LLUUID this_media_texture_id; + S32 this_parcel_id = 0; + + if (gParcelMgr) + { + this_parcel = gParcelMgr->getAgentParcel(); + } + + if (this_parcel) + { + this_media_url = std::string(this_parcel->getMediaURL()); + + this_media_texture_id = this_parcel->getMediaID(); + + this_parcel_id = this_parcel->getLocalID(); + } + + if (this_parcel_id != mLastParcelID) + { + // we've entered a new parcel + mPlayed = FALSE; // we haven't autoplayed yet + mTimeInParcel = 0; // reset our timer + mLastParcelID = this_parcel_id; + } + + mTimeInParcel += mPeriod; // increase mTimeInParcel by the amount of time between ticks + + if ((!mPlayed) && // if we've never played + (mTimeInParcel > AUTOPLAY_TIME) && // and if we've been here for so many seconds + (this_media_url.size() != 0) && // and if the parcel has media + (!LLViewerMedia::isMediaPlaying())) // and if the media is not already playing + { + if (this_media_texture_id.notNull()) // and if the media texture is good + { + LLViewerImage *image = gImageList.getImage(this_media_texture_id, FALSE); + + F32 image_size = 0; + + if (image) + { + image_size = image->mMaxVirtualSize; + } + + if (gAgent.getVelocity().magVec() < AUTOPLAY_SPEED) // and if the agent is stopped (slow enough) + { + if (image_size > AUTOPLAY_SIZE) // and if the target texture is big enough on screen + { + if (this_parcel) + { + if (gSavedSettings.getBOOL("ParcelMediaAutoPlayEnable")) + { + // and last but not least, only play when autoplay is enabled + LLViewerParcelMedia::play(this_parcel); + } + } + + mPlayed = TRUE; + } + } + } + } + + + return FALSE; // continue ticking forever please. +} + + + diff --git a/indra/newview/llviewerparcelmediaautoplay.h b/indra/newview/llviewerparcelmediaautoplay.h new file mode 100644 index 0000000000..20b132c827 --- /dev/null +++ b/indra/newview/llviewerparcelmediaautoplay.h @@ -0,0 +1,32 @@ +/** + * @file llviewerparcelmediaautoplay.h + * @author Karl Stiefvater + * @brief timer to automatically play media in a parcel + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +#ifndef LLVIEWERPARCELMEDIAAUTOPLAY_H +#define LLVIEWERPARCELMEDIAAUTOPLAY_H + +#include "llmediabase.h" +#include "lltimer.h" + +// timer to automatically play media +class LLViewerParcelMediaAutoPlay : LLEventTimer +{ + public: + LLViewerParcelMediaAutoPlay(); + virtual BOOL tick(); + static void initClass(); + static void cleanupClass(); + static void playStarted(); + + private: + S32 mLastParcelID; + BOOL mPlayed; + F32 mTimeInParcel; +}; + + +#endif // LLVIEWERPARCELMEDIAAUTOPLAY_H diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index eaea0438fa..e027588eaa 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -38,7 +38,6 @@ #include "indra_constants.h" #include "llcachename.h" #include "llgl.h" -#include "llmediaengine.h" #include "llparcel.h" #include "llsecondlifeurls.h" #include "message.h" @@ -55,14 +54,16 @@ #include "llfloatersellland.h" #include "llfloatertools.h" #include "llnotify.h" +#include "llparcelselection.h" #include "llresmgr.h" #include "llstatusbar.h" #include "llui.h" +#include "llviewerimage.h" #include "llviewerimagelist.h" #include "llviewermenu.h" +#include "llviewerparcelmedia.h" #include "llviewerparceloverlay.h" #include "llviewerregion.h" -//#include "llwebbrowserctrl.h" #include "llworld.h" #include "lloverlaybar.h" #include "roles_constants.h" @@ -78,11 +79,8 @@ U8* LLViewerParcelMgr::sPackedOverlay = NULL; LLUUID gCurrentMovieID = LLUUID::null; -static LLParcelSelection* get_null_parcel_selection(); -template<> - const LLHandle<LLParcelSelection>::NullFunc - LLHandle<LLParcelSelection>::sNullFunc = get_null_parcel_selection; - +LLPointer<LLViewerImage> sBlockedImage; +LLPointer<LLViewerImage> sPassImage; // Local functions void optionally_start_music(const LLString& music_url); @@ -141,10 +139,10 @@ LLViewerParcelMgr::LLViewerParcelMgr() resetSegments(mCollisionSegments); mBlockedImageID.set(gViewerArt.getString("noentrylines.tga")); - mBlockedImage = gImageList.getImage(mBlockedImageID, TRUE, TRUE); + sBlockedImage = gImageList.getImage(mBlockedImageID, TRUE, TRUE); mPassImageID.set(gViewerArt.getString("noentrypasslines.tga")); - mPassImage = gImageList.getImage(mPassImageID, TRUE, TRUE); + sPassImage = gImageList.getImage(mPassImageID, TRUE, TRUE); S32 overlay_size = mParcelsPerEdge * mParcelsPerEdge / PARCEL_OVERLAY_CHUNKS; sPackedOverlay = new U8[overlay_size]; @@ -189,6 +187,9 @@ LLViewerParcelMgr::~LLViewerParcelMgr() delete[] mAgentParcelOverlay; mAgentParcelOverlay = NULL; + + sBlockedImage = NULL; + sPassImage = NULL; } void LLViewerParcelMgr::dump() @@ -1255,30 +1256,45 @@ const LLString& LLViewerParcelMgr::getAgentParcelName() const } -void LLViewerParcelMgr::sendParcelPropertiesUpdate(LLParcel* parcel) +void LLViewerParcelMgr::sendParcelPropertiesUpdate(LLParcel* parcel, bool use_agent_region) { if (!parcel) return; if(!gWorldp) return; - LLViewerRegion *region = gWorldp->getRegionFromPosGlobal( mWestSouth ); + LLViewerRegion *region = use_agent_region ? gAgent.getRegion() : gWorldp->getRegionFromPosGlobal( mWestSouth ); if (!region) return; - LLMessageSystem *msg = gMessageSystem; + LLSD body; + std::string url = gAgent.getRegion()->getCapability("ParcelPropertiesUpdate"); + if (!url.empty()) + { + parcel->packMessage(body); - msg->newMessageFast(_PREHASH_ParcelPropertiesUpdate); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_ParcelData); - msg->addS32Fast(_PREHASH_LocalID, parcel->getLocalID() ); + llinfos << "Sending parcel properties update via capability to:" << url << llendl; - U32 flags = 0x0; - // request new properties update from simulator - flags |= 0x01; - msg->addU32("Flags", flags); + LLHTTPClient::post(url, body, new LLHTTPClient::Responder()); + } + else + { + LLMessageSystem *msg = gMessageSystem; + + msg->newMessageFast(_PREHASH_ParcelPropertiesUpdate); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_ParcelData); + msg->addS32Fast(_PREHASH_LocalID, parcel->getLocalID() ); + + U32 flags = 0x0; + // request new properties update from simulator + flags |= 0x01; + msg->addU32("Flags", flags); + + parcel->packMessage(msg); + + msg->sendReliable( region->getHost() ); + } - parcel->packMessage(msg); - msg->sendReliable( region->getHost() ); } @@ -1363,7 +1379,6 @@ void LLViewerParcelMgr::processParcelOverlay(LLMessageSystem *msg, void **user) } } - // static void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **user) { @@ -1657,19 +1672,6 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use } else { - // It's the agent parcel - BOOL new_parcel = parcel ? FALSE : TRUE; - if (parcel) - { - S32 parcelid = parcel->getLocalID(); - U64 regionid = gAgent.getRegion()->getHandle(); - if (parcelid != gParcelMgr->mMediaParcelId || regionid != gParcelMgr->mMediaRegionId) - { - gParcelMgr->mMediaParcelId = parcelid; - gParcelMgr->mMediaRegionId = regionid; - new_parcel = TRUE; - } - } // look for music. if (gAudiop) { @@ -1714,75 +1716,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use }//if gAudiop // now check for video - if (LLMediaEngine::getInstance ()->isAvailable ()) - { - // we have a player - if (parcel) - { - // we're in a parcel - std::string mediaUrl = std::string ( parcel->getMediaURL () ); - LLString::trim(mediaUrl); - - // clean spaces and whatnot - mediaUrl = LLWeb::escapeURL(mediaUrl); - - - // something changed - LLMediaEngine* me = LLMediaEngine::getInstance(); - if ( ( me->getUrl () != mediaUrl ) - || ( me->getImageUUID () != parcel->getMediaID () ) - || ( me->isAutoScaled () != parcel->getMediaAutoScale () ) ) - { - BOOL video_was_playing = FALSE; - LLMediaBase* renderer = me->getMediaRenderer(); - if (renderer && (renderer->isPlaying() || renderer->isLooping())) - { - video_was_playing = TRUE; - } - - stop_video(); - - if ( !mediaUrl.empty () ) - { - // Someone has "changed the channel", changing the URL of a video - // you were already watching. Do we want to automatically start playing? JC - if (!new_parcel - && gSavedSettings.getBOOL("AudioStreamingVideo") - && video_was_playing) - { - start_video(parcel); - } - else - { - // "Prepare" the media engine, but don't auto-play. JC - optionally_prepare_video(parcel); - } - } - } - } - else - { - stop_video(); - } - } - else - { - // no audio player, do a first use dialog if their is media here - if (parcel) - { - std::string mediaUrl = std::string ( parcel->getMediaURL () ); - if (!mediaUrl.empty ()) - { - if (gSavedSettings.getWarning("QuickTimeInstalled")) - { - gSavedSettings.setWarning("QuickTimeInstalled", FALSE); - - LLNotifyBox::showXml("NoQuickTime" ); - }; - } - } - } - + LLViewerParcelMedia::update( parcel ); }; } @@ -1832,94 +1766,6 @@ void callback_start_music(S32 option, void* data) music_url = NULL; } -void prepare_video(const LLParcel *parcel) -{ - std::string mediaUrl; - if (parcel->getParcelFlag(PF_URL_RAW_HTML)) - { - mediaUrl = std::string("data:"); - mediaUrl.append(parcel->getMediaURL()); - } - else - { - mediaUrl = std::string ( parcel->getMediaURL () ); - } - - // clean spaces and whatnot - mediaUrl = LLWeb::escapeURL(mediaUrl); - - LLMediaEngine::getInstance ()->setUrl ( mediaUrl ); - LLMediaEngine::getInstance ()->setImageUUID ( parcel->getMediaID () ); - LLMediaEngine::getInstance ()->setAutoScaled ( parcel->getMediaAutoScale () ? TRUE : FALSE ); // (U8 instead of BOOL for future expansion) -} - -void start_video(const LLParcel *parcel) -{ - prepare_video(parcel); - std::string path( "" ); - LLMediaEngine::getInstance ()->convertImageAndLoadUrl ( true, false, path); -} - -void stop_video() -{ - // set up remote control so stop is selected - LLMediaEngine::getInstance ()->stop (); - if (gOverlayBar) - { - gOverlayBar->refresh (); - } - - if (LLMediaEngine::getInstance ()->isLoaded()) - { - LLMediaEngine::getInstance ()->unload (); - - gImageList.updateMovieImage(LLUUID::null, FALSE); - gCurrentMovieID.setNull(); - } - - LLMediaEngine::getInstance ()->setUrl ( "" ); - LLMediaEngine::getInstance ()->setImageUUID ( LLUUID::null ); - -} - -void optionally_prepare_video(const LLParcel *parcelp) -{ - if (gSavedSettings.getWarning("FirstStreamingVideo")) - { - gViewerWindow->alertXml("ParcelCanPlayMedia", - callback_prepare_video, - (void*)parcelp); - } - else - { - llinfos << "Entering parcel " << parcelp->getLocalID() << " with video " << parcelp->getMediaURL() << llendl; - prepare_video(parcelp); - } -} - - -void callback_prepare_video(S32 option, void* data) -{ - const LLParcel *parcelp = (const LLParcel *)data; - - if (0 == option) - { - gSavedSettings.setBOOL("AudioStreamingVideo", TRUE); - llinfos << "Starting parcel video " << parcelp->getMediaURL() << " on parcel " << parcelp->getLocalID() << llendl; - gMessageSystem->setHandlerFunc("ParcelMediaCommandMessage", LLMediaEngine::process_parcel_media); - gMessageSystem->setHandlerFunc ( "ParcelMediaUpdate", LLMediaEngine::process_parcel_media_update ); - prepare_video(parcelp); - } - else - { - gMessageSystem->setHandlerFunc("ParcelMediaCommandMessage", null_message_callback); - gMessageSystem->setHandlerFunc ( "ParcelMediaUpdate", null_message_callback ); - gSavedSettings.setBOOL("AudioStreamingVideo", FALSE); - } - - gSavedSettings.setWarning("FirstStreamingVideo", FALSE); -} - // static void LLViewerParcelMgr::processParcelAccessListReply(LLMessageSystem *msg, void **user) { @@ -2548,71 +2394,20 @@ void sanitize_corners(const LLVector3d &corner1, east_north_top.mdV[VZ] = llmax( corner1.mdV[VZ], corner2.mdV[VZ] ); } -// -// LLParcelSelection -// -LLParcelSelection::LLParcelSelection() : - mParcel(NULL), - mSelectedMultipleOwners(FALSE), - mWholeParcelSelected(FALSE), - mSelectedSelfCount(0), - mSelectedOtherCount(0), - mSelectedPublicCount(0) -{ -} - -LLParcelSelection::LLParcelSelection(LLParcel* parcel) : - mParcel(parcel), - mSelectedMultipleOwners(FALSE), - mWholeParcelSelected(FALSE), - mSelectedSelfCount(0), - mSelectedOtherCount(0), - mSelectedPublicCount(0) -{ -} -LLParcelSelection::~LLParcelSelection() -{ -} - -BOOL LLParcelSelection::getMultipleOwners() const -{ - return mSelectedMultipleOwners; -} - - -BOOL LLParcelSelection::getWholeParcelSelected() const -{ - return mWholeParcelSelected; -} - - -S32 LLParcelSelection::getClaimableArea() const -{ - const S32 UNIT_AREA = S32( PARCEL_GRID_STEP_METERS * PARCEL_GRID_STEP_METERS ); - return mSelectedPublicCount * UNIT_AREA; -} - -bool LLParcelSelection::hasOthersSelected() const +void LLViewerParcelMgr::cleanupGlobals() { - return mSelectedOtherCount != 0; + delete gParcelMgr; + gParcelMgr = NULL; + LLParcelSelection::sNullSelection = NULL; } -static LLPointer<LLParcelSelection> sNullSelection; - -LLParcelSelection* get_null_parcel_selection() +LLViewerImage* LLViewerParcelMgr::getBlockedImage() const { - if (sNullSelection.isNull()) - { - sNullSelection = new LLParcelSelection; - } - - return sNullSelection; + return sBlockedImage; } -void LLViewerParcelMgr::cleanupGlobals() +LLViewerImage* LLViewerParcelMgr::getPassImage() const { - delete gParcelMgr; - gParcelMgr = NULL; - sNullSelection = NULL; + return sPassImage; } diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h index 640c8c5c57..efea18158c 100644 --- a/indra/newview/llviewerparcelmgr.h +++ b/indra/newview/llviewerparcelmgr.h @@ -36,11 +36,12 @@ #include "lldarray.h" #include "llframetimer.h" #include "llmemory.h" -#include "llviewerimage.h" +#include "llparcelselection.h" class LLUUID; class LLMessageSystem; class LLParcel; +class LLViewerImage; class LLViewerRegion; // Constants for sendLandOwner @@ -72,49 +73,6 @@ public: virtual void changed() = 0; }; -class LLParcelSelection : public LLRefCount -{ - friend class LLViewerParcelMgr; - -protected: - ~LLParcelSelection(); - -public: - LLParcelSelection(LLParcel* parcel); - LLParcelSelection(); - - // this can return NULL at any time, as parcel selection - // might have been invalidated. - LLParcel* getParcel() { return mParcel; } - - // Return the number of grid units that are owned by you within - // the selection (computed by server). - S32 getSelfCount() const { return mSelectedSelfCount; } - - // Returns area that will actually be claimed in meters squared. - S32 getClaimableArea() const; - bool hasOthersSelected() const; - - // Does the selection have multiple land owners in it? - BOOL getMultipleOwners() const; - - // Is the entire parcel selected, or just a part? - BOOL getWholeParcelSelected() const; - -protected: - void setParcel(LLParcel* parcel) { mParcel = parcel; } - -protected: - - LLParcel* mParcel; - BOOL mSelectedMultipleOwners; - BOOL mWholeParcelSelected; - S32 mSelectedSelfCount; - S32 mSelectedOtherCount; - S32 mSelectedPublicCount; -}; - -typedef LLHandle<LLParcelSelection> LLParcelSelectionHandle; class LLViewerParcelMgr { @@ -231,7 +189,7 @@ public: // containing the southwest corner of the selection. // If want_reply_to_update, simulator will send back a ParcelProperties // message. - void sendParcelPropertiesUpdate(LLParcel* parcel); + void sendParcelPropertiesUpdate(LLParcel* parcel, bool use_agent_region = false); // Takes an Access List flag, like AL_ACCESS or AL_BAN void sendParcelAccessListUpdate(U32 which); @@ -300,7 +258,7 @@ public: static BOOL isParcelOwnedByAgent(const LLParcel* parcelp, U64 group_proxy_power); static BOOL isParcelModifiableByAgent(const LLParcel* parcelp, U64 group_proxy_power); -protected: +private: static void releaseAlertCB(S32 option, void *data); // If the user is claiming land and the current selection @@ -322,6 +280,8 @@ protected: static void callbackJoinLand(S32 option, void* data); //void finishClaim(BOOL user_to_user_sale, U32 join); + LLViewerImage* getBlockedImage() const; + LLViewerImage* getPassImage() const; private: BOOL mSelected; @@ -367,8 +327,6 @@ private: LLFrameTimer mCollisionTimer; LLUUID mBlockedImageID; LLUUID mPassImageID; - LLPointer<LLViewerImage> mBlockedImage; - LLPointer<LLViewerImage> mPassImage; // Media S32 mMediaParcelId; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 2a7d2c1367..9f343abdae 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1360,6 +1360,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url) capabilityNames.append("MapLayerGod"); capabilityNames.append("NewFileAgentInventory"); capabilityNames.append("ParcelGodReserveForNewbie"); + capabilityNames.append("ParcelPropertiesUpdate"); capabilityNames.append("ParcelVoiceInfoRequest"); capabilityNames.append("ProvisionVoiceAccountRequest"); capabilityNames.append("RemoteParcelRequest"); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 49d4d72647..95adf32ed5 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -60,7 +60,6 @@ #include "linked_lists.h" #include "llassetstorage.h" #include "llfontgl.h" -#include "llmediaengine.h" // mute on minimize #include "llrect.h" #include "llsky.h" #include "llstring.h" diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp index eac24cebf5..21be936960 100644 --- a/indra/newview/llweb.cpp +++ b/indra/newview/llweb.cpp @@ -36,8 +36,8 @@ #include "llwindow.h" -//#include "llfloaterhtml.h" #include "llviewercontrol.h" +#include "llfloaterhtmlhelp.h" // static void LLWeb::initClass() @@ -48,7 +48,14 @@ void LLWeb::initClass() // static void LLWeb::loadURL(const std::string& url) { - loadURLExternal(url); + if (gSavedSettings.getBOOL("UseExternalBrowser")) + { + loadURLExternal(url); + } + else + { + LLFloaterMediaBrowser::showInstance(url); + } } @@ -56,9 +63,7 @@ void LLWeb::loadURL(const std::string& url) void LLWeb::loadURLExternal(const std::string& url) { std::string escaped_url = escapeURL(url); -#if LL_LIBXUL_ENABLED spawn_web_browser(escaped_url.c_str()); -#endif } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 0f17310840..8c5ad393ab 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -638,7 +638,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerImage* image bool alpha = te->getColor().mV[3] < 0.999f; if (imagep) { - alpha = alpha || (imagep->getComponents() == 4) || (imagep->getComponents() == 2); + alpha = alpha || (imagep->getComponents() == 4 && ! imagep->mIsMediaTexture) || (imagep->getComponents() == 2); } if (alpha) diff --git a/indra/newview/res-sdl/toolmediaopen.BMP b/indra/newview/res-sdl/toolmediaopen.BMP Binary files differnew file mode 100644 index 0000000000..ac4b231994 --- /dev/null +++ b/indra/newview/res-sdl/toolmediaopen.BMP diff --git a/indra/newview/res-sdl/toolpause.BMP b/indra/newview/res-sdl/toolpause.BMP Binary files differnew file mode 100644 index 0000000000..dd2c6857d2 --- /dev/null +++ b/indra/newview/res-sdl/toolpause.BMP diff --git a/indra/newview/res-sdl/toolplay.BMP b/indra/newview/res-sdl/toolplay.BMP Binary files differnew file mode 100644 index 0000000000..9c40d7dbec --- /dev/null +++ b/indra/newview/res-sdl/toolplay.BMP diff --git a/indra/newview/res/resource.h b/indra/newview/res/resource.h index 2a6a113cb9..4f2e88f7f2 100644 --- a/indra/newview/res/resource.h +++ b/indra/newview/res/resource.h @@ -50,6 +50,7 @@ #define IDC_CURSOR4 153 #define IDC_CURSOR5 154 #define IDI_LCD_LL_ICON 157 +#define IDC_CURSOR6 158 #define IDC_RADIO_56 1000 #define IDC_RADIO_128 1001 #define IDC_RADIO_256 1002 @@ -182,6 +183,7 @@ // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 159 #define _APS_NEXT_RESOURCE_VALUE 167 #define _APS_NEXT_COMMAND_VALUE 40002 #define _APS_NEXT_CONTROL_VALUE 1139 diff --git a/indra/newview/res/toolmediaopen.cur b/indra/newview/res/toolmediaopen.cur Binary files differnew file mode 100644 index 0000000000..7609989ba7 --- /dev/null +++ b/indra/newview/res/toolmediaopen.cur diff --git a/indra/newview/res/toolpause.cur b/indra/newview/res/toolpause.cur Binary files differnew file mode 100644 index 0000000000..7a6e85566b --- /dev/null +++ b/indra/newview/res/toolpause.cur diff --git a/indra/newview/res/toolplay.cur b/indra/newview/res/toolplay.cur Binary files differnew file mode 100644 index 0000000000..0776a17bbc --- /dev/null +++ b/indra/newview/res/toolplay.cur |