diff options
| author | Loren Shih <seraph@lindenlab.com> | 2011-03-21 10:38:39 -0400 | 
|---|---|---|
| committer | Loren Shih <seraph@lindenlab.com> | 2011-03-21 10:38:39 -0400 | 
| commit | be553242ef706e33260f3f9e62d02f4720f00473 (patch) | |
| tree | 553a150a63cd8105f8860780ef7d02f12a69eb23 | |
| parent | 9c1c791b29cb5087ebff142d4ad7a55b65be0ad0 (diff) | |
| parent | df63c6931e81c034887611711095e3134b9a7318 (diff) | |
Automated merge up from viewer-development into mesh-development
32 files changed, 1408 insertions, 1363 deletions
| @@ -81,3 +81,6 @@ b53a0576eec80614d7767ed72b40ed67aeff27c9 2.5.2-release  f1827b441e05bf37c68e2c15ebc6d09e9b03f527 2.6.0-start  f1827b441e05bf37c68e2c15ebc6d09e9b03f527 2.6.0-start  4e9eec6a347f89b2b3f295beb72f1cf7837dff66 2.6.0-start +9283d6d1d7eb71dfe4c330e7c9144857e7356bde 2.6.0-beta1 +9283d6d1d7eb71dfe4c330e7c9144857e7356bde DRTVWR-40_2.6.0-beta1 +c5bdef3aaa2744626aef3c217ce29e1900d357b3 2.6.1-start diff --git a/BuildParams b/BuildParams index c87f5a6034..7011875626 100755 --- a/BuildParams +++ b/BuildParams @@ -53,6 +53,7 @@ viewer-pre-beta.login_channel = "Second Life Beta Viewer"  viewer-pre-beta.build_debug_release_separately = true  viewer-pre-beta.build_viewer_update_version_manager = true +  # ========================================  # Viewer Release  # ======================================== @@ -68,14 +69,6 @@ viewer-pre-release.build_debug_release_separately = true  viewer-pre-release.build_viewer_update_version_manager = true  #viewer-pre-release.release-viewer.jira = DRTVWR-13 -# ======================================== -# aimee -# ======================================== - -viewer-development-import.build_debug_release_separately = true -viewer-development-fixes.build_debug_release_separately = true -viewer-development-tweaks.build_debug_release_separately = true -  # =======================================  # brad  # ======================================== @@ -189,55 +182,11 @@ media.build_viewer_update_version_manager = false  # oz  # ================ -oz_viewer-review1_coverity.coverity_product = viewer - -oz_viewer-review1.build_Linux = true -oz_viewer-review1_debug.build_Linux = false -oz_viewer-review1_coverity.build_Linux = false - -oz_viewer-review1.build_Darwin = true -oz_viewer-review1_debug.build_Darwin = false -oz_viewer-review1_coverity.build_Darwin = false - -oz_viewer-review1.build_CYGWIN = true -oz_viewer-review1.build_CYGWIN_Debug = false -oz_viewer-review1.build_CYGWIN_RelWithDebInfo = false -oz_viewer-review1.build_CYGWIN_Release = true -oz_viewer-review1_debug.build_CYGWIN_Debug = true -oz_viewer-review1_debug.build_CYGWIN_RelWithDebInfo = true -oz_viewer-review1_debug.build_CYGWIN_Release = false -oz_viewer-review1_coverity.build_coverity = true -oz_viewer-review1_coverity.build_CYGWIN_Debug = false -oz_viewer-review1_coverity.build_CYGWIN_RelWithDebInfo = false -oz_viewer-review1_coverity.build_CYGWIN_Release = false - -oz_viewer-review2_coverity.coverity_product = viewer - -oz_viewer-review2.build_Linux = true -oz_viewer-review2_debug.build_Linux = false -oz_viewer-review2_coverity.build_Linux = false - -oz_viewer-review2.build_Darwin = true -oz_viewer-review2_debug.build_Darwin = false -oz_viewer-review2_coverity.build_Darwin = false - -oz_viewer-review2.build_CYGWIN = true -oz_viewer-review2.build_CYGWIN_Debug = false -oz_viewer-review2.build_CYGWIN_RelWithDebInfo = false -oz_viewer-review2.build_CYGWIN_Release = true -oz_viewer-review2_debug.build_CYGWIN_Debug = true -oz_viewer-review2_debug.build_CYGWIN_RelWithDebInfo = true -oz_viewer-review2_debug.build_CYGWIN_Release = false -oz_viewer-review2_coverity.build_coverity = true -oz_viewer-review2_coverity.build_CYGWIN_Debug = false -oz_viewer-review2_coverity.build_CYGWIN_RelWithDebInfo = false -oz_viewer-review2_coverity.build_CYGWIN_Release = false - -# ======================================== -# tofu -# ======================================== - -tofu_viewer-development-staging.email = tofu.linden@lindenlab.com +oz-viewer-devreview.build_debug_release_separately = true +oz_viewer-poreview.build_debug_release_separately = true +oz-project-1.build_debug_release_separately = true +oz-project-2.build_debug_release_separately = true +oz-project-3.build_debug_release_separately = true  # ========================================  # enus diff --git a/doc/contributions.txt b/doc/contributions.txt index 337a3da6b8..3b1abcebed 100644 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -413,6 +413,7 @@ Jonathan Yap  	STORM-975
  	STORM-990
  	STORM-1020
 +	STORM-1064
  Kage Pixel
  	VWR-11
  Ken March
 diff --git a/indra/llcommon/llprocesslauncher.cpp b/indra/llcommon/llprocesslauncher.cpp index d46188104f..10950181fd 100644 --- a/indra/llcommon/llprocesslauncher.cpp +++ b/indra/llcommon/llprocesslauncher.cpp @@ -103,10 +103,30 @@ int LLProcessLauncher::launch(void)  	char *args2 = new char[args.size() + 1];  	strcpy(args2, args.c_str()); -	if( ! CreateProcessA( NULL, args2, NULL, NULL, FALSE, 0, NULL, mWorkingDir.c_str(), &sinfo, &pinfo ) ) +	const char * working_directory = 0; +	if(!mWorkingDir.empty()) working_directory = mWorkingDir.c_str(); +	if( ! CreateProcessA( NULL, args2, NULL, NULL, FALSE, 0, NULL, working_directory, &sinfo, &pinfo ) )  	{ -		// TODO: do better than returning the OS-specific error code on failure...  		result = GetLastError(); + +		LPTSTR error_str = 0; +		if( +			FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, +				NULL, +				result, +				0, +				(LPTSTR)&error_str, +				0, +				NULL)  +			!= 0)  +		{ +			char message[256]; +			wcstombs(message, error_str, 256); +			message[255] = 0; +			llwarns << "CreateProcessA failed: " << message << llendl; +			LocalFree(error_str); +		} +  		if(result == 0)  		{  			// Make absolutely certain we return a non-zero value on failure. diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h index 117d96ffa6..d22c879243 100644 --- a/indra/llcommon/llversionviewer.h +++ b/indra/llcommon/llversionviewer.h @@ -29,7 +29,7 @@  const S32 LL_VERSION_MAJOR = 2;  const S32 LL_VERSION_MINOR = 6; -const S32 LL_VERSION_PATCH = 1; +const S32 LL_VERSION_PATCH = 2;  const S32 LL_VERSION_BUILD = 0;  const char * const LL_CHANNEL = "Second Life Developer"; diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 35e0d9d890..d19e33ea55 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -2869,7 +2869,7 @@ void LLFloater::initFromParams(const LLFloater::Params& p)  	// close callback   	if (p.close_callback.isProvided())  	{ -		mCloseSignal.connect(initCommitCallback(p.close_callback)); +		setCloseCallback(initCommitCallback(p.close_callback));  	}  } @@ -2879,6 +2879,11 @@ boost::signals2::connection LLFloater::setMinimizeCallback( const commit_signal_  	return mMinimizeSignal->connect(cb);   } +boost::signals2::connection LLFloater::setCloseCallback( const commit_signal_t::slot_type& cb ) +{ +	return mCloseSignal.connect(cb); +} +  LLFastTimer::DeclareTimer POST_BUILD("Floater Post Build");  bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::string& filename, LLXMLNodePtr output_node) diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 0e83b80c89..5b7b020881 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -144,6 +144,7 @@ public:  	bool buildFromFile(const std::string &filename, LLXMLNodePtr output_node = NULL);  	boost::signals2::connection setMinimizeCallback( const commit_signal_t::slot_type& cb ); +	boost::signals2::connection setCloseCallback( const commit_signal_t::slot_type& cb );  	void initFromParams(const LLFloater::Params& p);  	bool initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::string& filename, LLXMLNodePtr output_node = NULL); diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 32d7be377a..f0374de98f 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -1936,9 +1936,15 @@ bool LLMenuGL::scrollItems(EScrollingDirection direction)  	{  		item_list_t::reverse_iterator first_visible_item_iter = mItems.rend(); +		// Need to scroll through number of actual existing items in menu. +		// Otherwise viewer will hang for a time needed to scroll U32_MAX +		// times in std::advance(). STORM-659. +		size_t nitems = mItems.size(); +		U32 scrollable_items = nitems < mMaxScrollableItems ? nitems : mMaxScrollableItems; +  		// Advance by mMaxScrollableItems back from the end of the list  		// to make the last item visible. -		std::advance(first_visible_item_iter, mMaxScrollableItems); +		std::advance(first_visible_item_iter, scrollable_items);  		mFirstVisibleItem = *first_visible_item_iter;  		break;  	} diff --git a/indra/media_plugins/winmmshim/CMakeLists.txt b/indra/media_plugins/winmmshim/CMakeLists.txt index 3e3a988310..bf74f81809 100644 --- a/indra/media_plugins/winmmshim/CMakeLists.txt +++ b/indra/media_plugins/winmmshim/CMakeLists.txt @@ -3,12 +3,12 @@  project(winmm_shim)  ### winmm_shim -# *HACK - override msvcrt implementation (intialized on 00-Common) to be
 -# statically linked for winmm.dll this relies on vc taking the last flag on
 -# the command line
 -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
 -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /MT")
 -set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
 +# *HACK - override msvcrt implementation (intialized on 00-Common) to be +# statically linked for winmm.dll this relies on vc taking the last flag on +# the command line +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /MT") +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")  set(winmm_shim_SOURCE_FILES      forwarding_api.cpp diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 92a3a0299a..e27397ab1a 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -3270,7 +3270,7 @@      <key>FirstRunThisInstall</key>      <map>        <key>Comment</key> -      <string>Specifies that you have not run the viewer since you installed the latest update</string> +      <string>Specifies that you have not run the viewer since you performed a clean install</string>        <key>Persist</key>        <integer>1</integer>        <key>Type</key> @@ -3278,7 +3278,18 @@        <key>Value</key>        <integer>1</integer>      </map> -    <key>FirstSelectedDisabledPopups</key> +  <key>FirstLoginThisInstall</key> +  <map> +    <key>Comment</key> +    <string>Specifies that you have not logged in with the viewer since you performed a clean install</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>1</integer> +  </map> +  <key>FirstSelectedDisabledPopups</key>      <map>        <key>Comment</key>        <string>Return false if there is not disabled popup selected in the list of floater preferences popups</string> diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 85447842e6..1184c8e76c 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2216,6 +2216,7 @@ bool LLAppViewer::initConfiguration()  	if (gSavedSettings.getBOOL("FirstRunThisInstall"))  	{  		gSavedSettings.setString("SessionSettingsFile", "settings_minimal.xml"); +		gSavedSettings.setBOOL("FirstRunThisInstall", FALSE);  	}  	if (clp.hasOption("sessionsettings")) diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp index 45d1cc2b53..641e64247b 100644 --- a/indra/newview/llfloatermap.cpp +++ b/indra/newview/llfloatermap.cpp @@ -42,7 +42,6 @@  #include "llviewercamera.h"  #include "lldraghandle.h"  #include "lltextbox.h" -#include "llviewermenu.h"  #include "llfloaterworldmap.h"  #include "llagent.h" @@ -63,7 +62,6 @@ const S32 MAP_PADDING_BOTTOM = 0;  LLFloaterMap::LLFloaterMap(const LLSD& key)   	: LLFloater(key), -	  mPopupMenu(NULL),  	  mTextBoxEast(NULL),  	  mTextBoxNorth(NULL),  	  mTextBoxWest(NULL), @@ -102,17 +100,6 @@ BOOL LLFloaterMap::postBuild()  	mTextBoxSouthWest = getChild<LLTextBox> ("floater_map_southwest");  	mTextBoxNorthWest = getChild<LLTextBox> ("floater_map_northwest"); -	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; -	 -	registrar.add("Minimap.Zoom", boost::bind(&LLFloaterMap::handleZoom, this, _2)); -	registrar.add("Minimap.Tracker", boost::bind(&LLFloaterMap::handleStopTracking, this, _2)); - -	mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_mini_map.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); -	if (mPopupMenu && !LLTracker::isTracking(0)) -	{ -		mPopupMenu->setItemEnabled ("Stop Tracking", false); -	} -  	stretchMiniMap(getRect().getWidth() - MAP_PADDING_LEFT - MAP_PADDING_RIGHT  		,getRect().getHeight() - MAP_PADDING_TOP - MAP_PADDING_BOTTOM); @@ -163,17 +150,6 @@ BOOL LLFloaterMap::handleDoubleClick(S32 x, S32 y, MASK mask)  	return TRUE;  } -BOOL LLFloaterMap::handleRightMouseDown(S32 x, S32 y, MASK mask) -{ -	if (mPopupMenu) -	{ -		mPopupMenu->buildDrawLabels(); -		mPopupMenu->updateParent(LLMenuGL::sMenuContainer); -		LLMenuGL::showPopup(this, mPopupMenu, x, y); -	} -	return TRUE; -} -  void LLFloaterMap::setDirectionPos( LLTextBox* text_box, F32 rotation )  {  	// Rotation is in radians. @@ -244,11 +220,6 @@ void LLFloaterMap::draw()  		getDragHandle()->setMouseOpaque(TRUE);  	} -	if (LLTracker::isTracking(0)) -	{ -		mPopupMenu->setItemEnabled ("Stop Tracking", true); -	} -	  	LLFloater::draw();  } @@ -315,14 +286,6 @@ void LLFloaterMap::handleZoom(const LLSD& userdata)  	}  } -void LLFloaterMap::handleStopTracking (const LLSD& userdata) -{ -	if (mPopupMenu) -	{ -		mPopupMenu->setItemEnabled ("Stop Tracking", false); -		LLTracker::stopTracking ((void*)LLTracker::isTracking(NULL)); -	} -}  void	LLFloaterMap::setMinimized(BOOL b)  {  	LLFloater::setMinimized(b); diff --git a/indra/newview/llfloatermap.h b/indra/newview/llfloatermap.h index 4cbb48fb3e..5cf66a594b 100644 --- a/indra/newview/llfloatermap.h +++ b/indra/newview/llfloatermap.h @@ -29,7 +29,6 @@  #include "llfloater.h" -class LLMenuGL;  class LLNetMap;  class LLTextBox; @@ -44,7 +43,6 @@ public:  	/*virtual*/ BOOL 	postBuild();  	/*virtual*/ BOOL	handleDoubleClick( S32 x, S32 y, MASK mask ); -	/*virtual*/ BOOL	handleRightMouseDown( S32 x, S32 y, MASK mask );  	/*virtual*/ void	reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);  	/*virtual*/ void	draw();  	/*virtual*/ void	onFocusLost(); @@ -54,14 +52,11 @@ public:  private:  	void handleZoom(const LLSD& userdata); -	void handleStopTracking (const LLSD& userdata);  	void setDirectionPos( LLTextBox* text_box, F32 rotation );  	void updateMinorDirections();  	void stretchMiniMap(S32 width,S32 height); -	LLMenuGL*		mPopupMenu; -  	LLTextBox*		mTextBoxEast;  	LLTextBox*		mTextBoxNorth;  	LLTextBox*		mTextBoxWest; diff --git a/indra/newview/llhudeffectblob.cpp b/indra/newview/llhudeffectblob.cpp index 26e8251899..d8687eed8d 100644 --- a/indra/newview/llhudeffectblob.cpp +++ b/indra/newview/llhudeffectblob.cpp @@ -30,13 +30,14 @@  #include "llagent.h"  #include "llviewercamera.h" -#include "llrendersphere.h" +#include "llui.h"  LLHUDEffectBlob::LLHUDEffectBlob(const U8 type)   :	LLHUDEffect(type),   	mPixelSize(10)  {  	mTimer.start(); +	mImage = LLUI::getUIImage("Camera_Drag_Dot");  }  LLHUDEffectBlob::~LLHUDEffectBlob() @@ -58,18 +59,29 @@ void LLHUDEffectBlob::render()  	LLViewerCamera::instance().getPixelVectors(pos_agent, pixel_up, pixel_right);  	LLGLSPipelineAlpha gls_pipeline_alpha; -	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +	gGL.getTexUnit(0)->bind(mImage->getImage());  	LLColor4U color = mColor;  	color.mV[VALPHA] = (U8)clamp_rescale(time, 0.f, mDuration, 255.f, 0.f); -	glColor4ubv(color.mV); +	gGL.color4ubv(color.mV); -	glPushMatrix(); -	glTranslatef(pos_agent.mV[0], pos_agent.mV[1], pos_agent.mV[2]); -	F32 scale = pixel_up.magVec() * (F32)mPixelSize; -	glScalef(scale, scale, scale); -	gSphere.render(0); -	glPopMatrix(); +	{ gGL.pushMatrix(); +		gGL.translatef(pos_agent.mV[0], pos_agent.mV[1], pos_agent.mV[2]); +		LLVector3 u_scale = pixel_right * (F32)mPixelSize; +		LLVector3 v_scale = pixel_up * (F32)mPixelSize; +		 +		{ gGL.begin(LLRender::QUADS); +			gGL.texCoord2f(0.f, 1.f); +			gGL.vertex3fv((v_scale - u_scale).mV); +			gGL.texCoord2f(0.f, 0.f); +			gGL.vertex3fv((-v_scale - u_scale).mV); +			gGL.texCoord2f(1.f, 0.f); +			gGL.vertex3fv((-v_scale + u_scale).mV); +			gGL.texCoord2f(1.f, 1.f); +			gGL.vertex3fv((v_scale + u_scale).mV); +		} gGL.end(); + +	} gGL.popMatrix();  }  void LLHUDEffectBlob::renderForTimer() diff --git a/indra/newview/llhudeffectblob.h b/indra/newview/llhudeffectblob.h index 5b0703cdaa..f4c1691108 100644 --- a/indra/newview/llhudeffectblob.h +++ b/indra/newview/llhudeffectblob.h @@ -28,6 +28,7 @@  #define LL_LLHUDEFFECTBLOB_H  #include "llhudeffect.h" +#include "lluiimage.h"  class LLHUDEffectBlob : public LLHUDEffect  { @@ -45,6 +46,7 @@ protected:  private:  	S32				mPixelSize;  	LLFrameTimer	mTimer; +	LLPointer<LLUIImage> mImage;  };  #endif // LL_LLHUDEFFECTBLOB_H diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp index 836ae9a0cf..162e465fef 100644 --- a/indra/newview/llnearbychatbar.cpp +++ b/indra/newview/llnearbychatbar.cpp @@ -157,6 +157,16 @@ BOOL LLGestureComboList::handleKeyHere(KEY key, MASK mask)  	return handled; 		  } +void LLGestureComboList::draw() +{ +	LLUICtrl::draw(); + +	if(mButton->getToggleState()) +	{ +		showList(); +	} +} +  void LLGestureComboList::showList()  {  	LLRect rect = mList->getRect(); @@ -180,6 +190,7 @@ void LLGestureComboList::showList()  	// Show the list and push the button down  	mButton->setToggleState(TRUE);  	mList->setVisible(TRUE); +	sendChildToFront(mList);  	LLUI::addPopup(mList);  } diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h index 033d1dd5a2..96ab45071b 100644 --- a/indra/newview/llnearbychatbar.h +++ b/indra/newview/llnearbychatbar.h @@ -72,6 +72,8 @@ public:  	virtual void	hideList();  	virtual BOOL	handleKeyHere(KEY key, MASK mask); +	virtual void	draw(); +  	S32				getCurrentIndex() const;  	void			onItemSelected(const LLSD& data);  	void			sortByName(bool ascending = true); diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index e29078c545..981b4dbee3 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -112,10 +112,6 @@ BOOL LLNetMap::postBuild()  	registrar.add("Minimap.Tracker", boost::bind(&LLNetMap::handleStopTracking, this, _2));  	mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_mini_map.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); -	if (mPopupMenu && !LLTracker::isTracking(0)) -	{ -		mPopupMenu->setItemEnabled ("Stop Tracking", false); -	}  	return TRUE;  } @@ -510,13 +506,6 @@ void LLNetMap::draw()  	gGL.popUIMatrix();  	LLUICtrl::draw(); - -	if (LLTracker::isTracking(0)) -	{ -		mPopupMenu->setItemEnabled ("Stop Tracking", true); -	} -	 -  }  void LLNetMap::reshape(S32 width, S32 height, BOOL called_from_parent) @@ -886,6 +875,7 @@ BOOL LLNetMap::handleRightMouseDown(S32 x, S32 y, MASK mask)  	{  		mPopupMenu->buildDrawLabels();  		mPopupMenu->updateParent(LLMenuGL::sMenuContainer); +		mPopupMenu->setItemEnabled("Stop Tracking", LLTracker::isTracking(0));  		LLMenuGL::showPopup(this, mPopupMenu, x, y);  	}  	return TRUE; diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index b472698a49..903cf4780d 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -1,1183 +1,1183 @@ -/** 
 - * @file llpanellogin.cpp
 - * @brief Login dialog and logo display
 - *
 - * $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 "llpanellogin.h"
 -
 -#include "indra_constants.h"		// for key and mask constants
 -#include "llfloaterreg.h"
 -#include "llfontgl.h"
 -#include "llmd5.h"
 -#include "llsecondlifeurls.h"
 -#include "v4color.h"
 -
 -#include "llappviewer.h"
 -#include "llbutton.h"
 -#include "llcheckboxctrl.h"
 -#include "llcommandhandler.h"		// for secondlife:///app/login/
 -#include "llcombobox.h"
 -#include "llcurl.h"
 -#include "llviewercontrol.h"
 -#include "llfloaterpreference.h"
 -#include "llfocusmgr.h"
 -#include "lllineeditor.h"
 -#include "llnotificationsutil.h"
 -#include "llsecapi.h"
 -#include "llstartup.h"
 -#include "lltextbox.h"
 -#include "llui.h"
 -#include "lluiconstants.h"
 -#include "llslurl.h"
 -#include "llversioninfo.h"
 -#include "llviewerhelp.h"
 -#include "llviewertexturelist.h"
 -#include "llviewermenu.h"			// for handle_preferences()
 -#include "llviewernetwork.h"
 -#include "llviewerwindow.h"			// to link into child list
 -#include "lluictrlfactory.h"
 -#include "llhttpclient.h"
 -#include "llweb.h"
 -#include "llmediactrl.h"
 -#include "llrootview.h"
 -
 -#include "llfloatertos.h"
 -#include "lltrans.h"
 -#include "llglheaders.h"
 -#include "llpanelloginlistener.h"
 -
 -#if LL_WINDOWS
 -#pragma warning(disable: 4355)      // 'this' used in initializer list
 -#endif  // LL_WINDOWS
 -
 -#include "llsdserialize.h"
 -
 -const S32 BLACK_BORDER_HEIGHT = 160;
 -const S32 MAX_PASSWORD = 16;
 -
 -LLPanelLogin *LLPanelLogin::sInstance = NULL;
 -BOOL LLPanelLogin::sCapslockDidNotification = FALSE;
 -
 -
 -class LLLoginRefreshHandler : public LLCommandHandler
 -{
 -public:
 -	// don't allow from external browsers
 -	LLLoginRefreshHandler() : LLCommandHandler("login_refresh", UNTRUSTED_BLOCK) { }
 -	bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web)
 -	{	
 -		if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP)
 -		{
 -			LLPanelLogin::loadLoginPage();
 -		}	
 -		return true;
 -	}
 -};
 -
 -LLLoginRefreshHandler gLoginRefreshHandler;
 -
 -
 -// helper class that trys to download a URL from a web site and calls a method 
 -// on parent class indicating if the web server is working or not
 -class LLIamHereLogin : public LLHTTPClient::Responder
 -{
 -	private:
 -		LLIamHereLogin( LLPanelLogin* parent ) :
 -		   mParent( parent )
 -		{}
 -
 -		LLPanelLogin* mParent;
 -
 -	public:
 -		static boost::intrusive_ptr< LLIamHereLogin > build( LLPanelLogin* parent )
 -		{
 -			return boost::intrusive_ptr< LLIamHereLogin >( new LLIamHereLogin( parent ) );
 -		};
 -
 -		virtual void  setParent( LLPanelLogin* parentIn )
 -		{
 -			mParent = parentIn;
 -		};
 -
 -		// We don't actually expect LLSD back, so need to override completedRaw
 -		virtual void completedRaw(U32 status, const std::string& reason,
 -								  const LLChannelDescriptors& channels,
 -								  const LLIOPipe::buffer_ptr_t& buffer)
 -		{
 -			completed(status, reason, LLSD()); // will call result() or error()
 -		}
 -	
 -		virtual void result( const LLSD& content )
 -		{
 -			if ( mParent )
 -				mParent->setSiteIsAlive( true );
 -		};
 -
 -		virtual void error( U32 status, const std::string& reason )
 -		{
 -			if ( mParent )
 -				mParent->setSiteIsAlive( false );
 -		};
 -};
 -
 -// this is global and not a class member to keep crud out of the header file
 -namespace {
 -	boost::intrusive_ptr< LLIamHereLogin > gResponsePtr = 0;
 -};
 -
 -
 -//---------------------------------------------------------------------------
 -// Public methods
 -//---------------------------------------------------------------------------
 -LLPanelLogin::LLPanelLogin(const LLRect &rect,
 -						 BOOL show_server,
 -						 void (*callback)(S32 option, void* user_data),
 -						 void *cb_data)
 -:	LLPanel(),
 -	mLogoImage(),
 -	mCallback(callback),
 -	mCallbackData(cb_data),
 -	mHtmlAvailable( TRUE ),
 -	mListener(new LLPanelLoginListener(this))
 -{
 -	setBackgroundVisible(FALSE);
 -	setBackgroundOpaque(TRUE);
 -
 -	// instance management
 -	if (LLPanelLogin::sInstance)
 -	{
 -		llwarns << "Duplicate instance of login view deleted" << llendl;
 -		// Don't leave bad pointer in gFocusMgr
 -		gFocusMgr.setDefaultKeyboardFocus(NULL);
 -
 -		delete LLPanelLogin::sInstance;
 -	}
 -
 -	mPasswordModified = FALSE;
 -	LLPanelLogin::sInstance = this;
 -
 -	LLView* login_holder = gViewerWindow->getLoginPanelHolder();
 -	if (login_holder)
 -	{
 -		login_holder->addChild(this);
 -	}
 -
 -	// Logo
 -	mLogoImage = LLUI::getUIImage("startup_logo");
 -
 -	buildFromFile( "panel_login.xml");
 -	
 -	// Legacy login web page is hidden under the menu bar.
 -	// Adjust reg-in-client web browser widget to not be hidden.
 -	if (gSavedSettings.getBOOL("RegInClient"))
 -	{
 -		reshape(rect.getWidth(), rect.getHeight() - MENU_BAR_HEIGHT);
 -	}
 -	else
 -	{
 -		reshape(rect.getWidth(), rect.getHeight());
 -	}
 -
 -	getChild<LLLineEditor>("password_edit")->setKeystrokeCallback(onPassKey, this);
 -
 -	// change z sort of clickable text to be behind buttons
 -	//sendChildToBack(getChildView("channel_text"));
 -	sendChildToBack(getChildView("forgot_password_text"));
 -
 -	if(LLStartUp::getStartSLURL().getType() != LLSLURL::LOCATION)
 -	{
 -		LLSLURL slurl(gSavedSettings.getString("LoginLocation"));
 -		LLStartUp::setStartSLURL(slurl);
 -	}
 -	updateLocationCombo(false);
 -
 -	gSavedSettings.getControl("SessionSettingsFile")->getSignal()->connect(boost::bind(&onModeChange));
 -
 -	LLComboBox* server_choice_combo = sInstance->getChild<LLComboBox>("server_combo");
 -	server_choice_combo->setCommitCallback(onSelectServer, NULL);
 -	server_choice_combo->setFocusLostCallback(boost::bind(onServerComboLostFocus, _1));
 -	updateServerCombo();
 -
 -	childSetAction("connect_btn", onClickConnect, this);
 -
 -	getChild<LLPanel>("login")->setDefaultBtn("connect_btn");
 -
 -	std::string channel = LLVersionInfo::getChannel();
 -	std::string version = llformat("%s (%d)",
 -								   LLVersionInfo::getShortVersion().c_str(),
 -								   LLVersionInfo::getBuild());
 -	//LLTextBox* channel_text = getChild<LLTextBox>("channel_text");
 -	//channel_text->setTextArg("[CHANNEL]", channel); // though not displayed
 -	//channel_text->setTextArg("[VERSION]", version);
 -	//channel_text->setClickedCallback(onClickVersion, this);
 -	
 -	LLTextBox* forgot_password_text = getChild<LLTextBox>("forgot_password_text");
 -	forgot_password_text->setClickedCallback(onClickForgotPassword, NULL);
 -
 -	LLTextBox* create_new_account_text = getChild<LLTextBox>("create_new_account_text");
 -	create_new_account_text->setClickedCallback(onClickNewAccount, NULL);
 -
 -	LLTextBox* need_help_text = getChild<LLTextBox>("login_help");
 -	need_help_text->setClickedCallback(onClickHelp, NULL);
 -	
 -	// get the web browser control
 -	LLMediaCtrl* web_browser = getChild<LLMediaCtrl>("login_html");
 -	web_browser->addObserver(this);
 -	
 -	// Clear the browser's cache to avoid any potential for the cache messing up the login screen.
 -	web_browser->clearCache();
 -
 -	reshapeBrowser();
 -
 -	// kick off a request to grab the url manually
 -	gResponsePtr = LLIamHereLogin::build( this );
 -
 -	LLHTTPClient::head( LLGridManager::getInstance()->getLoginPage(), gResponsePtr );
 -
 -	// Show last logged in user favorites in "Start at" combo.
 -	addUsersWithFavoritesToUsername();
 -	getChild<LLComboBox>("username_combo")->setTextChangedCallback(boost::bind(&LLPanelLogin::addFavoritesToStartLocation, this));
 -
 -	updateLocationCombo(false);
 -
 -}
 -
 -void LLPanelLogin::addUsersWithFavoritesToUsername()
 -{
 -	LLComboBox* combo = getChild<LLComboBox>("username_combo");
 -	if (!combo) return;
 -	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
 -	LLSD fav_llsd;
 -	llifstream file;
 -	file.open(filename);
 -	if (!file.is_open()) return;
 -	LLSDSerialize::fromXML(fav_llsd, file);
 -	for (LLSD::map_const_iterator iter = fav_llsd.beginMap();
 -		iter != fav_llsd.endMap(); ++iter)
 -	{
 -		combo->add(iter->first);
 -	}
 -}
 -
 -void LLPanelLogin::addFavoritesToStartLocation()
 -{
 -	LLComboBox* combo = getChild<LLComboBox>("start_location_combo");
 -	if (!combo) return;
 -	int num_items = combo->getItemCount();
 -	for (int i = num_items - 1; i > 2; i--)
 -	{
 -		combo->remove(i);
 -	}
 -	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
 -	LLSD fav_llsd;
 -	llifstream file;
 -	file.open(filename);
 -	if (!file.is_open()) return;
 -	LLSDSerialize::fromXML(fav_llsd, file);
 -	for (LLSD::map_const_iterator iter = fav_llsd.beginMap();
 -		iter != fav_llsd.endMap(); ++iter)
 -	{
 -		if(iter->first != getChild<LLComboBox>("username_combo")->getSimple()) continue;
 -		combo->addSeparator();
 -		LLSD user_llsd = iter->second;
 -		for (LLSD::array_const_iterator iter1 = user_llsd.beginArray();
 -			iter1 != user_llsd.endArray(); ++iter1)
 -		{
 -			std::string label = (*iter1)["name"].asString();
 -			std::string value = (*iter1)["slurl"].asString();
 -			if(label != "" && value != "")
 -			{
 -				combo->add(label, value);
 -			}
 -		}
 -		break;
 -	}
 -}
 -
 -// force the size to be correct (XML doesn't seem to be sufficient to do this)
 -// (with some padding so the other login screen doesn't show through)
 -void LLPanelLogin::reshapeBrowser()
 -{
 -	LLMediaCtrl* web_browser = getChild<LLMediaCtrl>("login_html");
 -	LLRect rect = gViewerWindow->getWindowRectScaled();
 -	LLRect html_rect;
 -	html_rect.setCenterAndSize(
 -		rect.getCenterX() - 2, rect.getCenterY() + 40,
 -		rect.getWidth() + 6, rect.getHeight() - 78 );
 -	web_browser->setRect( html_rect );
 -	web_browser->reshape( html_rect.getWidth(), html_rect.getHeight(), TRUE );
 -	reshape( rect.getWidth(), rect.getHeight(), 1 );
 -}
 -
 -void LLPanelLogin::setSiteIsAlive( bool alive )
 -{
 -	LLMediaCtrl* web_browser = getChild<LLMediaCtrl>("login_html");
 -	// if the contents of the site was retrieved
 -	if ( alive )
 -	{
 -		if ( web_browser )
 -		{
 -			loadLoginPage();
 -			
 -			// mark as available
 -			mHtmlAvailable = TRUE;
 -		}
 -	}
 -	else
 -	// the site is not available (missing page, server down, other badness)
 -	{
 -		if ( web_browser )
 -		{
 -			// hide browser control (revealing default one)
 -			web_browser->setVisible( FALSE );
 -
 -			// mark as unavailable
 -			mHtmlAvailable = FALSE;
 -		}
 -	}
 -}
 -
 -
 -LLPanelLogin::~LLPanelLogin()
 -{
 -	LLPanelLogin::sInstance = NULL;
 -
 -	// tell the responder we're not here anymore
 -	if ( gResponsePtr )
 -		gResponsePtr->setParent( 0 );
 -
 -	//// We know we're done with the image, so be rid of it.
 -	//gTextureList.deleteImage( mLogoImage );
 -
 -	// Controls having keyboard focus by default
 -	// must reset it on destroy. (EXT-2748)
 -	gFocusMgr.setDefaultKeyboardFocus(NULL);
 -}
 -
 -// virtual
 -void LLPanelLogin::draw()
 -{
 -	glPushMatrix();
 -	{
 -		F32 image_aspect = 1.333333f;
 -		F32 view_aspect = (F32)getRect().getWidth() / (F32)getRect().getHeight();
 -		// stretch image to maintain aspect ratio
 -		if (image_aspect > view_aspect)
 -		{
 -			glTranslatef(-0.5f * (image_aspect / view_aspect - 1.f) * getRect().getWidth(), 0.f, 0.f);
 -			glScalef(image_aspect / view_aspect, 1.f, 1.f);
 -		}
 -
 -		S32 width = getRect().getWidth();
 -		S32 height = getRect().getHeight();
 -
 -		if ( mHtmlAvailable )
 -		{
 -			if (getChild<LLView>("login_widgets")->getVisible())
 -			{
 -				// draw a background box in black
 -				gl_rect_2d( 0, height - 264, width, 264, LLColor4::black );
 -				// draw the bottom part of the background image
 -				// just the blue background to the native client UI
 -				mLogoImage->draw(0, -264, width + 8, mLogoImage->getHeight());
 -			}
 -		}
 -		else
 -		{
 -			// the HTML login page is not available so default to the original screen
 -			S32 offscreen_part = height / 3;
 -			mLogoImage->draw(0, -offscreen_part, width, height+offscreen_part);
 -		};
 -	}
 -	glPopMatrix();
 -
 -	LLPanel::draw();
 -}
 -
 -// virtual
 -BOOL LLPanelLogin::handleKeyHere(KEY key, MASK mask)
 -{
 -	if ( KEY_F1 == key )
 -	{
 -		LLViewerHelp* vhelp = LLViewerHelp::getInstance();
 -		vhelp->showTopic(vhelp->f1HelpTopic());
 -		return TRUE;
 -	}
 -
 -	return LLPanel::handleKeyHere(key, mask);
 -}
 -
 -// virtual 
 -void LLPanelLogin::setFocus(BOOL b)
 -{
 -	if(b != hasFocus())
 -	{
 -		if(b)
 -		{
 -			LLPanelLogin::giveFocus();
 -		}
 -		else
 -		{
 -			LLPanel::setFocus(b);
 -		}
 -	}
 -}
 -
 -// static
 -void LLPanelLogin::giveFocus()
 -{
 -	if( sInstance )
 -	{
 -		// Grab focus and move cursor to first blank input field
 -		std::string username = sInstance->getChild<LLUICtrl>("username_combo")->getValue().asString();
 -		std::string pass = sInstance->getChild<LLUICtrl>("password_edit")->getValue().asString();
 -
 -		BOOL have_username = !username.empty();
 -		BOOL have_pass = !pass.empty();
 -
 -		LLLineEditor* edit = NULL;
 -		LLComboBox* combo = NULL;
 -		if (have_username && !have_pass)
 -		{
 -			// User saved his name but not his password.  Move
 -			// focus to password field.
 -			edit = sInstance->getChild<LLLineEditor>("password_edit");
 -		}
 -		else
 -		{
 -			// User doesn't have a name, so start there.
 -			combo = sInstance->getChild<LLComboBox>("username_combo");
 -		}
 -
 -		if (edit)
 -		{
 -			edit->setFocus(TRUE);
 -			edit->selectAll();
 -		}
 -		else if (combo)
 -		{
 -			combo->setFocus(TRUE);
 -		}
 -	}
 -}
 -
 -// static
 -void LLPanelLogin::showLoginWidgets()
 -{
 -	// *NOTE: Mani - This may or may not be obselete code.
 -	// It seems to be part of the defunct? reg-in-client project.
 -	sInstance->getChildView("login_widgets")->setVisible( true);
 -	LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html");
 -	sInstance->reshapeBrowser();
 -	// *TODO: Append all the usual login parameters, like first_login=Y etc.
 -	std::string splash_screen_url = LLGridManager::getInstance()->getLoginPage();
 -	web_browser->navigateTo( splash_screen_url, "text/html" );
 -	LLUICtrl* username_combo = sInstance->getChild<LLUICtrl>("username_combo");
 -	username_combo->setFocus(TRUE);
 -}
 -
 -// static
 -void LLPanelLogin::show(const LLRect &rect,
 -						BOOL show_server,
 -						void (*callback)(S32 option, void* user_data),
 -						void* callback_data)
 -{
 -	new LLPanelLogin(rect, show_server, callback, callback_data);
 -
 -	if( !gFocusMgr.getKeyboardFocus() )
 -	{
 -		// Grab focus and move cursor to first enabled control
 -		sInstance->setFocus(TRUE);
 -	}
 -
 -	// Make sure that focus always goes here (and use the latest sInstance that was just created)
 -	gFocusMgr.setDefaultKeyboardFocus(sInstance);
 -}
 -
 -// static
 -void LLPanelLogin::setFields(LLPointer<LLCredential> credential,
 -							 BOOL remember)
 -{
 -	if (!sInstance)
 -	{
 -		llwarns << "Attempted fillFields with no login view shown" << llendl;
 -		return;
 -	}
 -	LL_INFOS("Credentials") << "Setting login fields to " << *credential << LL_ENDL;
 -
 -	LLSD identifier = credential->getIdentifier();
 -	if((std::string)identifier["type"] == "agent") 
 -	{
 -		std::string firstname = identifier["first_name"].asString();
 -		std::string lastname = identifier["last_name"].asString();
 -	    std::string login_id = firstname;
 -	    if (!lastname.empty() && lastname != "Resident")
 -	    {
 -		    // support traditional First Last name SLURLs
 -		    login_id += " ";
 -		    login_id += lastname;
 -	    }
 -		sInstance->getChild<LLComboBox>("username_combo")->setLabel(login_id);	
 -	}
 -	else if((std::string)identifier["type"] == "account")
 -	{
 -		sInstance->getChild<LLComboBox>("username_combo")->setLabel((std::string)identifier["account_name"]);		
 -	}
 -	else
 -	{
 -	  sInstance->getChild<LLComboBox>("username_combo")->setLabel(std::string());	
 -	}
 -	sInstance->addFavoritesToStartLocation();
 -	// if the password exists in the credential, set the password field with
 -	// a filler to get some stars
 -	LLSD authenticator = credential->getAuthenticator();
 -	LL_INFOS("Credentials") << "Setting authenticator field " << authenticator["type"].asString() << LL_ENDL;
 -	if(authenticator.isMap() && 
 -	   authenticator.has("secret") && 
 -	   (authenticator["secret"].asString().size() > 0))
 -	{
 -		
 -		// This is a MD5 hex digest of a password.
 -		// We don't actually use the password input field, 
 -		// fill it with MAX_PASSWORD characters so we get a 
 -		// nice row of asterixes.
 -		const std::string filler("123456789!123456");
 -		sInstance->getChild<LLUICtrl>("password_edit")->setValue(std::string("123456789!123456"));
 -	}
 -	else
 -	{
 -		sInstance->getChild<LLUICtrl>("password_edit")->setValue(std::string());		
 -	}
 -	sInstance->getChild<LLUICtrl>("remember_check")->setValue(remember);
 -}
 -
 -
 -// static
 -void LLPanelLogin::getFields(LLPointer<LLCredential>& credential,
 -							 BOOL& remember)
 -{
 -	if (!sInstance)
 -	{
 -		llwarns << "Attempted getFields with no login view shown" << llendl;
 -		return;
 -	}
 -	
 -	// load the credential so we can pass back the stored password or hash if the user did
 -	// not modify the password field.
 -	
 -	credential = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
 -
 -	LLSD identifier = LLSD::emptyMap();
 -	LLSD authenticator = LLSD::emptyMap();
 -	
 -	if(credential.notNull())
 -	{
 -		authenticator = credential->getAuthenticator();
 -	}
 -
 -	std::string username = sInstance->getChild<LLUICtrl>("username_combo")->getValue().asString();
 -	LLStringUtil::trim(username);
 -	std::string password = sInstance->getChild<LLUICtrl>("password_edit")->getValue().asString();
 -
 -	LL_INFOS2("Credentials", "Authentication") << "retrieving username:" << username << LL_ENDL;
 -	// determine if the username is a first/last form or not.
 -	size_t separator_index = username.find_first_of(' ');
 -	if (separator_index == username.npos
 -		&& !LLGridManager::getInstance()->isSystemGrid())
 -	{
 -		LL_INFOS2("Credentials", "Authentication") << "account: " << username << LL_ENDL;
 -		// single username, so this is a 'clear' identifier
 -		identifier["type"] = CRED_IDENTIFIER_TYPE_ACCOUNT;
 -		identifier["account_name"] = username;
 -		
 -		if (LLPanelLogin::sInstance->mPasswordModified)
 -		{
 -			authenticator = LLSD::emptyMap();
 -			// password is plaintext
 -			authenticator["type"] = CRED_AUTHENTICATOR_TYPE_CLEAR;
 -			authenticator["secret"] = password;
 -		}
 -	}
 -	else
 -	{
 -		// Be lenient in terms of what separators we allow for two-word names
 -		// and allow legacy users to login with firstname.lastname
 -		separator_index = username.find_first_of(" ._");
 -		std::string first = username.substr(0, separator_index);
 -		std::string last;
 -		if (separator_index != username.npos)
 -		{
 -			last = username.substr(separator_index+1, username.npos);
 -		LLStringUtil::trim(last);
 -		}
 -		else
 -		{
 -			// ...on Linden grids, single username users as considered to have
 -			// last name "Resident"
 -			// *TODO: Make login.cgi support "account_name" like above
 -			last = "Resident";
 -		}
 -		
 -		if (last.find_first_of(' ') == last.npos)
 -		{
 -			LL_INFOS2("Credentials", "Authentication") << "agent: " << username << LL_ENDL;
 -			// traditional firstname / lastname
 -			identifier["type"] = CRED_IDENTIFIER_TYPE_AGENT;
 -			identifier["first_name"] = first;
 -			identifier["last_name"] = last;
 -		
 -			if (LLPanelLogin::sInstance->mPasswordModified)
 -			{
 -				authenticator = LLSD::emptyMap();
 -				authenticator["type"] = CRED_AUTHENTICATOR_TYPE_HASH;
 -				authenticator["algorithm"] = "md5";
 -				LLMD5 pass((const U8 *)password.c_str());
 -				char md5pass[33];               /* Flawfinder: ignore */
 -				pass.hex_digest(md5pass);
 -				authenticator["secret"] = md5pass;
 -			}
 -		}
 -	}
 -	credential = gSecAPIHandler->createCredential(LLGridManager::getInstance()->getGrid(), identifier, authenticator);
 -	remember = sInstance->getChild<LLUICtrl>("remember_check")->getValue();
 -}
 -
 -// static
 -BOOL LLPanelLogin::isGridComboDirty()
 -{
 -	BOOL user_picked = FALSE;
 -	if (!sInstance)
 -	{
 -		llwarns << "Attempted getServer with no login view shown" << llendl;
 -	}
 -	else
 -	{
 -		LLComboBox* combo = sInstance->getChild<LLComboBox>("server_combo");
 -		user_picked = combo->isDirty();
 -	}
 -	return user_picked;
 -}
 -
 -// static
 -BOOL LLPanelLogin::areCredentialFieldsDirty()
 -{
 -	if (!sInstance)
 -	{
 -		llwarns << "Attempted getServer with no login view shown" << llendl;
 -	}
 -	else
 -	{
 -		std::string username = sInstance->getChild<LLUICtrl>("username_combo")->getValue().asString();
 -		LLStringUtil::trim(username);
 -		std::string password = sInstance->getChild<LLUICtrl>("password_edit")->getValue().asString();
 -		LLComboBox* combo = sInstance->getChild<LLComboBox>("username_combo");
 -		if(combo && combo->isDirty())
 -		{
 -			return true;
 -		}
 -		LLLineEditor* ctrl = sInstance->getChild<LLLineEditor>("password_edit");
 -		if(ctrl && ctrl->isDirty()) 
 -		{
 -			return true;
 -		}
 -	}
 -	return false;	
 -}
 -
 -
 -// static
 -void LLPanelLogin::updateLocationCombo( bool force_visible )
 -{
 -	if (!sInstance) 
 -	{
 -		return;
 -	}	
 -	
 -	LLComboBox* combo = sInstance->getChild<LLComboBox>("start_location_combo");
 -	
 -	switch(LLStartUp::getStartSLURL().getType())
 -	{
 -		case LLSLURL::LOCATION:
 -		{
 -			
 -			combo->setCurrentByIndex( 2 );	
 -			combo->setTextEntry(LLStartUp::getStartSLURL().getLocationString());	
 -			break;
 -		}
 -		case LLSLURL::HOME_LOCATION:
 -			combo->setCurrentByIndex(1);
 -			break;
 -		default:
 -			combo->setCurrentByIndex(0);
 -			break;
 -	}
 -	
 -	BOOL show_start = TRUE;
 -	
 -	if ( ! force_visible )
 -		show_start = gSavedSettings.getBOOL("ShowStartLocation");
 -	
 -	sInstance->getChildView("start_location_combo")->setVisible( show_start);
 -	sInstance->getChildView("start_location_text")->setVisible( show_start);
 -	
 -	BOOL show_server = gSavedSettings.getBOOL("ForceShowGrid");
 -	sInstance->getChildView("server_combo_text")->setVisible( show_server);	
 -	sInstance->getChildView("server_combo")->setVisible( show_server);
 -}
 -
 -// static
 -void LLPanelLogin::updateStartSLURL()
 -{
 -	if (!sInstance) return;
 -	
 -	LLComboBox* combo = sInstance->getChild<LLComboBox>("start_location_combo");
 -	S32 index = combo->getCurrentIndex();
 -	
 -	switch (index)
 -	{
 -		case 0:
 -		{
 -			LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_LAST));
 -			break;
 -		}			
 -		case 1:
 -		{
 -			LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_HOME));
 -			break;
 -		}
 -		default:
 -		{
 -			LLSLURL slurl = LLSLURL(combo->getValue().asString());
 -			if(slurl.getType() == LLSLURL::LOCATION)
 -			{
 -				// we've changed the grid, so update the grid selection
 -				LLStartUp::setStartSLURL(slurl);
 -			}
 -			break;
 -		}			
 -	}
 -}
 -
 -
 -void LLPanelLogin::setLocation(const LLSLURL& slurl)
 -{
 -	LLStartUp::setStartSLURL(slurl);
 -	updateServer();
 -}
 -
 -// static
 -void LLPanelLogin::closePanel()
 -{
 -	if (sInstance)
 -	{
 -		LLPanelLogin::sInstance->getParent()->removeChild( LLPanelLogin::sInstance );
 -
 -		delete sInstance;
 -		sInstance = NULL;
 -	}
 -}
 -
 -// static
 -void LLPanelLogin::setAlwaysRefresh(bool refresh)
 -{
 -	if (LLStartUp::getStartupState() >= STATE_LOGIN_CLEANUP) return;
 -
 -	LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html");
 -
 -	if (web_browser)
 -	{
 -		web_browser->setAlwaysRefresh(refresh);
 -	}
 -}
 -
 -
 -
 -void LLPanelLogin::loadLoginPage()
 -{
 -	if (!sInstance) return;
 -	
 -	std::ostringstream oStr;
 -
 -	std::string login_page = LLGridManager::getInstance()->getLoginPage();
 -
 -	oStr << login_page;
 -	
 -	// Use the right delimeter depending on how LLURI parses the URL
 -	LLURI login_page_uri = LLURI(login_page);
 -	
 -	std::string first_query_delimiter = "&";
 -	if (login_page_uri.queryMap().size() == 0)
 -	{
 -		first_query_delimiter = "?";
 -	}
 -
 -	// Language
 -	std::string language = LLUI::getLanguage();
 -	oStr << first_query_delimiter<<"lang=" << language;
 -	
 -	// First Login?
 -	if (gSavedSettings.getBOOL("FirstLoginThisInstall"))
 -	{
 -		oStr << "&firstlogin=TRUE";
 -	}
 -
 -	// Channel and Version
 -	std::string version = llformat("%s (%d)",
 -								   LLVersionInfo::getShortVersion().c_str(),
 -								   LLVersionInfo::getBuild());
 -
 -	char* curl_channel = curl_escape(LLVersionInfo::getChannel().c_str(), 0);
 -	char* curl_version = curl_escape(version.c_str(), 0);
 -
 -	oStr << "&channel=" << curl_channel;
 -	oStr << "&version=" << curl_version;
 -
 -	curl_free(curl_channel);
 -	curl_free(curl_version);
 -
 -	// Grid
 -	char* curl_grid = curl_escape(LLGridManager::getInstance()->getGridLabel().c_str(), 0);
 -	oStr << "&grid=" << curl_grid;
 -	curl_free(curl_grid);
 -	
 -	// add OS info
 -	char * os_info = curl_escape(LLAppViewer::instance()->getOSInfo().getOSStringSimple().c_str(), 0);
 -	oStr << "&os=" << os_info;
 -	curl_free(os_info);
 -	
 -	
 -	gViewerWindow->setMenuBackgroundColor(false, !LLGridManager::getInstance()->isInProductionGrid());
 -	gLoginMenuBarView->setBackgroundColor(gMenuBarView->getBackgroundColor());
 -	
 -	LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html");
 -
 -	// navigate to the "real" page
 -	if (gSavedSettings.getBOOL("RegInClient"))
 -	{
 -		web_browser->setFocus(TRUE);
 -		login_page = sInstance->getString("reg_in_client_url");
 -		web_browser->navigateTo(login_page, "text/html");
 -	}
 -	else
 -	{
 -		web_browser->navigateTo( oStr.str(), "text/html" );
 -	}
 -}
 -
 -void LLPanelLogin::handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent event)
 -{
 -	if(event == MEDIA_EVENT_NAVIGATE_COMPLETE)
 -	{
 -		LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html");
 -		if (web_browser)
 -		{
 -			// *HACK HACK HACK HACK!
 -			/* Stuff a Tab key into the browser now so that the first field will
 -			** get the focus!  The embedded javascript on the page that properly
 -			** sets the initial focus in a real web browser is not working inside
 -			** the viewer, so this is an UGLY HACK WORKAROUND for now.
 -			*/
 -			// Commented out as it's not reliable
 -			//web_browser->handleKey(KEY_TAB, MASK_NONE, false);
 -		}
 -	}
 -}
 -
 -//---------------------------------------------------------------------------
 -// Protected methods
 -//---------------------------------------------------------------------------
 -
 -// static
 -void LLPanelLogin::onClickConnect(void *)
 -{
 -	if (sInstance && sInstance->mCallback)
 -	{
 -		// tell the responder we're not here anymore
 -		if ( gResponsePtr )
 -			gResponsePtr->setParent( 0 );
 -
 -		// JC - Make sure the fields all get committed.
 -		sInstance->setFocus(FALSE);
 -
 -		LLComboBox* combo = sInstance->getChild<LLComboBox>("server_combo");
 -		LLSD combo_val = combo->getSelectedValue();
 -		if (combo_val.isUndefined())
 -		{
 -			combo_val = combo->getValue();
 -		}
 -		if(combo_val.isUndefined())
 -		{
 -			LLNotificationsUtil::add("StartRegionEmpty");
 -			return;
 -		}		
 -		try
 -		{
 -			LLGridManager::getInstance()->setGridChoice(combo_val.asString());
 -		}
 -		catch (LLInvalidGridName ex)
 -		{
 -			LLSD args;
 -			args["GRID"] = combo_val.asString();
 -			LLNotificationsUtil::add("InvalidGrid", args);
 -			return;
 -		}
 -		updateStartSLURL();
 -		std::string username = sInstance->getChild<LLUICtrl>("username_combo")->getValue().asString();
 -
 -		
 -		if(username.empty())
 -		{
 -			// user must type in something into the username field
 -			LLNotificationsUtil::add("MustHaveAccountToLogIn");
 -		}
 -		else
 -		{
 -			LLPointer<LLCredential> cred;
 -			BOOL remember;
 -			getFields(cred, remember);
 -			std::string identifier_type;
 -			cred->identifierType(identifier_type);
 -			LLSD allowed_credential_types;
 -			LLGridManager::getInstance()->getLoginIdentifierTypes(allowed_credential_types);
 -			
 -			// check the typed in credential type against the credential types expected by the server.
 -			for(LLSD::array_iterator i = allowed_credential_types.beginArray();
 -				i != allowed_credential_types.endArray();
 -				i++)
 -			{
 -				
 -				if(i->asString() == identifier_type)
 -				{
 -					// yay correct credential type
 -					sInstance->mCallback(0, sInstance->mCallbackData);
 -					return;
 -				}
 -			}
 -			
 -			// Right now, maingrid is the only thing that is picky about
 -			// credential format, as it doesn't yet allow account (single username)
 -			// format creds.  - Rox.  James, we wanna fix the message when we change
 -			// this.
 -			LLNotificationsUtil::add("InvalidCredentialFormat");			
 -		}
 -	}
 -}
 -
 -/*
 -// static
 -bool LLPanelLogin::newAccountAlertCallback(const LLSD& notification, const LLSD& response)
 -{
 -	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
 -	if (0 == option)
 -	{
 -		llinfos << "Going to account creation URL" << llendl;
 -		LLWeb::loadURLExternal( LLNotifications::instance().getGlobalString("CREATE_ACCOUNT_URL")); 
 -	}
 -	else
 -	{
 -		sInstance->setFocus(TRUE);
 -	}
 -	return false;
 -}
 -*/
 -
 -// static
 -void LLPanelLogin::onClickNewAccount(void*)
 -{
 -	LLWeb::loadURLExternal(sInstance->getString("create_account_url"));
 -}
 -
 -
 -// static
 -void LLPanelLogin::onClickVersion(void*)
 -{
 -	LLFloaterReg::showInstance("sl_about"); 
 -}
 -
 -//static
 -void LLPanelLogin::onClickForgotPassword(void*)
 -{
 -	if (sInstance )
 -	{
 -		LLWeb::loadURLExternal(sInstance->getString( "forgot_password_url" ));
 -	}
 -}
 -
 -//static
 -void LLPanelLogin::onClickHelp(void*)
 -{
 -	if (sInstance)
 -	{
 -		LLViewerHelp* vhelp = LLViewerHelp::getInstance();
 -		vhelp->showTopic(vhelp->preLoginTopic());
 -	}
 -}
 -
 -// static
 -void LLPanelLogin::onPassKey(LLLineEditor* caller, void* user_data)
 -{
 -	LLPanelLogin *This = (LLPanelLogin *) user_data;
 -	This->mPasswordModified = TRUE;
 -	if (gKeyboard->getKeyDown(KEY_CAPSLOCK) && sCapslockDidNotification == FALSE)
 -	{
 -// *TODO: use another way to notify user about enabled caps lock, see EXT-6858
 -		sCapslockDidNotification = TRUE;
 -	}
 -}
 -
 -
 -void LLPanelLogin::updateServer()
 -{
 -	try 
 -	{
 -
 -		updateServerCombo();	
 -		// if they've selected another grid, we should load the credentials
 -		// for that grid and set them to the UI.
 -		if(sInstance && !sInstance->areCredentialFieldsDirty())
 -		{
 -			LLPointer<LLCredential> credential = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());	
 -			bool remember = sInstance->getChild<LLUICtrl>("remember_check")->getValue();
 -			sInstance->setFields(credential, remember);
 -		}
 -		// grid changed so show new splash screen (possibly)
 -		loadLoginPage();
 -		updateLocationCombo(LLStartUp::getStartSLURL().getType() == LLSLURL::LOCATION);
 -	}
 -	catch (LLInvalidGridName ex)
 -	{
 -		// do nothing
 -	}
 -}
 -
 -void LLPanelLogin::updateServerCombo()
 -{
 -	if (!sInstance) 
 -	{
 -		return;	
 -	}
 -	// We add all of the possible values, sorted, and then add a bar and the current value at the top
 -	LLComboBox* server_choice_combo = sInstance->getChild<LLComboBox>("server_combo");	
 -	server_choice_combo->removeall();
 -
 -	std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids(!gSavedSettings.getBOOL("ShowBetaGrids"));
 -
 -	for (std::map<std::string, std::string>::iterator grid_choice = known_grids.begin();
 -		 grid_choice != known_grids.end();
 -		 grid_choice++)
 -	{
 -		if (!grid_choice->first.empty())
 -		{
 -			server_choice_combo->add(grid_choice->second, grid_choice->first);
 -		}
 -	}
 -	server_choice_combo->sortByName();
 -	
 -	server_choice_combo->addSeparator(ADD_TOP);
 -	
 -	server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(), 
 -		LLGridManager::getInstance()->getGrid(), ADD_TOP);	
 -	
 -	server_choice_combo->selectFirstItem();	
 -}
 -
 -// static
 -void LLPanelLogin::onSelectServer(LLUICtrl*, void*)
 -{
 -	// *NOTE: The paramters for this method are ignored. 
 -	// LLPanelLogin::onServerComboLostFocus(LLFocusableElement* fe, void*)
 -	// calls this method.
 -	LL_INFOS("AppInit") << "onSelectServer" << LL_ENDL;
 -	// The user twiddled with the grid choice ui.
 -	// apply the selection to the grid setting.
 -	LLPointer<LLCredential> credential;
 -	
 -	LLComboBox* combo = sInstance->getChild<LLComboBox>("server_combo");
 -	LLSD combo_val = combo->getSelectedValue();
 -	if (combo_val.isUndefined())
 -	{
 -		combo_val = combo->getValue();
 -	}
 -	
 -	combo = sInstance->getChild<LLComboBox>("start_location_combo");	
 -	combo->setCurrentByIndex(1);
 -	LLStartUp::setStartSLURL(LLSLURL(gSavedSettings.getString("LoginLocation")));
 -	LLGridManager::getInstance()->setGridChoice(combo_val.asString());
 -	// This new selection will override preset uris
 -	// from the command line.
 -	updateServer();
 -	updateLocationCombo(false);
 -	updateLoginPanelLinks();
 -}
 -
 -void LLPanelLogin::onServerComboLostFocus(LLFocusableElement* fe)
 -{
 -	if (!sInstance)
 -	{
 -		return;
 -	}
 -
 -	LLComboBox* combo = sInstance->getChild<LLComboBox>("server_combo");
 -	if(fe == combo)
 -	{
 -		onSelectServer(combo, NULL);	
 -	}
 -}
 -
 -void LLPanelLogin::updateLoginPanelLinks()
 -{
 -	LLSD grid_data;
 -	LLGridManager::getInstance()->getGridInfo(grid_data);
 -	bool system_grid = grid_data.has(GRID_IS_SYSTEM_GRID_VALUE);
 -	
 -	// need to call through sInstance, as it's called from onSelectServer, which
 -	// is static.
 -	sInstance->getChildView("create_new_account_text")->setVisible( system_grid);
 -	sInstance->getChildView("forgot_password_text")->setVisible( system_grid);
 -}
 -
 -//static
 -void LLPanelLogin::onModeChange()
 -{
 -	LLNotificationsUtil::add("ModeChange", LLSD(), LLSD(), boost::bind(&onModeChangeConfirm, _1, _2));
 -}
 -
 -//static
 -void LLPanelLogin::onModeChangeConfirm(const LLSD& notification, const LLSD& response)
 -{
 -	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
 -	switch (option)
 -	{
 -	case 0:
 -		LLAppViewer::instance()->requestQuit();
 -		break;
 -	case 1:
 -		// do nothing
 -		break;
 -	default:
 -		break;
 -	}
 -}
 +/**  + * @file llpanellogin.cpp + * @brief Login dialog and logo display + * + * $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 "llpanellogin.h" + +#include "indra_constants.h"		// for key and mask constants +#include "llfloaterreg.h" +#include "llfontgl.h" +#include "llmd5.h" +#include "llsecondlifeurls.h" +#include "v4color.h" + +#include "llappviewer.h" +#include "llbutton.h" +#include "llcheckboxctrl.h" +#include "llcommandhandler.h"		// for secondlife:///app/login/ +#include "llcombobox.h" +#include "llcurl.h" +#include "llviewercontrol.h" +#include "llfloaterpreference.h" +#include "llfocusmgr.h" +#include "lllineeditor.h" +#include "llnotificationsutil.h" +#include "llsecapi.h" +#include "llstartup.h" +#include "lltextbox.h" +#include "llui.h" +#include "lluiconstants.h" +#include "llslurl.h" +#include "llversioninfo.h" +#include "llviewerhelp.h" +#include "llviewertexturelist.h" +#include "llviewermenu.h"			// for handle_preferences() +#include "llviewernetwork.h" +#include "llviewerwindow.h"			// to link into child list +#include "lluictrlfactory.h" +#include "llhttpclient.h" +#include "llweb.h" +#include "llmediactrl.h" +#include "llrootview.h" + +#include "llfloatertos.h" +#include "lltrans.h" +#include "llglheaders.h" +#include "llpanelloginlistener.h" + +#if LL_WINDOWS +#pragma warning(disable: 4355)      // 'this' used in initializer list +#endif  // LL_WINDOWS + +#include "llsdserialize.h" + +const S32 BLACK_BORDER_HEIGHT = 160; +const S32 MAX_PASSWORD = 16; + +LLPanelLogin *LLPanelLogin::sInstance = NULL; +BOOL LLPanelLogin::sCapslockDidNotification = FALSE; + + +class LLLoginRefreshHandler : public LLCommandHandler +{ +public: +	// don't allow from external browsers +	LLLoginRefreshHandler() : LLCommandHandler("login_refresh", UNTRUSTED_BLOCK) { } +	bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web) +	{	 +		if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP) +		{ +			LLPanelLogin::loadLoginPage(); +		}	 +		return true; +	} +}; + +LLLoginRefreshHandler gLoginRefreshHandler; + + +// helper class that trys to download a URL from a web site and calls a method  +// on parent class indicating if the web server is working or not +class LLIamHereLogin : public LLHTTPClient::Responder +{ +	private: +		LLIamHereLogin( LLPanelLogin* parent ) : +		   mParent( parent ) +		{} + +		LLPanelLogin* mParent; + +	public: +		static boost::intrusive_ptr< LLIamHereLogin > build( LLPanelLogin* parent ) +		{ +			return boost::intrusive_ptr< LLIamHereLogin >( new LLIamHereLogin( parent ) ); +		}; + +		virtual void  setParent( LLPanelLogin* parentIn ) +		{ +			mParent = parentIn; +		}; + +		// We don't actually expect LLSD back, so need to override completedRaw +		virtual void completedRaw(U32 status, const std::string& reason, +								  const LLChannelDescriptors& channels, +								  const LLIOPipe::buffer_ptr_t& buffer) +		{ +			completed(status, reason, LLSD()); // will call result() or error() +		} +	 +		virtual void result( const LLSD& content ) +		{ +			if ( mParent ) +				mParent->setSiteIsAlive( true ); +		}; + +		virtual void error( U32 status, const std::string& reason ) +		{ +			if ( mParent ) +				mParent->setSiteIsAlive( false ); +		}; +}; + +// this is global and not a class member to keep crud out of the header file +namespace { +	boost::intrusive_ptr< LLIamHereLogin > gResponsePtr = 0; +}; + + +//--------------------------------------------------------------------------- +// Public methods +//--------------------------------------------------------------------------- +LLPanelLogin::LLPanelLogin(const LLRect &rect, +						 BOOL show_server, +						 void (*callback)(S32 option, void* user_data), +						 void *cb_data) +:	LLPanel(), +	mLogoImage(), +	mCallback(callback), +	mCallbackData(cb_data), +	mHtmlAvailable( TRUE ), +	mListener(new LLPanelLoginListener(this)) +{ +	setBackgroundVisible(FALSE); +	setBackgroundOpaque(TRUE); + +	// instance management +	if (LLPanelLogin::sInstance) +	{ +		llwarns << "Duplicate instance of login view deleted" << llendl; +		// Don't leave bad pointer in gFocusMgr +		gFocusMgr.setDefaultKeyboardFocus(NULL); + +		delete LLPanelLogin::sInstance; +	} + +	mPasswordModified = FALSE; +	LLPanelLogin::sInstance = this; + +	LLView* login_holder = gViewerWindow->getLoginPanelHolder(); +	if (login_holder) +	{ +		login_holder->addChild(this); +	} + +	// Logo +	mLogoImage = LLUI::getUIImage("startup_logo"); + +	buildFromFile( "panel_login.xml"); +	 +	// Legacy login web page is hidden under the menu bar. +	// Adjust reg-in-client web browser widget to not be hidden. +	if (gSavedSettings.getBOOL("RegInClient")) +	{ +		reshape(rect.getWidth(), rect.getHeight() - MENU_BAR_HEIGHT); +	} +	else +	{ +		reshape(rect.getWidth(), rect.getHeight()); +	} + +	getChild<LLLineEditor>("password_edit")->setKeystrokeCallback(onPassKey, this); + +	// change z sort of clickable text to be behind buttons +	//sendChildToBack(getChildView("channel_text")); +	sendChildToBack(getChildView("forgot_password_text")); + +	if(LLStartUp::getStartSLURL().getType() != LLSLURL::LOCATION) +	{ +		LLSLURL slurl(gSavedSettings.getString("LoginLocation")); +		LLStartUp::setStartSLURL(slurl); +	} +	updateLocationCombo(false); + +	gSavedSettings.getControl("SessionSettingsFile")->getSignal()->connect(boost::bind(&onModeChange)); + +	LLComboBox* server_choice_combo = sInstance->getChild<LLComboBox>("server_combo"); +	server_choice_combo->setCommitCallback(onSelectServer, NULL); +	server_choice_combo->setFocusLostCallback(boost::bind(onServerComboLostFocus, _1)); +	updateServerCombo(); + +	childSetAction("connect_btn", onClickConnect, this); + +	getChild<LLPanel>("login")->setDefaultBtn("connect_btn"); + +	std::string channel = LLVersionInfo::getChannel(); +	std::string version = llformat("%s (%d)", +								   LLVersionInfo::getShortVersion().c_str(), +								   LLVersionInfo::getBuild()); +	//LLTextBox* channel_text = getChild<LLTextBox>("channel_text"); +	//channel_text->setTextArg("[CHANNEL]", channel); // though not displayed +	//channel_text->setTextArg("[VERSION]", version); +	//channel_text->setClickedCallback(onClickVersion, this); +	 +	LLTextBox* forgot_password_text = getChild<LLTextBox>("forgot_password_text"); +	forgot_password_text->setClickedCallback(onClickForgotPassword, NULL); + +	LLTextBox* create_new_account_text = getChild<LLTextBox>("create_new_account_text"); +	create_new_account_text->setClickedCallback(onClickNewAccount, NULL); + +	LLTextBox* need_help_text = getChild<LLTextBox>("login_help"); +	need_help_text->setClickedCallback(onClickHelp, NULL); +	 +	// get the web browser control +	LLMediaCtrl* web_browser = getChild<LLMediaCtrl>("login_html"); +	web_browser->addObserver(this); +	 +	// Clear the browser's cache to avoid any potential for the cache messing up the login screen. +	web_browser->clearCache(); + +	reshapeBrowser(); + +	// kick off a request to grab the url manually +	gResponsePtr = LLIamHereLogin::build( this ); + +	LLHTTPClient::head( LLGridManager::getInstance()->getLoginPage(), gResponsePtr ); + +	// Show last logged in user favorites in "Start at" combo. +	addUsersWithFavoritesToUsername(); +	getChild<LLComboBox>("username_combo")->setTextChangedCallback(boost::bind(&LLPanelLogin::addFavoritesToStartLocation, this)); + +	updateLocationCombo(false); + +} + +void LLPanelLogin::addUsersWithFavoritesToUsername() +{ +	LLComboBox* combo = getChild<LLComboBox>("username_combo"); +	if (!combo) return; +	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml"); +	LLSD fav_llsd; +	llifstream file; +	file.open(filename); +	if (!file.is_open()) return; +	LLSDSerialize::fromXML(fav_llsd, file); +	for (LLSD::map_const_iterator iter = fav_llsd.beginMap(); +		iter != fav_llsd.endMap(); ++iter) +	{ +		combo->add(iter->first); +	} +} + +void LLPanelLogin::addFavoritesToStartLocation() +{ +	LLComboBox* combo = getChild<LLComboBox>("start_location_combo"); +	if (!combo) return; +	int num_items = combo->getItemCount(); +	for (int i = num_items - 1; i > 2; i--) +	{ +		combo->remove(i); +	} +	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml"); +	LLSD fav_llsd; +	llifstream file; +	file.open(filename); +	if (!file.is_open()) return; +	LLSDSerialize::fromXML(fav_llsd, file); +	for (LLSD::map_const_iterator iter = fav_llsd.beginMap(); +		iter != fav_llsd.endMap(); ++iter) +	{ +		if(iter->first != getChild<LLComboBox>("username_combo")->getSimple()) continue; +		combo->addSeparator(); +		LLSD user_llsd = iter->second; +		for (LLSD::array_const_iterator iter1 = user_llsd.beginArray(); +			iter1 != user_llsd.endArray(); ++iter1) +		{ +			std::string label = (*iter1)["name"].asString(); +			std::string value = (*iter1)["slurl"].asString(); +			if(label != "" && value != "") +			{ +				combo->add(label, value); +			} +		} +		break; +	} +} + +// force the size to be correct (XML doesn't seem to be sufficient to do this) +// (with some padding so the other login screen doesn't show through) +void LLPanelLogin::reshapeBrowser() +{ +	LLMediaCtrl* web_browser = getChild<LLMediaCtrl>("login_html"); +	LLRect rect = gViewerWindow->getWindowRectScaled(); +	LLRect html_rect; +	html_rect.setCenterAndSize( +		rect.getCenterX() - 2, rect.getCenterY() + 40, +		rect.getWidth() + 6, rect.getHeight() - 78 ); +	web_browser->setRect( html_rect ); +	web_browser->reshape( html_rect.getWidth(), html_rect.getHeight(), TRUE ); +	reshape( rect.getWidth(), rect.getHeight(), 1 ); +} + +void LLPanelLogin::setSiteIsAlive( bool alive ) +{ +	LLMediaCtrl* web_browser = getChild<LLMediaCtrl>("login_html"); +	// if the contents of the site was retrieved +	if ( alive ) +	{ +		if ( web_browser ) +		{ +			loadLoginPage(); +			 +			// mark as available +			mHtmlAvailable = TRUE; +		} +	} +	else +	// the site is not available (missing page, server down, other badness) +	{ +		if ( web_browser ) +		{ +			// hide browser control (revealing default one) +			web_browser->setVisible( FALSE ); + +			// mark as unavailable +			mHtmlAvailable = FALSE; +		} +	} +} + + +LLPanelLogin::~LLPanelLogin() +{ +	LLPanelLogin::sInstance = NULL; + +	// tell the responder we're not here anymore +	if ( gResponsePtr ) +		gResponsePtr->setParent( 0 ); + +	//// We know we're done with the image, so be rid of it. +	//gTextureList.deleteImage( mLogoImage ); + +	// Controls having keyboard focus by default +	// must reset it on destroy. (EXT-2748) +	gFocusMgr.setDefaultKeyboardFocus(NULL); +} + +// virtual +void LLPanelLogin::draw() +{ +	glPushMatrix(); +	{ +		F32 image_aspect = 1.333333f; +		F32 view_aspect = (F32)getRect().getWidth() / (F32)getRect().getHeight(); +		// stretch image to maintain aspect ratio +		if (image_aspect > view_aspect) +		{ +			glTranslatef(-0.5f * (image_aspect / view_aspect - 1.f) * getRect().getWidth(), 0.f, 0.f); +			glScalef(image_aspect / view_aspect, 1.f, 1.f); +		} + +		S32 width = getRect().getWidth(); +		S32 height = getRect().getHeight(); + +		if ( mHtmlAvailable ) +		{ +			if (getChild<LLView>("login_widgets")->getVisible()) +			{ +				// draw a background box in black +				gl_rect_2d( 0, height - 264, width, 264, LLColor4::black ); +				// draw the bottom part of the background image +				// just the blue background to the native client UI +				mLogoImage->draw(0, -264, width + 8, mLogoImage->getHeight()); +			} +		} +		else +		{ +			// the HTML login page is not available so default to the original screen +			S32 offscreen_part = height / 3; +			mLogoImage->draw(0, -offscreen_part, width, height+offscreen_part); +		}; +	} +	glPopMatrix(); + +	LLPanel::draw(); +} + +// virtual +BOOL LLPanelLogin::handleKeyHere(KEY key, MASK mask) +{ +	if ( KEY_F1 == key ) +	{ +		LLViewerHelp* vhelp = LLViewerHelp::getInstance(); +		vhelp->showTopic(vhelp->f1HelpTopic()); +		return TRUE; +	} + +	return LLPanel::handleKeyHere(key, mask); +} + +// virtual  +void LLPanelLogin::setFocus(BOOL b) +{ +	if(b != hasFocus()) +	{ +		if(b) +		{ +			LLPanelLogin::giveFocus(); +		} +		else +		{ +			LLPanel::setFocus(b); +		} +	} +} + +// static +void LLPanelLogin::giveFocus() +{ +	if( sInstance ) +	{ +		// Grab focus and move cursor to first blank input field +		std::string username = sInstance->getChild<LLUICtrl>("username_combo")->getValue().asString(); +		std::string pass = sInstance->getChild<LLUICtrl>("password_edit")->getValue().asString(); + +		BOOL have_username = !username.empty(); +		BOOL have_pass = !pass.empty(); + +		LLLineEditor* edit = NULL; +		LLComboBox* combo = NULL; +		if (have_username && !have_pass) +		{ +			// User saved his name but not his password.  Move +			// focus to password field. +			edit = sInstance->getChild<LLLineEditor>("password_edit"); +		} +		else +		{ +			// User doesn't have a name, so start there. +			combo = sInstance->getChild<LLComboBox>("username_combo"); +		} + +		if (edit) +		{ +			edit->setFocus(TRUE); +			edit->selectAll(); +		} +		else if (combo) +		{ +			combo->setFocus(TRUE); +		} +	} +} + +// static +void LLPanelLogin::showLoginWidgets() +{ +	// *NOTE: Mani - This may or may not be obselete code. +	// It seems to be part of the defunct? reg-in-client project. +	sInstance->getChildView("login_widgets")->setVisible( true); +	LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html"); +	sInstance->reshapeBrowser(); +	// *TODO: Append all the usual login parameters, like first_login=Y etc. +	std::string splash_screen_url = LLGridManager::getInstance()->getLoginPage(); +	web_browser->navigateTo( splash_screen_url, "text/html" ); +	LLUICtrl* username_combo = sInstance->getChild<LLUICtrl>("username_combo"); +	username_combo->setFocus(TRUE); +} + +// static +void LLPanelLogin::show(const LLRect &rect, +						BOOL show_server, +						void (*callback)(S32 option, void* user_data), +						void* callback_data) +{ +	new LLPanelLogin(rect, show_server, callback, callback_data); + +	if( !gFocusMgr.getKeyboardFocus() ) +	{ +		// Grab focus and move cursor to first enabled control +		sInstance->setFocus(TRUE); +	} + +	// Make sure that focus always goes here (and use the latest sInstance that was just created) +	gFocusMgr.setDefaultKeyboardFocus(sInstance); +} + +// static +void LLPanelLogin::setFields(LLPointer<LLCredential> credential, +							 BOOL remember) +{ +	if (!sInstance) +	{ +		llwarns << "Attempted fillFields with no login view shown" << llendl; +		return; +	} +	LL_INFOS("Credentials") << "Setting login fields to " << *credential << LL_ENDL; + +	LLSD identifier = credential->getIdentifier(); +	if((std::string)identifier["type"] == "agent")  +	{ +		std::string firstname = identifier["first_name"].asString(); +		std::string lastname = identifier["last_name"].asString(); +	    std::string login_id = firstname; +	    if (!lastname.empty() && lastname != "Resident") +	    { +		    // support traditional First Last name SLURLs +		    login_id += " "; +		    login_id += lastname; +	    } +		sInstance->getChild<LLComboBox>("username_combo")->setLabel(login_id);	 +	} +	else if((std::string)identifier["type"] == "account") +	{ +		sInstance->getChild<LLComboBox>("username_combo")->setLabel((std::string)identifier["account_name"]);		 +	} +	else +	{ +	  sInstance->getChild<LLComboBox>("username_combo")->setLabel(std::string());	 +	} +	sInstance->addFavoritesToStartLocation(); +	// if the password exists in the credential, set the password field with +	// a filler to get some stars +	LLSD authenticator = credential->getAuthenticator(); +	LL_INFOS("Credentials") << "Setting authenticator field " << authenticator["type"].asString() << LL_ENDL; +	if(authenticator.isMap() &&  +	   authenticator.has("secret") &&  +	   (authenticator["secret"].asString().size() > 0)) +	{ +		 +		// This is a MD5 hex digest of a password. +		// We don't actually use the password input field,  +		// fill it with MAX_PASSWORD characters so we get a  +		// nice row of asterixes. +		const std::string filler("123456789!123456"); +		sInstance->getChild<LLUICtrl>("password_edit")->setValue(std::string("123456789!123456")); +	} +	else +	{ +		sInstance->getChild<LLUICtrl>("password_edit")->setValue(std::string());		 +	} +	sInstance->getChild<LLUICtrl>("remember_check")->setValue(remember); +} + + +// static +void LLPanelLogin::getFields(LLPointer<LLCredential>& credential, +							 BOOL& remember) +{ +	if (!sInstance) +	{ +		llwarns << "Attempted getFields with no login view shown" << llendl; +		return; +	} +	 +	// load the credential so we can pass back the stored password or hash if the user did +	// not modify the password field. +	 +	credential = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid()); + +	LLSD identifier = LLSD::emptyMap(); +	LLSD authenticator = LLSD::emptyMap(); +	 +	if(credential.notNull()) +	{ +		authenticator = credential->getAuthenticator(); +	} + +	std::string username = sInstance->getChild<LLUICtrl>("username_combo")->getValue().asString(); +	LLStringUtil::trim(username); +	std::string password = sInstance->getChild<LLUICtrl>("password_edit")->getValue().asString(); + +	LL_INFOS2("Credentials", "Authentication") << "retrieving username:" << username << LL_ENDL; +	// determine if the username is a first/last form or not. +	size_t separator_index = username.find_first_of(' '); +	if (separator_index == username.npos +		&& !LLGridManager::getInstance()->isSystemGrid()) +	{ +		LL_INFOS2("Credentials", "Authentication") << "account: " << username << LL_ENDL; +		// single username, so this is a 'clear' identifier +		identifier["type"] = CRED_IDENTIFIER_TYPE_ACCOUNT; +		identifier["account_name"] = username; +		 +		if (LLPanelLogin::sInstance->mPasswordModified) +		{ +			authenticator = LLSD::emptyMap(); +			// password is plaintext +			authenticator["type"] = CRED_AUTHENTICATOR_TYPE_CLEAR; +			authenticator["secret"] = password; +		} +	} +	else +	{ +		// Be lenient in terms of what separators we allow for two-word names +		// and allow legacy users to login with firstname.lastname +		separator_index = username.find_first_of(" ._"); +		std::string first = username.substr(0, separator_index); +		std::string last; +		if (separator_index != username.npos) +		{ +			last = username.substr(separator_index+1, username.npos); +		LLStringUtil::trim(last); +		} +		else +		{ +			// ...on Linden grids, single username users as considered to have +			// last name "Resident" +			// *TODO: Make login.cgi support "account_name" like above +			last = "Resident"; +		} +		 +		if (last.find_first_of(' ') == last.npos) +		{ +			LL_INFOS2("Credentials", "Authentication") << "agent: " << username << LL_ENDL; +			// traditional firstname / lastname +			identifier["type"] = CRED_IDENTIFIER_TYPE_AGENT; +			identifier["first_name"] = first; +			identifier["last_name"] = last; +		 +			if (LLPanelLogin::sInstance->mPasswordModified) +			{ +				authenticator = LLSD::emptyMap(); +				authenticator["type"] = CRED_AUTHENTICATOR_TYPE_HASH; +				authenticator["algorithm"] = "md5"; +				LLMD5 pass((const U8 *)password.c_str()); +				char md5pass[33];               /* Flawfinder: ignore */ +				pass.hex_digest(md5pass); +				authenticator["secret"] = md5pass; +			} +		} +	} +	credential = gSecAPIHandler->createCredential(LLGridManager::getInstance()->getGrid(), identifier, authenticator); +	remember = sInstance->getChild<LLUICtrl>("remember_check")->getValue(); +} + +// static +BOOL LLPanelLogin::isGridComboDirty() +{ +	BOOL user_picked = FALSE; +	if (!sInstance) +	{ +		llwarns << "Attempted getServer with no login view shown" << llendl; +	} +	else +	{ +		LLComboBox* combo = sInstance->getChild<LLComboBox>("server_combo"); +		user_picked = combo->isDirty(); +	} +	return user_picked; +} + +// static +BOOL LLPanelLogin::areCredentialFieldsDirty() +{ +	if (!sInstance) +	{ +		llwarns << "Attempted getServer with no login view shown" << llendl; +	} +	else +	{ +		std::string username = sInstance->getChild<LLUICtrl>("username_combo")->getValue().asString(); +		LLStringUtil::trim(username); +		std::string password = sInstance->getChild<LLUICtrl>("password_edit")->getValue().asString(); +		LLComboBox* combo = sInstance->getChild<LLComboBox>("username_combo"); +		if(combo && combo->isDirty()) +		{ +			return true; +		} +		LLLineEditor* ctrl = sInstance->getChild<LLLineEditor>("password_edit"); +		if(ctrl && ctrl->isDirty())  +		{ +			return true; +		} +	} +	return false;	 +} + + +// static +void LLPanelLogin::updateLocationCombo( bool force_visible ) +{ +	if (!sInstance)  +	{ +		return; +	}	 +	 +	LLComboBox* combo = sInstance->getChild<LLComboBox>("start_location_combo"); +	 +	switch(LLStartUp::getStartSLURL().getType()) +	{ +		case LLSLURL::LOCATION: +		{ +			 +			combo->setCurrentByIndex( 2 );	 +			combo->setTextEntry(LLStartUp::getStartSLURL().getLocationString());	 +			break; +		} +		case LLSLURL::HOME_LOCATION: +			combo->setCurrentByIndex(1); +			break; +		default: +			combo->setCurrentByIndex(0); +			break; +	} +	 +	BOOL show_start = TRUE; +	 +	if ( ! force_visible ) +		show_start = gSavedSettings.getBOOL("ShowStartLocation"); +	 +	sInstance->getChildView("start_location_combo")->setVisible( show_start); +	sInstance->getChildView("start_location_text")->setVisible( show_start); +	 +	BOOL show_server = gSavedSettings.getBOOL("ForceShowGrid"); +	sInstance->getChildView("server_combo_text")->setVisible( show_server);	 +	sInstance->getChildView("server_combo")->setVisible( show_server); +} + +// static +void LLPanelLogin::updateStartSLURL() +{ +	if (!sInstance) return; +	 +	LLComboBox* combo = sInstance->getChild<LLComboBox>("start_location_combo"); +	S32 index = combo->getCurrentIndex(); +	 +	switch (index) +	{ +		case 0: +		{ +			LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_LAST)); +			break; +		}			 +		case 1: +		{ +			LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_HOME)); +			break; +		} +		default: +		{ +			LLSLURL slurl = LLSLURL(combo->getValue().asString()); +			if(slurl.getType() == LLSLURL::LOCATION) +			{ +				// we've changed the grid, so update the grid selection +				LLStartUp::setStartSLURL(slurl); +			} +			break; +		}			 +	} +} + + +void LLPanelLogin::setLocation(const LLSLURL& slurl) +{ +	LLStartUp::setStartSLURL(slurl); +	updateServer(); +} + +// static +void LLPanelLogin::closePanel() +{ +	if (sInstance) +	{ +		LLPanelLogin::sInstance->getParent()->removeChild( LLPanelLogin::sInstance ); + +		delete sInstance; +		sInstance = NULL; +	} +} + +// static +void LLPanelLogin::setAlwaysRefresh(bool refresh) +{ +	if (LLStartUp::getStartupState() >= STATE_LOGIN_CLEANUP) return; + +	LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html"); + +	if (web_browser) +	{ +		web_browser->setAlwaysRefresh(refresh); +	} +} + + + +void LLPanelLogin::loadLoginPage() +{ +	if (!sInstance) return; +	 +	std::ostringstream oStr; + +	std::string login_page = LLGridManager::getInstance()->getLoginPage(); + +	oStr << login_page; +	 +	// Use the right delimeter depending on how LLURI parses the URL +	LLURI login_page_uri = LLURI(login_page); +	 +	std::string first_query_delimiter = "&"; +	if (login_page_uri.queryMap().size() == 0) +	{ +		first_query_delimiter = "?"; +	} + +	// Language +	std::string language = LLUI::getLanguage(); +	oStr << first_query_delimiter<<"lang=" << language; +	 +	// First Login? +	if (gSavedSettings.getBOOL("FirstLoginThisInstall")) +	{ +		oStr << "&firstlogin=TRUE"; +	} + +	// Channel and Version +	std::string version = llformat("%s (%d)", +								   LLVersionInfo::getShortVersion().c_str(), +								   LLVersionInfo::getBuild()); + +	char* curl_channel = curl_escape(LLVersionInfo::getChannel().c_str(), 0); +	char* curl_version = curl_escape(version.c_str(), 0); + +	oStr << "&channel=" << curl_channel; +	oStr << "&version=" << curl_version; + +	curl_free(curl_channel); +	curl_free(curl_version); + +	// Grid +	char* curl_grid = curl_escape(LLGridManager::getInstance()->getGridLabel().c_str(), 0); +	oStr << "&grid=" << curl_grid; +	curl_free(curl_grid); +	 +	// add OS info +	char * os_info = curl_escape(LLAppViewer::instance()->getOSInfo().getOSStringSimple().c_str(), 0); +	oStr << "&os=" << os_info; +	curl_free(os_info); +	 +	 +	gViewerWindow->setMenuBackgroundColor(false, !LLGridManager::getInstance()->isInProductionGrid()); +	gLoginMenuBarView->setBackgroundColor(gMenuBarView->getBackgroundColor()); +	 +	LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html"); + +	// navigate to the "real" page +	if (gSavedSettings.getBOOL("RegInClient")) +	{ +		web_browser->setFocus(TRUE); +		login_page = sInstance->getString("reg_in_client_url"); +		web_browser->navigateTo(login_page, "text/html"); +	} +	else +	{ +		web_browser->navigateTo( oStr.str(), "text/html" ); +	} +} + +void LLPanelLogin::handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent event) +{ +	if(event == MEDIA_EVENT_NAVIGATE_COMPLETE) +	{ +		LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html"); +		if (web_browser) +		{ +			// *HACK HACK HACK HACK! +			/* Stuff a Tab key into the browser now so that the first field will +			** get the focus!  The embedded javascript on the page that properly +			** sets the initial focus in a real web browser is not working inside +			** the viewer, so this is an UGLY HACK WORKAROUND for now. +			*/ +			// Commented out as it's not reliable +			//web_browser->handleKey(KEY_TAB, MASK_NONE, false); +		} +	} +} + +//--------------------------------------------------------------------------- +// Protected methods +//--------------------------------------------------------------------------- + +// static +void LLPanelLogin::onClickConnect(void *) +{ +	if (sInstance && sInstance->mCallback) +	{ +		// tell the responder we're not here anymore +		if ( gResponsePtr ) +			gResponsePtr->setParent( 0 ); + +		// JC - Make sure the fields all get committed. +		sInstance->setFocus(FALSE); + +		LLComboBox* combo = sInstance->getChild<LLComboBox>("server_combo"); +		LLSD combo_val = combo->getSelectedValue(); +		if (combo_val.isUndefined()) +		{ +			combo_val = combo->getValue(); +		} +		if(combo_val.isUndefined()) +		{ +			LLNotificationsUtil::add("StartRegionEmpty"); +			return; +		}		 +		try +		{ +			LLGridManager::getInstance()->setGridChoice(combo_val.asString()); +		} +		catch (LLInvalidGridName ex) +		{ +			LLSD args; +			args["GRID"] = combo_val.asString(); +			LLNotificationsUtil::add("InvalidGrid", args); +			return; +		} +		updateStartSLURL(); +		std::string username = sInstance->getChild<LLUICtrl>("username_combo")->getValue().asString(); + +		 +		if(username.empty()) +		{ +			// user must type in something into the username field +			LLNotificationsUtil::add("MustHaveAccountToLogIn"); +		} +		else +		{ +			LLPointer<LLCredential> cred; +			BOOL remember; +			getFields(cred, remember); +			std::string identifier_type; +			cred->identifierType(identifier_type); +			LLSD allowed_credential_types; +			LLGridManager::getInstance()->getLoginIdentifierTypes(allowed_credential_types); +			 +			// check the typed in credential type against the credential types expected by the server. +			for(LLSD::array_iterator i = allowed_credential_types.beginArray(); +				i != allowed_credential_types.endArray(); +				i++) +			{ +				 +				if(i->asString() == identifier_type) +				{ +					// yay correct credential type +					sInstance->mCallback(0, sInstance->mCallbackData); +					return; +				} +			} +			 +			// Right now, maingrid is the only thing that is picky about +			// credential format, as it doesn't yet allow account (single username) +			// format creds.  - Rox.  James, we wanna fix the message when we change +			// this. +			LLNotificationsUtil::add("InvalidCredentialFormat");			 +		} +	} +} + +/* +// static +bool LLPanelLogin::newAccountAlertCallback(const LLSD& notification, const LLSD& response) +{ +	S32 option = LLNotificationsUtil::getSelectedOption(notification, response); +	if (0 == option) +	{ +		llinfos << "Going to account creation URL" << llendl; +		LLWeb::loadURLExternal( LLNotifications::instance().getGlobalString("CREATE_ACCOUNT_URL"));  +	} +	else +	{ +		sInstance->setFocus(TRUE); +	} +	return false; +} +*/ + +// static +void LLPanelLogin::onClickNewAccount(void*) +{ +	LLWeb::loadURLExternal(sInstance->getString("create_account_url")); +} + + +// static +void LLPanelLogin::onClickVersion(void*) +{ +	LLFloaterReg::showInstance("sl_about");  +} + +//static +void LLPanelLogin::onClickForgotPassword(void*) +{ +	if (sInstance ) +	{ +		LLWeb::loadURLExternal(sInstance->getString( "forgot_password_url" )); +	} +} + +//static +void LLPanelLogin::onClickHelp(void*) +{ +	if (sInstance) +	{ +		LLViewerHelp* vhelp = LLViewerHelp::getInstance(); +		vhelp->showTopic(vhelp->preLoginTopic()); +	} +} + +// static +void LLPanelLogin::onPassKey(LLLineEditor* caller, void* user_data) +{ +	LLPanelLogin *This = (LLPanelLogin *) user_data; +	This->mPasswordModified = TRUE; +	if (gKeyboard->getKeyDown(KEY_CAPSLOCK) && sCapslockDidNotification == FALSE) +	{ +// *TODO: use another way to notify user about enabled caps lock, see EXT-6858 +		sCapslockDidNotification = TRUE; +	} +} + + +void LLPanelLogin::updateServer() +{ +	try  +	{ + +		updateServerCombo();	 +		// if they've selected another grid, we should load the credentials +		// for that grid and set them to the UI. +		if(sInstance && !sInstance->areCredentialFieldsDirty()) +		{ +			LLPointer<LLCredential> credential = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());	 +			bool remember = sInstance->getChild<LLUICtrl>("remember_check")->getValue(); +			sInstance->setFields(credential, remember); +		} +		// grid changed so show new splash screen (possibly) +		loadLoginPage(); +		updateLocationCombo(LLStartUp::getStartSLURL().getType() == LLSLURL::LOCATION); +	} +	catch (LLInvalidGridName ex) +	{ +		// do nothing +	} +} + +void LLPanelLogin::updateServerCombo() +{ +	if (!sInstance)  +	{ +		return;	 +	} +	// We add all of the possible values, sorted, and then add a bar and the current value at the top +	LLComboBox* server_choice_combo = sInstance->getChild<LLComboBox>("server_combo");	 +	server_choice_combo->removeall(); + +	std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids(!gSavedSettings.getBOOL("ShowBetaGrids")); + +	for (std::map<std::string, std::string>::iterator grid_choice = known_grids.begin(); +		 grid_choice != known_grids.end(); +		 grid_choice++) +	{ +		if (!grid_choice->first.empty()) +		{ +			server_choice_combo->add(grid_choice->second, grid_choice->first); +		} +	} +	server_choice_combo->sortByName(); +	 +	server_choice_combo->addSeparator(ADD_TOP); +	 +	server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(),  +		LLGridManager::getInstance()->getGrid(), ADD_TOP);	 +	 +	server_choice_combo->selectFirstItem();	 +} + +// static +void LLPanelLogin::onSelectServer(LLUICtrl*, void*) +{ +	// *NOTE: The paramters for this method are ignored.  +	// LLPanelLogin::onServerComboLostFocus(LLFocusableElement* fe, void*) +	// calls this method. +	LL_INFOS("AppInit") << "onSelectServer" << LL_ENDL; +	// The user twiddled with the grid choice ui. +	// apply the selection to the grid setting. +	LLPointer<LLCredential> credential; +	 +	LLComboBox* combo = sInstance->getChild<LLComboBox>("server_combo"); +	LLSD combo_val = combo->getSelectedValue(); +	if (combo_val.isUndefined()) +	{ +		combo_val = combo->getValue(); +	} +	 +	combo = sInstance->getChild<LLComboBox>("start_location_combo");	 +	combo->setCurrentByIndex(1); +	LLStartUp::setStartSLURL(LLSLURL(gSavedSettings.getString("LoginLocation"))); +	LLGridManager::getInstance()->setGridChoice(combo_val.asString()); +	// This new selection will override preset uris +	// from the command line. +	updateServer(); +	updateLocationCombo(false); +	updateLoginPanelLinks(); +} + +void LLPanelLogin::onServerComboLostFocus(LLFocusableElement* fe) +{ +	if (!sInstance) +	{ +		return; +	} + +	LLComboBox* combo = sInstance->getChild<LLComboBox>("server_combo"); +	if(fe == combo) +	{ +		onSelectServer(combo, NULL);	 +	} +} + +void LLPanelLogin::updateLoginPanelLinks() +{ +	LLSD grid_data; +	LLGridManager::getInstance()->getGridInfo(grid_data); +	bool system_grid = grid_data.has(GRID_IS_SYSTEM_GRID_VALUE); +	 +	// need to call through sInstance, as it's called from onSelectServer, which +	// is static. +	sInstance->getChildView("create_new_account_text")->setVisible( system_grid); +	sInstance->getChildView("forgot_password_text")->setVisible( system_grid); +} + +//static +void LLPanelLogin::onModeChange() +{ +	LLNotificationsUtil::add("ModeChange", LLSD(), LLSD(), boost::bind(&onModeChangeConfirm, _1, _2)); +} + +//static +void LLPanelLogin::onModeChangeConfirm(const LLSD& notification, const LLSD& response) +{ +	S32 option = LLNotificationsUtil::getSelectedOption(notification, response); +	switch (option) +	{ +	case 0: +		LLAppViewer::instance()->requestQuit(); +		break; +	case 1: +		// do nothing +		break; +	default: +		break; +	} +} diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp index 8aaa7f0e13..a9bb01ac70 100644 --- a/indra/newview/llsidetray.cpp +++ b/indra/newview/llsidetray.cpp @@ -96,6 +96,7 @@ bool	LLSideTray::instanceCreated	()  class LLSideTrayTab: public LLPanel  { +	LOG_CLASS(LLSideTrayTab);  	friend class LLUICtrlFactory;  	friend class LLSideTray;  public: @@ -122,6 +123,8 @@ protected:  	void			undock(LLFloater* floater_tab);  	LLSideTray*		getSideTray(); + +	void			onFloaterClose(LLSD::Boolean app_quitting);  public:  	virtual ~LLSideTrayTab(); @@ -140,6 +143,8 @@ public:  	void			onOpen		(const LLSD& key);  	void			toggleTabDocked(); +	void			setDocked(bool dock); +	bool			isDocked() const;  	BOOL			handleScrollWheel(S32 x, S32 y, S32 clicks); @@ -151,6 +156,7 @@ private:  	std::string	mDescription;  	LLView*	mMainPanel; +	boost::signals2::connection mFloaterCloseConn;  };  LLSideTrayTab::LLSideTrayTab(const Params& p) @@ -271,6 +277,35 @@ void LLSideTrayTab::toggleTabDocked()  	LLFloaterReg::toggleInstance("side_bar_tab", tab_name);  } +// Same as toggleTabDocked() apart from making sure that we do exactly what we want. +void LLSideTrayTab::setDocked(bool dock) +{ +	if (isDocked() == dock) +	{ +		llwarns << "Tab " << getName() << " is already " << (dock ? "docked" : "undocked") << llendl; +		return; +	} + +	toggleTabDocked(); +} + +bool LLSideTrayTab::isDocked() const +{ +	return dynamic_cast<LLSideTray*>(getParent()) != NULL; +} + +void LLSideTrayTab::onFloaterClose(LLSD::Boolean app_quitting) +{ +	// If user presses Ctrl-Shift-W, handle that gracefully by docking all +	// undocked tabs before their floaters get destroyed (STORM-1016). + +	// Don't dock on quit for the current dock state to be correctly saved. +	if (app_quitting) return; + +	lldebugs << "Forcibly docking tab " << getName() << llendl; +	setDocked(true); +} +  BOOL LLSideTrayTab::handleScrollWheel(S32 x, S32 y, S32 clicks)  {  	// Let children handle the event @@ -294,6 +329,7 @@ void LLSideTrayTab::dock(LLFloater* floater_tab)  		return;  	} +	mFloaterCloseConn.disconnect();  	setRect(side_tray->getLocalRect());  	reshape(getRect().getWidth(), getRect().getHeight()); @@ -342,6 +378,7 @@ void LLSideTrayTab::undock(LLFloater* floater_tab)  	}  	floater_tab->addChild(this); +	mFloaterCloseConn = floater_tab->setCloseCallback(boost::bind(&LLSideTrayTab::onFloaterClose, this, _2));  	floater_tab->setTitle(mTabTitle);  	floater_tab->setName(getName()); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 86087ba0a1..87b33980d6 100755 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -749,8 +749,6 @@ bool idle_startup()  			}       			LLPanelLogin::giveFocus(); -			gSavedSettings.setBOOL("FirstRunThisInstall", FALSE); -  			LLStartUp::setStartupState( STATE_LOGIN_WAIT );		// Wait for user input  		}  		else diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 582f50ba37..9549f180df 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -83,7 +83,7 @@ LLToolPie::LLToolPie()  	mMouseOutsideSlop( false ),  	mMouseSteerX(-1),  	mMouseSteerY(-1), -	mAbortClickToWalk(false), +	mBlockClickToWalk(false),  	mClickAction(0),  	mClickActionBuyEnabled( gSavedSettings.getBOOL("ClickActionBuyEnabled") ),  	mClickActionPayEnabled( gSavedSettings.getBOOL("ClickActionPayEnabled") ) @@ -303,7 +303,7 @@ BOOL LLToolPie::handleLeftClickPick()  	if (gFocusMgr.getKeyboardFocus())  	{  		// don't click to walk on attempt to give focus to world -		mAbortClickToWalk = true; +		mBlockClickToWalk = true;  		gFocusMgr.setKeyboardFocus(NULL);  	} @@ -625,7 +625,7 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)  	// let media have first pass at click  	if (handleMediaMouseUp() || LLViewerMediaFocus::getInstance()->getFocus())  	{ -		mAbortClickToWalk = true; +		mBlockClickToWalk = true;  	}  	stopCameraSteering();  	mMouseButtonDown = false; @@ -633,7 +633,7 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)  	if (click_action == CLICK_ACTION_NONE				// not doing 1-click action  		&& gSavedSettings.getBOOL("ClickToWalk")		// click to walk enabled  		&& !gAgent.getFlying()							// don't auto-navigate while flying until that works -		&& !mAbortClickToWalk							// another behavior hasn't cancelled click to walk +		&& !mBlockClickToWalk							// another behavior hasn't cancelled click to walk  		&& !mPick.mPosGlobal.isExactlyZero()			// valid coordinates for pick  		&& (mPick.mPickType == LLPickInfo::PICK_LAND	// we clicked on land  			|| mPick.mObjectID.notNull()))				// or on an object @@ -658,11 +658,11 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)  		mAutoPilotDestination = (LLHUDEffectBlob *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BLOB, FALSE);  		mAutoPilotDestination->setPositionGlobal(mPick.mPosGlobal);  		mAutoPilotDestination->setPixelSize(5); -		mAutoPilotDestination->setColor(LLColor4U(50, 50, 200)); +		mAutoPilotDestination->setColor(LLColor4U(170, 210, 190));  		mAutoPilotDestination->setDuration(3.f);  		handle_go_to(); -		mAbortClickToWalk = false; +		mBlockClickToWalk = false;  		return TRUE;  	} @@ -675,7 +675,7 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)  	LLToolMgr::getInstance()->clearTransientTool();  	gAgentCamera.setLookAt(LOOKAT_TARGET_CONVERSATION, obj); // maybe look at object/person clicked on -	mAbortClickToWalk = false; +	mBlockClickToWalk = false;  	return LLTool::handleMouseUp(x, y, mask);  } @@ -1298,7 +1298,8 @@ void LLToolPie::VisitHomePage(const LLPickInfo& info)  void LLToolPie::handleSelect()  { -	mAbortClickToWalk = true;	 +	// tool is reselected when app gets focus, etc. +	mBlockClickToWalk = true;	  }  void LLToolPie::handleDeselect() @@ -1738,7 +1739,7 @@ bool intersect_ray_with_sphere( const LLVector3& ray_pt, const LLVector3& ray_di  void LLToolPie::startCameraSteering()  {  	mMouseOutsideSlop = true; -	mAbortClickToWalk = true; +	mBlockClickToWalk = true;  	if (gAgentCamera.getFocusOnAvatar())  	{ @@ -1777,7 +1778,7 @@ void LLToolPie::startCameraSteering()  		if (mMouseSteerGrabPoint) { mMouseSteerGrabPoint->markDead(); }  		mMouseSteerGrabPoint = (LLHUDEffectBlob *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BLOB, FALSE);  		mMouseSteerGrabPoint->setPositionGlobal(mSteerPick.mPosGlobal); -		mMouseSteerGrabPoint->setColor(LLColor4U(50, 50, 200)); +		mMouseSteerGrabPoint->setColor(LLColor4U(170, 210, 190));  		mMouseSteerGrabPoint->setPixelSize(5);  		mMouseSteerGrabPoint->setDuration(2.f);  	} diff --git a/indra/newview/lltoolpie.h b/indra/newview/lltoolpie.h index 22e77a3159..22359a6db8 100644 --- a/indra/newview/lltoolpie.h +++ b/indra/newview/lltoolpie.h @@ -66,6 +66,7 @@ public:  	LLViewerObject*		getClickActionObject() { return mClickActionObject; }  	LLObjectSelection*	getLeftClickSelection() { return (LLObjectSelection*)mLeftClickSelection; }  	void 				resetSelection(); +	void				blockClickToWalk() { mBlockClickToWalk = true; }  	static void			selectionPropertiesReceived(); @@ -105,7 +106,7 @@ private:  	LLPointer<LLHUDEffectBlob>	mAutoPilotDestination;  	LLPointer<LLHUDEffectBlob>	mMouseSteerGrabPoint;  	bool				mClockwise;			 -	bool				mAbortClickToWalk; +	bool				mBlockClickToWalk;  	LLUUID				mMediaMouseCaptureID;  	LLPickInfo			mPick;  	LLPickInfo			mHoverPick; diff --git a/indra/newview/lltracker.h b/indra/newview/lltracker.h index c0c154abe8..8e916af315 100644 --- a/indra/newview/lltracker.h +++ b/indra/newview/lltracker.h @@ -75,7 +75,7 @@ public:  	// these are static so that they can be used a callbacks  	static ETrackingStatus getTrackingStatus() { return instance()->mTrackingStatus; }  	static ETrackingLocationType getTrackedLocationType() { return instance()->mTrackingLocationType; } -	static BOOL isTracking(void*) { return (BOOL) instance()->mTrackingStatus; } +	static BOOL isTracking(void*) { return instance()->mTrackingStatus != TRACKING_NOTHING; }  	static void stopTracking(void*);  	static void clearFocus(); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 26b6ffa19e..f5b0857425 100755 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -845,37 +845,50 @@ class LLAdvancedCheckFeature : public view_listener_t  void toggle_destination_and_avatar_picker(const LLSD& show)  {  	S32 panel_idx = show.isDefined() ? show.asInteger() : -1; -	LLView* container = gViewerWindow->getRootView()->getChildView("avatar_picker_and_destination_guide_container"); +	LLView* container = gViewerWindow->getRootView()->findChildView("avatar_picker_and_destination_guide_container"); +	if (!container) return; +  	LLMediaCtrl* destinations = container->findChild<LLMediaCtrl>("destination_guide_contents");  	LLMediaCtrl* avatar_picker = container->findChild<LLMediaCtrl>("avatar_picker_contents"); +	if (!destinations || !avatar_picker) return; +  	LLButton* avatar_btn = gViewerWindow->getRootView()->getChildView("bottom_tray")->getChild<LLButton>("avatar_btn");  	LLButton* destination_btn = gViewerWindow->getRootView()->getChildView("bottom_tray")->getChild<LLButton>("destination_btn");  	switch(panel_idx)  	{  	case 0: -		container->setVisible(true); -		destinations->setVisible(true); -		avatar_picker->setVisible(false); -		LLFirstUse::notUsingDestinationGuide(false); -		avatar_btn->setToggleState(false); -		destination_btn->setToggleState(true); +		if (!destinations->getVisible()) +		{ +			container->setVisible(true); +			destinations->setVisible(true); +			avatar_picker->setVisible(false); +			LLFirstUse::notUsingDestinationGuide(false); +			avatar_btn->setToggleState(false); +			destination_btn->setToggleState(true); +			return; +		}  		break;  	case 1: -		container->setVisible(true); -		destinations->setVisible(false); -		avatar_picker->setVisible(true); -		avatar_btn->setToggleState(true); -		destination_btn->setToggleState(false); +		if (!avatar_picker->getVisible()) +		{	 +			container->setVisible(true); +			destinations->setVisible(false); +			avatar_picker->setVisible(true); +			avatar_btn->setToggleState(true); +			destination_btn->setToggleState(false); +			return; +		}  		break;  	default: -		container->setVisible(false); -		destinations->setVisible(false); -		avatar_picker->setVisible(false); -		avatar_btn->setToggleState(false); -		destination_btn->setToggleState(false);  		break;  	} + +	container->setVisible(false); +	destinations->setVisible(false); +	avatar_picker->setVisible(false); +	avatar_btn->setToggleState(false); +	destination_btn->setToggleState(false);  }; @@ -7166,7 +7179,13 @@ LLViewerMenuHolderGL::LLViewerMenuHolderGL(const LLViewerMenuHolderGL::Params& p  BOOL LLViewerMenuHolderGL::hideMenus()  { -	BOOL handled = LLMenuHolderGL::hideMenus(); +	BOOL handled = FALSE; +	 +	if (LLMenuHolderGL::hideMenus()) +	{ +		LLToolPie::instance().blockClickToWalk(); +		handled = TRUE; +	}  	// drop pie menu selection  	mParcelSelection = NULL; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index f1acd34e11..39ef56d156 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1930,6 +1930,11 @@ void LLViewerWindow::initWorldUI()  		avatar_picker->navigateTo(gSavedSettings.getString("AvatarPickerURL"), "text/html");  	} +	if (gSavedSettings.getBOOL("FirstLoginThisInstall")) +	{ +		toggle_destination_and_avatar_picker(0); +		gSavedSettings.setBOOL("FirstLoginThisInstall", FALSE); +	}  }  // Destroy the UI diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 87d8e54a89..bfcf130e33 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -696,4 +696,5 @@ with the same filename but different name    <texture name="Yellow_Gradient" file_name="windows/yellow_gradient.png"/>    <texture name="Popup_Caution" file_name="icons/pop_up_caution.png"/> +  <texture name="Camera_Drag_Dot" file_name="world/CameraDragDot.png"/>  </textures> diff --git a/indra/newview/skins/default/textures/world/CameraDragDot.png b/indra/newview/skins/default/textures/world/CameraDragDot.pngBinary files differ new file mode 100644 index 0000000000..57698e1956 --- /dev/null +++ b/indra/newview/skins/default/textures/world/CameraDragDot.png diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 8655a6bf97..ea40a08c95 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -261,6 +261,17 @@               function="Floater.Toggle"               parameter="world_map" />          </menu_item_check> +        <menu_item_check +        label="Search" +        name="Search" +        shortcut="control|F"> +            <menu_item_check.on_check +             function="Floater.Visible" +             parameter="search" /> +            <menu_item_check.on_click +             function="Floater.Toggle" +             parameter="search" /> +            </menu_item_check>          <menu_item_call           label="Snapshot"           name="Take Snapshot" diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index 43431ea7c1..1a00416b2a 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -76,7 +76,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M       follows="all"       height="383"       layout="topleft" -     left="5" +     left="3"       name="tabs"       tab_group="1"       tab_min_width="70" @@ -84,7 +84,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M       tab_position="top"       top_pad="10"       halign="center" -     width="317"> +     width="319">       	<panel           background_opaque="true"         background_visible="true" @@ -106,20 +106,20 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M  			 left="3"  			 mouse_opaque="false"  			 name="Net Map" -			 width="307" +			 width="305"  			 height="140" -			 top="0"/> +			 top="5"/>  			<avatar_list               allow_select="true"               follows="top|left|bottom|right" -             height="216" +             height="211"               ignore_online_status="true"               layout="topleft"               left="3"               multi_select="true"               name="avatar_list"               top="145" -             width="307" /> +             width="306" />              <panel               background_visible="true"               follows="left|right|bottom" @@ -165,7 +165,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M               layout="topleft"               left_pad="1"               name="dummy_icon" -             width="241" +             width="243"               />              </panel>          </panel> @@ -251,7 +251,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M  				   top_pad="1"  				   left="0"  				   name="bottom_panel" -				   width="305"> +				   width="308">  				      <layout_panel  				       auto_resize="false"  				       height="25" @@ -300,7 +300,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M  				       layout="topleft"  				       name="dummy_panel"  				       user_resize="false" -				       width="212"> +				       width="210">  				          <icon  				           follows="bottom|left|right"  				           height="25" @@ -309,7 +309,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M  				           left="0"  				           top="0"  				           name="dummy_icon" -				           width="211" /> +				           width="210" />  				      </layout_panel>  				      <layout_panel  				       auto_resize="false" @@ -471,7 +471,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M               	 layout="topleft"               	 left_pad="1"               	 name="dummy_icon" -             	 width="209" +             	 width="212"               />              </panel>          </panel> @@ -506,7 +506,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M               height="27"               label="bottom_panel"               layout="topleft" -             left="0" +             left="3"               name="bottom_panel"               top_pad="0"               width="313"> @@ -544,7 +544,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M               	 layout="topleft"               	 left_pad="1"               	 name="dummy_icon" -             	 width="241" +             	 width="244"               />              </panel>          </panel> diff --git a/indra/newview/skins/default/xui/es/panel_landmark_info.xml b/indra/newview/skins/default/xui/es/panel_landmark_info.xml index 49a9f84cfe..1a0ac3ba79 100644 --- a/indra/newview/skins/default/xui/es/panel_landmark_info.xml +++ b/indra/newview/skins/default/xui/es/panel_landmark_info.xml @@ -19,7 +19,7 @@  		[wkday,datetime,local][day,datetime,local] [mth,datetime,local] [year,datetime,local][hour,datetime,local]:[min,datetime,local]:[second,datetime,local]  	</string>  	<button name="back_btn" tool_tip="Atrás"/> -	<text name="title" value="Añadir el perfil"/> +	<text name="title" value="Perfil del lugar"/>  	<scroll_container name="place_scroll">  		<panel name="scrolling_panel">  			<text name="maturity_value" value="desconocido"/> diff --git a/indra/newview/skins/default/xui/es/panel_place_profile.xml b/indra/newview/skins/default/xui/es/panel_place_profile.xml index 524ba2253b..3c363859a4 100644 --- a/indra/newview/skins/default/xui/es/panel_place_profile.xml +++ b/indra/newview/skins/default/xui/es/panel_place_profile.xml @@ -5,7 +5,7 @@  	<string name="anyone" value="Cualquiera"/>  	<string name="available" value="disponible"/>  	<string name="allocated" value="asignados"/> -	<string name="title_place" value="Añadir el perfil"/> +	<string name="title_place" value="Perfil del lugar"/>  	<string name="title_teleport_history" value="Historial de teleportes"/>  	<string name="not_available" value="(No disp.)"/>  	<string name="unknown" value="(desconocido)"/> @@ -42,7 +42,7 @@  		[wkday,datetime,local][day,datetime,local] [mth,datetime,local] [year,datetime,local][hour,datetime,local]:[min,datetime,local]:[second,datetime,local]  	</string>  	<button name="back_btn" tool_tip="Atrás"/> -	<text name="title" value="Añadir el perfil"/> +	<text name="title" value="Perfil del lugar"/>  	<scroll_container name="place_scroll">  		<panel name="scrolling_panel">  			<text name="owner_label" value="Propietario:"/> | 
