PageRenderTime 78ms CodeModel.GetById 42ms app.highlight 31ms RepoModel.GetById 1ms app.codeStats 1ms

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