From ad89c3e401e5889bb49239e0fbe8c9f9d7327cc1 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sat, 15 Jun 2013 05:14:27 -0500 Subject: [PATCH] Added media support to prim face editor. Todo: Translations for all these floaters and panels. --- indra/newview/CMakeLists.txt | 10 + indra/newview/llfloatermediasettings.cpp | 319 +++++++ indra/newview/llfloatermediasettings.h | 89 ++ indra/newview/llfloatertools.cpp | 874 +++++++++++++++++- indra/newview/llfloatertools.h | 20 +- indra/newview/llfloaterwhitelistentry.cpp | 91 ++ indra/newview/llfloaterwhitelistentry.h | 50 + indra/newview/llmediactrl.cpp | 2 +- indra/newview/llpanelcontents.cpp | 7 + indra/newview/llpanelcontents.h | 11 + indra/newview/llpanelface.cpp | 211 ++--- indra/newview/llpanelface.h | 15 +- indra/newview/llpanelmediasettingsgeneral.cpp | 515 +++++++++++ indra/newview/llpanelmediasettingsgeneral.h | 100 ++ .../llpanelmediasettingspermissions.cpp | 285 ++++++ .../newview/llpanelmediasettingspermissions.h | 73 ++ .../newview/llpanelmediasettingssecurity.cpp | 366 ++++++++ indra/newview/llpanelmediasettingssecurity.h | 82 ++ indra/newview/llselectmgr.h | 47 + indra/newview/skins/default/textures/Flag.png | Bin 0 -> 3238 bytes .../skins/default/textures/textures.xml | 2 + .../xui/en-us/floater_media_settings.xml | 73 ++ .../skins/default/xui/en-us/floater_tools.xml | 123 ++- .../xui/en-us/floater_whitelist_entry.xml | 29 + .../skins/default/xui/en-us/notifications.xml | 46 + .../en-us/panel_media_settings_general.xml | 226 +++++ .../panel_media_settings_permissions.xml | 172 ++++ .../en-us/panel_media_settings_security.xml | 91 ++ .../xui/en-us/panel_prim_media_controls.xml | 9 +- .../skins/default/xui/en-us/strings.xml | 4 + 30 files changed, 3794 insertions(+), 148 deletions(-) create mode 100644 indra/newview/llfloatermediasettings.cpp create mode 100644 indra/newview/llfloatermediasettings.h create mode 100644 indra/newview/llfloaterwhitelistentry.cpp create mode 100644 indra/newview/llfloaterwhitelistentry.h create mode 100644 indra/newview/llpanelmediasettingsgeneral.cpp create mode 100644 indra/newview/llpanelmediasettingsgeneral.h create mode 100644 indra/newview/llpanelmediasettingspermissions.cpp create mode 100644 indra/newview/llpanelmediasettingspermissions.h create mode 100644 indra/newview/llpanelmediasettingssecurity.cpp create mode 100644 indra/newview/llpanelmediasettingssecurity.h create mode 100644 indra/newview/skins/default/textures/Flag.png create mode 100644 indra/newview/skins/default/xui/en-us/floater_media_settings.xml create mode 100644 indra/newview/skins/default/xui/en-us/floater_whitelist_entry.xml create mode 100644 indra/newview/skins/default/xui/en-us/panel_media_settings_general.xml create mode 100644 indra/newview/skins/default/xui/en-us/panel_media_settings_permissions.xml create mode 100644 indra/newview/skins/default/xui/en-us/panel_media_settings_security.xml diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 682c43939..878141ad0 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -219,6 +219,7 @@ set(viewer_SOURCE_FILES llfloaterlandholdings.cpp llfloaterlandmark.cpp llfloatermap.cpp + llfloatermediasettings.cpp llfloatermemleak.cpp llfloatermessagelog.cpp llfloatermodelpreview.cpp @@ -260,6 +261,7 @@ set(viewer_SOURCE_FILES llfloatervoicedevicesettings.cpp llfloaterwater.cpp llfloaterwebcontent.cpp + llfloaterwhitelistentry.cpp llfloaterwindlight.cpp llfloaterworldmap.cpp llfolderview.cpp @@ -365,6 +367,9 @@ set(viewer_SOURCE_FILES llpanellogin.cpp llpanelmaininventory.cpp llpanelmarketplaceoutboxinventory.cpp + llpanelmediasettingsgeneral.cpp + llpanelmediasettingspermissions.cpp + llpanelmediasettingssecurity.cpp llpanelmorph.cpp llpanelmsgs.cpp llpanelnetwork.cpp @@ -715,6 +720,7 @@ set(viewer_HEADER_FILES llfloaterlandholdings.h llfloaterlandmark.h llfloatermap.h + llfloatermediasettings.h llfloatermemleak.h llfloatermessagelog.h llfloatermodelpreview.h @@ -756,6 +762,7 @@ set(viewer_HEADER_FILES llfloatervoicedevicesettings.h llfloaterwater.h llfloaterwebcontent.h + llfloaterwhitelistentry.h llfloaterwindlight.h llfloaterworldmap.h llfolderview.h @@ -861,6 +868,9 @@ set(viewer_HEADER_FILES llpanellogin.h llpanelmaininventory.h llpanelmarketplaceoutboxinventory.h + llpanelmediasettingsgeneral.h + llpanelmediasettingspermissions.h + llpanelmediasettingssecurity.h llpanelmorph.h llpanelmsgs.h llpanelnetwork.h diff --git a/indra/newview/llfloatermediasettings.cpp b/indra/newview/llfloatermediasettings.cpp new file mode 100644 index 000000000..151ed53b6 --- /dev/null +++ b/indra/newview/llfloatermediasettings.cpp @@ -0,0 +1,319 @@ +/** + * @file llfloatermediasettings.cpp + * @brief Tabbed dialog for media settings - class implementation + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloatermediasettings.h" +#include "llfloaterwhitelistentry.h" +#include "llpanelmediasettingsgeneral.h" +#include "llpanelmediasettingssecurity.h" +#include "llpanelmediasettingspermissions.h" +#include "llviewercontrol.h" +#include "lluictrlfactory.h" +#include "llbutton.h" +#include "llselectmgr.h" +#include "llsdutil.h" + +LLFloaterMediaSettings* LLFloaterMediaSettings::sInstance = NULL; + +//////////////////////////////////////////////////////////////////////////////// +// +LLFloaterMediaSettings::LLFloaterMediaSettings(const LLSD& key) + : LLFloater(key), + mTabContainer(NULL), + mPanelMediaSettingsGeneral(NULL), + mPanelMediaSettingsSecurity(NULL), + mPanelMediaSettingsPermissions(NULL), + mWaitingToClose( false ), + mIdenticalHasMediaInfo( true ), + mMultipleMedia(false), + mMultipleValidMedia(false) +{ + LLUICtrlFactory::getInstance()->buildFloater(this,"floater_media_settings.xml"); +} + +//////////////////////////////////////////////////////////////////////////////// +// +LLFloaterMediaSettings::~LLFloaterMediaSettings() +{ + if ( mPanelMediaSettingsGeneral ) + { + delete mPanelMediaSettingsGeneral; + mPanelMediaSettingsGeneral = NULL; + } + + if ( mPanelMediaSettingsSecurity ) + { + delete mPanelMediaSettingsSecurity; + mPanelMediaSettingsSecurity = NULL; + } + + if ( mPanelMediaSettingsPermissions ) + { + delete mPanelMediaSettingsPermissions; + mPanelMediaSettingsPermissions = NULL; + } + + sInstance = NULL; +} + +//////////////////////////////////////////////////////////////////////////////// +// +BOOL LLFloaterMediaSettings::postBuild() +{ + mApplyBtn = getChild("Apply"); + mApplyBtn->setClickedCallback(onBtnApply, this); + + mCancelBtn = getChild("Cancel"); + mCancelBtn->setClickedCallback(onBtnCancel, this); + + mOKBtn = getChild("OK"); + mOKBtn->setClickedCallback(onBtnOK, this); + + mTabContainer = getChild( "tab_container" ); + + mPanelMediaSettingsGeneral = new LLPanelMediaSettingsGeneral(); + mTabContainer->addTabPanel( mPanelMediaSettingsGeneral, mPanelMediaSettingsGeneral->getLabel() ); + mPanelMediaSettingsGeneral->setParent( this ); + + // note that "permissions" tab is really "Controls" tab - refs to 'perms' and + // 'permissions' not changed to 'controls' since we don't want to change + // shared files in server code and keeping everything the same seemed best. + mPanelMediaSettingsPermissions = new LLPanelMediaSettingsPermissions(); + mTabContainer->addTabPanel( mPanelMediaSettingsPermissions, mPanelMediaSettingsPermissions->getLabel() ); + + mPanelMediaSettingsSecurity = new LLPanelMediaSettingsSecurity(); + mTabContainer->addTabPanel( mPanelMediaSettingsSecurity, mPanelMediaSettingsSecurity->getLabel() ); + mPanelMediaSettingsSecurity->setParent( this ); + + // restore the last tab viewed from persistance variable storage + if (!mTabContainer->selectTab(gSavedSettings.getS32("LastMediaSettingsTab"))) + { + mTabContainer->selectFirstTab(); + }; + + sInstance = this; + + return TRUE; +} + +//static +LLFloaterMediaSettings* LLFloaterMediaSettings::getInstance() +{ + if ( !sInstance ) + { + sInstance = new LLFloaterMediaSettings(LLSD()); + sInstance->setVisible(FALSE); + } + + return sInstance; +} + +//static +void LLFloaterMediaSettings::apply() +{ + if (sInstance->haveValuesChanged()) + { + LLSD settings; + sInstance->mPanelMediaSettingsGeneral->preApply(); + sInstance->mPanelMediaSettingsGeneral->getValues( settings, false ); + sInstance->mPanelMediaSettingsSecurity->preApply(); + sInstance->mPanelMediaSettingsSecurity->getValues( settings, false ); + sInstance->mPanelMediaSettingsPermissions->preApply(); + sInstance->mPanelMediaSettingsPermissions->getValues( settings, false ); + + LLSelectMgr::getInstance()->selectionSetMedia( LLTextureEntry::MF_HAS_MEDIA, settings ); + + sInstance->mPanelMediaSettingsGeneral->postApply(); + sInstance->mPanelMediaSettingsSecurity->postApply(); + sInstance->mPanelMediaSettingsPermissions->postApply(); + } +} + +//////////////////////////////////////////////////////////////////////////////// +void LLFloaterMediaSettings::onClose(bool app_quitting) +{ + if(mPanelMediaSettingsGeneral) + { + mPanelMediaSettingsGeneral->onClose(app_quitting); + } + if(LLFloaterWhiteListEntry::instanceExists()) + LLFloaterWhiteListEntry::getInstance()->close(app_quitting); + + LLFloater::onClose(app_quitting); +} + +//////////////////////////////////////////////////////////////////////////////// +//static +void LLFloaterMediaSettings::initValues( const LLSD& media_settings, bool editable ) +{ + if (sInstance->hasFocus()) return; + + sInstance->clearValues(editable); + // update all panels with values from simulator + sInstance->mPanelMediaSettingsGeneral-> + initValues( sInstance->mPanelMediaSettingsGeneral, media_settings, editable ); + + sInstance->mPanelMediaSettingsSecurity-> + initValues( sInstance->mPanelMediaSettingsSecurity, media_settings, editable ); + + sInstance->mPanelMediaSettingsPermissions-> + initValues( sInstance->mPanelMediaSettingsPermissions, media_settings, editable ); + + // Squirrel away initial values + sInstance->mInitialValues.clear(); + sInstance->mPanelMediaSettingsGeneral->getValues( sInstance->mInitialValues ); + sInstance->mPanelMediaSettingsSecurity->getValues( sInstance->mInitialValues ); + sInstance->mPanelMediaSettingsPermissions->getValues( sInstance->mInitialValues ); + + sInstance->mApplyBtn->setEnabled(editable); + sInstance->mOKBtn->setEnabled(editable); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLFloaterMediaSettings::commitFields() +{ + if (hasFocus()) + { + LLUICtrl* cur_focus = dynamic_cast(gFocusMgr.getKeyboardFocus()); + if (cur_focus && cur_focus->acceptsTextInput()) + { + cur_focus->onCommit(); + }; + }; +} + +//////////////////////////////////////////////////////////////////////////////// +//static +void LLFloaterMediaSettings::clearValues( bool editable) +{ + if (sInstance) + { + // clean up all panels before updating + sInstance->mPanelMediaSettingsGeneral ->clearValues(sInstance->mPanelMediaSettingsGeneral, editable); + sInstance->mPanelMediaSettingsSecurity ->clearValues(sInstance->mPanelMediaSettingsSecurity, editable); + sInstance->mPanelMediaSettingsPermissions->clearValues(sInstance->mPanelMediaSettingsPermissions, editable); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// static +void LLFloaterMediaSettings::onBtnOK( void* userdata ) +{ + sInstance->commitFields(); + + sInstance->apply(); + + sInstance->close(); +} + +//////////////////////////////////////////////////////////////////////////////// +// static +void LLFloaterMediaSettings::onBtnApply( void* userdata ) +{ + sInstance->commitFields(); + + sInstance->apply(); + + sInstance->mInitialValues.clear(); + sInstance->mPanelMediaSettingsGeneral->getValues( sInstance->mInitialValues ); + sInstance->mPanelMediaSettingsSecurity->getValues( sInstance->mInitialValues ); + sInstance->mPanelMediaSettingsPermissions->getValues( sInstance->mInitialValues ); + +} + +//////////////////////////////////////////////////////////////////////////////// +// static +void LLFloaterMediaSettings::onBtnCancel( void* userdata ) +{ + sInstance->close(); +} + +//////////////////////////////////////////////////////////////////////////////// +// static +void LLFloaterMediaSettings::onTabChanged(void* user_data, bool from_click) +{ + LLTabContainer* self = (LLTabContainer*)user_data; + gSavedSettings.setS32("LastMediaSettingsTab", self->getCurrentPanelIndex()); +} +//////////////////////////////////////////////////////////////////////////////// +// +const std::string LLFloaterMediaSettings::getHomeUrl() +{ + if ( mPanelMediaSettingsGeneral ) + return mPanelMediaSettingsGeneral->getHomeUrl(); + else + return std::string( "" ); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +void LLFloaterMediaSettings::draw() +{ + if (NULL != mApplyBtn) + { + // Set the enabled state of the "Apply" button if values changed + mApplyBtn->setEnabled( haveValuesChanged() ); + } + + LLFloater::draw(); +} + + +//private +bool LLFloaterMediaSettings::haveValuesChanged() const +{ + bool values_changed = false; + // *NOTE: The code below is very inefficient. Better to do this + // only when data change. + // Every frame, check to see what the values are. If they are not + // the same as the initial media data, enable the OK/Apply buttons + LLSD settings; + sInstance->mPanelMediaSettingsGeneral->getValues( settings ); + sInstance->mPanelMediaSettingsSecurity->getValues( settings ); + sInstance->mPanelMediaSettingsPermissions->getValues( settings ); + LLSD::map_const_iterator iter = settings.beginMap(); + LLSD::map_const_iterator end = settings.endMap(); + for ( ; iter != end; ++iter ) + { + const std::string ¤t_key = iter->first; + const LLSD ¤t_value = iter->second; + if ( ! llsd_equals(current_value, mInitialValues[current_key])) + { + values_changed = true; + break; + } + } + return values_changed; +} + +bool LLFloaterMediaSettings::instanceExists() +{ + return sInstance; +} + + diff --git a/indra/newview/llfloatermediasettings.h b/indra/newview/llfloatermediasettings.h new file mode 100644 index 000000000..1d2553098 --- /dev/null +++ b/indra/newview/llfloatermediasettings.h @@ -0,0 +1,89 @@ +/** + * @file llfloatermediasettings.cpp + * @brief Tabbed dialog for media settings - class definition + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLFLOATERMEDIASETTINGS_H +#define LL_LLFLOATERMEDIASETTINGS_H + +#include "llfloater.h" +#include "lltabcontainer.h" + +class LLPanelMediaSettingsGeneral; +class LLPanelMediaSettingsSecurity; +class LLPanelMediaSettingsPermissions; + +class LLFloaterMediaSettings : + public LLFloater +{ +public: + LLFloaterMediaSettings(const LLSD& key); + ~LLFloaterMediaSettings(); + + /*virtual*/ BOOL postBuild(); + /*virtual*/ void onClose(bool app_quitting); + + static LLFloaterMediaSettings* getInstance(); + static bool instanceExists(); + static void apply(); + static void initValues( const LLSD& media_settings , bool editable); + static void clearValues( bool editable); + + LLPanelMediaSettingsSecurity* getPanelSecurity(){return mPanelMediaSettingsSecurity;}; + const std::string getHomeUrl(); + //bool passesWhiteList( const std::string& test_url ); + + virtual void draw(); + + bool mIdenticalHasMediaInfo; + bool mMultipleMedia; + bool mMultipleValidMedia; + +protected: + LLButton *mOKBtn; + LLButton *mCancelBtn; + LLButton *mApplyBtn; + + LLTabContainer *mTabContainer; + LLPanelMediaSettingsGeneral* mPanelMediaSettingsGeneral; + LLPanelMediaSettingsSecurity* mPanelMediaSettingsSecurity; + LLPanelMediaSettingsPermissions* mPanelMediaSettingsPermissions; + + static void onBtnOK(void*); + static void onBtnCancel(void*); + static void onBtnApply(void*); + static void onTabChanged(void* user_data, bool from_click); + void commitFields(); + + static LLFloaterMediaSettings* sInstance; + +private: + + bool haveValuesChanged() const; + + LLSD mInitialValues; + bool mWaitingToClose; +}; + +#endif // LL_LLFLOATERMEDIASETTINGS_H diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 5b7d59c28..d63fde073 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -45,9 +45,13 @@ #include "llcombobox.h" #include "lldraghandle.h" #include "llfloaterbuildoptions.h" +#include "llfloatermediasettings.h" #include "llfloateropenobject.h" #include "llfocusmgr.h" +#include "llmediaentry.h" +#include "llmediactrl.h" #include "llmenugl.h" +#include "llnotificationsutil.h" #include "llpanelcontents.h" #include "llpanelface.h" #include "llpanelland.h" @@ -55,6 +59,7 @@ #include "llpanelobject.h" #include "llpanelvolume.h" #include "llpanelpermissions.h" +#include "llparcel.h" #include "llresmgr.h" #include "llselectmgr.h" #include "llslider.h" @@ -74,12 +79,15 @@ #include "lltoolpipette.h" #include "lltoolplacer.h" #include "lltoolselectland.h" +#include "lltrans.h" #include "llui.h" #include "llviewercontrol.h" #include "llviewerjoystick.h" +#include "llviewerregion.h" #include "llviewermenu.h" #include "llviewerparcelmgr.h" #include "llviewerwindow.h" +#include "llvovolume.h" #include "lluictrlfactory.h" #include "llmeshrepository.h" @@ -241,6 +249,7 @@ BOOL LLFloaterTools::postBuild() mRadioStretch = getChild("radio stretch"); mRadioSelectFace = getChild("radio select face"); mRadioAlign = getChild("radio align"); + mTitleMedia = getChild("title_media"); mCheckSelectIndividual = getChild("checkbox edit linked parts"); getChild("checkbox edit linked parts")->setValue((BOOL)gSavedSettings.getBOOL("EditLinkedParts")); @@ -331,14 +340,17 @@ LLFloaterTools::LLFloaterTools() mBtnLand(NULL), mTextStatus(NULL), + //Camera Focus mRadioOrbit(NULL), mRadioZoom(NULL), mRadioPan(NULL), + //Move via physics mRadioMove(NULL), mRadioLift(NULL), mRadioSpin(NULL), + //Edit prim mRadioPosition(NULL), mRadioRotate(NULL), mRadioStretch(NULL), @@ -349,6 +361,7 @@ LLFloaterTools::LLFloaterTools() mCheckSnapToGrid(NULL), mBtnGridOptions(NULL), mTextGridMode(NULL), + mTitleMedia(NULL), mComboGridMode(NULL), mCheckStretchUniform(NULL), mCheckStretchTexture(NULL), @@ -369,6 +382,8 @@ LLFloaterTools::LLFloaterTools() mCheckCopySelection(NULL), mCheckCopyCenters(NULL), mCheckCopyRotates(NULL), + + //Edit land mRadioSelectLand(NULL), mRadioDozerFlatten(NULL), mRadioDozerRaise(NULL), @@ -376,6 +391,7 @@ LLFloaterTools::LLFloaterTools() mRadioDozerSmooth(NULL), mRadioDozerNoise(NULL), mRadioDozerRevert(NULL), + mSliderDozerSize(NULL), mSliderDozerForce(NULL), mBtnApplyToSelection(NULL), @@ -388,7 +404,8 @@ LLFloaterTools::LLFloaterTools() mPanelFace(NULL), mPanelLandInfo(NULL), - mDirty(TRUE) + mDirty(TRUE), + mNeedMediaTitle(TRUE) { setAutoFocus(FALSE); LLCallbackMap::map_t factory_map; @@ -413,6 +430,10 @@ LLFloaterTools::LLFloaterTools() mCommitCallbackRegistrar.add("BuildTool.applyToSelection", boost::bind(&click_apply_to_selection, this)); mCommitCallbackRegistrar.add("BuildTool.commitRadioLand", boost::bind(&commit_radio_group_land,_1)); mCommitCallbackRegistrar.add("BuildTool.LandBrushForce", boost::bind(&commit_slider_dozer_force,_1)); + mCommitCallbackRegistrar.add("BuildTool.AddMedia", boost::bind(&LLFloaterTools::onClickBtnAddMedia,this)); + mCommitCallbackRegistrar.add("BuildTool.DeleteMedia", boost::bind(&LLFloaterTools::onClickBtnDeleteMedia,this)); + mCommitCallbackRegistrar.add("BuildTool.EditMedia", boost::bind(&LLFloaterTools::onClickBtnEditMedia,this)); + LLUICtrlFactory::getInstance()->buildFloater(this,"floater_tools.xml",&factory_map,FALSE); } @@ -521,6 +542,8 @@ void LLFloaterTools::refresh() mPanelObject->refresh(); mPanelVolume->refresh(); mPanelFace->refresh(); + if(mTitleMedia) + refreshMedia(); mPanelContents->refresh(); mPanelLandInfo->refresh(); } @@ -533,6 +556,10 @@ void LLFloaterTools::draw() mDirty = FALSE; } + // grab media name/title and update the UI widget + if(mTitleMedia) + updateMediaTitle(); + // mCheckSelectIndividual->set(gSavedSettings.getBOOL("EditLinkedParts")); LLFloater::draw(); } @@ -737,8 +764,8 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) if (mCheckCopyCenters) mCheckCopyCenters ->setVisible( create_visible ); if (mCheckCopyRotates) mCheckCopyRotates ->setVisible( create_visible ); - if (mCheckCopyCenters) mCheckCopyCenters->setEnabled( mCheckCopySelection->get() ); - if (mCheckCopyRotates) mCheckCopyRotates->setEnabled( mCheckCopySelection->get() ); + if (mCheckCopyCenters && mCheckCopySelection) mCheckCopyCenters->setEnabled( mCheckCopySelection->get() ); + if (mCheckCopyRotates && mCheckCopySelection) mCheckCopyRotates->setEnabled( mCheckCopySelection->get() ); // Land buttons BOOL land_visible = (tool == LLToolBrushLand::getInstance() || tool == LLToolSelectLand::getInstance() ); @@ -833,6 +860,10 @@ void LLFloaterTools::onClose(bool app_quitting) LLViewerJoystick::getInstance()->moveAvatar(false); + // destroy media source used to grab media title + if( mTitleMedia ) + mTitleMedia->unloadMediaSource(); + // Different from handle_reset_view in that it doesn't actually // move the camera if EditCameraMovement is not set. gAgentCamera.resetView(gSavedSettings.getBOOL("EditCameraMovement")); @@ -867,6 +898,9 @@ void LLFloaterTools::onClose(bool app_quitting) // gMenuBarView->setItemVisible(std::string("Tools"), FALSE); // gMenuBarView->arrange(); + + if(LLFloaterMediaSettings::instanceExists()) + LLFloaterMediaSettings::getInstance()->close(); } void LLFloaterTools::showPanel(EInfoPanel panel) @@ -1047,8 +1081,7 @@ void commit_grid_mode(LLUICtrl *ctrl) LLSelectMgr::getInstance()->setGridMode((EGridMode)combo->getCurrentIndex()); } -// static -void LLFloaterTools::onClickGridOptions(void* data) +void LLFloaterTools::onClickGridOptions() { //LLFloaterTools* floaterp = (LLFloaterTools*)data; LLFloaterBuildOptions::show(NULL); @@ -1086,6 +1119,836 @@ void LLFloaterTools::onFocusReceived() LLFloater::onFocusReceived(); } +// Media stuff +void LLFloaterTools::refreshMedia() +{ + if(!mTitleMedia) + return; + getMediaState(); +} + +bool LLFloaterTools::selectedMediaEditable() +{ + U32 owner_mask_on; + U32 owner_mask_off; + U32 valid_owner_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_OWNER, + &owner_mask_on, &owner_mask_off ); + U32 group_mask_on; + U32 group_mask_off; + U32 valid_group_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_GROUP, + &group_mask_on, &group_mask_off ); + U32 everyone_mask_on; + U32 everyone_mask_off; + S32 valid_everyone_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_EVERYONE, + &everyone_mask_on, &everyone_mask_off ); + + bool selected_Media_editable = false; + + // if perms we got back are valid + if ( valid_owner_perms && + valid_group_perms && + valid_everyone_perms ) + { + + if ( ( owner_mask_on & PERM_MODIFY ) || + ( group_mask_on & PERM_MODIFY ) || + ( group_mask_on & PERM_MODIFY ) ) + { + selected_Media_editable = true; + } + else + // user is NOT allowed to press the RESET button + { + selected_Media_editable = false; + }; + }; + + return selected_Media_editable; +} +void LLFloaterTools::getMediaState() +{ + LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection(); + LLViewerObject* first_object = selected_objects->getFirstObject(); + LLTextBox* media_info = getChild("media_info"); + + if( !(first_object + && first_object->getPCode() == LL_PCODE_VOLUME + &&first_object->permModify() + )) + { + getChildView("Add_Media")->setEnabled(FALSE); + media_info->setValue(""); + clearMediaSettings(); + return; + } + + std::string url = first_object->getRegion()->getCapability("ObjectMedia"); + bool has_media_capability = (!url.empty()); + + if(!has_media_capability) + { + getChildView("Add_Media")->setEnabled(FALSE); + LL_WARNS("LLFloaterTools: media") << "Media not enabled (no capability) in this region!" << LL_ENDL; + clearMediaSettings(); + return; + } + + BOOL is_nonpermanent_enforced = (LLSelectMgr::getInstance()->getSelection()->getFirstRootNode() + && LLSelectMgr::getInstance()->selectGetRootsNonPermanentEnforced()) + || LLSelectMgr::getInstance()->selectGetNonPermanentEnforced(); + bool editable = is_nonpermanent_enforced && (first_object->permModify() || selectedMediaEditable()); + + // Check modify permissions and whether any selected objects are in + // the process of being fetched. If they are, then we're not editable + if (editable) + { + LLObjectSelection::iterator iter = selected_objects->begin(); + LLObjectSelection::iterator end = selected_objects->end(); + for ( ; iter != end; ++iter) + { + LLSelectNode* node = *iter; + LLVOVolume* object = dynamic_cast(node->getObject()); + if (NULL != object) + { + if (!object->permModify()) + { + LL_INFOS("LLFloaterTools: media") + << "Selection not editable due to lack of modify permissions on object id " + << object->getID() << LL_ENDL; + + editable = false; + break; + } + // XXX DISABLE this for now, because when the fetch finally + // does come in, the state of this floater doesn't properly + // update. Re-selecting fixes the problem, but there is + // contention as to whether this is a sufficient solution. +// if (object->isMediaDataBeingFetched()) +// { +// LL_INFOS("LLFloaterTools: media") +// << "Selection not editable due to media data being fetched for object id " +// << object->getID() << LL_ENDL; +// +// editable = false; +// break; +// } + } + } + } + + // Media settings + bool bool_has_media = false; + struct media_functor : public LLSelectedTEGetFunctor + { + bool get(LLViewerObject* object, S32 face) + { + LLTextureEntry *te = object->getTE(face); + if (te) + { + return te->hasMedia(); + } + return false; + } + } func; + + + // check if all faces have media(or, all dont have media) + LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue( &func, bool_has_media ); + + const LLMediaEntry default_media_data; + + struct functor_getter_media_data : public LLSelectedTEGetFunctor< LLMediaEntry> + { + functor_getter_media_data(const LLMediaEntry& entry): mMediaEntry(entry) {} + + LLMediaEntry get( LLViewerObject* object, S32 face ) + { + if ( object ) + if ( object->getTE(face) ) + if ( object->getTE(face)->getMediaData() ) + return *(object->getTE(face)->getMediaData()); + return mMediaEntry; + }; + + const LLMediaEntry& mMediaEntry; + + } func_media_data(default_media_data); + + LLMediaEntry media_data_get; + LLFloaterMediaSettings::getInstance()->mMultipleMedia = !(selected_objects->getSelectedTEValue( &func_media_data, media_data_get )); + + std::string multi_media_info_str = LLTrans::getString("Multiple Media"); + std::string media_title = ""; + mNeedMediaTitle = false; + // update UI depending on whether "object" (prim or face) has media + // and whether or not you are allowed to edit it. + + getChildView("Add_Media")->setEnabled(editable); + // IF all the faces have media (or all dont have media) + if ( LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo ) + { + // TODO: get media title and set it. + media_info->setValue(""); + // if identical is set, all faces are same (whether all empty or has the same media) + if(!(LLFloaterMediaSettings::getInstance()->mMultipleMedia) ) + { + // Media data is valid + if(media_data_get!=default_media_data) + { + // initial media title is the media URL (until we get the name) + media_title = media_data_get.getHomeURL(); + + // kick off a navigate and flag that we need to update the title + navigateToTitleMedia( media_data_get.getHomeURL() ); + mNeedMediaTitle = true; + } + // else all faces might be empty. + } + else // there' re Different Medias' been set on on the faces. + { + media_title = multi_media_info_str; + mNeedMediaTitle = false; + } + + getChildView("media_tex")->setEnabled(bool_has_media && editable); + getChildView("edit_media")->setEnabled(bool_has_media && LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo && editable ); + getChildView("delete_media")->setEnabled(bool_has_media && editable ); + getChildView("add_media")->setEnabled(( ! bool_has_media ) && editable ); + // TODO: display a list of all media on the face - use 'identical' flag + } + else // not all face has media but at least one does. + { + // seleted faces have not identical value + LLFloaterMediaSettings::getInstance()->mMultipleValidMedia = selected_objects->isMultipleTEValue(&func_media_data, default_media_data ); + + if(LLFloaterMediaSettings::getInstance()->mMultipleValidMedia) + { + media_title = multi_media_info_str; + mNeedMediaTitle = false; + } + else + { + // Media data is valid + if(media_data_get!=default_media_data) + { + // initial media title is the media URL (until we get the name) + media_title = media_data_get.getHomeURL(); + + // kick off a navigate and flag that we need to update the title + navigateToTitleMedia( media_data_get.getHomeURL() ); + mNeedMediaTitle = true; + } + } + + getChildView("media_tex")->setEnabled(TRUE); + getChildView("edit_media")->setEnabled(LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo); + getChildView("delete_media")->setEnabled(TRUE); + getChildView("add_media")->setEnabled(FALSE ); + } + media_info->setText(media_title); + + // load values for media settings + updateMediaSettings(); + + if(mTitleMedia) + LLFloaterMediaSettings::initValues(mMediaSettings, editable ); +} +////////////////////////////////////////////////////////////////////////////// +// called when a user wants to add media to a prim or prim face +void LLFloaterTools::onClickBtnAddMedia() +{ + // check if multiple faces are selected + if(LLSelectMgr::getInstance()->getSelection()->isMultipleTESelected()) + { + LLNotificationsUtil::add("MultipleFacesSelected", LLSD(), LLSD(), multipleFacesSelectedConfirm); + } + else + { + onClickBtnEditMedia(); + } +} + +// static +bool LLFloaterTools::multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + switch( option ) + { + case 0: // "Yes" + gFloaterTools->onClickBtnEditMedia(); + break; + case 1: // "No" + default: + break; + } + return false; +} + +////////////////////////////////////////////////////////////////////////////// +// called when a user wants to edit existing media settings on a prim or prim face +// TODO: test if there is media on the item and only allow editing if present +void LLFloaterTools::onClickBtnEditMedia() +{ + refreshMedia(); + LLFloaterMediaSettings::getInstance()->open(); + LLFloaterMediaSettings::getInstance()->setVisible(TRUE); + const LLRect& rect = getRect(); + U32 height_offset = rect.getHeight() - LLFloaterMediaSettings::getInstance()->getRect().getHeight(); + LLFloaterMediaSettings::getInstance()->setOrigin(rect.mRight, rect.mBottom + height_offset); +} + +////////////////////////////////////////////////////////////////////////////// +// called when a user wants to delete media from a prim or prim face +void LLFloaterTools::onClickBtnDeleteMedia() +{ + LLNotificationsUtil::add("DeleteMedia", LLSD(), LLSD(), deleteMediaConfirm); +} + + +// static +bool LLFloaterTools::deleteMediaConfirm(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + switch( option ) + { + case 0: // "Yes" + LLSelectMgr::getInstance()->selectionSetMedia( 0, LLSD() ); + if(LLFloaterMediaSettings::instanceExists()) + { + LLFloaterMediaSettings::getInstance()->close(); + } + break; + + case 1: // "No" + default: + break; + } + return false; +} + +////////////////////////////////////////////////////////////////////////////// +// +void LLFloaterTools::clearMediaSettings() +{ + LLFloaterMediaSettings::clearValues(false); +} + +////////////////////////////////////////////////////////////////////////////// +// +void LLFloaterTools::navigateToTitleMedia( const std::string url ) +{ + if ( mTitleMedia ) + { + LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin(); + if ( media_plugin ) + { + // if it's a movie, we don't want to hear it + media_plugin->setVolume( 0 ); + }; + mTitleMedia->navigateTo( url ); + }; +} + +////////////////////////////////////////////////////////////////////////////// +// +void LLFloaterTools::updateMediaTitle() +{ + // only get the media name if we need it + if ( ! mNeedMediaTitle || !mTitleMedia ) + return; + + // get plugin impl + LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin(); + if ( media_plugin ) + { + // get the media name (asynchronous - must call repeatedly) + std::string media_title = media_plugin->getMediaName(); + + // only replace the title if what we get contains something + if ( ! media_title.empty() ) + { + // update the UI widget + LLTextBox* media_title_field = getChild("media_info"); + if ( media_title_field ) + { + media_title_field->setText( media_title ); + + // stop looking for a title when we get one + // FIXME: check this is the right approach + mNeedMediaTitle = false; + }; + }; + }; +} + +////////////////////////////////////////////////////////////////////////////// +// +void LLFloaterTools::updateMediaSettings() +{ + bool identical( false ); + std::string base_key( "" ); + std::string value_str( "" ); + int value_int = 0; + bool value_bool = false; + LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection(); + // TODO: (CP) refactor this using something clever or boost or both !! + + const LLMediaEntry default_media_data; + + // controls + U8 value_u8 = default_media_data.getControls(); + struct functor_getter_controls : public LLSelectedTEGetFunctor< U8 > + { + functor_getter_controls(const LLMediaEntry &entry) : mMediaEntry(entry) {} + + U8 get( LLViewerObject* object, S32 face ) + { + if ( object ) + if ( object->getTE(face) ) + if ( object->getTE(face)->getMediaData() ) + return object->getTE(face)->getMediaData()->getControls(); + return mMediaEntry.getControls(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_controls(default_media_data); + identical = selected_objects->getSelectedTEValue( &func_controls, value_u8 ); + base_key = std::string( LLMediaEntry::CONTROLS_KEY ); + mMediaSettings[ base_key ] = value_u8; + mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; + + // First click (formerly left click) + value_bool = default_media_data.getFirstClickInteract(); + struct functor_getter_first_click : public LLSelectedTEGetFunctor< bool > + { + functor_getter_first_click(const LLMediaEntry& entry): mMediaEntry(entry) {} + + bool get( LLViewerObject* object, S32 face ) + { + if ( object ) + if ( object->getTE(face) ) + if ( object->getTE(face)->getMediaData() ) + return object->getTE(face)->getMediaData()->getFirstClickInteract(); + return mMediaEntry.getFirstClickInteract(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_first_click(default_media_data); + identical = selected_objects->getSelectedTEValue( &func_first_click, value_bool ); + base_key = std::string( LLMediaEntry::FIRST_CLICK_INTERACT_KEY ); + mMediaSettings[ base_key ] = value_bool; + mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; + + // Home URL + value_str = default_media_data.getHomeURL(); + struct functor_getter_home_url : public LLSelectedTEGetFunctor< std::string > + { + functor_getter_home_url(const LLMediaEntry& entry): mMediaEntry(entry) {} + + std::string get( LLViewerObject* object, S32 face ) + { + if ( object ) + if ( object->getTE(face) ) + if ( object->getTE(face)->getMediaData() ) + return object->getTE(face)->getMediaData()->getHomeURL(); + return mMediaEntry.getHomeURL(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_home_url(default_media_data); + identical = selected_objects->getSelectedTEValue( &func_home_url, value_str ); + base_key = std::string( LLMediaEntry::HOME_URL_KEY ); + mMediaSettings[ base_key ] = value_str; + mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; + + // Current URL + value_str = default_media_data.getCurrentURL(); + struct functor_getter_current_url : public LLSelectedTEGetFunctor< std::string > + { + functor_getter_current_url(const LLMediaEntry& entry): mMediaEntry(entry) {} + + std::string get( LLViewerObject* object, S32 face ) + { + if ( object ) + if ( object->getTE(face) ) + if ( object->getTE(face)->getMediaData() ) + return object->getTE(face)->getMediaData()->getCurrentURL(); + return mMediaEntry.getCurrentURL(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_current_url(default_media_data); + identical = selected_objects->getSelectedTEValue( &func_current_url, value_str ); + base_key = std::string( LLMediaEntry::CURRENT_URL_KEY ); + mMediaSettings[ base_key ] = value_str; + mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; + + // Auto zoom + value_bool = default_media_data.getAutoZoom(); + struct functor_getter_auto_zoom : public LLSelectedTEGetFunctor< bool > + { + + functor_getter_auto_zoom(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get( LLViewerObject* object, S32 face ) + { + if ( object ) + if ( object->getTE(face) ) + if ( object->getTE(face)->getMediaData() ) + return object->getTE(face)->getMediaData()->getAutoZoom(); + return mMediaEntry.getAutoZoom(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_auto_zoom(default_media_data); + identical = selected_objects->getSelectedTEValue( &func_auto_zoom, value_bool ); + base_key = std::string( LLMediaEntry::AUTO_ZOOM_KEY ); + mMediaSettings[ base_key ] = value_bool; + mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; + + // Auto play + //value_bool = default_media_data.getAutoPlay(); + // set default to auto play TRUE -- angela EXT-5172 + value_bool = true; + struct functor_getter_auto_play : public LLSelectedTEGetFunctor< bool > + { + functor_getter_auto_play(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get( LLViewerObject* object, S32 face ) + { + if ( object ) + if ( object->getTE(face) ) + if ( object->getTE(face)->getMediaData() ) + return object->getTE(face)->getMediaData()->getAutoPlay(); + //return mMediaEntry.getAutoPlay(); set default to auto play TRUE -- angela EXT-5172 + return true; + }; + + const LLMediaEntry &mMediaEntry; + + } func_auto_play(default_media_data); + identical = selected_objects->getSelectedTEValue( &func_auto_play, value_bool ); + base_key = std::string( LLMediaEntry::AUTO_PLAY_KEY ); + mMediaSettings[ base_key ] = value_bool; + mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; + + + // Auto scale + // set default to auto scale TRUE -- angela EXT-5172 + //value_bool = default_media_data.getAutoScale(); + value_bool = true; + struct functor_getter_auto_scale : public LLSelectedTEGetFunctor< bool > + { + functor_getter_auto_scale(const LLMediaEntry& entry): mMediaEntry(entry) {} + + bool get( LLViewerObject* object, S32 face ) + { + if ( object ) + if ( object->getTE(face) ) + if ( object->getTE(face)->getMediaData() ) + return object->getTE(face)->getMediaData()->getAutoScale(); + // return mMediaEntry.getAutoScale(); set default to auto scale TRUE -- angela EXT-5172 + return true; + }; + + const LLMediaEntry &mMediaEntry; + + } func_auto_scale(default_media_data); + identical = selected_objects->getSelectedTEValue( &func_auto_scale, value_bool ); + base_key = std::string( LLMediaEntry::AUTO_SCALE_KEY ); + mMediaSettings[ base_key ] = value_bool; + mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; + + // Auto loop + value_bool = default_media_data.getAutoLoop(); + struct functor_getter_auto_loop : public LLSelectedTEGetFunctor< bool > + { + functor_getter_auto_loop(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get( LLViewerObject* object, S32 face ) + { + if ( object ) + if ( object->getTE(face) ) + if ( object->getTE(face)->getMediaData() ) + return object->getTE(face)->getMediaData()->getAutoLoop(); + return mMediaEntry.getAutoLoop(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_auto_loop(default_media_data); + identical = selected_objects->getSelectedTEValue( &func_auto_loop, value_bool ); + base_key = std::string( LLMediaEntry::AUTO_LOOP_KEY ); + mMediaSettings[ base_key ] = value_bool; + mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; + + // width pixels (if not auto scaled) + value_int = default_media_data.getWidthPixels(); + struct functor_getter_width_pixels : public LLSelectedTEGetFunctor< int > + { + functor_getter_width_pixels(const LLMediaEntry& entry): mMediaEntry(entry) {} + + int get( LLViewerObject* object, S32 face ) + { + if ( object ) + if ( object->getTE(face) ) + if ( object->getTE(face)->getMediaData() ) + return object->getTE(face)->getMediaData()->getWidthPixels(); + return mMediaEntry.getWidthPixels(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_width_pixels(default_media_data); + identical = selected_objects->getSelectedTEValue( &func_width_pixels, value_int ); + base_key = std::string( LLMediaEntry::WIDTH_PIXELS_KEY ); + mMediaSettings[ base_key ] = value_int; + mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; + + // height pixels (if not auto scaled) + value_int = default_media_data.getHeightPixels(); + struct functor_getter_height_pixels : public LLSelectedTEGetFunctor< int > + { + functor_getter_height_pixels(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + int get( LLViewerObject* object, S32 face ) + { + if ( object ) + if ( object->getTE(face) ) + if ( object->getTE(face)->getMediaData() ) + return object->getTE(face)->getMediaData()->getHeightPixels(); + return mMediaEntry.getHeightPixels(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_height_pixels(default_media_data); + identical = selected_objects->getSelectedTEValue( &func_height_pixels, value_int ); + base_key = std::string( LLMediaEntry::HEIGHT_PIXELS_KEY ); + mMediaSettings[ base_key ] = value_int; + mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; + + // Enable Alt image + value_bool = default_media_data.getAltImageEnable(); + struct functor_getter_enable_alt_image : public LLSelectedTEGetFunctor< bool > + { + functor_getter_enable_alt_image(const LLMediaEntry& entry): mMediaEntry(entry) {} + + bool get( LLViewerObject* object, S32 face ) + { + if ( object ) + if ( object->getTE(face) ) + if ( object->getTE(face)->getMediaData() ) + return object->getTE(face)->getMediaData()->getAltImageEnable(); + return mMediaEntry.getAltImageEnable(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_enable_alt_image(default_media_data); + identical = selected_objects->getSelectedTEValue( &func_enable_alt_image, value_bool ); + base_key = std::string( LLMediaEntry::ALT_IMAGE_ENABLE_KEY ); + mMediaSettings[ base_key ] = value_bool; + mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; + + // Perms - owner interact + value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_OWNER ); + struct functor_getter_perms_owner_interact : public LLSelectedTEGetFunctor< bool > + { + functor_getter_perms_owner_interact(const LLMediaEntry& entry): mMediaEntry(entry) {} + + bool get( LLViewerObject* object, S32 face ) + { + if ( object ) + if ( object->getTE(face) ) + if ( object->getTE(face)->getMediaData() ) + return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_OWNER)); + return 0 != ( mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_OWNER ); + }; + + const LLMediaEntry &mMediaEntry; + + } func_perms_owner_interact(default_media_data); + identical = selected_objects->getSelectedTEValue( &func_perms_owner_interact, value_bool ); + base_key = std::string( LLPanelContents::PERMS_OWNER_INTERACT_KEY ); + mMediaSettings[ base_key ] = value_bool; + mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; + + // Perms - owner control + value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_OWNER ); + struct functor_getter_perms_owner_control : public LLSelectedTEGetFunctor< bool > + { + functor_getter_perms_owner_control(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get( LLViewerObject* object, S32 face ) + { + if ( object ) + if ( object->getTE(face) ) + if ( object->getTE(face)->getMediaData() ) + return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_OWNER)); + return 0 != ( mMediaEntry.getPermsControl() & LLMediaEntry::PERM_OWNER ); + }; + + const LLMediaEntry &mMediaEntry; + + } func_perms_owner_control(default_media_data); + identical = selected_objects ->getSelectedTEValue( &func_perms_owner_control, value_bool ); + base_key = std::string( LLPanelContents::PERMS_OWNER_CONTROL_KEY ); + mMediaSettings[ base_key ] = value_bool; + mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; + + // Perms - group interact + value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_GROUP ); + struct functor_getter_perms_group_interact : public LLSelectedTEGetFunctor< bool > + { + functor_getter_perms_group_interact(const LLMediaEntry& entry): mMediaEntry(entry) {} + + bool get( LLViewerObject* object, S32 face ) + { + if ( object ) + if ( object->getTE(face) ) + if ( object->getTE(face)->getMediaData() ) + return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_GROUP)); + return 0 != ( mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_GROUP ); + }; + + const LLMediaEntry &mMediaEntry; + + } func_perms_group_interact(default_media_data); + identical = selected_objects->getSelectedTEValue( &func_perms_group_interact, value_bool ); + base_key = std::string( LLPanelContents::PERMS_GROUP_INTERACT_KEY ); + mMediaSettings[ base_key ] = value_bool; + mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; + + // Perms - group control + value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_GROUP ); + struct functor_getter_perms_group_control : public LLSelectedTEGetFunctor< bool > + { + functor_getter_perms_group_control(const LLMediaEntry& entry): mMediaEntry(entry) {} + + bool get( LLViewerObject* object, S32 face ) + { + if ( object ) + if ( object->getTE(face) ) + if ( object->getTE(face)->getMediaData() ) + return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_GROUP)); + return 0 != ( mMediaEntry.getPermsControl() & LLMediaEntry::PERM_GROUP ); + }; + + const LLMediaEntry &mMediaEntry; + + } func_perms_group_control(default_media_data); + identical = selected_objects->getSelectedTEValue( &func_perms_group_control, value_bool ); + base_key = std::string( LLPanelContents::PERMS_GROUP_CONTROL_KEY ); + mMediaSettings[ base_key ] = value_bool; + mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; + + // Perms - anyone interact + value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_ANYONE ); + struct functor_getter_perms_anyone_interact : public LLSelectedTEGetFunctor< bool > + { + functor_getter_perms_anyone_interact(const LLMediaEntry& entry): mMediaEntry(entry) {} + + bool get( LLViewerObject* object, S32 face ) + { + if ( object ) + if ( object->getTE(face) ) + if ( object->getTE(face)->getMediaData() ) + return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_ANYONE)); + return 0 != ( mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_ANYONE ); + }; + + const LLMediaEntry &mMediaEntry; + + } func_perms_anyone_interact(default_media_data); + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func_perms_anyone_interact, value_bool ); + base_key = std::string( LLPanelContents::PERMS_ANYONE_INTERACT_KEY ); + mMediaSettings[ base_key ] = value_bool; + mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; + + // Perms - anyone control + value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_ANYONE ); + struct functor_getter_perms_anyone_control : public LLSelectedTEGetFunctor< bool > + { + functor_getter_perms_anyone_control(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get( LLViewerObject* object, S32 face ) + { + if ( object ) + if ( object->getTE(face) ) + if ( object->getTE(face)->getMediaData() ) + return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_ANYONE)); + return 0 != ( mMediaEntry.getPermsControl() & LLMediaEntry::PERM_ANYONE ); + }; + + const LLMediaEntry &mMediaEntry; + + } func_perms_anyone_control(default_media_data); + identical = selected_objects->getSelectedTEValue( &func_perms_anyone_control, value_bool ); + base_key = std::string( LLPanelContents::PERMS_ANYONE_CONTROL_KEY ); + mMediaSettings[ base_key ] = value_bool; + mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; + + // security - whitelist enable + value_bool = default_media_data.getWhiteListEnable(); + struct functor_getter_whitelist_enable : public LLSelectedTEGetFunctor< bool > + { + functor_getter_whitelist_enable(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get( LLViewerObject* object, S32 face ) + { + if ( object ) + if ( object->getTE(face) ) + if ( object->getTE(face)->getMediaData() ) + return object->getTE(face)->getMediaData()->getWhiteListEnable(); + return mMediaEntry.getWhiteListEnable(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_whitelist_enable(default_media_data); + identical = selected_objects->getSelectedTEValue( &func_whitelist_enable, value_bool ); + base_key = std::string( LLMediaEntry::WHITELIST_ENABLE_KEY ); + mMediaSettings[ base_key ] = value_bool; + mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; + + // security - whitelist URLs + std::vector value_vector_str = default_media_data.getWhiteList(); + struct functor_getter_whitelist_urls : public LLSelectedTEGetFunctor< std::vector > + { + functor_getter_whitelist_urls(const LLMediaEntry& entry): mMediaEntry(entry) {} + + std::vector get( LLViewerObject* object, S32 face ) + { + if ( object ) + if ( object->getTE(face) ) + if ( object->getTE(face)->getMediaData() ) + return object->getTE(face)->getMediaData()->getWhiteList(); + return mMediaEntry.getWhiteList(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_whitelist_urls(default_media_data); + identical = selected_objects->getSelectedTEValue( &func_whitelist_urls, value_vector_str ); + base_key = std::string( LLMediaEntry::WHITELIST_KEY ); + mMediaSettings[ base_key ].clear(); + std::vector< std::string >::iterator iter = value_vector_str.begin(); + while( iter != value_vector_str.end() ) + { + std::string white_list_url = *iter; + mMediaSettings[ base_key ].append( white_list_url ); + ++iter; + }; + + mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; +} + // static void LLFloaterTools::onSelectTreesGrass(LLUICtrl*, void*) { @@ -1159,3 +2022,4 @@ void LLFloaterTools::updateTreeGrassCombo(bool visible) mComboTreesGrass->setVisible(visible); tree_grass_label->setVisible(visible); } + diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h index 84e04df69..fec736819 100644 --- a/indra/newview/llfloatertools.h +++ b/indra/newview/llfloatertools.h @@ -49,6 +49,7 @@ class LLPanelLandInfo; class LLSlider; class LLTabContainer; class LLTextBox; +class LLMediaCtrl; class LLTool; class LLParcelSelection; class LLObjectSelection; @@ -102,12 +103,23 @@ public: static void setEditTool(void* data); void setTool(const LLSD& user_data); void saveLastTool(); + void onClickBtnDeleteMedia(); + void onClickBtnAddMedia(); + void onClickBtnEditMedia(); + void clearMediaSettings(); + void updateMediaTitle(); + void navigateToTitleMedia( const std::string url ); + bool selectedMediaEditable(); private: void refresh(); - + void refreshMedia(); + void getMediaState(); + void updateMediaSettings(); + static bool deleteMediaConfirm(const LLSD& notification, const LLSD& response); + static bool multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response); static void setObjectType( LLPCode pcode ); - static void onClickGridOptions(void* data); + void onClickGridOptions(); public: LLButton *mBtnFocus; @@ -191,6 +203,8 @@ public: LLParcelSelectionHandle mParcelSelection; LLObjectSelectionHandle mObjectSelection; + LLMediaCtrl *mTitleMedia; + bool mNeedMediaTitle; private: BOOL mDirty; @@ -198,6 +212,8 @@ private: void updateTreeGrassCombo(bool visible); static void onSelectTreesGrass(LLUICtrl*, void*); +protected: + LLSD mMediaSettings; }; extern LLFloaterTools *gFloaterTools; diff --git a/indra/newview/llfloaterwhitelistentry.cpp b/indra/newview/llfloaterwhitelistentry.cpp new file mode 100644 index 000000000..f930e0940 --- /dev/null +++ b/indra/newview/llfloaterwhitelistentry.cpp @@ -0,0 +1,91 @@ +/** + * @file llfloaterwhitelistentry.cpp + * @brief LLFloaterWhistListEntry class implementation + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloatermediasettings.h" +#include "llfloaterwhitelistentry.h" +#include "llpanelmediasettingssecurity.h" +#include "lluictrlfactory.h" +#include "llwindow.h" +#include "llviewerwindow.h" +#include "lllineeditor.h" + + +/////////////////////////////////////////////////////////////////////////////// +// +LLFloaterWhiteListEntry::LLFloaterWhiteListEntry() : + LLFloater() +{ + LLUICtrlFactory::getInstance()->buildFloater(this, "floater_whitelist_entry.xml"); +} + +/////////////////////////////////////////////////////////////////////////////// +// +LLFloaterWhiteListEntry::~LLFloaterWhiteListEntry() +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// +BOOL LLFloaterWhiteListEntry::postBuild() +{ + mWhiteListEdit = getChild("whitelist_entry"); + + childSetAction("cancel_btn", onBtnCancel, this); + childSetAction("ok_btn", onBtnOK, this); + + setDefaultBtn("ok_btn"); + + return TRUE; +} + +/////////////////////////////////////////////////////////////////////////////// +// static +void LLFloaterWhiteListEntry::onBtnOK( void* userdata ) +{ + LLFloaterWhiteListEntry *self =(LLFloaterWhiteListEntry *)userdata; + + LLPanelMediaSettingsSecurity* panel = LLFloaterMediaSettings::instanceExists() ? LLFloaterMediaSettings::getInstance()->getPanelSecurity() : NULL; + if ( panel ) + { + std::string white_list_item = self->mWhiteListEdit->getText(); + + panel->addWhiteListEntry( white_list_item ); + panel->updateWhitelistEnableStatus(); + }; + + self->close(); +} + +/////////////////////////////////////////////////////////////////////////////// +// static +void LLFloaterWhiteListEntry::onBtnCancel( void* userdata ) +{ + LLFloaterWhiteListEntry *self =(LLFloaterWhiteListEntry *)userdata; + + self->close(); +} diff --git a/indra/newview/llfloaterwhitelistentry.h b/indra/newview/llfloaterwhitelistentry.h new file mode 100644 index 000000000..da23b1ebf --- /dev/null +++ b/indra/newview/llfloaterwhitelistentry.h @@ -0,0 +1,50 @@ +/** + * @file llfloaterwhitelistentry.h + * @brief LLFloaterWhiteListEntry class definition + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLFLOATERWHITELISTENTRY_H +#define LL_LLFLOATERWHITELISTENTRY_H + +#include "llfloater.h" + +class LLLineEditor; + +class LLFloaterWhiteListEntry : + public LLFloater, public LLSingleton +{ + public: + LLFloaterWhiteListEntry(); + ~LLFloaterWhiteListEntry(); + + BOOL postBuild(); + + private: + LLLineEditor* mWhiteListEdit; + + static void onBtnOK(void*); + static void onBtnCancel(void*); +}; + +#endif // LL_LLFLOATERWHITELISTENTRY_H diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index af7c6d131..eeaa6aacd 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -1161,7 +1161,7 @@ LLView* LLMediaCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory if(node->getAttributeBOOL("focus_on_click", bval)) p.focus_on_click = bval; if(node->getAttributeBOOL("decouple_texture_size", bval)) - p.focus_on_click = bval; + p.decouple_texture_size = bval; if(node->getAttributeBOOL("trusted_content", bval)) p.trusted_content = bval; if(node->getAttributeS32("texture_width", ival)) diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp index 5eda11310..c44a855b7 100644 --- a/indra/newview/llpanelcontents.cpp +++ b/indra/newview/llpanelcontents.cpp @@ -82,6 +82,13 @@ // // Globals // +const char* LLPanelContents::TENTATIVE_SUFFIX = "_tentative"; +const char* LLPanelContents::PERMS_OWNER_INTERACT_KEY = "perms_owner_interact"; +const char* LLPanelContents::PERMS_OWNER_CONTROL_KEY = "perms_owner_control"; +const char* LLPanelContents::PERMS_GROUP_INTERACT_KEY = "perms_group_interact"; +const char* LLPanelContents::PERMS_GROUP_CONTROL_KEY = "perms_group_control"; +const char* LLPanelContents::PERMS_ANYONE_INTERACT_KEY = "perms_anyone_interact"; +const char* LLPanelContents::PERMS_ANYONE_CONTROL_KEY = "perms_anyone_control"; BOOL LLPanelContents::postBuild() { diff --git a/indra/newview/llpanelcontents.h b/indra/newview/llpanelcontents.h index b7b103d5b..8e4aa7c4e 100644 --- a/indra/newview/llpanelcontents.h +++ b/indra/newview/llpanelcontents.h @@ -54,6 +54,17 @@ public: static void onClickNewScript( void* userdata); static void onClickPermissions( void* userdata); + // Key suffix for "tentative" fields + static const char* TENTATIVE_SUFFIX; + + // These aren't fields in LLMediaEntry, so we have to define them ourselves for checkbox control + static const char* PERMS_OWNER_INTERACT_KEY; + static const char* PERMS_OWNER_CONTROL_KEY; + static const char* PERMS_GROUP_INTERACT_KEY; + static const char* PERMS_GROUP_CONTROL_KEY; + static const char* PERMS_ANYONE_INTERACT_KEY; + static const char* PERMS_ANYONE_CONTROL_KEY; + protected: void getState(LLViewerObject *object); diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 2d7da3bc7..1e6269fa0 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -79,6 +79,22 @@ BOOL LLPanelFace::postBuild() { + childSetCommitCallback("combobox shininess",&LLPanelFace::onCommitShiny,this); + childSetCommitCallback("combobox bumpiness",&LLPanelFace::onCommitBump,this); + + childSetCommitCallback("TexScaleU",&LLPanelFace::onCommitTextureInfo, this); + childSetCommitCallback("checkbox flip s",&LLPanelFace::onCommitTextureInfo, this); + childSetCommitCallback("TexScaleV",&LLPanelFace::onCommitTextureInfo, this); + childSetCommitCallback("checkbox flip t",&LLPanelFace::onCommitTextureInfo, this); + childSetCommitCallback("TexRot",&LLPanelFace::onCommitTextureInfo, this); + childSetAction("button apply",&LLPanelFace::onClickApply,this); + childSetCommitCallback("checkbox planar align",&LLPanelFace::onCommitPlanarAlign, this); + childSetCommitCallback("TexOffsetU",LLPanelFace::onCommitTextureInfo, this); + childSetCommitCallback("TexOffsetV",LLPanelFace::onCommitTextureInfo, this); + childSetAction("button align",&LLPanelFace::onClickAutoFix,this); + childSetAction("copytextures",&LLPanelFace::onClickCopy,this); + childSetAction("pastetextures",&LLPanelFace::onClickPaste,this); + LLTextureCtrl* mTextureCtrl; LLColorSwatchCtrl* mColorSwatch; @@ -96,7 +112,7 @@ BOOL LLPanelFace::postBuild() if(mTextureCtrl) { mTextureCtrl->setDefaultImageAssetID(LLUUID( gSavedSettings.getString( "DefaultObjectTexture" ))); - mTextureCtrl->setCommitCallback( LLPanelFace::onCommitTexture ); + mTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitTexture, this, _2) ); mTextureCtrl->setOnCancelCallback( LLPanelFace::onCancelTexture ); mTextureCtrl->setOnSelectCallback( LLPanelFace::onSelectTexture ); mTextureCtrl->setDragCallback(LLPanelFace::onDragTexture); @@ -127,7 +143,7 @@ BOOL LLPanelFace::postBuild() mColorSwatch = getChild("colorswatch"); if(mColorSwatch) { - mColorSwatch->setCommitCallback(LLPanelFace::onCommitColor); + mColorSwatch->setCommitCallback(boost::bind(&LLPanelFace::onCommitColor, this, _2)); mColorSwatch->setOnCancelCallback(LLPanelFace::onCancelColor); mColorSwatch->setOnSelectCallback(LLPanelFace::onSelectColor); mColorSwatch->setCallbackUserData( this ); @@ -146,8 +162,7 @@ BOOL LLPanelFace::postBuild() mCtrlColorTransp = getChild("ColorTrans"); if(mCtrlColorTransp) { - mCtrlColorTransp->setCommitCallback(LLPanelFace::onCommitAlpha); - mCtrlColorTransp->setCallbackUserData(this); + mCtrlColorTransp->setCommitCallback(boost::bind(&LLPanelFace::onCommitAlpha, this, _2)); mCtrlColorTransp->setPrecision(0); mCtrlColorTransp->setFollowsTop(); mCtrlColorTransp->setFollowsLeft(); @@ -156,39 +171,22 @@ BOOL LLPanelFace::postBuild() mCheckFullbright = getChild("checkbox fullbright"); if (mCheckFullbright) { - mCheckFullbright->setCommitCallback(LLPanelFace::onCommitFullbright); - mCheckFullbright->setCallbackUserData( this ); + mCheckFullbright->setCommitCallback(LLPanelFace::onCommitFullbright, this); } mComboTexGen = getChild("combobox texgen"); if(mComboTexGen) { - mComboTexGen->setCommitCallback(LLPanelFace::onCommitTexGen); + mComboTexGen->setCommitCallback(LLPanelFace::onCommitTexGen, this); mComboTexGen->setFollows(FOLLOWS_LEFT | FOLLOWS_TOP); - mComboTexGen->setCallbackUserData( this ); } mCtrlGlow = getChild("glow"); if(mCtrlGlow) { - mCtrlGlow->setCommitCallback(LLPanelFace::onCommitGlow); - mCtrlGlow->setCallbackUserData(this); + mCtrlGlow->setCommitCallback(LLPanelFace::onCommitGlow, this); } - childSetCommitCallback("combobox shininess",&LLPanelFace::onCommitShiny,this); - childSetCommitCallback("combobox bumpiness",&LLPanelFace::onCommitBump,this); - childSetCommitCallback("checkbox planar align",&LLPanelFace::onCommitPlanarAlign, this); - childSetCommitCallback("TexScaleU",&LLPanelFace::onCommitTextureInfo, this); - childSetCommitCallback("checkbox flip s",&LLPanelFace::onCommitTextureInfo, this); - childSetCommitCallback("TexScaleV",&LLPanelFace::onCommitTextureInfo, this); - childSetCommitCallback("checkbox flip t",&LLPanelFace::onCommitTextureInfo, this); - childSetCommitCallback("TexRot",&LLPanelFace::onCommitTextureInfo, this); - childSetAction("button apply",&onClickApply,this); - childSetCommitCallback("TexOffsetU",LLPanelFace::onCommitTextureInfo, this); - childSetCommitCallback("TexOffsetV",LLPanelFace::onCommitTextureInfo, this); - childSetAction("button align",onClickAutoFix,this); - childSetAction("copytextures",onClickCopy,this); - childSetAction("pastetextures",onClickPaste,this); clearCtrls(); @@ -521,12 +519,9 @@ void LLPanelFace::getState() { BOOL editable = objectp->permModify() && !objectp->isPermanentEnforced(); - // only turn on auto-adjust button if there is a media renderer and the media is loaded - childSetEnabled("textbox autofix",FALSE); - //mLabelTexAutoFix->setEnabled ( FALSE ); - childSetEnabled("button align",FALSE); - //mBtnAutoFix->setEnabled ( FALSE ); + getChildView("textbox autofix")->setEnabled(editable); + getChildView("button align")->setEnabled(editable); //if ( LLMediaEngine::getInstance()->getMediaRenderer () ) // if ( LLMediaEngine::getInstance()->getMediaRenderer ()->isLoaded () ) @@ -543,7 +538,7 @@ void LLPanelFace::getState() childSetEnabled("copytextures", single_volume && editable); childSetEnabled("pastetextures", single_volume && editable); childSetEnabled("textbox params", single_volume && editable); - childSetEnabled("button apply",editable); + getChildView("button apply")->setEnabled(editable); bool identical; LLTextureCtrl* texture_ctrl = getChild("texture control"); @@ -684,7 +679,7 @@ void LLPanelFace::getState() // Texture scale { - childSetEnabled("tex scale",editable); + getChildView("tex scale")->setEnabled(editable); //mLabelTexScale->setEnabled( editable ); F32 scale_s = 1.f; struct f2 : public LLSelectedTEGetFunctor @@ -696,12 +691,12 @@ void LLPanelFace::getState() } func; identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, scale_s ); identical = align_planar ? identical_planar_aligned : identical; - childSetValue("TexScaleU",editable ? llabs(scale_s) : 0); - childSetTentative("TexScaleU",LLSD((BOOL)(!identical))); - childSetEnabled("TexScaleU",editable); - childSetValue("checkbox flip s",LLSD((BOOL)(scale_s < 0 ? TRUE : FALSE ))); - childSetTentative("checkbox flip s",LLSD((BOOL)((!identical) ? TRUE : FALSE ))); - childSetEnabled("checkbox flip s",editable); + getChild("TexScaleU")->setValue(editable ? llabs(scale_s) : 0); + getChild("TexScaleU")->setTentative(LLSD((BOOL)(!identical))); + getChildView("TexScaleU")->setEnabled(editable); + getChild("checkbox flip s")->setValue(LLSD((BOOL)(scale_s < 0 ? TRUE : FALSE ))); + getChild("checkbox flip s")->setTentative(LLSD((BOOL)((!identical) ? TRUE : FALSE ))); + getChildView("checkbox flip s")->setEnabled(editable); } { @@ -716,17 +711,17 @@ void LLPanelFace::getState() identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, scale_t ); identical = align_planar ? identical_planar_aligned : identical; - childSetValue("TexScaleV",llabs(editable ? llabs(scale_t) : 0)); - childSetTentative("TexScaleV",LLSD((BOOL)(!identical))); - childSetEnabled("TexScaleV",editable); - childSetValue("checkbox flip t",LLSD((BOOL)(scale_t< 0 ? TRUE : FALSE ))); - childSetTentative("checkbox flip t",LLSD((BOOL)((!identical) ? TRUE : FALSE ))); - childSetEnabled("checkbox flip t",editable); + getChild("TexScaleV")->setValue(llabs(editable ? llabs(scale_t) : 0)); + getChild("TexScaleV")->setTentative(LLSD((BOOL)(!identical))); + getChildView("TexScaleV")->setEnabled(editable); + getChild("checkbox flip t")->setValue(LLSD((BOOL)(scale_t< 0 ? TRUE : FALSE ))); + getChild("checkbox flip t")->setTentative(LLSD((BOOL)((!identical) ? TRUE : FALSE ))); + getChildView("checkbox flip t")->setEnabled(editable); } // Texture offset { - childSetEnabled("tex offset",editable); + getChildView("tex offset")->setEnabled(editable); F32 offset_s = 0.f; struct f4 : public LLSelectedTEGetFunctor { @@ -737,9 +732,9 @@ void LLPanelFace::getState() } func; identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, offset_s ); identical = align_planar ? identical_planar_aligned : identical; - childSetValue("TexOffsetU", editable ? offset_s : 0); - childSetTentative("TexOffsetU",!identical); - childSetEnabled("TexOffsetU",editable); + getChild("TexOffsetU")->setValue(editable ? offset_s : 0); + getChild("TexOffsetU")->setTentative(!identical); + getChildView("TexOffsetU")->setEnabled(editable); } { @@ -753,14 +748,14 @@ void LLPanelFace::getState() } func; identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, offset_t ); identical = align_planar ? identical_planar_aligned : identical; - childSetValue("TexOffsetV", editable ? offset_t : 0); - childSetTentative("TexOffsetV",!identical); - childSetEnabled("TexOffsetV",editable); + getChild("TexOffsetV")->setValue(editable ? offset_t : 0); + getChild("TexOffsetV")->setTentative(!identical); + getChildView("TexOffsetV")->setEnabled(editable); } // Texture rotation { - childSetEnabled("tex rotate",editable); + getChildView("tex rotate")->setEnabled(editable); F32 rotation = 0.f; struct f6 : public LLSelectedTEGetFunctor { @@ -771,9 +766,9 @@ void LLPanelFace::getState() } func; identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, rotation ); identical = align_planar ? identical_planar_aligned : identical; - childSetValue("TexRot", editable ? rotation * RAD_TO_DEG : 0); - childSetTentative("TexRot",!identical); - childSetEnabled("TexRot",editable); + getChild("TexRot")->setValue(editable ? rotation * RAD_TO_DEG : 0); + getChild("TexRot")->setTentative(!identical); + getChildView("TexRot")->setEnabled(editable); } // Color swatch @@ -799,13 +794,13 @@ void LLPanelFace::getState() } // Color transparency { - childSetEnabled("color trans",editable); + getChildView("color trans")->setEnabled(editable); } F32 transparency = (1.f - color.mV[VALPHA]) * 100.f; { - childSetValue("ColorTrans", editable ? transparency : 0); - childSetEnabled("ColorTrans",editable); + getChild("ColorTrans")->setValue(editable ? transparency : 0); + getChildView("ColorTrans")->setEnabled(editable); } { @@ -819,10 +814,10 @@ void LLPanelFace::getState() } func; identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, glow ); - childSetValue("glow",glow); - childSetEnabled("glow",editable); - childSetTentative("glow",!identical); - childSetEnabled("glow label",editable); + getChild("glow")->setValue(glow); + getChildView("glow")->setEnabled(editable); + getChild("glow")->setTentative(!identical); + getChildView("glow label")->setEnabled(editable); } @@ -847,9 +842,9 @@ void LLPanelFace::getState() { llwarns << "failed childGetSelectionInterface for 'combobox shininess'" << llendl; } - childSetEnabled("combobox shininess",editable); - childSetTentative("combobox shininess",!identical); - childSetEnabled("label shininess",editable); + getChildView("combobox shininess")->setEnabled(editable); + getChild("combobox shininess")->setTentative(!identical); + getChildView("label shininess")->setEnabled(editable); } { @@ -872,9 +867,9 @@ void LLPanelFace::getState() { llwarns << "failed childGetSelectionInterface for 'combobox bumpiness'" << llendl; } - childSetEnabled("combobox bumpiness",editable); - childSetTentative("combobox bumpiness",!identical); - childSetEnabled("label bumpiness",editable); + getChildView("combobox bumpiness")->setEnabled(editable); + getChild("combobox bumpiness")->setTentative(!identical); + getChildView("label bumpiness")->setEnabled(editable); } { @@ -898,19 +893,21 @@ void LLPanelFace::getState() { llwarns << "failed childGetSelectionInterface for 'combobox texgen'" << llendl; } - childSetEnabled("combobox texgen",editable); - childSetTentative("combobox texgen",!identical); - childSetEnabled("tex gen",editable); + getChildView("combobox texgen")->setEnabled(editable); + getChild("combobox texgen")->setTentative(!identical); + getChildView("tex gen")->setEnabled(editable); if (selected_texgen == 1) { - childSetText("tex scale",getString("string repeats per meter")); - childSetValue("TexScaleU", 2.0f * childGetValue("TexScaleU").asReal() ); - childSetValue("TexScaleV", 2.0f * childGetValue("TexScaleV").asReal() ); + getChild("TexScaleU")->setValue(2.0f * getChild("TexScaleU")->getValue().asReal() ); + getChild("TexScaleV")->setValue(2.0f * getChild("TexScaleV")->getValue().asReal() ); + + // EXP-1507 (change label based on the mapping mode) + getChild("tex scale")->setValue(getString("string repeats per meter")); } else { - childSetText("tex scale",getString("string repeats per face")); + getChild("tex scale")->setValue(getString("string repeats per face")); } } @@ -926,14 +923,14 @@ void LLPanelFace::getState() } func; identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, fullbrightf ); - childSetValue("checkbox fullbright",(S32)fullbrightf); - childSetEnabled("checkbox fullbright",editable); - childSetTentative("checkbox fullbright",!identical); + getChild("checkbox fullbright")->setValue((S32)fullbrightf); + getChildView("checkbox fullbright")->setEnabled(editable); + getChild("checkbox fullbright")->setTentative(!identical); } // Repeats per meter label { - childSetEnabled("rpt",editable); + getChildView("rpt")->setEnabled(editable); } // Repeats per meter @@ -953,14 +950,14 @@ void LLPanelFace::getState() } func; identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, repeats ); - childSetValue("rptctrl", editable ? repeats : 0); - childSetTentative("rptctrl",!identical); + getChild("rptctrl")->setValue(editable ? repeats : 0); + getChild("rptctrl")->setTentative(!identical); LLComboBox* mComboTexGen = getChild("combobox texgen"); if (mComboTexGen) { BOOL enabled = editable && (!mComboTexGen || mComboTexGen->getCurrentIndex() != 1); - childSetEnabled("rptctrl",enabled); - childSetEnabled("button apply",enabled); + getChildView("rptctrl")->setEnabled(enabled); + getChildView("button apply")->setEnabled(enabled); } } @@ -994,19 +991,21 @@ void LLPanelFace::getState() mColorSwatch->setFallbackImageName("locked_image.j2c" ); mColorSwatch->setValid(FALSE); } - childSetEnabled("color trans",FALSE); - childSetEnabled("rpt",FALSE); - childSetEnabled("tex scale",FALSE); - childSetEnabled("tex offset",FALSE); - childSetEnabled("tex rotate",FALSE); - childSetEnabled("tex gen",FALSE); - childSetEnabled("label shininess",FALSE); - childSetEnabled("label bumpiness",FALSE); + getChildView("color trans")->setEnabled(FALSE); + getChildView("rpt")->setEnabled(FALSE); + getChildView("tex scale")->setEnabled(FALSE); + getChildView("tex offset")->setEnabled(FALSE); + getChildView("tex rotate")->setEnabled(FALSE); + getChildView("tex gen")->setEnabled(FALSE); + getChildView("label shininess")->setEnabled(FALSE); + getChildView("label bumpiness")->setEnabled(FALSE); - childSetEnabled("textbox autofix",FALSE); + getChildView("textbox autofix")->setEnabled(FALSE); - childSetEnabled("button align",FALSE); - childSetEnabled("button apply",FALSE); + getChildView("button align")->setEnabled(FALSE); + getChildView("button apply")->setEnabled(FALSE); + //getChildView("has media")->setEnabled(FALSE); + //getChildView("media info set")->setEnabled(FALSE); // Set variable values for numeric expressions @@ -1037,18 +1036,14 @@ F32 LLPanelFace::valueGlow(LLViewerObject* object, S32 face) } -// static -void LLPanelFace::onCommitColor(LLUICtrl* ctrl, void* userdata) +void LLPanelFace::onCommitColor(const LLSD& data) { - LLPanelFace* self = (LLPanelFace*) userdata; - self->sendColor(); + sendColor(); } -// static -void LLPanelFace::onCommitAlpha(LLUICtrl* ctrl, void* userdata) +void LLPanelFace::onCommitAlpha(const LLSD& data) { - LLPanelFace* self = (LLPanelFace*) userdata; - self->sendAlpha(); + sendAlpha(); } // static @@ -1118,14 +1113,10 @@ BOOL LLPanelFace::onDragTexture(LLUICtrl*, LLInventoryItem* item, void*) return accept; } -// static -void LLPanelFace::onCommitTexture( LLUICtrl* ctrl, void* userdata ) +void LLPanelFace::onCommitTexture( const LLSD& data ) { - LLPanelFace* self = (LLPanelFace*) userdata; - LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT ); - - self->sendTexture(); + sendTexture(); } // static @@ -1138,7 +1129,7 @@ void LLPanelFace::onCancelTexture(LLUICtrl* ctrl, void* userdata) void LLPanelFace::onSelectTexture(LLUICtrl* ctrl, void* userdata) { LLPanelFace* self = (LLPanelFace*) userdata; - LLSelectMgr::getInstance()->saveSelectedObjectTextures(); + LLSelectMgr::getInstance()->saveSelectedObjectTextures(); self->sendTexture(); } @@ -1159,12 +1150,10 @@ void LLPanelFace::onClickApply(void* userdata) gFocusMgr.setKeyboardFocus( NULL ); //F32 repeats_per_meter = self->mCtrlRepeatsPerMeter->get(); - F32 repeats_per_meter = (F32)self->childGetValue( "rptctrl" ).asReal();//self->mCtrlRepeatsPerMeter->get(); + F32 repeats_per_meter = (F32)self->getChild("rptctrl")->getValue().asReal();//self->mCtrlRepeatsPerMeter->get(); LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter ); } -// commit the fit media texture to prim button - struct LLPanelFaceSetMediaFunctor : public LLSelectedTEFunctor { virtual bool apply(LLViewerObject* object, S32 te) diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 2f9a7887a..e9700a21e 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -73,17 +73,18 @@ protected: void sendGlow(); void sendMedia(); - // this function is to return TRUE if the dra should succeed. + // this function is to return TRUE if the drag should succeed. static BOOL onDragTexture(LLUICtrl* ctrl, LLInventoryItem* item, void* ud); - static void onCommitTexture( LLUICtrl* ctrl, void* userdata); - static void onCancelTexture( LLUICtrl* ctrl, void* userdata); - static void onSelectTexture( LLUICtrl* ctrl, void* userdata); - static void onCommitTextureInfo( LLUICtrl* ctrl, void* userdata); - static void onCommitColor( LLUICtrl* ctrl, void* userdata); - static void onCommitAlpha( LLUICtrl* ctrl, void* userdata); + void onCommitTexture(const LLSD& data); + static void onCancelTexture( LLUICtrl* ctrl, void* userdata); + static void onSelectTexture( LLUICtrl* ctrl, void* userdata); + void onCommitColor(const LLSD& data); + void onCommitAlpha(const LLSD& data); static void onCancelColor( LLUICtrl* ctrl, void* userdata); static void onSelectColor( LLUICtrl* ctrl, void* userdata); + + static void onCommitTextureInfo( LLUICtrl* ctrl, void* userdata); static void onCommitBump( LLUICtrl* ctrl, void* userdata); static void onCommitTexGen( LLUICtrl* ctrl, void* userdata); static void onCommitShiny( LLUICtrl* ctrl, void* userdata); diff --git a/indra/newview/llpanelmediasettingsgeneral.cpp b/indra/newview/llpanelmediasettingsgeneral.cpp new file mode 100644 index 000000000..d6fb6b2cc --- /dev/null +++ b/indra/newview/llpanelmediasettingsgeneral.cpp @@ -0,0 +1,515 @@ +/** + * @file llpanelmediasettingsgeneral.cpp + * @brief LLPanelMediaSettingsGeneral class implementation + * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llpanelmediasettingsgeneral.h" + +// library includes +#include "llcombobox.h" +#include "llcheckboxctrl.h" +#include "llnotificationsutil.h" +#include "llspinctrl.h" +#include "lluictrlfactory.h" + +// project includes +#include "llagent.h" +#include "llviewerwindow.h" +#include "llviewermedia.h" +#include "llsdutil.h" +#include "llselectmgr.h" +#include "llbutton.h" +#include "lltexturectrl.h" +#include "llurl.h" +#include "llwindow.h" +#include "llmediaentry.h" +#include "llmediactrl.h" +#include "llpanelcontents.h" +#include "llpermissions.h" +#include "llpluginclassmedia.h" +#include "llfloatermediasettings.h" +#include "llfloatertools.h" +#include "lltrans.h" +#include "lltextbox.h" +#include "llpanelmediasettingssecurity.h" + +const char *CHECKERBOARD_DATA_URL = "data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 width=%22100%%22 height=%22100%%22 %3E%3Cdefs%3E%3Cpattern id=%22checker%22 patternUnits=%22userSpaceOnUse%22 x=%220%22 y=%220%22 width=%22128%22 height=%22128%22 viewBox=%220 0 128 128%22 %3E%3Crect x=%220%22 y=%220%22 width=%2264%22 height=%2264%22 fill=%22#ddddff%22 /%3E%3Crect x=%2264%22 y=%2264%22 width=%2264%22 height=%2264%22 fill=%22#ddddff%22 /%3E%3C/pattern%3E%3C/defs%3E%3Crect x=%220%22 y=%220%22 width=%22100%%22 height=%22100%%22 fill=%22url(#checker)%22 /%3E%3C/svg%3E"; + +//////////////////////////////////////////////////////////////////////////////// +// +LLPanelMediaSettingsGeneral::LLPanelMediaSettingsGeneral() : + mAutoLoop( NULL ), + mFirstClick( NULL ), + mAutoZoom( NULL ), + mAutoPlay( NULL ), + mAutoScale( NULL ), + mWidthPixels( NULL ), + mHeightPixels( NULL ), + mHomeURL( NULL ), + mCurrentURL( NULL ), + mParent( NULL ), + mMediaEditable(false) +{ + // build dialog from XML + LLUICtrlFactory::getInstance()->buildPanel(this,"panel_media_settings_general.xml"); +} + +//////////////////////////////////////////////////////////////////////////////// +// +BOOL LLPanelMediaSettingsGeneral::postBuild() +{ + // connect member vars with UI widgets + mAutoLoop = getChild< LLCheckBoxCtrl >( LLMediaEntry::AUTO_LOOP_KEY ); + mAutoPlay = getChild< LLCheckBoxCtrl >( LLMediaEntry::AUTO_PLAY_KEY ); + mAutoScale = getChild< LLCheckBoxCtrl >( LLMediaEntry::AUTO_SCALE_KEY ); + mAutoZoom = getChild< LLCheckBoxCtrl >( LLMediaEntry::AUTO_ZOOM_KEY ); + mCurrentURL = getChild< LLTextBox >( LLMediaEntry::CURRENT_URL_KEY ); + mFirstClick = getChild< LLCheckBoxCtrl >( LLMediaEntry::FIRST_CLICK_INTERACT_KEY ); + mHeightPixels = getChild< LLSpinCtrl >( LLMediaEntry::HEIGHT_PIXELS_KEY ); + mHomeURL = getChild< LLLineEditor >( LLMediaEntry::HOME_URL_KEY ); + mWidthPixels = getChild< LLSpinCtrl >( LLMediaEntry::WIDTH_PIXELS_KEY ); + mPreviewMedia = getChild("preview_media"); + mFailWhiteListText = getChild( "home_fails_whitelist_label" ); + + // watch commit action for HOME URL + childSetCommitCallback( LLMediaEntry::HOME_URL_KEY, onCommitHomeURL, this); + childSetCommitCallback( "current_url_reset_btn",onBtnResetCurrentUrl, this); + + // interrogates controls and updates widgets as required + updateMediaPreview(); + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +LLPanelMediaSettingsGeneral::~LLPanelMediaSettingsGeneral() +{ +} + +//////////////////////////////////////////////////////////////////////////////// +// static +void LLPanelMediaSettingsGeneral::draw() +{ + // housekeeping + LLPanel::draw(); + + // TODO: we need to call this repeatedly until the floater panels are fully + // created but once we have a valid answer, we should stop looking here - the + // commit callback will handle it + checkHomeUrlPassesWhitelist(); + + // enable/disable pixel values image entry based on auto scale checkbox + if ( mAutoScale->getValue().asBoolean() == false ) + { + getChildView( LLMediaEntry::WIDTH_PIXELS_KEY )->setEnabled( true ); + getChildView( LLMediaEntry::HEIGHT_PIXELS_KEY )->setEnabled( true ); + } + else + { + getChildView( LLMediaEntry::WIDTH_PIXELS_KEY )->setEnabled( false ); + getChildView( LLMediaEntry::HEIGHT_PIXELS_KEY )->setEnabled( false ); + }; + + // enable/disable UI based on type of media + bool reset_button_is_active = true; + if( mPreviewMedia ) + { + LLPluginClassMedia* media_plugin = mPreviewMedia->getMediaPlugin(); + if( media_plugin ) + { + // turn off volume (if we can) for preview. Note: this really only + // works for QuickTime movies right now - no way to control the + // volume of a flash app embedded in a page for example + media_plugin->setVolume( 0 ); + + // some controls are only appropriate for time or browser type plugins + // so we selectively enable/disable them - need to do it in draw + // because the information from plugins arrives assynchronously + bool show_time_controls = media_plugin->pluginSupportsMediaTime(); + if ( show_time_controls ) + { + getChildView( LLMediaEntry::CURRENT_URL_KEY )->setEnabled( false ); + reset_button_is_active = false; + getChildView("current_url_label")->setEnabled(false ); + getChildView( LLMediaEntry::AUTO_LOOP_KEY )->setEnabled( true ); + } + else + { + getChildView( LLMediaEntry::CURRENT_URL_KEY )->setEnabled( true ); + reset_button_is_active = true; + getChildView("current_url_label")->setEnabled(true ); + getChildView( LLMediaEntry::AUTO_LOOP_KEY )->setEnabled( false ); + }; + }; + }; + + // current URL can change over time, update it here + updateCurrentUrl(); + + LLPermissions perm; + bool user_can_press_reset = mMediaEditable; + + // several places modify this widget so we must collect states in one place + if ( reset_button_is_active ) + { + // user has perms to press reset button and it is active + if ( user_can_press_reset ) + { + getChildView("current_url_reset_btn")->setEnabled(true ); + } + // user does not has perms to press reset button and it is active + else + { + getChildView("current_url_reset_btn")->setEnabled(false ); + }; + } + else + // reset button is inactive so we just slam it to off - other states don't matter + { + getChildView("current_url_reset_btn")->setEnabled(false ); + }; +} + +//////////////////////////////////////////////////////////////////////////////// +// static +void LLPanelMediaSettingsGeneral::clearValues( void* userdata, bool editable) +{ + LLPanelMediaSettingsGeneral *self =(LLPanelMediaSettingsGeneral *)userdata; + self->mAutoLoop->clear(); + self->mAutoPlay->clear(); + self->mAutoScale->clear(); + self->mAutoZoom ->clear(); + self->mCurrentURL->clear(); + self->mFirstClick->clear(); + self->mHeightPixels->clear(); + self->mHomeURL->clear(); + self->mWidthPixels->clear(); + self->mAutoLoop ->setEnabled(editable); + self->mAutoPlay ->setEnabled(editable); + self->mAutoScale ->setEnabled(editable); + self->mAutoZoom ->setEnabled(editable); + self->mCurrentURL ->setEnabled(editable); + self->mFirstClick ->setEnabled(editable); + self->mHeightPixels ->setEnabled(editable); + self->mHomeURL ->setEnabled(editable); + self->mWidthPixels ->setEnabled(editable); + self->updateMediaPreview(); +} + +// static +bool LLPanelMediaSettingsGeneral::isMultiple() +{ + // IF all the faces have media (or all dont have media) + if ( LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo ) + { + if(LLFloaterMediaSettings::getInstance()->mMultipleMedia) + { + return true; + } + + } + else + { + if(LLFloaterMediaSettings::getInstance()->mMultipleValidMedia) + { + return true; + } + } + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// static +void LLPanelMediaSettingsGeneral::initValues( void* userdata, const LLSD& _media_settings, bool editable) +{ + LLPanelMediaSettingsGeneral *self =(LLPanelMediaSettingsGeneral *)userdata; + self->mMediaEditable = editable; + + LLSD media_settings = _media_settings; + + if ( LLPanelMediaSettingsGeneral::isMultiple() ) + { + // *HACK: "edit" the incoming media_settings + media_settings[LLMediaEntry::CURRENT_URL_KEY] = LLTrans::getString("Multiple Media"); + media_settings[LLMediaEntry::HOME_URL_KEY] = LLTrans::getString("Multiple Media"); + } + + std::string base_key( "" ); + std::string tentative_key( "" ); + + struct + { + std::string key_name; + LLUICtrl* ctrl_ptr; + std::string ctrl_type; + + } data_set [] = + { + { LLMediaEntry::AUTO_LOOP_KEY, self->mAutoLoop, "LLCheckBoxCtrl" }, + { LLMediaEntry::AUTO_PLAY_KEY, self->mAutoPlay, "LLCheckBoxCtrl" }, + { LLMediaEntry::AUTO_SCALE_KEY, self->mAutoScale, "LLCheckBoxCtrl" }, + { LLMediaEntry::AUTO_ZOOM_KEY, self->mAutoZoom, "LLCheckBoxCtrl" }, + { LLMediaEntry::CURRENT_URL_KEY, self->mCurrentURL, "LLTextBox" }, + { LLMediaEntry::HEIGHT_PIXELS_KEY, self->mHeightPixels, "LLSpinCtrl" }, + { LLMediaEntry::HOME_URL_KEY, self->mHomeURL, "LLLineEditor" }, + { LLMediaEntry::FIRST_CLICK_INTERACT_KEY, self->mFirstClick, "LLCheckBoxCtrl" }, + { LLMediaEntry::WIDTH_PIXELS_KEY, self->mWidthPixels, "LLSpinCtrl" }, + { "", NULL , "" } + }; + + for( int i = 0; data_set[ i ].key_name.length() > 0; ++i ) + { + base_key = std::string( data_set[ i ].key_name ); + tentative_key = base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ); + // TODO: CP - I bet there is a better way to do this using Boost + if ( media_settings[ base_key ].isDefined() ) + { + if ( data_set[ i ].ctrl_type == "LLLineEditor" ) + { + static_cast< LLLineEditor* >( data_set[ i ].ctrl_ptr )-> + setText( media_settings[ base_key ].asString() ); + } + else + if ( data_set[ i ].ctrl_type == "LLCheckBoxCtrl" ) + static_cast< LLCheckBoxCtrl* >( data_set[ i ].ctrl_ptr )-> + setValue( media_settings[ base_key ].asBoolean() ); + else + if ( data_set[ i ].ctrl_type == "LLComboBox" ) + static_cast< LLComboBox* >( data_set[ i ].ctrl_ptr )-> + setCurrentByIndex( media_settings[ base_key ].asInteger() ); + else + if ( data_set[ i ].ctrl_type == "LLSpinCtrl" ) + static_cast< LLSpinCtrl* >( data_set[ i ].ctrl_ptr )-> + setValue( media_settings[ base_key ].asInteger() ); + + data_set[ i ].ctrl_ptr->setEnabled(self->mMediaEditable); + data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() ); + }; + }; + + // interrogates controls and updates widgets as required + self->updateMediaPreview(); +} + +//////////////////////////////////////////////////////////////////////////////// +// Helper to set media control to media URL as required +void LLPanelMediaSettingsGeneral::updateMediaPreview() +{ + if ( mHomeURL->getValue().asString().length() > 0 ) + { + if(mPreviewMedia->getCurrentNavUrl() != mHomeURL->getValue().asString()) + { + mPreviewMedia->navigateTo( mHomeURL->getValue().asString() ); + } + } + else + // new home URL will be empty if media is deleted so display a + // "preview goes here" data url page + { + if(mPreviewMedia->getCurrentNavUrl() != CHECKERBOARD_DATA_URL) + { + mPreviewMedia->navigateTo( CHECKERBOARD_DATA_URL ); + } + }; +} + +//////////////////////////////////////////////////////////////////////////////// + +// virtual +void LLPanelMediaSettingsGeneral::onClose(bool app_quitting) +{ + if(mPreviewMedia) + { + mPreviewMedia->unloadMediaSource(); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLPanelMediaSettingsGeneral::checkHomeUrlPassesWhitelist() +{ + // parent floater has not constructed the security panel yet + if ( mParent->getPanelSecurity() == 0 ) + return; + + std::string home_url = getHomeUrl(); + if ( home_url.empty() || mParent->getPanelSecurity()->urlPassesWhiteList( home_url ) ) + { + // Home URL is empty or passes the white list so hide the warning message + mFailWhiteListText->setVisible( false ); + } + else + { + // Home URL does not pass the white list so show the warning message + mFailWhiteListText->setVisible( true ); + }; +} + +//////////////////////////////////////////////////////////////////////////////// +// static +void LLPanelMediaSettingsGeneral::onCommitHomeURL( LLUICtrl* ctrl, void *userdata ) +{ + LLPanelMediaSettingsGeneral* self =(LLPanelMediaSettingsGeneral *)userdata; + + // check home url passes whitelist and display warning if not + self->checkHomeUrlPassesWhitelist(); + + self->updateMediaPreview(); +} + +//////////////////////////////////////////////////////////////////////////////// +// static +void LLPanelMediaSettingsGeneral::onBtnResetCurrentUrl(LLUICtrl* ctrl, void *userdata) +{ + LLPanelMediaSettingsGeneral* self =(LLPanelMediaSettingsGeneral *)userdata; + self->navigateHomeSelectedFace(false); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLPanelMediaSettingsGeneral::preApply() +{ + // Make sure the home URL entry is committed + mHomeURL->onCommit(); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLPanelMediaSettingsGeneral::getValues( LLSD &fill_me_in, bool include_tentative ) +{ + if (include_tentative || !mAutoLoop->getTentative()) fill_me_in[LLMediaEntry::AUTO_LOOP_KEY] = (LLSD::Boolean)mAutoLoop->getValue(); + if (include_tentative || !mAutoPlay->getTentative()) fill_me_in[LLMediaEntry::AUTO_PLAY_KEY] = (LLSD::Boolean)mAutoPlay->getValue(); + if (include_tentative || !mAutoScale->getTentative()) fill_me_in[LLMediaEntry::AUTO_SCALE_KEY] = (LLSD::Boolean)mAutoScale->getValue(); + if (include_tentative || !mAutoZoom->getTentative()) fill_me_in[LLMediaEntry::AUTO_ZOOM_KEY] = (LLSD::Boolean)mAutoZoom->getValue(); + //Don't fill in current URL: this is only supposed to get changed via navigate + // if (include_tentative || !mCurrentURL->getTentative()) fill_me_in[LLMediaEntry::CURRENT_URL_KEY] = mCurrentURL->getValue(); + if (include_tentative || !mHeightPixels->getTentative()) fill_me_in[LLMediaEntry::HEIGHT_PIXELS_KEY] = (LLSD::Integer)mHeightPixels->getValue(); + // Don't fill in the home URL if it is the special "Multiple Media" string! + if ((include_tentative || !mHomeURL->getTentative()) + && LLTrans::getString("Multiple Media") != mHomeURL->getValue()) + fill_me_in[LLMediaEntry::HOME_URL_KEY] = (LLSD::String)mHomeURL->getValue(); + if (include_tentative || !mFirstClick->getTentative()) fill_me_in[LLMediaEntry::FIRST_CLICK_INTERACT_KEY] = (LLSD::Boolean)mFirstClick->getValue(); + if (include_tentative || !mWidthPixels->getTentative()) fill_me_in[LLMediaEntry::WIDTH_PIXELS_KEY] = (LLSD::Integer)mWidthPixels->getValue(); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLPanelMediaSettingsGeneral::postApply() +{ + // Make sure to navigate to the home URL if the current URL is empty and + // autoplay is on + navigateHomeSelectedFace(true); +} + + +//////////////////////////////////////////////////////////////////////////////// +// +void LLPanelMediaSettingsGeneral::setParent( LLFloaterMediaSettings* parent ) +{ + mParent = parent; +}; + +//////////////////////////////////////////////////////////////////////////////// +// +bool LLPanelMediaSettingsGeneral::navigateHomeSelectedFace(bool only_if_current_is_empty) +{ + struct functor_navigate_media : public LLSelectedTEGetFunctor< bool> + { + functor_navigate_media(bool flag) : only_if_current_is_empty(flag) {} + bool get( LLViewerObject* object, S32 face ) + { + if ( object && object->getTE(face) && object->permModify() ) + { + const LLMediaEntry *media_data = object->getTE(face)->getMediaData(); + if ( media_data ) + { + if (!only_if_current_is_empty || (media_data->getCurrentURL().empty() && media_data->getAutoPlay())) + { + viewer_media_t media_impl = + LLViewerMedia::getMediaImplFromTextureID(object->getTE(face)->getMediaData()->getMediaID()); + if(media_impl) + { + media_impl->navigateHome(); + return true; + } + } + } + } + return false; + }; + bool only_if_current_is_empty; + + } functor_navigate_media(only_if_current_is_empty); + + bool all_face_media_navigated = false; + LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection(); + selected_objects->getSelectedTEValue( &functor_navigate_media, all_face_media_navigated ); + + // Note: we don't update the 'current URL' field until the media data itself changes + + return all_face_media_navigated; +} + +//////////////////////////////////////////////////////////////////////////////// +// +const std::string LLPanelMediaSettingsGeneral::getHomeUrl() +{ + return mHomeURL->getValue().asString(); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLPanelMediaSettingsGeneral::updateCurrentUrl() +{ + // Get the current URL from the selection + const LLMediaEntry default_media_data; + std::string value_str = default_media_data.getCurrentURL(); + struct functor_getter_current_url : public LLSelectedTEGetFunctor< std::string > + { + functor_getter_current_url(const LLMediaEntry& entry): mMediaEntry(entry) {} + + std::string get( LLViewerObject* object, S32 face ) + { + if ( object ) + if ( object->getTE(face) ) + if ( object->getTE(face)->getMediaData() ) + return object->getTE(face)->getMediaData()->getCurrentURL(); + return mMediaEntry.getCurrentURL(); + }; + + const LLMediaEntry & mMediaEntry; + + } func_current_url(default_media_data); + bool identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func_current_url, value_str ); + mCurrentURL->setText(value_str); + mCurrentURL->setTentative(identical); + + if ( LLPanelMediaSettingsGeneral::isMultiple() ) + { + mCurrentURL->setText(LLTrans::getString("Multiple Media")); + } +} diff --git a/indra/newview/llpanelmediasettingsgeneral.h b/indra/newview/llpanelmediasettingsgeneral.h new file mode 100644 index 000000000..0ae1401ab --- /dev/null +++ b/indra/newview/llpanelmediasettingsgeneral.h @@ -0,0 +1,100 @@ +/** + * @file llpanelmediasettingsgeneral.h + * @brief LLPanelMediaSettingsGeneral class definition + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLPANELMEDIAMEDIASETTINGSGENERAL_H +#define LL_LLPANELMEDIAMEDIASETTINGSGENERAL_H + +#include "llpanel.h" + +class LLButton; +class LLCheckBoxCtrl; +class LLLineEditor; +class LLSpinCtrl; +class LLTextureCtrl; +class LLMediaCtrl; +class LLTextBox; +class LLFloaterMediaSettings; + +class LLPanelMediaSettingsGeneral : public LLPanel +{ +public: + LLPanelMediaSettingsGeneral(); + ~LLPanelMediaSettingsGeneral(); + + // XXX TODO: put these into a common parent class? + // Hook that the floater calls before applying changes from the panel + void preApply(); + // Function that asks the panel to fill in values associated with the panel + // 'include_tentative' means fill in tentative values as well, otherwise do not + void getValues(LLSD &fill_me_in, bool include_tentative = true); + // Hook that the floater calls after applying changes to the panel + void postApply(); + + BOOL postBuild(); + /*virtual*/ void draw(); + /*virtual*/ void onClose(bool app_quitting); + + void setParent( LLFloaterMediaSettings* parent ); + static void initValues( void* userdata, const LLSD& media_settings ,bool editable); + static void clearValues( void* userdata, bool editable); + + // Navigates the current selected face to the Home URL. + // If 'only_if_current_is_empty' is "true", it only performs + // the operation if: 1) the current URL is empty, and 2) auto play is true. + bool navigateHomeSelectedFace(bool only_if_current_is_empty); + + void updateMediaPreview(); + + const std::string getHomeUrl(); + +protected: + LLFloaterMediaSettings* mParent; + bool mMediaEditable; + +private: + void updateCurrentUrl(); + + static void onBtnResetCurrentUrl(LLUICtrl* ctrl, void *userdata); + static void onCommitHomeURL(LLUICtrl* ctrl, void *userdata ); + + static bool isMultiple(); + + void checkHomeUrlPassesWhitelist(); + + LLCheckBoxCtrl* mAutoLoop; + LLCheckBoxCtrl* mFirstClick; + LLCheckBoxCtrl* mAutoZoom; + LLCheckBoxCtrl* mAutoPlay; + LLCheckBoxCtrl* mAutoScale; + LLSpinCtrl* mWidthPixels; + LLSpinCtrl* mHeightPixels; + LLLineEditor* mHomeURL; + LLTextBox* mCurrentURL; + LLMediaCtrl* mPreviewMedia; + LLTextBox* mFailWhiteListText; +}; + +#endif // LL_LLPANELMEDIAMEDIASETTINGSGENERAL_H diff --git a/indra/newview/llpanelmediasettingspermissions.cpp b/indra/newview/llpanelmediasettingspermissions.cpp new file mode 100644 index 000000000..5f7042a3c --- /dev/null +++ b/indra/newview/llpanelmediasettingspermissions.cpp @@ -0,0 +1,285 @@ +/** + * @file llpanelmediasettingspermissions.cpp + * @brief LLPanelMediaSettingsPermissions class implementation + * + * note that "permissions" tab is really "Controls" tab - refs to 'perms' and + * 'permissions' not changed to 'controls' since we don't want to change + * shared files in server code and keeping everything the same seemed best. + * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llpanelmediasettingspermissions.h" +#include "llpanelcontents.h" +#include "llcombobox.h" +#include "llcheckboxctrl.h" +#include "llspinctrl.h" +#include "llurlhistory.h" +#include "lluictrlfactory.h" +#include "llwindow.h" +#include "llviewerwindow.h" +#include "llsdutil.h" +#include "llselectmgr.h" +#include "llmediaentry.h" +#include "llnamebox.h" +#include "lltrans.h" +#include "llfloatermediasettings.h" + +//////////////////////////////////////////////////////////////////////////////// +// +LLPanelMediaSettingsPermissions::LLPanelMediaSettingsPermissions() : + mControls( NULL ), + mPermsOwnerInteract( 0 ), + mPermsOwnerControl( 0 ), + mPermsGroupName( 0 ), + mPermsGroupInteract( 0 ), + mPermsGroupControl( 0 ), + mPermsWorldInteract( 0 ), + mPermsWorldControl( 0 ) +{ + // build dialog from XML + //buildFromFile( "panel_media_settings_permissions.xml"); + LLUICtrlFactory::getInstance()->buildPanel(this,"panel_media_settings_permissions.xml"); +} + +//////////////////////////////////////////////////////////////////////////////// +// +BOOL LLPanelMediaSettingsPermissions::postBuild() +{ + // connect member vars with UI widgets + mControls = getChild< LLComboBox >( LLMediaEntry::CONTROLS_KEY ); + mPermsOwnerInteract = getChild< LLCheckBoxCtrl >( LLPanelContents::PERMS_OWNER_INTERACT_KEY ); + mPermsOwnerControl = getChild< LLCheckBoxCtrl >( LLPanelContents::PERMS_OWNER_CONTROL_KEY ); + mPermsGroupInteract = getChild< LLCheckBoxCtrl >( LLPanelContents::PERMS_GROUP_INTERACT_KEY ); + mPermsGroupControl = getChild< LLCheckBoxCtrl >( LLPanelContents::PERMS_GROUP_CONTROL_KEY ); + mPermsWorldInteract = getChild< LLCheckBoxCtrl >( LLPanelContents::PERMS_ANYONE_INTERACT_KEY ); + mPermsWorldControl = getChild< LLCheckBoxCtrl >( LLPanelContents::PERMS_ANYONE_CONTROL_KEY ); + + //mPermsGroupName = getChild< LLNameBox >( "perms_group_name" ); + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +LLPanelMediaSettingsPermissions::~LLPanelMediaSettingsPermissions() +{ +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +void LLPanelMediaSettingsPermissions::draw() +{ + // housekeeping + LLPanel::draw(); + + //getChild("perms_group_name")->setValue(LLStringUtil::null); + LLUUID group_id; + BOOL groups_identical = LLSelectMgr::getInstance()->selectGetGroup(group_id); + if (groups_identical) + { + if(mPermsGroupName) + { + mPermsGroupName->setNameID(group_id, true); + } + } + else + { + if(mPermsGroupName) + { + mPermsGroupName->setNameID(LLUUID::null, TRUE); + mPermsGroupName->refresh(LLUUID::null, std::string(), true); + } + } +} + +//////////////////////////////////////////////////////////////////////////////// +// static +void LLPanelMediaSettingsPermissions::clearValues( void* userdata, bool editable) +{ + LLPanelMediaSettingsPermissions *self =(LLPanelMediaSettingsPermissions *)userdata; + + self->mControls->clear(); + self->mPermsOwnerInteract->clear(); + self->mPermsOwnerControl->clear(); + self->mPermsGroupInteract->clear(); + self->mPermsGroupControl->clear(); + self->mPermsWorldInteract->clear(); + self->mPermsWorldControl->clear(); + + self->mControls->setEnabled(editable); + self->mPermsOwnerInteract->setEnabled(editable); + self->mPermsOwnerControl->setEnabled(editable); + self->mPermsGroupInteract->setEnabled(editable); + self->mPermsGroupControl->setEnabled(editable); + self->mPermsWorldInteract->setEnabled(editable); + self->mPermsWorldControl->setEnabled(editable); + + self->getChild< LLTextBox >("controls_label")->setEnabled(editable); + self->getChild< LLTextBox >("owner_label")->setEnabled(editable); + self->getChild< LLTextBox >("group_label")->setEnabled(editable); + //self->getChild< LLNameBox >("perms_group_name")->setEnabled(editable); + self->getChild< LLTextBox >("anyone_label")->setEnabled(editable); +} + +//////////////////////////////////////////////////////////////////////////////// +// static +void LLPanelMediaSettingsPermissions::initValues( void* userdata, const LLSD& media_settings , bool editable) +{ + LLPanelMediaSettingsPermissions *self =(LLPanelMediaSettingsPermissions *)userdata; + std::string base_key( "" ); + std::string tentative_key( "" ); + + struct + { + std::string key_name; + LLUICtrl* ctrl_ptr; + std::string ctrl_type; + + } data_set [] = + { + { LLMediaEntry::CONTROLS_KEY, self->mControls, "LLComboBox" }, + { LLPanelContents::PERMS_OWNER_INTERACT_KEY, self->mPermsOwnerInteract, "LLCheckBoxCtrl" }, + { LLPanelContents::PERMS_OWNER_CONTROL_KEY, self->mPermsOwnerControl, "LLCheckBoxCtrl" }, + { LLPanelContents::PERMS_GROUP_INTERACT_KEY, self->mPermsGroupInteract, "LLCheckBoxCtrl" }, + { LLPanelContents::PERMS_GROUP_CONTROL_KEY, self->mPermsGroupControl, "LLCheckBoxCtrl" }, + { LLPanelContents::PERMS_ANYONE_INTERACT_KEY, self->mPermsWorldInteract, "LLCheckBoxCtrl" }, + { LLPanelContents::PERMS_ANYONE_CONTROL_KEY, self->mPermsWorldControl, "LLCheckBoxCtrl" }, + { "", NULL , "" } + }; + + for( int i = 0; data_set[ i ].key_name.length() > 0; ++i ) + { + base_key = std::string( data_set[ i ].key_name ); + tentative_key = base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ); + + // TODO: CP - I bet there is a better way to do this using Boost + if ( media_settings[ base_key ].isDefined() ) + { + if ( data_set[ i ].ctrl_type == "LLCheckBoxCtrl" ) + { + // Most recent change to the "sense" of these checkboxes + // means the value in the checkbox matches that on the server + static_cast< LLCheckBoxCtrl* >( data_set[ i ].ctrl_ptr )-> + setValue( media_settings[ base_key ].asBoolean() ); + } + else + if ( data_set[ i ].ctrl_type == "LLComboBox" ) + static_cast< LLComboBox* >( data_set[ i ].ctrl_ptr )-> + setCurrentByIndex( media_settings[ base_key ].asInteger() ); + + data_set[ i ].ctrl_ptr->setEnabled(editable); + data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() ); + }; + }; + + // *NOTE: If any of a particular flavor is tentative, we have to disable + // them all because of an architectural issue: namely that we represent + // these as a bit field, and we can't selectively apply only one bit to all selected + // faces if they don't match. Also see the *NOTE below. + if ( self->mPermsOwnerInteract->getTentative() || + self->mPermsGroupInteract->getTentative() || + self->mPermsWorldInteract->getTentative()) + { + self->mPermsOwnerInteract->setEnabled(false); + self->mPermsGroupInteract->setEnabled(false); + self->mPermsWorldInteract->setEnabled(false); + } + if ( self->mPermsOwnerControl->getTentative() || + self->mPermsGroupControl->getTentative() || + self->mPermsWorldControl->getTentative()) + { + self->mPermsOwnerControl->setEnabled(false); + self->mPermsGroupControl->setEnabled(false); + self->mPermsWorldControl->setEnabled(false); + } + + self->getChild< LLTextBox >("controls_label")->setEnabled(editable); + self->getChild< LLTextBox >("owner_label")->setEnabled(editable); + self->getChild< LLTextBox >("group_label")->setEnabled(editable); + //self->getChild< LLNameBox >("perms_group_name")->setEnabled(editable); + self->getChild< LLTextBox >("anyone_label")->setEnabled(editable); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLPanelMediaSettingsPermissions::preApply() +{ + // no-op +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLPanelMediaSettingsPermissions::getValues( LLSD &fill_me_in, bool include_tentative ) +{ + // moved over from the 'General settings' tab + if (include_tentative || !mControls->getTentative()) fill_me_in[LLMediaEntry::CONTROLS_KEY] = (LLSD::Integer)mControls->getCurrentIndex(); + + // *NOTE: For some reason, gcc does not like these symbol references in the + // expressions below (inside the static_casts). I have NO idea why :(. + // For some reason, assigning them to const temp vars here fixes the link + // error. Bizarre. + const U8 none = LLMediaEntry::PERM_NONE; + const U8 owner = LLMediaEntry::PERM_OWNER; + const U8 group = LLMediaEntry::PERM_GROUP; + const U8 anyone = LLMediaEntry::PERM_ANYONE; + const LLSD::Integer control = static_cast( + (mPermsOwnerControl->getValue() ? owner : none ) | + (mPermsGroupControl->getValue() ? group: none ) | + (mPermsWorldControl->getValue() ? anyone : none )); + const LLSD::Integer interact = static_cast( + (mPermsOwnerInteract->getValue() ? owner: none ) | + (mPermsGroupInteract->getValue() ? group : none ) | + (mPermsWorldInteract->getValue() ? anyone : none )); + + // *TODO: This will fill in the values of all permissions values, even if + // one or more is tentative. This is not quite the user expectation...what + // it should do is only change the bit that was made "untentative", but in + // a multiple-selection situation, this isn't possible given the architecture + // for how settings are applied. + if (include_tentative || + !mPermsOwnerControl->getTentative() || + !mPermsGroupControl->getTentative() || + !mPermsWorldControl->getTentative()) + { + fill_me_in[LLMediaEntry::PERMS_CONTROL_KEY] = control; + } + if (include_tentative || + !mPermsOwnerInteract->getTentative() || + !mPermsGroupInteract->getTentative() || + !mPermsWorldInteract->getTentative()) + { + fill_me_in[LLMediaEntry::PERMS_INTERACT_KEY] = interact; + } +} + + +//////////////////////////////////////////////////////////////////////////////// +// +void LLPanelMediaSettingsPermissions::postApply() +{ + // no-op +} + + diff --git a/indra/newview/llpanelmediasettingspermissions.h b/indra/newview/llpanelmediasettingspermissions.h new file mode 100644 index 000000000..f97672018 --- /dev/null +++ b/indra/newview/llpanelmediasettingspermissions.h @@ -0,0 +1,73 @@ +/** + * @file llpanelmediasettingspermissions.h + * @brief LLPanelMediaSettingsPermissions class definition + * + * note that "permissions" tab is really "Controls" tab - refs to 'perms' and + * 'permissions' not changed to 'controls' since we don't want to change + * shared files in server code and keeping everything the same seemed best. + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLPANELMEDIAMEDIASETTINGSPERMISSIONS_H +#define LL_LLPANELMEDIAMEDIASETTINGSPERMISSIONS_H + +#include "llpanel.h" +#include "lluuid.h" + +class LLComboBox; +class LLCheckBoxCtrl; +class LLNameBox; + +class LLPanelMediaSettingsPermissions : public LLPanel +{ +public: + LLPanelMediaSettingsPermissions(); + ~LLPanelMediaSettingsPermissions(); + + BOOL postBuild(); + virtual void draw(); + + // XXX TODO: put these into a common parent class? + // Hook that the floater calls before applying changes from the panel + void preApply(); + // Function that asks the panel to fill in values associated with the panel + // 'include_tentative' means fill in tentative values as well, otherwise do not + void getValues(LLSD &fill_me_in, bool include_tentative = true); + // Hook that the floater calls after applying changes to the panel + void postApply(); + + static void initValues( void* userdata, const LLSD& media_settings, bool editable ); + static void clearValues( void* userdata, bool editable); + +private: + LLComboBox* mControls; + LLCheckBoxCtrl* mPermsOwnerInteract; + LLCheckBoxCtrl* mPermsOwnerControl; + LLNameBox* mPermsGroupName; + LLCheckBoxCtrl* mPermsGroupInteract; + LLCheckBoxCtrl* mPermsGroupControl; + LLCheckBoxCtrl* mPermsWorldInteract; + LLCheckBoxCtrl* mPermsWorldControl; +}; + +#endif // LL_LLPANELMEDIAMEDIASETTINGSPERMISSIONS_H diff --git a/indra/newview/llpanelmediasettingssecurity.cpp b/indra/newview/llpanelmediasettingssecurity.cpp new file mode 100644 index 000000000..509560b37 --- /dev/null +++ b/indra/newview/llpanelmediasettingssecurity.cpp @@ -0,0 +1,366 @@ +/** + * @file llpanelmediasettingssecurity.cpp + * @brief LLPanelMediaSettingsSecurity class implementation + * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llpanelmediasettingssecurity.h" + +#include "llpanelcontents.h" +#include "llcheckboxctrl.h" +#include "llnotificationsutil.h" +#include "llscrolllistctrl.h" +#include "lluictrlfactory.h" +#include "llwindow.h" +#include "llviewerwindow.h" +#include "llsdutil.h" +#include "llselectmgr.h" +#include "llmediaentry.h" +#include "lltextbox.h" +#include "llfloaterwhitelistentry.h" +#include "llfloatermediasettings.h" + +//////////////////////////////////////////////////////////////////////////////// +// +LLPanelMediaSettingsSecurity::LLPanelMediaSettingsSecurity() : + mParent( NULL ) +{ + mCommitCallbackRegistrar.add("Media.whitelistAdd", boost::bind(&LLPanelMediaSettingsSecurity::onBtnAdd, this)); + mCommitCallbackRegistrar.add("Media.whitelistDelete", boost::bind(&LLPanelMediaSettingsSecurity::onBtnDel, this)); + + // build dialog from XML + //buildFromFile( "panel_media_settings_security.xml"); + LLUICtrlFactory::getInstance()->buildPanel(this,"panel_media_settings_security.xml"); +} + +//////////////////////////////////////////////////////////////////////////////// +// +BOOL LLPanelMediaSettingsSecurity::postBuild() +{ + mEnableWhiteList = getChild< LLCheckBoxCtrl >( LLMediaEntry::WHITELIST_ENABLE_KEY ); + mWhiteListList = getChild< LLScrollListCtrl >( LLMediaEntry::WHITELIST_KEY ); + mHomeUrlFailsWhiteListText = getChild( "home_url_fails_whitelist" ); + + setDefaultBtn("whitelist_add"); + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +LLPanelMediaSettingsSecurity::~LLPanelMediaSettingsSecurity() +{ +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLPanelMediaSettingsSecurity::draw() +{ + // housekeeping + LLPanel::draw(); +} + +//////////////////////////////////////////////////////////////////////////////// +// static +void LLPanelMediaSettingsSecurity::initValues( void* userdata, const LLSD& media_settings , bool editable) +{ + LLPanelMediaSettingsSecurity *self =(LLPanelMediaSettingsSecurity *)userdata; + std::string base_key( "" ); + std::string tentative_key( "" ); + + struct + { + std::string key_name; + LLUICtrl* ctrl_ptr; + std::string ctrl_type; + + } data_set [] = + { + { LLMediaEntry::WHITELIST_ENABLE_KEY, self->mEnableWhiteList, "LLCheckBoxCtrl" }, + { LLMediaEntry::WHITELIST_KEY, self->mWhiteListList, "LLScrollListCtrl" }, + { "", NULL , "" } + }; + + for( int i = 0; data_set[ i ].key_name.length() > 0; ++i ) + { + base_key = std::string( data_set[ i ].key_name ); + tentative_key = base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ); + + bool enabled_overridden = false; + + // TODO: CP - I bet there is a better way to do this using Boost + if ( media_settings[ base_key ].isDefined() ) + { + if ( data_set[ i ].ctrl_type == "LLCheckBoxCtrl" ) + { + static_cast< LLCheckBoxCtrl* >( data_set[ i ].ctrl_ptr )-> + setValue( media_settings[ base_key ].asBoolean() ); + } + else + if ( data_set[ i ].ctrl_type == "LLScrollListCtrl" ) + { + // get control + LLScrollListCtrl* list = static_cast< LLScrollListCtrl* >( data_set[ i ].ctrl_ptr ); + list->deleteAllItems(); + + // points to list of white list URLs + LLSD url_list = media_settings[ base_key ]; + + // better be the whitelist + llassert(data_set[ i ].ctrl_ptr == self->mWhiteListList); + + // If tentative, don't add entries + if (media_settings[ tentative_key ].asBoolean()) + { + self->mWhiteListList->setEnabled(false); + enabled_overridden = true; + } + else { + // iterate over them and add to scroll list + LLSD::array_iterator iter = url_list.beginArray(); + while( iter != url_list.endArray() ) + { + std::string entry = *iter; + self->addWhiteListEntry( entry ); + ++iter; + } + } + }; + if ( ! enabled_overridden) data_set[ i ].ctrl_ptr->setEnabled(editable); + data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() ); + }; + }; + + // initial update - hides/shows status messages etc. + self->updateWhitelistEnableStatus(); +} + +//////////////////////////////////////////////////////////////////////////////// +// static +void LLPanelMediaSettingsSecurity::clearValues( void* userdata , bool editable) +{ + LLPanelMediaSettingsSecurity *self =(LLPanelMediaSettingsSecurity *)userdata; + self->mEnableWhiteList->clear(); + self->mWhiteListList->deleteAllItems(); + self->mEnableWhiteList->setEnabled(editable); + self->mWhiteListList->setEnabled(editable); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLPanelMediaSettingsSecurity::preApply() +{ + // no-op +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLPanelMediaSettingsSecurity::getValues( LLSD &fill_me_in, bool include_tentative ) +{ + if (include_tentative || !mEnableWhiteList->getTentative()) + fill_me_in[LLMediaEntry::WHITELIST_ENABLE_KEY] = (LLSD::Boolean)mEnableWhiteList->getValue(); + + if (include_tentative || !mWhiteListList->getTentative()) + { + // iterate over white list and extract items + std::vector< LLScrollListItem* > whitelist_items = mWhiteListList->getAllData(); + std::vector< LLScrollListItem* >::iterator iter = whitelist_items.begin(); + + // *NOTE: need actually set the key to be an emptyArray(), or the merge + // we do with this LLSD will think there's nothing to change. + fill_me_in[LLMediaEntry::WHITELIST_KEY] = LLSD::emptyArray(); + while( iter != whitelist_items.end() ) + { + LLScrollListCell* cell = (*iter)->getColumn( ENTRY_COLUMN ); + std::string whitelist_url = cell->getValue().asString(); + + fill_me_in[ LLMediaEntry::WHITELIST_KEY ].append( whitelist_url ); + ++iter; + }; + } +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLPanelMediaSettingsSecurity::postApply() +{ + // no-op +} + +/////////////////////////////////////////////////////////////////////////////// +// Try to make a valid URL if a fragment ( +// white list list box widget and build a list to test against. Can also +const std::string LLPanelMediaSettingsSecurity::makeValidUrl( const std::string& src_url ) +{ + // use LLURI to determine if we have a valid scheme + LLURI candidate_url( src_url ); + if ( candidate_url.scheme().empty() ) + { + // build a URL comprised of default scheme and the original fragment + const std::string default_scheme( "http://" ); + return default_scheme + src_url; + }; + + // we *could* test the "default scheme" + "original fragment" URL again + // using LLURI to see if it's valid but I think the outcome is the same + // in either case - our only option is to return the original URL + + // we *think* the original url passed in was valid + return src_url; +} + +/////////////////////////////////////////////////////////////////////////////// +// wrapper for testing a URL against the whitelist. We grab entries from +// white list list box widget and build a list to test against. +bool LLPanelMediaSettingsSecurity::urlPassesWhiteList( const std::string& test_url ) +{ + // If the whitlelist list is tentative, it means we have multiple settings. + // In that case, we have no choice but to return true + if ( mWhiteListList->getTentative() ) return true; + + // the checkUrlAgainstWhitelist(..) function works on a vector + // of strings for the white list entries - in this panel, the white list + // is stored in the widgets themselves so we need to build something compatible. + std::vector< std::string > whitelist_strings; + whitelist_strings.clear(); // may not be required - I forget what the spec says. + + // step through whitelist widget entries and grab them as strings + std::vector< LLScrollListItem* > whitelist_items = mWhiteListList->getAllData(); + std::vector< LLScrollListItem* >::iterator iter = whitelist_items.begin(); + while( iter != whitelist_items.end() ) + { + LLScrollListCell* cell = (*iter)->getColumn( ENTRY_COLUMN ); + std::string whitelist_url = cell->getValue().asString(); + + whitelist_strings.push_back( whitelist_url ); + + ++iter; + }; + + // possible the URL is just a fragment so we validize it + const std::string valid_url = makeValidUrl( test_url ); + + // indicate if the URL passes whitelist + return LLMediaEntry::checkUrlAgainstWhitelist( valid_url, whitelist_strings ); +} + +/////////////////////////////////////////////////////////////////////////////// +// +void LLPanelMediaSettingsSecurity::updateWhitelistEnableStatus() +{ + // get the value for home URL and make it a valid URL + const std::string valid_url = makeValidUrl( mParent->getHomeUrl() ); + + // now check to see if the home url passes the whitelist in its entirity + if ( urlPassesWhiteList( valid_url ) ) + { + mEnableWhiteList->setEnabled( true ); + mHomeUrlFailsWhiteListText->setVisible( false ); + } + else + { + mEnableWhiteList->set( false ); + mEnableWhiteList->setEnabled( false ); + mHomeUrlFailsWhiteListText->setVisible( true ); + }; +} + +/////////////////////////////////////////////////////////////////////////////// +// Add an entry to the whitelist scrollbox and indicate if the current +// home URL passes this entry or not using an icon +void LLPanelMediaSettingsSecurity::addWhiteListEntry( const std::string& entry ) +{ + // grab the home url + std::string home_url( "" ); + if ( mParent ) + home_url = mParent->getHomeUrl(); + + // try to make a valid URL based on what the user entered - missing scheme for example + const std::string valid_url = makeValidUrl( home_url ); + + // check the home url against this single whitelist entry + std::vector< std::string > whitelist_entries; + whitelist_entries.push_back( entry ); + bool home_url_passes_entry = LLMediaEntry::checkUrlAgainstWhitelist( valid_url, whitelist_entries ); + + // build an icon cell based on whether or not the home url pases it or not + LLSD row; + if ( home_url_passes_entry || home_url.empty() ) + { + row[ "columns" ][ ICON_COLUMN ][ "type" ] = "icon"; + row[ "columns" ][ ICON_COLUMN ][ "value" ] = ""; + row[ "columns" ][ ICON_COLUMN ][ "width" ] = 20; + } + else + { + row[ "columns" ][ ICON_COLUMN ][ "type" ] = "icon"; + row[ "columns" ][ ICON_COLUMN ][ "value" ] = "Parcel_Exp_Color.png"; + row[ "columns" ][ ICON_COLUMN ][ "width" ] = 20; + }; + + // always add in the entry itself + row[ "columns" ][ ENTRY_COLUMN ][ "type" ] = "text"; + row[ "columns" ][ ENTRY_COLUMN ][ "value" ] = entry; + + // add to the white list scroll box + mWhiteListList->addElement( row ); +}; + +/////////////////////////////////////////////////////////////////////////////// +// static +void LLPanelMediaSettingsSecurity::onBtnAdd( void* userdata ) +{ + + LLPanelMediaSettingsSecurity* self = (LLPanelMediaSettingsSecurity*)userdata; + LLFloaterWhiteListEntry::getInstance()->open(); + + for(LLView* parent = self->getParent(); parent !=NULL; parent = parent->getParent()) + { + if(dynamic_cast(parent)) + { + LLFloaterWhiteListEntry::getInstance()->centerWithin(parent->getRect()); + break; + } + } +} + +/////////////////////////////////////////////////////////////////////////////// +// static +void LLPanelMediaSettingsSecurity::onBtnDel( void* userdata ) +{ + LLPanelMediaSettingsSecurity *self =(LLPanelMediaSettingsSecurity *)userdata; + + self->mWhiteListList->deleteSelectedItems(); + + // contents of whitelist changed so recheck it against home url + self->updateWhitelistEnableStatus(); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void LLPanelMediaSettingsSecurity::setParent( LLFloaterMediaSettings* parent ) +{ + mParent = parent; +}; diff --git a/indra/newview/llpanelmediasettingssecurity.h b/indra/newview/llpanelmediasettingssecurity.h new file mode 100644 index 000000000..fe8e84357 --- /dev/null +++ b/indra/newview/llpanelmediasettingssecurity.h @@ -0,0 +1,82 @@ +/** + * @file llpanelmediasettingssecurity.h + * @brief LLPanelMediaSettingsSecurity class definition + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLPANELMEDIAMEDIASETTINGSSECURITY_H +#define LL_LLPANELMEDIAMEDIASETTINGSSECURITY_H + +#include "llpanel.h" + +class LLCheckBoxCtrl; +class LLScrollListCtrl; +class LLTextBox; +class LLFloaterMediaSettings; + +class LLPanelMediaSettingsSecurity : public LLPanel +{ +public: + LLPanelMediaSettingsSecurity(); + ~LLPanelMediaSettingsSecurity(); + + BOOL postBuild(); + virtual void draw(); + + // XXX TODO: put these into a common parent class? + // Hook that the floater calls before applying changes from the panel + void preApply(); + // Function that asks the panel to fill in values associated with the panel + // 'include_tentative' means fill in tentative values as well, otherwise do not + void getValues(LLSD &fill_me_in, bool include_tentative = true); + // Hook that the floater calls after applying changes to the panel + void postApply(); + + static void initValues( void* userdata, const LLSD& media_settings, bool editable); + static void clearValues( void* userdata, bool editable); + void addWhiteListEntry( const std::string& url ); + void setParent( LLFloaterMediaSettings* parent ); + bool urlPassesWhiteList( const std::string& test_url ); + const std::string makeValidUrl( const std::string& src_url ); + + void updateWhitelistEnableStatus(); + +protected: + LLFloaterMediaSettings* mParent; + +private: + enum ColumnIndex + { + ICON_COLUMN = 0, + ENTRY_COLUMN = 1, + }; + + LLCheckBoxCtrl* mEnableWhiteList; + LLScrollListCtrl* mWhiteListList; + LLTextBox* mHomeUrlFailsWhiteListText; + + static void onBtnAdd(void*); + static void onBtnDel(void*); +}; + +#endif // LL_LLPANELMEDIAMEDIASETTINGSSECURITY_H diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 3526d93d6..22175932f 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -845,5 +845,52 @@ template bool LLObjectSelection::getSelectedTEValue(LLSelectedTEGet return identical; } +// Templates +//----------------------------------------------------------------------------- +// isMultipleTEValue iterate through all TEs and test for uniqueness +// with certain return value ignored when performing the test. +// e.g. when testing if the selection has a unique non-empty homeurl : +// you can set ignore_value = "" and it will only compare among the non-empty +// homeUrls and ignore the empty ones. +//----------------------------------------------------------------------------- +template bool LLObjectSelection::isMultipleTEValue(LLSelectedTEGetFunctor* func, const T& ignore_value) +{ + bool have_first = false; + T selected_value = T(); + + // Now iterate through all TEs to test for sameness + bool unique = TRUE; + for (iterator iter = begin(); iter != end(); iter++) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + for (S32 te = 0; te < object->getNumTEs(); ++te) + { + if (!node->isTESelected(te)) + { + continue; + } + T value = func->get(object, te); + if(value == ignore_value) + { + continue; + } + if (!have_first) + { + have_first = true; + } + else + { + if (value !=selected_value ) + { + unique = false; + return !unique; + } + } + } + } + return !unique; +} + #endif diff --git a/indra/newview/skins/default/textures/Flag.png b/indra/newview/skins/default/textures/Flag.png new file mode 100644 index 0000000000000000000000000000000000000000..66739e9bf39cf5325796c0d878ba51854e93700f GIT binary patch literal 3238 zcmV;X3|aGuP)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z0005eNkl<{LENu;hX~z1!r52 zg{SrDbozM!#+a8~+<6m~iTI;VteF&h}>miO~)OGzPFN8o8MM#naS(br_5JeG$ z5Lm5Nn9XL;T7SI*)>`~{e8l+S;cA_f5<&<_DbekAA*DnZhM3RiR{`F&U^1BmKcAmb zRn>hoEQ$ign2YWID;gf7X&L}PS(YaYgb;}17*Q167QkAI&1QqLEKddiK&R6|mSs>% zAxRRXX$mRjZ2+F0o&eyL=S|air4)`sYB(HXzu&*Iz*_r#fZuscM1j^CT5B-IuvjcS z=NxBq;Ln_a4?sd|9lTKP%_wef!xo?gXaQP)fAd-X=`UgooO2(BA&3ahIZs3Z5#1hu zF$O86AB{%PT4TH2Vz=9&u50hT4{i>?Irn*j Y05^C0By~#@LjV8(07*qoM6N<$f+VZ^%m4rY literal 0 HcmV?d00001 diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 49333fd78..92938cd5c 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -403,6 +403,8 @@ + + diff --git a/indra/newview/skins/default/xui/en-us/floater_media_settings.xml b/indra/newview/skins/default/xui/en-us/floater_media_settings.xml new file mode 100644 index 000000000..8a5bae62f --- /dev/null +++ b/indra/newview/skins/default/xui/en-us/floater_media_settings.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + Note: Residents can override this setting + + + + + + Size: + + + + + + X + + + + diff --git a/indra/newview/skins/default/xui/en-us/panel_media_settings_permissions.xml b/indra/newview/skins/default/xui/en-us/panel_media_settings_permissions.xml new file mode 100644 index 000000000..3773ff361 --- /dev/null +++ b/indra/newview/skins/default/xui/en-us/panel_media_settings_permissions.xml @@ -0,0 +1,172 @@ + + + + + Controls: + + + + Standard + + + Mini + + + + + Owner + + + + + + + + Group: + + + + + + + + + + Anyone + + + + + + + diff --git a/indra/newview/skins/default/xui/en-us/panel_media_settings_security.xml b/indra/newview/skins/default/xui/en-us/panel_media_settings_security.xml new file mode 100644 index 000000000..828635262 --- /dev/null +++ b/indra/newview/skins/default/xui/en-us/panel_media_settings_security.xml @@ -0,0 +1,91 @@ + + + + + + + Entries that the home page fails against are marked: + + + + +Warning: the home page specified in the General tab fails to +pass this whitelist. It has been disabled until a valid entry +has been added. + + + diff --git a/indra/newview/skins/default/xui/en-us/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/en-us/panel_prim_media_controls.xml index 444c990f5..003c4e8cc 100644 --- a/indra/newview/skins/default/xui/en-us/panel_prim_media_controls.xml +++ b/indra/newview/skins/default/xui/en-us/panel_prim_media_controls.xml @@ -268,7 +268,8 @@ follows="top|right" height="20" width="38" - right="-1" + left="140" + bottom="0" border_size="0" mouse_opaque="false" orientation="horizontal"> @@ -281,9 +282,9 @@ name="media_whitelist_flag" follows="top|right" height="16" - image_name="Flag" + image_name="Flag.png" layout="topleft" - bottom="-22" + bottom="-16" width="16" /> diff --git a/indra/newview/skins/default/xui/en-us/strings.xml b/indra/newview/skins/default/xui/en-us/strings.xml index e8bacfa91..29363d81c 100644 --- a/indra/newview/skins/default/xui/en-us/strings.xml +++ b/indra/newview/skins/default/xui/en-us/strings.xml @@ -3380,6 +3380,10 @@ Expected .wav, .tga, .bmp, .jpg, .jpeg, or .bvh ' --- + + Multiple Media + Play/Pause Media + An error was found parsing the command line.