PageRenderTime 45ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/newview/llpanelmediasettingsgeneral.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 515 lines | 356 code | 56 blank | 103 comment | 61 complexity | e248c5e7272930b55e7c463c61f9acce MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llpanelmediasettingsgeneral.cpp
  3. * @brief LLPanelMediaSettingsGeneral class implementation
  4. *
  5. * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "llviewerprecompiledheaders.h"
  27. #include "llpanelmediasettingsgeneral.h"
  28. // library includes
  29. #include "llcombobox.h"
  30. #include "llcheckboxctrl.h"
  31. #include "llnotificationsutil.h"
  32. #include "llspinctrl.h"
  33. #include "lluictrlfactory.h"
  34. // project includes
  35. #include "llagent.h"
  36. #include "llviewerwindow.h"
  37. #include "llviewermedia.h"
  38. #include "llsdutil.h"
  39. #include "llselectmgr.h"
  40. #include "llbutton.h"
  41. #include "lltexturectrl.h"
  42. #include "llurl.h"
  43. #include "llwindow.h"
  44. #include "llmediaentry.h"
  45. #include "llmediactrl.h"
  46. #include "llpanelcontents.h"
  47. #include "llpermissions.h"
  48. #include "llpluginclassmedia.h"
  49. #include "llfloatermediasettings.h"
  50. #include "llfloatertools.h"
  51. #include "lltrans.h"
  52. #include "lltextbox.h"
  53. #include "llpanelmediasettingssecurity.h"
  54. 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";
  55. ////////////////////////////////////////////////////////////////////////////////
  56. //
  57. LLPanelMediaSettingsGeneral::LLPanelMediaSettingsGeneral() :
  58. mAutoLoop( NULL ),
  59. mFirstClick( NULL ),
  60. mAutoZoom( NULL ),
  61. mAutoPlay( NULL ),
  62. mAutoScale( NULL ),
  63. mWidthPixels( NULL ),
  64. mHeightPixels( NULL ),
  65. mHomeURL( NULL ),
  66. mCurrentURL( NULL ),
  67. mParent( NULL ),
  68. mMediaEditable(false)
  69. {
  70. // build dialog from XML
  71. buildFromFile( "panel_media_settings_general.xml");
  72. }
  73. ////////////////////////////////////////////////////////////////////////////////
  74. //
  75. BOOL LLPanelMediaSettingsGeneral::postBuild()
  76. {
  77. // connect member vars with UI widgets
  78. mAutoLoop = getChild< LLCheckBoxCtrl >( LLMediaEntry::AUTO_LOOP_KEY );
  79. mAutoPlay = getChild< LLCheckBoxCtrl >( LLMediaEntry::AUTO_PLAY_KEY );
  80. mAutoScale = getChild< LLCheckBoxCtrl >( LLMediaEntry::AUTO_SCALE_KEY );
  81. mAutoZoom = getChild< LLCheckBoxCtrl >( LLMediaEntry::AUTO_ZOOM_KEY );
  82. mCurrentURL = getChild< LLTextBox >( LLMediaEntry::CURRENT_URL_KEY );
  83. mFirstClick = getChild< LLCheckBoxCtrl >( LLMediaEntry::FIRST_CLICK_INTERACT_KEY );
  84. mHeightPixels = getChild< LLSpinCtrl >( LLMediaEntry::HEIGHT_PIXELS_KEY );
  85. mHomeURL = getChild< LLLineEditor >( LLMediaEntry::HOME_URL_KEY );
  86. mWidthPixels = getChild< LLSpinCtrl >( LLMediaEntry::WIDTH_PIXELS_KEY );
  87. mPreviewMedia = getChild<LLMediaCtrl>("preview_media");
  88. mFailWhiteListText = getChild<LLTextBox>( "home_fails_whitelist_label" );
  89. // watch commit action for HOME URL
  90. childSetCommitCallback( LLMediaEntry::HOME_URL_KEY, onCommitHomeURL, this);
  91. childSetCommitCallback( "current_url_reset_btn",onBtnResetCurrentUrl, this);
  92. // interrogates controls and updates widgets as required
  93. updateMediaPreview();
  94. return true;
  95. }
  96. ////////////////////////////////////////////////////////////////////////////////
  97. // virtual
  98. LLPanelMediaSettingsGeneral::~LLPanelMediaSettingsGeneral()
  99. {
  100. }
  101. ////////////////////////////////////////////////////////////////////////////////
  102. // static
  103. void LLPanelMediaSettingsGeneral::draw()
  104. {
  105. // housekeeping
  106. LLPanel::draw();
  107. // TODO: we need to call this repeatedly until the floater panels are fully
  108. // created but once we have a valid answer, we should stop looking here - the
  109. // commit callback will handle it
  110. checkHomeUrlPassesWhitelist();
  111. // enable/disable pixel values image entry based on auto scale checkbox
  112. if ( mAutoScale->getValue().asBoolean() == false )
  113. {
  114. getChildView( LLMediaEntry::WIDTH_PIXELS_KEY )->setEnabled( true );
  115. getChildView( LLMediaEntry::HEIGHT_PIXELS_KEY )->setEnabled( true );
  116. }
  117. else
  118. {
  119. getChildView( LLMediaEntry::WIDTH_PIXELS_KEY )->setEnabled( false );
  120. getChildView( LLMediaEntry::HEIGHT_PIXELS_KEY )->setEnabled( false );
  121. };
  122. // enable/disable UI based on type of media
  123. bool reset_button_is_active = true;
  124. if( mPreviewMedia )
  125. {
  126. LLPluginClassMedia* media_plugin = mPreviewMedia->getMediaPlugin();
  127. if( media_plugin )
  128. {
  129. // turn off volume (if we can) for preview. Note: this really only
  130. // works for QuickTime movies right now - no way to control the
  131. // volume of a flash app embedded in a page for example
  132. media_plugin->setVolume( 0 );
  133. // some controls are only appropriate for time or browser type plugins
  134. // so we selectively enable/disable them - need to do it in draw
  135. // because the information from plugins arrives assynchronously
  136. bool show_time_controls = media_plugin->pluginSupportsMediaTime();
  137. if ( show_time_controls )
  138. {
  139. getChildView( LLMediaEntry::CURRENT_URL_KEY )->setEnabled( false );
  140. reset_button_is_active = false;
  141. getChildView("current_url_label")->setEnabled(false );
  142. getChildView( LLMediaEntry::AUTO_LOOP_KEY )->setEnabled( true );
  143. }
  144. else
  145. {
  146. getChildView( LLMediaEntry::CURRENT_URL_KEY )->setEnabled( true );
  147. reset_button_is_active = true;
  148. getChildView("current_url_label")->setEnabled(true );
  149. getChildView( LLMediaEntry::AUTO_LOOP_KEY )->setEnabled( false );
  150. };
  151. };
  152. };
  153. // current URL can change over time, update it here
  154. updateCurrentUrl();
  155. LLPermissions perm;
  156. bool user_can_press_reset = mMediaEditable;
  157. // several places modify this widget so we must collect states in one place
  158. if ( reset_button_is_active )
  159. {
  160. // user has perms to press reset button and it is active
  161. if ( user_can_press_reset )
  162. {
  163. getChildView("current_url_reset_btn")->setEnabled(true );
  164. }
  165. // user does not has perms to press reset button and it is active
  166. else
  167. {
  168. getChildView("current_url_reset_btn")->setEnabled(false );
  169. };
  170. }
  171. else
  172. // reset button is inactive so we just slam it to off - other states don't matter
  173. {
  174. getChildView("current_url_reset_btn")->setEnabled(false );
  175. };
  176. }
  177. ////////////////////////////////////////////////////////////////////////////////
  178. // static
  179. void LLPanelMediaSettingsGeneral::clearValues( void* userdata, bool editable)
  180. {
  181. LLPanelMediaSettingsGeneral *self =(LLPanelMediaSettingsGeneral *)userdata;
  182. self->mAutoLoop->clear();
  183. self->mAutoPlay->clear();
  184. self->mAutoScale->clear();
  185. self->mAutoZoom ->clear();
  186. self->mCurrentURL->clear();
  187. self->mFirstClick->clear();
  188. self->mHeightPixels->clear();
  189. self->mHomeURL->clear();
  190. self->mWidthPixels->clear();
  191. self->mAutoLoop ->setEnabled(editable);
  192. self->mAutoPlay ->setEnabled(editable);
  193. self->mAutoScale ->setEnabled(editable);
  194. self->mAutoZoom ->setEnabled(editable);
  195. self->mCurrentURL ->setEnabled(editable);
  196. self->mFirstClick ->setEnabled(editable);
  197. self->mHeightPixels ->setEnabled(editable);
  198. self->mHomeURL ->setEnabled(editable);
  199. self->mWidthPixels ->setEnabled(editable);
  200. self->updateMediaPreview();
  201. }
  202. // static
  203. bool LLPanelMediaSettingsGeneral::isMultiple()
  204. {
  205. // IF all the faces have media (or all dont have media)
  206. if ( LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo )
  207. {
  208. if(LLFloaterMediaSettings::getInstance()->mMultipleMedia)
  209. {
  210. return true;
  211. }
  212. }
  213. else
  214. {
  215. if(LLFloaterMediaSettings::getInstance()->mMultipleValidMedia)
  216. {
  217. return true;
  218. }
  219. }
  220. return false;
  221. }
  222. ////////////////////////////////////////////////////////////////////////////////
  223. // static
  224. void LLPanelMediaSettingsGeneral::initValues( void* userdata, const LLSD& _media_settings, bool editable)
  225. {
  226. LLPanelMediaSettingsGeneral *self =(LLPanelMediaSettingsGeneral *)userdata;
  227. self->mMediaEditable = editable;
  228. LLSD media_settings = _media_settings;
  229. if ( LLPanelMediaSettingsGeneral::isMultiple() )
  230. {
  231. // *HACK: "edit" the incoming media_settings
  232. media_settings[LLMediaEntry::CURRENT_URL_KEY] = LLTrans::getString("Multiple Media");
  233. media_settings[LLMediaEntry::HOME_URL_KEY] = LLTrans::getString("Multiple Media");
  234. }
  235. std::string base_key( "" );
  236. std::string tentative_key( "" );
  237. struct
  238. {
  239. std::string key_name;
  240. LLUICtrl* ctrl_ptr;
  241. std::string ctrl_type;
  242. } data_set [] =
  243. {
  244. { LLMediaEntry::AUTO_LOOP_KEY, self->mAutoLoop, "LLCheckBoxCtrl" },
  245. { LLMediaEntry::AUTO_PLAY_KEY, self->mAutoPlay, "LLCheckBoxCtrl" },
  246. { LLMediaEntry::AUTO_SCALE_KEY, self->mAutoScale, "LLCheckBoxCtrl" },
  247. { LLMediaEntry::AUTO_ZOOM_KEY, self->mAutoZoom, "LLCheckBoxCtrl" },
  248. { LLMediaEntry::CURRENT_URL_KEY, self->mCurrentURL, "LLTextBox" },
  249. { LLMediaEntry::HEIGHT_PIXELS_KEY, self->mHeightPixels, "LLSpinCtrl" },
  250. { LLMediaEntry::HOME_URL_KEY, self->mHomeURL, "LLLineEditor" },
  251. { LLMediaEntry::FIRST_CLICK_INTERACT_KEY, self->mFirstClick, "LLCheckBoxCtrl" },
  252. { LLMediaEntry::WIDTH_PIXELS_KEY, self->mWidthPixels, "LLSpinCtrl" },
  253. { "", NULL , "" }
  254. };
  255. for( int i = 0; data_set[ i ].key_name.length() > 0; ++i )
  256. {
  257. base_key = std::string( data_set[ i ].key_name );
  258. tentative_key = base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX );
  259. // TODO: CP - I bet there is a better way to do this using Boost
  260. if ( media_settings[ base_key ].isDefined() )
  261. {
  262. if ( data_set[ i ].ctrl_type == "LLLineEditor" )
  263. {
  264. static_cast< LLLineEditor* >( data_set[ i ].ctrl_ptr )->
  265. setText( media_settings[ base_key ].asString() );
  266. }
  267. else
  268. if ( data_set[ i ].ctrl_type == "LLCheckBoxCtrl" )
  269. static_cast< LLCheckBoxCtrl* >( data_set[ i ].ctrl_ptr )->
  270. setValue( media_settings[ base_key ].asBoolean() );
  271. else
  272. if ( data_set[ i ].ctrl_type == "LLComboBox" )
  273. static_cast< LLComboBox* >( data_set[ i ].ctrl_ptr )->
  274. setCurrentByIndex( media_settings[ base_key ].asInteger() );
  275. else
  276. if ( data_set[ i ].ctrl_type == "LLSpinCtrl" )
  277. static_cast< LLSpinCtrl* >( data_set[ i ].ctrl_ptr )->
  278. setValue( media_settings[ base_key ].asInteger() );
  279. data_set[ i ].ctrl_ptr->setEnabled(self->mMediaEditable);
  280. data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() );
  281. };
  282. };
  283. // interrogates controls and updates widgets as required
  284. self->updateMediaPreview();
  285. }
  286. ////////////////////////////////////////////////////////////////////////////////
  287. // Helper to set media control to media URL as required
  288. void LLPanelMediaSettingsGeneral::updateMediaPreview()
  289. {
  290. if ( mHomeURL->getValue().asString().length() > 0 )
  291. {
  292. if(mPreviewMedia->getCurrentNavUrl() != mHomeURL->getValue().asString())
  293. {
  294. mPreviewMedia->navigateTo( mHomeURL->getValue().asString() );
  295. }
  296. }
  297. else
  298. // new home URL will be empty if media is deleted so display a
  299. // "preview goes here" data url page
  300. {
  301. if(mPreviewMedia->getCurrentNavUrl() != CHECKERBOARD_DATA_URL)
  302. {
  303. mPreviewMedia->navigateTo( CHECKERBOARD_DATA_URL );
  304. }
  305. };
  306. }
  307. ////////////////////////////////////////////////////////////////////////////////
  308. // virtual
  309. void LLPanelMediaSettingsGeneral::onClose(bool app_quitting)
  310. {
  311. if(mPreviewMedia)
  312. {
  313. mPreviewMedia->unloadMediaSource();
  314. }
  315. }
  316. ////////////////////////////////////////////////////////////////////////////////
  317. //
  318. void LLPanelMediaSettingsGeneral::checkHomeUrlPassesWhitelist()
  319. {
  320. // parent floater has not constructed the security panel yet
  321. if ( mParent->getPanelSecurity() == 0 )
  322. return;
  323. std::string home_url = getHomeUrl();
  324. if ( home_url.empty() || mParent->getPanelSecurity()->urlPassesWhiteList( home_url ) )
  325. {
  326. // Home URL is empty or passes the white list so hide the warning message
  327. mFailWhiteListText->setVisible( false );
  328. }
  329. else
  330. {
  331. // Home URL does not pass the white list so show the warning message
  332. mFailWhiteListText->setVisible( true );
  333. };
  334. }
  335. ////////////////////////////////////////////////////////////////////////////////
  336. // static
  337. void LLPanelMediaSettingsGeneral::onCommitHomeURL( LLUICtrl* ctrl, void *userdata )
  338. {
  339. LLPanelMediaSettingsGeneral* self =(LLPanelMediaSettingsGeneral *)userdata;
  340. // check home url passes whitelist and display warning if not
  341. self->checkHomeUrlPassesWhitelist();
  342. self->updateMediaPreview();
  343. }
  344. ////////////////////////////////////////////////////////////////////////////////
  345. // static
  346. void LLPanelMediaSettingsGeneral::onBtnResetCurrentUrl(LLUICtrl* ctrl, void *userdata)
  347. {
  348. LLPanelMediaSettingsGeneral* self =(LLPanelMediaSettingsGeneral *)userdata;
  349. self->navigateHomeSelectedFace(false);
  350. }
  351. ////////////////////////////////////////////////////////////////////////////////
  352. //
  353. void LLPanelMediaSettingsGeneral::preApply()
  354. {
  355. // Make sure the home URL entry is committed
  356. mHomeURL->onCommit();
  357. }
  358. ////////////////////////////////////////////////////////////////////////////////
  359. //
  360. void LLPanelMediaSettingsGeneral::getValues( LLSD &fill_me_in, bool include_tentative )
  361. {
  362. if (include_tentative || !mAutoLoop->getTentative()) fill_me_in[LLMediaEntry::AUTO_LOOP_KEY] = (LLSD::Boolean)mAutoLoop->getValue();
  363. if (include_tentative || !mAutoPlay->getTentative()) fill_me_in[LLMediaEntry::AUTO_PLAY_KEY] = (LLSD::Boolean)mAutoPlay->getValue();
  364. if (include_tentative || !mAutoScale->getTentative()) fill_me_in[LLMediaEntry::AUTO_SCALE_KEY] = (LLSD::Boolean)mAutoScale->getValue();
  365. if (include_tentative || !mAutoZoom->getTentative()) fill_me_in[LLMediaEntry::AUTO_ZOOM_KEY] = (LLSD::Boolean)mAutoZoom->getValue();
  366. //Don't fill in current URL: this is only supposed to get changed via navigate
  367. // if (include_tentative || !mCurrentURL->getTentative()) fill_me_in[LLMediaEntry::CURRENT_URL_KEY] = mCurrentURL->getValue();
  368. if (include_tentative || !mHeightPixels->getTentative()) fill_me_in[LLMediaEntry::HEIGHT_PIXELS_KEY] = (LLSD::Integer)mHeightPixels->getValue();
  369. // Don't fill in the home URL if it is the special "Multiple Media" string!
  370. if ((include_tentative || !mHomeURL->getTentative())
  371. && LLTrans::getString("Multiple Media") != mHomeURL->getValue())
  372. fill_me_in[LLMediaEntry::HOME_URL_KEY] = (LLSD::String)mHomeURL->getValue();
  373. if (include_tentative || !mFirstClick->getTentative()) fill_me_in[LLMediaEntry::FIRST_CLICK_INTERACT_KEY] = (LLSD::Boolean)mFirstClick->getValue();
  374. if (include_tentative || !mWidthPixels->getTentative()) fill_me_in[LLMediaEntry::WIDTH_PIXELS_KEY] = (LLSD::Integer)mWidthPixels->getValue();
  375. }
  376. ////////////////////////////////////////////////////////////////////////////////
  377. //
  378. void LLPanelMediaSettingsGeneral::postApply()
  379. {
  380. // Make sure to navigate to the home URL if the current URL is empty and
  381. // autoplay is on
  382. navigateHomeSelectedFace(true);
  383. }
  384. ////////////////////////////////////////////////////////////////////////////////
  385. //
  386. void LLPanelMediaSettingsGeneral::setParent( LLFloaterMediaSettings* parent )
  387. {
  388. mParent = parent;
  389. };
  390. ////////////////////////////////////////////////////////////////////////////////
  391. //
  392. bool LLPanelMediaSettingsGeneral::navigateHomeSelectedFace(bool only_if_current_is_empty)
  393. {
  394. struct functor_navigate_media : public LLSelectedTEGetFunctor< bool>
  395. {
  396. functor_navigate_media(bool flag) : only_if_current_is_empty(flag) {}
  397. bool get( LLViewerObject* object, S32 face )
  398. {
  399. if ( object && object->getTE(face) && object->permModify() )
  400. {
  401. const LLMediaEntry *media_data = object->getTE(face)->getMediaData();
  402. if ( media_data )
  403. {
  404. if (!only_if_current_is_empty || (media_data->getCurrentURL().empty() && media_data->getAutoPlay()))
  405. {
  406. viewer_media_t media_impl =
  407. LLViewerMedia::getMediaImplFromTextureID(object->getTE(face)->getMediaData()->getMediaID());
  408. if(media_impl)
  409. {
  410. media_impl->navigateHome();
  411. return true;
  412. }
  413. }
  414. }
  415. }
  416. return false;
  417. };
  418. bool only_if_current_is_empty;
  419. } functor_navigate_media(only_if_current_is_empty);
  420. bool all_face_media_navigated = false;
  421. LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection();
  422. selected_objects->getSelectedTEValue( &functor_navigate_media, all_face_media_navigated );
  423. // Note: we don't update the 'current URL' field until the media data itself changes
  424. return all_face_media_navigated;
  425. }
  426. ////////////////////////////////////////////////////////////////////////////////
  427. //
  428. const std::string LLPanelMediaSettingsGeneral::getHomeUrl()
  429. {
  430. return mHomeURL->getValue().asString();
  431. }
  432. ////////////////////////////////////////////////////////////////////////////////
  433. //
  434. void LLPanelMediaSettingsGeneral::updateCurrentUrl()
  435. {
  436. // Get the current URL from the selection
  437. const LLMediaEntry default_media_data;
  438. std::string value_str = default_media_data.getCurrentURL();
  439. struct functor_getter_current_url : public LLSelectedTEGetFunctor< std::string >
  440. {
  441. functor_getter_current_url(const LLMediaEntry& entry): mMediaEntry(entry) {}
  442. std::string get( LLViewerObject* object, S32 face )
  443. {
  444. if ( object )
  445. if ( object->getTE(face) )
  446. if ( object->getTE(face)->getMediaData() )
  447. return object->getTE(face)->getMediaData()->getCurrentURL();
  448. return mMediaEntry.getCurrentURL();
  449. };
  450. const LLMediaEntry & mMediaEntry;
  451. } func_current_url(default_media_data);
  452. bool identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func_current_url, value_str );
  453. mCurrentURL->setText(value_str);
  454. mCurrentURL->setTentative(identical);
  455. if ( LLPanelMediaSettingsGeneral::isMultiple() )
  456. {
  457. mCurrentURL->setText(LLTrans::getString("Multiple Media"));
  458. }
  459. }