From 6c70154cd1e5757e879f3f7463c0fedd69d82b63 Mon Sep 17 00:00:00 2001
From: Richard Nelson <richard@lindenlab.com>
Date: Wed, 30 Sep 2009 01:00:51 +0000
Subject: converted focus change callbacks to use signals replaced
 mFocusChangedSignal that PE added with our hierarchical focus mgmt

reviewed by Leyla
---
 indra/llui/llcombobox.cpp        |  1 -
 indra/llui/llfocusmgr.cpp        | 42 +++++++---------------------------------
 indra/llui/llfocusmgr.h          | 27 ++++++++++----------------
 indra/llui/llmultisliderctrl.cpp |  2 +-
 indra/llui/llscrollbar.h         |  6 ------
 indra/llui/llsliderctrl.cpp      |  2 +-
 indra/llui/llspinctrl.cpp        |  2 +-
 indra/llui/lluictrl.cpp          | 10 +---------
 indra/llui/lluictrl.h            |  7 -------
 indra/llui/llview.cpp            | 10 ----------
 indra/llui/llview.h              |  4 ----
 11 files changed, 21 insertions(+), 92 deletions(-)

(limited to 'indra/llui')

diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index 58aeb61728..0170ac0c6a 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -483,7 +483,6 @@ void LLComboBox::createLineEditor(const LLComboBox::Params& p)
 		params.max_length_bytes(mMaxChars);
 		params.commit_callback.function(boost::bind(&LLComboBox::onTextCommit, this, _2));
 		params.keystroke_callback(boost::bind(&LLComboBox::onTextEntry, this, _1));
-		params.focus_lost_callback(NULL);
 		params.handle_edit_keys_directly(true);
 		params.commit_on_focus_lost(false);
 		params.follows.flags(FOLLOWS_ALL);
diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp
index ab9b59e252..279cbaa923 100644
--- a/indra/llui/llfocusmgr.cpp
+++ b/indra/llui/llfocusmgr.cpp
@@ -41,11 +41,6 @@ const F32 FOCUS_FADE_TIME = 0.3f;
 // NOTE: the LLFocusableElement implementation has been moved here from lluictrl.cpp.
 
 LLFocusableElement::LLFocusableElement()
-:	mFocusLostCallback(NULL),
-	mFocusReceivedCallback(NULL),
-	mFocusChangedCallback(NULL),
-	mTopLostCallback(NULL),
-	mFocusCallbackUserData(NULL)
 {
 }
 
@@ -68,35 +63,19 @@ LLFocusableElement::~LLFocusableElement()
 
 void LLFocusableElement::onFocusReceived()
 {
-	if( mFocusReceivedCallback )
-	{
-		mFocusReceivedCallback( this, mFocusCallbackUserData );
-	}
-	if( mFocusChangedCallback )
-	{
-		mFocusChangedCallback( this, mFocusCallbackUserData );
-	}
+	mFocusReceivedCallback(this);
+	mFocusChangedCallback(this);
 }
 
 void LLFocusableElement::onFocusLost()
 {
-	if( mFocusLostCallback )
-	{
-		mFocusLostCallback( this, mFocusCallbackUserData );
-	}
-
-	if( mFocusChangedCallback )
-	{
-		mFocusChangedCallback( this, mFocusCallbackUserData );
-	}
+	mFocusLostCallback(this);
+	mFocusChangedCallback(this);
 }
 
 void LLFocusableElement::onTopLost()
 {
-	if (mTopLostCallback)
-	{
-		mTopLostCallback(this, mFocusCallbackUserData);
-	}
+	mTopLostCallback(this);
 }
 
 BOOL LLFocusableElement::hasFocus() const
@@ -188,12 +167,9 @@ void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL
 		view_handle_list_t new_focus_list;
 
 		// walk up the tree to root and add all views to the new_focus_list
-		for (LLView* ctrl = dynamic_cast<LLView*>(mKeyboardFocus); ctrl && ctrl != LLUI::getRootView(); ctrl = ctrl->getParent())
+		for (LLView* ctrl = dynamic_cast<LLView*>(mKeyboardFocus); ctrl; ctrl = ctrl->getParent())
 		{
-			if (ctrl) 
-			{
-				new_focus_list.push_back(ctrl->getHandle());
-			}
+			new_focus_list.push_back(ctrl->getHandle());
 		}
 
 		// remove all common ancestors since their focus is unchanged
@@ -216,10 +192,6 @@ void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL
 			{
 				mCachedKeyboardFocusList.pop_front();
 				old_focus_view->onFocusLost();
-
-				// part of fix of EXT-996
-				// this need to handle event when user click inside in-world area
-				mFocusChangeSignal();
 			}
 		}
 
diff --git a/indra/llui/llfocusmgr.h b/indra/llui/llfocusmgr.h
index 2c2dae216a..2fa4e124fb 100644
--- a/indra/llui/llfocusmgr.h
+++ b/indra/llui/llfocusmgr.h
@@ -54,11 +54,12 @@ public:
 	virtual void	setFocus( BOOL b );
 	virtual BOOL	hasFocus() const;
 
-	typedef boost::function<void(LLFocusableElement*, void*)> focus_callback_t;
-	void	setFocusLostCallback(focus_callback_t cb, void* user_data = NULL)	{ mFocusLostCallback = cb; mFocusCallbackUserData = user_data; }
-	void	setFocusReceivedCallback(focus_callback_t cb, void* user_data = NULL)	{ mFocusReceivedCallback = cb; mFocusCallbackUserData = user_data; }
-	void	setFocusChangedCallback(focus_callback_t cb, void* user_data = NULL )	{ mFocusChangedCallback = cb; mFocusCallbackUserData = user_data; }
-	void	setTopLostCallback(focus_callback_t cb, void* user_data = NULL )	{ mTopLostCallback = cb; mFocusCallbackUserData = user_data; }
+	typedef boost::signals2::signal<void(LLFocusableElement*)> focus_signal_t;
+	
+	boost::signals2::connection setFocusLostCallback( const focus_signal_t::slot_type& cb)	{ return mFocusLostCallback.connect(cb);}
+	boost::signals2::connection	setFocusReceivedCallback(const focus_signal_t::slot_type& cb)	{ return mFocusReceivedCallback.connect(cb);}
+	boost::signals2::connection	setFocusChangedCallback(const focus_signal_t::slot_type& cb)	{ return mFocusChangedCallback.connect(cb);}
+	void	setTopLostCallback(const focus_signal_t::slot_type& cb)	{ mTopLostCallback.connect(cb);}
 
 	// These were brought up the hierarchy from LLView so that we don't have to use dynamic_cast when dealing with keyboard focus.
 	virtual BOOL	handleKey(KEY key, MASK mask, BOOL called_from_parent);
@@ -68,11 +69,10 @@ protected:
 	virtual void	onFocusReceived();
 	virtual void	onFocusLost();
 	virtual void	onTopLost();	// called when registered as top ctrl and user clicks elsewhere
-	focus_callback_t mFocusLostCallback;
-	focus_callback_t mFocusReceivedCallback;
-	focus_callback_t mFocusChangedCallback;
-	focus_callback_t mTopLostCallback;
-	void*			mFocusCallbackUserData;
+	focus_signal_t  mFocusLostCallback;
+	focus_signal_t  mFocusReceivedCallback;
+	focus_signal_t  mFocusChangedCallback;
+	focus_signal_t  mTopLostCallback;
 };
 
 
@@ -124,11 +124,6 @@ public:
 	void			unlockFocus();
 	BOOL			focusLocked() const { return mLockedView != NULL; }
 
-	void			addFocusChangeCallback(const boost::signals2::signal<void ()>::slot_type& cb)
-	{
-		mFocusChangeSignal.connect(cb);
-	}
-
 private:
 	LLUICtrl*			mLockedView;
 
@@ -155,8 +150,6 @@ private:
 	typedef std::map<LLHandle<LLView>, LLHandle<LLView> > focus_history_map_t;
 	focus_history_map_t mFocusHistory;
 
-	boost::signals2::signal<void()>	mFocusChangeSignal;
-
 	#ifdef _DEBUG
 		std::string		mMouseCaptorName;
 		std::string		mKeyboardFocusName;
diff --git a/indra/llui/llmultisliderctrl.cpp b/indra/llui/llmultisliderctrl.cpp
index 01a3b5fdc7..0fbb7ced54 100644
--- a/indra/llui/llmultisliderctrl.cpp
+++ b/indra/llui/llmultisliderctrl.cpp
@@ -140,7 +140,7 @@ LLMultiSliderCtrl::LLMultiSliderCtrl(const LLMultiSliderCtrl::Params& p)
 			params.prevalidate_callback(&LLLineEditor::prevalidateFloat);
 			params.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM);
 			mEditor = LLUICtrlFactory::create<LLLineEditor> (params);
-			mEditor->setFocusReceivedCallback( &LLMultiSliderCtrl::onEditorGainFocus );
+			mEditor->setFocusReceivedCallback( boost::bind(LLMultiSliderCtrl::onEditorGainFocus, _1, this) );
 			// don't do this, as selecting the entire text is single clicking in some cases
 			// and double clicking in others
 			//mEditor->setSelectAllonFocusReceived(TRUE);
diff --git a/indra/llui/llscrollbar.h b/indra/llui/llscrollbar.h
index 7e72331a3f..7e88b16561 100644
--- a/indra/llui/llscrollbar.h
+++ b/indra/llui/llscrollbar.h
@@ -130,12 +130,6 @@ public:
 	void				onLineUpBtnPressed(const LLSD& data);
 	void				onLineDownBtnPressed(const LLSD& data);
 
-	void				setBGColor(const LLUIColor& color) { mBGColor = color; }
-	const LLUIColor&	getBGColor() const { return mBGColor; }
-
-	void				setBGVisible() { mBGVisible = true; }
-	bool				getBGVisible() const { return mBGVisible; }
-
 private:
 	void				updateThumbRect();
 	void				changeLine(S32 delta, BOOL update_thumb );
diff --git a/indra/llui/llsliderctrl.cpp b/indra/llui/llsliderctrl.cpp
index 15584c8dc7..fb71b60725 100644
--- a/indra/llui/llsliderctrl.cpp
+++ b/indra/llui/llsliderctrl.cpp
@@ -143,7 +143,7 @@ LLSliderCtrl::LLSliderCtrl(const LLSliderCtrl::Params& p)
 			line_p.prevalidate_callback(&LLLineEditor::prevalidateFloat);
 			mEditor = LLUICtrlFactory::create<LLLineEditor>(line_p);
 
-			mEditor->setFocusReceivedCallback( &LLSliderCtrl::onEditorGainFocus, this );
+			mEditor->setFocusReceivedCallback( boost::bind(&LLSliderCtrl::onEditorGainFocus, _1, this ));
 			// don't do this, as selecting the entire text is single clicking in some cases
 			// and double clicking in others
 			//mEditor->setSelectAllonFocusReceived(TRUE);
diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp
index 3a96bc8f93..83d71006aa 100644
--- a/indra/llui/llspinctrl.cpp
+++ b/indra/llui/llspinctrl.cpp
@@ -142,7 +142,7 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p)
 	params.prevalidate_callback(&LLLineEditor::prevalidateFloat);
 	params.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM);
 	mEditor = LLUICtrlFactory::create<LLLineEditor> (params);
-	mEditor->setFocusReceivedCallback( &LLSpinCtrl::onEditorGainFocus, this );
+	mEditor->setFocusReceivedCallback( boost::bind(&LLSpinCtrl::onEditorGainFocus, _1, this ));
 	//RN: this seems to be a BAD IDEA, as it makes the editor behavior different when it has focus
 	// than when it doesn't.  Instead, if you always have to double click to select all the text, 
 	// it's easier to understand
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
index 8807e26f6b..2cd9c8844e 100644
--- a/indra/llui/lluictrl.cpp
+++ b/indra/llui/lluictrl.cpp
@@ -114,7 +114,6 @@ void LLUICtrl::initFromParams(const Params& p)
 	}
 
 	setTabStop(p.tab_stop);
-	setFocusLostCallback(p.focus_lost_callback());
 
 	if (p.initial_value.isProvided() 
 		&& !p.control_name.isProvided())
@@ -800,14 +799,7 @@ namespace LLInitParam
     	return false;
     }
     
-    template<> 
-	bool ParamCompare<LLUICtrl::focus_callback_t>::equals(
-		const LLUICtrl::focus_callback_t &a, 
-		const LLUICtrl::focus_callback_t &b)
-    {
-    	return false;
-    }
-    
+   
     template<> 
 	bool ParamCompare<LLUICtrl::enable_callback_t>::equals(
 		const LLUICtrl::enable_callback_t &a, 
diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h
index 3add9393ea..0ca3acfa1c 100644
--- a/indra/llui/lluictrl.h
+++ b/indra/llui/lluictrl.h
@@ -124,8 +124,6 @@ public:
 		Optional<CommitCallbackParam>	mouseenter_callback;
 		Optional<CommitCallbackParam>	mouseleave_callback;
 		
-		Optional<focus_callback_t>		focus_lost_callback;
-		
 		Optional<std::string>			control_name;
 		Optional<EnableControls>		enabled_controls;
 		Optional<ControlVisibility>		controls_visibility;
@@ -309,11 +307,6 @@ namespace LLInitParam
 		const LLUICtrl::enable_callback_t &a, 
 		const LLUICtrl::enable_callback_t &b); 
     
-	template<> 
-	bool ParamCompare<LLUICtrl::focus_callback_t>::equals(
-		const LLUICtrl::focus_callback_t &a, 
-		const LLUICtrl::focus_callback_t &b); 
-	
     template<>
 	bool ParamCompare<LLLazyValue<LLColor4> >::equals(
 		const LLLazyValue<LLColor4> &a, const LLLazyValue<LLColor4> &b); 
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 256c776293..10cb3fb377 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -466,16 +466,6 @@ LLRect LLView::getRequiredRect()
 	return mRect;
 }
 
-//virtual
-void LLView::onFocusLost()
-{
-}
-
-//virtual
-void LLView::onFocusReceived()
-{
-}
-
 BOOL LLView::focusNextRoot()
 {
 	LLView::child_list_t result = LLView::getFocusRootsQuery().run(this);
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index bf3b5d0614..7a37d6f430 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -405,10 +405,6 @@ public:
 	BOOL getSaveToXML() const { return mSaveToXML; }
 	void setSaveToXML(BOOL b) { mSaveToXML = b; }
 
-	// inherited from LLFocusableElement
-	/* virtual */ void onFocusLost();
-	/* virtual */ void onFocusReceived();
-
 	typedef enum e_hit_test_type
 	{
 		HIT_TEST_USE_BOUNDING_RECT,
-- 
cgit v1.2.3


From feabeb496518f28359f654fdc397354355743589 Mon Sep 17 00:00:00 2001
From: Adam Moss <moss@lindenlab.com>
Date: Wed, 30 Sep 2009 17:46:31 +0000
Subject: DEV-35039 Viewer 2.0 Help System - Viewer Development

svn merge -r134800:134805 svn+ssh://svn.lindenlab.com/svn/linden/branches/viewer2help-3
---
 indra/llui/CMakeLists.txt  |   2 +-
 indra/llui/llbutton.cpp    |  45 +++++++---------
 indra/llui/llbutton.h      |   7 +--
 indra/llui/llfloater.cpp   | 129 +++++++++++++++++----------------------------
 indra/llui/llfloater.h     |  14 ++---
 indra/llui/llhelp.h        |  45 ++++++++++++++++
 indra/llui/llpanel.cpp     |   3 ++
 indra/llui/llpanel.h       |   8 ++-
 indra/llui/llui.cpp        |  53 +++----------------
 indra/llui/llui.h          |   7 +--
 indra/llui/lluictrl.cpp    |  21 ++++++++
 indra/llui/lluictrl.h      |   4 ++
 indra/llui/llurlaction.cpp |   1 -
 13 files changed, 160 insertions(+), 179 deletions(-)
 create mode 100644 indra/llui/llhelp.h

(limited to 'indra/llui')

diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 1e6b216a61..d7d411dee6 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -129,7 +129,7 @@ set(llui_HEADER_FILES
     llfocusmgr.h
     llfunctorregistry.h
     llhandle.h
-    llhtmlhelp.h
+    llhelp.h
     lliconctrl.h
     llkeywords.h
     lllayoutstack.h
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index fa13ced037..b9613b502c 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -39,7 +39,6 @@
 #include "llstring.h"
 
 // Project includes
-#include "llhtmlhelp.h"
 #include "llkeyboard.h"
 #include "llui.h"
 #include "lluiconstants.h"
@@ -49,8 +48,10 @@
 #include "llfloaterreg.h"
 #include "llfocusmgr.h"
 #include "llwindow.h"
+#include "llnotifications.h"
 #include "llrender.h"
 #include "lluictrlfactory.h"
+#include "llhelp.h"
 
 static LLDefaultChildRegistry::Register<LLButton> r("button");
 
@@ -92,7 +93,6 @@ LLButton::Params::Params()
 	mouse_held_callback("mouse_held_callback"),
 	is_toggle("is_toggle", false),
 	scale_image("scale_image", true),
-	help_url("help_url"),
 	hover_glow_amount("hover_glow_amount"),
 	commit_on_return("commit_on_return", true),
 	picture_style("picture_style", false)
@@ -173,11 +173,6 @@ LLButton::LLButton(const LLButton::Params& p)
 	
 	mMouseDownTimer.stop();
 
-	if (p.help_url.isProvided())
-	{
-		setHelpURLCallback(p.help_url);
-	}
-
 	// if custom unselected button image provided...
 	if (p.image_unselected != default_params.image_unselected)
 	{
@@ -1034,24 +1029,6 @@ void LLButton::addImageAttributeToXML(LLXMLNodePtr node,
 	}
 }
 
-void clicked_help(void* data)
-{
-	LLButton* self = (LLButton*)data;
-	if (!self) return;
-	
-	if (!LLUI::sHtmlHelp)
-	{
-		return;
-	}
-	
-	LLUI::sHtmlHelp->show(self->getHelpURL());
-}
-
-void LLButton::setHelpURLCallback(const std::string &help_url)
-{
-	mHelpURL = help_url;
-	setClickedCallback(clicked_help,this);
-}
 
 // static
 void LLButton::toggleFloaterAndSetToggleState(LLUICtrl* ctrl, const LLSD& sdname)
@@ -1077,6 +1054,24 @@ void LLButton::setFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname)
 	button->setClickedCallback(boost::bind(&LLFloaterReg::toggleFloaterInstance, sdname));
 }
 
+// static
+void LLButton::showHelp(LLUICtrl* ctrl, const LLSD& sdname)
+{
+	// search back through the button's parents for a panel
+	// with a help_topic string defined
+	std::string help_topic;
+	if (LLUI::sHelpImpl &&
+	    ctrl->findHelpTopic(help_topic))
+	{
+		LLUI::sHelpImpl->showTopic(help_topic);
+		return; // success
+	}
+
+	// display an error if we can't find a help_topic string.
+	// fix this by adding a help_topic attribute to the xui file
+	LLNotifications::instance().add("UnableToFindHelpTopic");
+}
+
 void LLButton::resetMouseDownTimer()
 {
 	mMouseDownTimer.stop();
diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h
index 06e1dac914..04716d605b 100644
--- a/indra/llui/llbutton.h
+++ b/indra/llui/llbutton.h
@@ -118,7 +118,6 @@ public:
 								commit_on_return,
 								picture_style;      //if true, don't display label
 		
-		Optional<std::string>		help_url;
 		Optional<F32>				hover_glow_amount;
 		Optional<TimeIntervalParam>	held_down_delay;
 
@@ -230,12 +229,10 @@ public:
 	void			setCommitOnReturn(BOOL commit) { mCommitOnReturn = commit; }
 	BOOL			getCommitOnReturn() const { return mCommitOnReturn; }
 
-	void			setHelpURLCallback(const std::string &help_url);
-	const std::string&	getHelpURL() const { return mHelpURL; }
-
 	static void		onHeldDown(void *userdata);  // to be called by gIdleCallbacks
 	static void		toggleFloaterAndSetToggleState(LLUICtrl* ctrl, const LLSD& sdname);
 	static void		setFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname);
+	static void		showHelp(LLUICtrl* ctrl, const LLSD& sdname);
 	
 protected:
 	const LLPointer<LLUIImage>&	getImageUnselected() const	{ return mImageUnselected; }
@@ -314,8 +311,6 @@ private:
 	BOOL						mCommitOnReturn;
 	BOOL						mFadeWhenDisabled;
 
-	std::string					mHelpURL;
-
 	LLFrameTimer				mFlashingTimer;
 };
 
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 81915731c3..ff0288a32f 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -59,6 +59,7 @@
 #include "lltabcontainer.h"
 #include "v2math.h"
 #include "lltrans.h"
+#include "llhelp.h"
 #include "llmultifloater.h"
 
 // use this to control "jumping" behavior when Ctrl-Tabbing
@@ -66,48 +67,35 @@ const S32 TABBED_FLOATER_OFFSET = 0;
 
 std::string	LLFloater::sButtonActiveImageNames[BUTTON_COUNT] = 
 {
-	"Icon_Close_Foreground",		//BUTTON_CLOSE
-	"restore.tga",	//BUTTON_RESTORE
-	"minimize.tga",	//BUTTON_MINIMIZE
-	"tearoffbox.tga",	//BUTTON_TEAR_OFF
-	"closebox.tga",		//BUTTON_EDIT
-	"Icon_Dock_Foreground",
-	"Icon_Undock_Foreground"
-};
-
-// Empty string means programmatic glow effect, achieved by
-// not setting explicit image.
-std::string	LLFloater::sButtonHoveredImageNames[BUTTON_COUNT] = 
-{
-	"",						//BUTTON_CLOSE
-	"restore_pressed.tga",	//BUTTON_RESTORE
-	"minimize_pressed.tga",	//BUTTON_MINIMIZE
-	"tearoff_pressed.tga",	//BUTTON_TEAR_OFF
-	"close_in_blue.tga",	//BUTTON_EDIT
-	"",						//BUTTON_DOCK
-	"",						//BUTTON_UNDOCK
+	"Icon_Close_Foreground",	//BUTTON_CLOSE
+	"Icon_Restore_Foreground",	//BUTTON_RESTORE
+	"Icon_Minimize_Foreground",	//BUTTON_MINIMIZE
+	"tearoffbox.tga",			//BUTTON_TEAR_OFF
+	"Icon_Dock_Foreground",		//BUTTON_DOCK
+	"Icon_Undock_Foreground",	//BUTTON_UNDOCK
+	"Icon_Help_Foreground"		//BUTTON_HELP
 };
 
 std::string	LLFloater::sButtonPressedImageNames[BUTTON_COUNT] = 
 {
-	"Icon_Close_Press",		//BUTTON_CLOSE
-	"restore_pressed.tga",	//BUTTON_RESTORE
-	"minimize_pressed.tga",	//BUTTON_MINIMIZE
-	"tearoff_pressed.tga",	//BUTTON_TEAR_OFF
-	"close_in_blue.tga",		//BUTTON_EDIT
-	"Icon_Dock_Press",
-	"Icon_Undock_Press"
+	"Icon_Close_Press",			//BUTTON_CLOSE
+	"Icon_Restore_Press",		//BUTTON_RESTORE
+	"Icon_Minimize_Press",		//BUTTON_MINIMIZE
+	"tearoff_pressed.tga",		//BUTTON_TEAR_OFF
+	"Icon_Dock_Press",			//BUTTON_DOCK
+	"Icon_Undock_Press",		//BUTTON_UNDOCK
+	"Icon_Help_Press"			//BUTTON_HELP
 };
 
 std::string	LLFloater::sButtonNames[BUTTON_COUNT] = 
 {
-	"llfloater_close_btn",	//BUTTON_CLOSE
+	"llfloater_close_btn",		//BUTTON_CLOSE
 	"llfloater_restore_btn",	//BUTTON_RESTORE
 	"llfloater_minimize_btn",	//BUTTON_MINIMIZE
 	"llfloater_tear_off_btn",	//BUTTON_TEAR_OFF
-	"llfloater_edit_btn",		//BUTTON_EDIT
-	"llfloater_dock_btn",
-	"llfloater_undock_btn"
+	"llfloater_dock_btn",		//BUTTON_DOCK
+	"llfloater_undock_btn",		//BUTTON_UNDOCK
+	"llfloater_help_btn"		//BUTTON_HELP
 };
 
 std::string LLFloater::sButtonToolTips[BUTTON_COUNT];
@@ -122,9 +110,9 @@ std::string LLFloater::sButtonToolTipsIndex[BUTTON_COUNT]=
 	"BUTTON_RESTORE",		//"Restore",	//BUTTON_RESTORE
 	"BUTTON_MINIMIZE",		//"Minimize",	//BUTTON_MINIMIZE
 	"BUTTON_TEAR_OFF",		//"Tear Off",	//BUTTON_TEAR_OFF
-	"BUTTON_EDIT",			//"Edit",		//BUTTON_EDIT
 	"BUTTON_DOCK",
-	"BUTTON_UNDOCK"
+	"BUTTON_UNDOCK",
+	"BUTTON_HELP"
 };
 
 LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] =
@@ -133,13 +121,12 @@ LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] =
 	LLFloater::onClickMinimize, //BUTTON_RESTORE
 	LLFloater::onClickMinimize, //BUTTON_MINIMIZE
 	LLFloater::onClickTearOff,	//BUTTON_TEAR_OFF
-	LLFloater::onClickEdit,	//BUTTON_EDIT
-	LLFloater::onClickDock,
-	LLFloater::onClickDock
+	LLFloater::onClickDock,		//BUTTON_DOCK
+	LLFloater::onClickDock,		//BUTTON_UNDOCK
+	LLFloater::onClickHelp		//BUTTON_HELP
 };
 
 LLMultiFloater* LLFloater::sHostp = NULL;
-BOOL			LLFloater::sEditModeEnabled = FALSE;
 BOOL			LLFloater::sQuitting = FALSE; // Flag to prevent storing visibility controls while quitting
 LLFloater::handle_map_t	LLFloater::sFloaterMap;
 
@@ -259,7 +246,6 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
 	mMinimized(FALSE),
 	mForeground(FALSE),
 	mFirstLook(TRUE),
-	mEditing(FALSE),
 	mButtonScale(1.0f),
 	mAutoFocus(TRUE), // automatically take focus when opened
 	mCanDock(false),
@@ -314,6 +300,12 @@ void LLFloater::initFloater()
 		mButtonsEnabled[BUTTON_CLOSE] = TRUE;
 	}
 
+	// Help button: '?'
+	if ( !mHelpTopic.empty() )
+	{
+		mButtonsEnabled[BUTTON_HELP] = TRUE;
+	}
+
 	// Minimize button only for top draggers
 	if ( !mDragOnLeft && mCanMinimize )
 	{
@@ -804,7 +796,7 @@ void LLFloater::setTitle( const std::string& title )
 	applyTitle();
 }
 
-std::string LLFloater::getTitle()
+std::string LLFloater::getTitle() const
 {
 	if (mTitle.empty())
 	{
@@ -822,7 +814,7 @@ void LLFloater::setShortTitle( const std::string& short_title )
 	applyTitle();
 }
 
-std::string LLFloater::getShortTitle()
+std::string LLFloater::getShortTitle() const
 {
 	if (mShortTitle.empty())
 	{
@@ -834,8 +826,6 @@ std::string LLFloater::getShortTitle()
 	}
 }
 
-
-
 BOOL LLFloater::canSnapTo(const LLView* other_view)
 {
 	if (NULL == other_view)
@@ -1051,6 +1041,10 @@ void LLFloater::setMinimized(BOOL minimize)
 		reshape( mExpandedRect.getWidth(), mExpandedRect.getHeight(), TRUE );
 	}
 	
+	// don't show the help button while minimized - it's
+	// not very useful when minimized and uses up space
+	mButtonsEnabled[BUTTON_HELP] = !minimize;
+
 	applyTitle ();
 
 	make_ui_sound("UISndWindowClose");
@@ -1387,28 +1381,6 @@ void LLFloater::setDocked(bool docked, bool pop_on_undock)
 	}
 }
 
-//static
-void LLFloater::setEditModeEnabled(BOOL enable)
-{
-	if (enable != sEditModeEnabled)
-	{
-		S32 count = 0;
-		for(handle_map_iter_t iter = sFloaterMap.begin(); iter != sFloaterMap.end(); ++iter)
-		{
-			LLFloater* floater = iter->second;
-			if (!floater->isDead())
-			{
-				iter->second->mButtonsEnabled[BUTTON_EDIT] = enable;
-				iter->second->updateButtons();
-			}
-			count++;
-		}
-	}
-
-	sEditModeEnabled = enable;
-}
-
-
 // static
 void LLFloater::onClickMinimize(LLFloater* self)
 {
@@ -1456,19 +1428,20 @@ void LLFloater::onClickTearOff(LLFloater* self)
 }
 
 // static
-void LLFloater::onClickEdit(LLFloater* self)
+void LLFloater::onClickDock(LLFloater* self)
 {
-	if (!self)
-		return;
-	self->mEditing = self->mEditing ? FALSE : TRUE;
+	if(self && self->mCanDock)
+	{
+		self->setDocked(!self->mDocked, true);
+	}
 }
 
 // static
-void LLFloater::onClickDock(LLFloater* self)
+void LLFloater::onClickHelp( LLFloater* self )
 {
-	if(self && self->mCanDock)
+	if (self && LLUI::sHelpImpl)
 	{
-		self->setDocked(!self->mDocked, true);
+		LLUI::sHelpImpl->showTopic(self->getHelpTopic());
 	}
 }
 
@@ -1807,17 +1780,9 @@ void LLFloater::buildButtons()
 		// Selected, no matter if hovered or not, is "pressed"
 		p.image_selected.name(sButtonPressedImageNames[i]);
 		p.image_hover_selected.name(sButtonPressedImageNames[i]);
-		// Empty string means programmatic glow effect, achieved by
-		// not setting explicit image.
-		if (sButtonHoveredImageNames[i].empty())
-		{
-			// These icons are really small, need glow amount increased
-			p.hover_glow_amount( 0.22f );
-		}
-		else
-		{
-			p.image_hover_unselected.name(sButtonHoveredImageNames[i]);
-		}
+		// Use a glow effect when the user hovers over the button
+		// These icons are really small, need glow amount increased
+		p.hover_glow_amount( 0.33f );
 		p.click_callback.function(boost::bind(sButtonCallbacks[i], this));
 		p.tab_stop(false);
 		p.follows.flags(FOLLOWS_TOP|FOLLOWS_RIGHT);
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 513f6a6918..2a31ba4e8f 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -101,9 +101,9 @@ public:
 		BUTTON_RESTORE,
 		BUTTON_MINIMIZE,
 		BUTTON_TEAR_OFF,
-		BUTTON_EDIT,
 		BUTTON_DOCK,
 		BUTTON_UNDOCK,
+		BUTTON_HELP,
 		BUTTON_COUNT
 	};
 	
@@ -173,9 +173,9 @@ public:
 	void			applyTitle();
 	const std::string&	getCurrentTitle() const;
 	void			setTitle( const std::string& title);
-	std::string		getTitle();
+	std::string		getTitle() const;
 	void			setShortTitle( const std::string& short_title );
-	std::string		getShortTitle();
+	std::string		getShortTitle() const;
 	void			setTitleVisible(bool visible);
 	virtual void	setMinimized(BOOL b);
 	void			moveResizeHandlesToFront();
@@ -256,12 +256,10 @@ public:
 	static void		onClickClose(LLFloater* floater);
 	static void		onClickMinimize(LLFloater* floater);
 	static void		onClickTearOff(LLFloater* floater);
-	static void		onClickEdit(LLFloater* floater);
 	static void     onClickDock(LLFloater* floater);
+	static void		onClickHelp(LLFloater* floater);
 
 	static void		setFloaterHost(LLMultiFloater* hostp) {sHostp = hostp; }
-	static void		setEditModeEnabled(BOOL enable);
-	static BOOL		getEditModeEnabled() { return sEditModeEnabled; }
 	static LLMultiFloater* getFloaterHost() {return sHostp; }
 		
 protected:
@@ -331,7 +329,6 @@ private:
 	
 
 	BOOL			mFirstLook;			// TRUE if the _next_ time this floater is visible will be the first time in the session that it is visible.
-	BOOL			mEditing;
 	
 	typedef std::set<LLHandle<LLFloater> > handle_set_t;
 	typedef std::set<LLHandle<LLFloater> >::iterator handle_set_iter_t;
@@ -350,11 +347,8 @@ private:
 	bool            mDocked;
 
 	static LLMultiFloater* sHostp;
-	static BOOL		sEditModeEnabled;
 	static BOOL		sQuitting;
 	static std::string	sButtonActiveImageNames[BUTTON_COUNT];
-	// Images to use when cursor hovered over an enabled button
-	static std::string	sButtonHoveredImageNames[BUTTON_COUNT];
 	static std::string	sButtonPressedImageNames[BUTTON_COUNT];
 	static std::string	sButtonNames[BUTTON_COUNT];
 	static std::string	sButtonToolTips[BUTTON_COUNT];
diff --git a/indra/llui/llhelp.h b/indra/llui/llhelp.h
new file mode 100644
index 0000000000..c06d29a4bd
--- /dev/null
+++ b/indra/llui/llhelp.h
@@ -0,0 +1,45 @@
+/** 
+ * @file llhelp.h
+ * @brief Abstract interface to the Help system
+ * @author Tofu Linden
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * 
+ * Copyright (c) 2009, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLHELP_H
+#define LL_LLHELP_H
+
+class LLHelp
+{
+ public:
+	virtual void showTopic(const std::string &topic) = 0;
+	// return default (fallback) topic name suitable for showTopic()
+	virtual std::string defaultTopic() = 0;
+};
+
+#endif // headerguard
diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp
index 26136e0a23..b9bbb4db22 100644
--- a/indra/llui/llpanel.cpp
+++ b/indra/llui/llpanel.cpp
@@ -80,6 +80,7 @@ LLPanel::Params::Params()
 	strings("string"),
 	filename("filename"),
 	class_name("class"),
+	help_topic("help_topic"),
 	visible_callback("visible_callback")
 {
 	name = "panel";
@@ -98,6 +99,7 @@ LLPanel::LLPanel(const LLPanel::Params& p)
 	mDefaultBtn(NULL),
 	mBorder(NULL),
 	mLabel(p.label),
+	mHelpTopic(p.help_topic),
 	mCommitCallbackRegistrar(false),
 	mEnableCallbackRegistrar(false),
 	mXMLFilename(p.filename)
@@ -416,6 +418,7 @@ void LLPanel::initFromParams(const LLPanel::Params& p)
 	}
 
 	setLabel(p.label());
+	setHelpTopic(p.help_topic);
 	setShape(p.rect);
 	parseFollowsFlags(p);
 
diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h
index 81b5b68f05..8b23ea7030 100644
--- a/indra/llui/llpanel.h
+++ b/indra/llui/llpanel.h
@@ -83,6 +83,7 @@ public:
 
 		Optional<std::string>	filename;
 		Optional<std::string>	class_name;
+		Optional<std::string>   help_topic;
 
 		Multiple<LocalizedString>	strings;
 		
@@ -139,10 +140,11 @@ public:
 	void			updateDefaultBtn();
 	void			setLabel(const LLStringExplicit& label) { mLabel = label; }
 	std::string		getLabel() const { return mLabel; }
+	void			setHelpTopic(const std::string& help_topic) { mHelpTopic = help_topic; }
+	std::string		getHelpTopic() const { return mHelpTopic; }
 	
 	void			setCtrlsEnabled(BOOL b);
 
-
 	LLHandle<LLPanel>	getHandle() const { return mPanelHandle; }
 
 	const LLCallbackMap::map_t& getFactoryMap() const { return mFactoryMap; }
@@ -243,6 +245,8 @@ protected:
 	EnableCallbackRegistry::ScopedRegistrar mEnableCallbackRegistrar;
 	
 	commit_signal_t mVisibleSignal;		// Called when visibility changes, passes new visibility as LLSD()
+
+	std::string		mHelpTopic;         // the name of this panel's help topic to display in the Help Viewer
 	
 private:
 	LLUIColor		mBgColorAlpha;
@@ -259,7 +263,7 @@ private:
 
 	// for setting the xml filename when building panel in context dependent cases
 	std::string		mXMLFilename;
-	
+
 }; // end class LLPanel
 
 #endif
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index 000e85f78c..d5b67f53b7 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -79,10 +79,10 @@ std::list<std::string> gUntranslated;
 /*static*/ LLUIAudioCallback LLUI::sAudioCallback = NULL;
 /*static*/ LLVector2		LLUI::sGLScaleFactor(1.f, 1.f);
 /*static*/ LLWindow*		LLUI::sWindow = NULL;
-/*static*/ LLHtmlHelp*		LLUI::sHtmlHelp = NULL;
 /*static*/ LLView*			LLUI::sRootView = NULL;
-/*static*/ BOOL				LLUI::sDirty = FALSE;
-/*static*/ LLRect			LLUI::sDirtyRect;
+/*static*/ BOOL                         LLUI::sDirty = FALSE;
+/*static*/ LLRect                       LLUI::sDirtyRect;
+/*static*/ LLHelp*			LLUI::sHelpImpl = NULL;
 /*static*/ std::vector<std::string> LLUI::sXUIPaths;
 /*static*/ LLFrameTimer		LLUI::sMouseIdleTimer;
 
@@ -695,44 +695,6 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
 }
 
 
-void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
-{
-	if (NULL == image)
-	{
-		llwarns << "image == NULL; aborting function" << llendl;
-		return;
-	}
-
-	LLGLSUIDefault gls_ui;
-
-	gGL.pushMatrix();
-	{
-		gGL.translatef((F32)x, (F32)y, 0.f);
-
-		gGL.getTexUnit(0)->bind(image);
-
-		gGL.color4fv(color.mV);
-		
-		gGL.begin(LLRender::QUADS);
-		{
-			gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom);
-			gGL.vertex2i(width, height );
-
-			gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom);
-			gGL.vertex2i(0, height );
-
-			gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop);
-			gGL.vertex2i(0, 0);
-
-			gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop);
-			gGL.vertex2i(width, 0);
-		}
-		gGL.end();
-	}
-	gGL.popMatrix();
-}
-
-
 void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase )
 {
 	phase = fmod(phase, 1.f);
@@ -1592,6 +1554,9 @@ void LLUI::initClass(const settings_map_t& settings,
 	// Button initialization callback for toggle buttons
 	LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.SetFloaterToggle", boost::bind(&LLButton::setFloaterToggle, _1, _2));
 	
+	// Display the help topic for the current context
+	LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.ShowHelp", boost::bind(&LLButton::showHelp, _1, _2));
+
 	// Currently unused, but kept for reference:
 	LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.ToggleFloater", boost::bind(&LLButton::toggleFloaterAndSetToggleState, _1, _2));
 	
@@ -1850,12 +1815,6 @@ LLPointer<LLUIImage> LLUI::getUIImage(const std::string& name)
 		return NULL;
 }
 
-// static 
-void LLUI::setHtmlHelp(LLHtmlHelp* html_help)
-{
-	LLUI::sHtmlHelp = html_help;
-}
-
 LLControlGroup& LLUI::getControlControlGroup (const std::string& controlname)
 {
 	for (settings_map_t::iterator itor = sSettingGroups.begin();
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index fddf8192ad..86cb516500 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -57,13 +57,13 @@
 #include "llfontgl.h"
 
 class LLColor4; 
-class LLHtmlHelp;
 class LLVector3;
 class LLVector2;
 class LLUIImage;
 class LLUUID;
 class LLWindow;
 class LLView;
+class LLHelp;
 
 // UI colors
 extern const LLColor4 UI_VERTEX_COLOR;
@@ -104,8 +104,6 @@ void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LL
 void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
 void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
 void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
-// Flip vertical, used for LLFloaterHTML
-void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
 
 void gl_rect_2d_xor(S32 left, S32 top, S32 right, S32 bottom);
 void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase = 0.f ); 
@@ -203,7 +201,6 @@ public:
 	static void glPointToScreen(S32 gl_x, S32 gl_y, S32 *screen_x, S32 *screen_y);
 	static void screenRectToGL(const LLRect& screen, LLRect *gl);
 	static void glRectToScreen(const LLRect& gl, LLRect *screen);
-	static void setHtmlHelp(LLHtmlHelp* html_help);
 	// Returns the control group containing the control name, or the default group
 	static LLControlGroup& getControlControlGroup (const std::string& controlname);
 	static F32 getMouseIdleTime() { return sMouseIdleTimer.getElapsedTimeF32(); }
@@ -223,8 +220,8 @@ public:
 	static LLUIAudioCallback sAudioCallback;
 	static LLVector2		sGLScaleFactor;
 	static LLWindow*		sWindow;
-	static LLHtmlHelp*		sHtmlHelp;
 	static LLView*			sRootView;
+	static LLHelp*			sHelpImpl;
 private:
 	static LLImageProviderInterface* sImageProvider;
 	static std::vector<std::string> sXUIPaths;
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
index 2cd9c8844e..fe99d9c267 100644
--- a/indra/llui/lluictrl.cpp
+++ b/indra/llui/lluictrl.cpp
@@ -762,6 +762,27 @@ LLUICtrl* LLUICtrl::getParentUICtrl() const
 	return NULL;
 }
 
+bool LLUICtrl::findHelpTopic(std::string& help_topic_out)
+{
+	LLUICtrl* ctrl = this;
+
+	// search back through the control's parents for a panel
+	// with a help_topic string defined
+	while (ctrl)
+	{
+		LLPanel *panel = dynamic_cast<LLPanel *>(ctrl);
+		if (panel && !panel->getHelpTopic().empty())
+		{
+			help_topic_out = panel->getHelpTopic();
+			return true; // success
+		}
+		
+		ctrl = ctrl->getParentUICtrl();
+	}
+
+	return false; // no help topic found
+}
+
 // *TODO: Deprecate; for backwards compatability only:
 boost::signals2::connection LLUICtrl::setCommitCallback( boost::function<void (LLUICtrl*,void*)> cb, void* data)
 {
diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h
index 0ca3acfa1c..c2502732f3 100644
--- a/indra/llui/lluictrl.h
+++ b/indra/llui/lluictrl.h
@@ -223,6 +223,10 @@ public:
 
 	LLUICtrl*		getParentUICtrl() const;
 
+	// return true if help topic found by crawling through parents -
+	// topic then put in help_topic_out
+	bool                    findHelpTopic(std::string& help_topic_out);
+
 	boost::signals2::connection setCommitCallback( const commit_signal_t::slot_type& cb ) { return mCommitSignal.connect(cb); }
 	boost::signals2::connection setValidateCallback( const enable_signal_t::slot_type& cb ) { return mValidateSignal.connect(cb); }
 
diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp
index 3b689b93c0..f3401f91f7 100644
--- a/indra/llui/llurlaction.cpp
+++ b/indra/llui/llurlaction.cpp
@@ -134,4 +134,3 @@ void LLUrlAction::copyLabelToClipboard(std::string url)
 		LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(match.getLabel()));
 	}	
 }
-
-- 
cgit v1.2.3


From f05df68656d2abdc38d86cd6746398fa90eb8614 Mon Sep 17 00:00:00 2001
From: Steven Bennetts <steve@lindenlab.com>
Date: Thu, 1 Oct 2009 17:44:44 +0000
Subject: merge
 https://svn.aws.productengine.com/secondlife/export-from-ll/viewer-2-0@1868
 https://svn.aws.productengine.com/secondlife/pe/stable-2@1876 ->
 viewer-2.0.0-3 * Bugs: EXT-1111 EXT-915 EXT-1131 EXT-1200 EXT-1202 EXT-1201
 EXT-1205 EXT-1212 EXT-1173 EXT-1229 EXT-1218 EXT-1164 EXT-996 EXT-821
 EXT-1030 EXT-1031 EXT-816 * Major Bugs: EXT-1142 (timeout during login due to
 processing group IMs) * Changes: EXT-1216 (minimize message well)

---
 indra/llui/CMakeLists.txt        |  2 ++
 indra/llui/lldockablefloater.cpp | 18 +++++-----
 indra/llui/lldockcontrol.cpp     | 78 ++++++++++++++++++++--------------------
 indra/llui/lldockcontrol.h       | 10 +++---
 indra/llui/llflatlistview.cpp    |  4 +--
 indra/llui/lltexteditor.cpp      | 43 ++++++++++++++++++++++
 indra/llui/lltexteditor.h        | 10 +++++-
 7 files changed, 109 insertions(+), 56 deletions(-)

(limited to 'indra/llui')

diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index d7d411dee6..0a284f0088 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -85,6 +85,7 @@ set(llui_SOURCE_FILES
     lltextbox.cpp
     lltexteditor.cpp
     lltextparser.cpp
+    lltransientfloatermgr.cpp
     lltransutil.cpp
     lltooltip.cpp
     llui.cpp
@@ -171,6 +172,7 @@ set(llui_HEADER_FILES
     lltexteditor.h
     lltextparser.h
     lltooltip.h
+    lltransientfloatermgr.h
     lltransutil.h
     lluicolortable.h
     lluiconstants.h
diff --git a/indra/llui/lldockablefloater.cpp b/indra/llui/lldockablefloater.cpp
index 93d62fd7c2..4525f0a45b 100644
--- a/indra/llui/lldockablefloater.cpp
+++ b/indra/llui/lldockablefloater.cpp
@@ -71,9 +71,9 @@ void LLDockableFloater::resetInstance()
 		if (sInstanceHandle.get() != NULL && sInstanceHandle.get()->isDocked())
 		{
 			sInstanceHandle.get()->setVisible(FALSE);
-			}
+		}
 		sInstanceHandle = getHandle();
-			}
+	}
 }
 
 void LLDockableFloater::setVisible(BOOL visible)
@@ -105,11 +105,11 @@ void LLDockableFloater::setDocked(bool docked, bool pop_on_undock)
 			mDockControl.get()->off();
 		}
 
-	if (!docked && pop_on_undock)
-	{
-		// visually pop up a little bit to emphasize the undocking
-		translate(0, UNDOCK_LEAP_HEIGHT);
-	}
+		if (!docked && pop_on_undock)
+		{
+			// visually pop up a little bit to emphasize the undocking
+			translate(0, UNDOCK_LEAP_HEIGHT);
+		}
 	}
 	else
 	{
@@ -126,8 +126,8 @@ void LLDockableFloater::draw()
 		mDockControl.get()->repositionDockable();
 		if (isDocked())
 		{
-		mDockControl.get()->drawToungue();
-	}
+			mDockControl.get()->drawToungue();
+		}
 	}
 	LLFloater::draw();
 }
diff --git a/indra/llui/lldockcontrol.cpp b/indra/llui/lldockcontrol.cpp
index 0b16b2554c..146c7a969a 100644
--- a/indra/llui/lldockcontrol.cpp
+++ b/indra/llui/lldockcontrol.cpp
@@ -35,7 +35,7 @@
 #include "lldockcontrol.h"
 
 LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
-		const LLUIImagePtr& dockTongue, DocAt dockAt, get_rect_callback_t get_rect_callback) :
+		const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_allowed_rect_callback) :
 		mDockWidget(dockWidget), mDockableFloater(dockableFloater), mDockTongue(dockTongue)		
 {
 	mDockAt = dockAt;
@@ -49,13 +49,13 @@ LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
 		off();
 	}
 
-	if (!(get_rect_callback))
+	if (!(get_allowed_rect_callback))
 	{
-		mGetRectCallback = boost::bind(&LLDockControl::getEnabledRect, this, _1);
+		mGetAllowedRectCallback = boost::bind(&LLDockControl::getAllowedRect, this, _1);
 	}
 	else
 	{
-		mGetRectCallback = get_rect_callback;
+		mGetAllowedRectCallback = get_allowed_rect_callback;
 	}
 
 	if (dockWidget != NULL) 
@@ -77,7 +77,7 @@ void LLDockControl::setDock(LLView* dockWidget)
 	}
 }
 
-void LLDockControl::getEnabledRect(LLRect& rect)
+void LLDockControl::getAllowedRect(LLRect& rect)
 {
 	rect = mDockableFloater->getRootView()->getRect();
 }
@@ -86,7 +86,7 @@ void LLDockControl::repositionDockable()
 {
 	LLRect dockRect = mDockWidget->calcScreenRect();
 	LLRect rootRect;
-	mGetRectCallback(rootRect);
+	mGetAllowedRectCallback(rootRect);
 	static BOOL prev_visibility = !mDockWidget->getVisible();
 
 	// recalculate dockable position if dock position changed, dock visibility changed,
@@ -100,7 +100,7 @@ void LLDockControl::repositionDockable()
 			mDockableFloater->setDocked(false);
 			// force off() since dockable may not have dockControll at this time
 			off();
-	}
+		}
 		else
 		{
 			moveDockable();
@@ -123,10 +123,10 @@ bool LLDockControl::isDockVisible()
 		res = mDockWidget->isInVisibleChain();
 		if (res)
 		{
-	LLRect dockRect = mDockWidget->calcScreenRect();
+			LLRect dockRect = mDockWidget->calcScreenRect();
 
 			switch (mDockAt)
-	{
+			{
 			case TOP:
 				// check is dock inside parent rect
 				LLRect dockParentRect =
@@ -149,25 +149,25 @@ void LLDockControl::moveDockable()
 	// calculate new dockable position
 	LLRect dockRect = mDockWidget->calcScreenRect();
 	LLRect rootRect;
-	mGetRectCallback(rootRect);
+	mGetAllowedRectCallback(rootRect);
 
-		LLRect dockableRect = mDockableFloater->calcScreenRect();
-		S32 x = 0;
-		S32 y = 0;
-		switch (mDockAt)
-		{
-		case TOP:
-			x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
+	LLRect dockableRect = mDockableFloater->calcScreenRect();
+	S32 x = 0;
+	S32 y = 0;
+	switch (mDockAt)
+	{
+	case TOP:
+		x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
 		y = dockRect.mTop + mDockTongue->getHeight() + dockableRect.getHeight();
 		// check is dockable inside root view rect
-			if (x < rootRect.mLeft)
-			{
-				x = rootRect.mLeft;
-			}
-			if (x + dockableRect.getWidth() > rootRect.mRight)
-			{
-				x = rootRect.mRight - dockableRect.getWidth();
-			}
+		if (x < rootRect.mLeft)
+		{
+			x = rootRect.mLeft;
+		}
+		if (x + dockableRect.getWidth() > rootRect.mRight)
+		{
+			x = rootRect.mRight - dockableRect.getWidth();
+		}
 
 
 		// calculate dock tongue position
@@ -185,21 +185,21 @@ void LLDockControl::moveDockable()
 		{
 			mDockTongueX = dockRect.getCenterX() - mDockTongue->getWidth() / 2;
 		}
-			mDockTongueY = dockRect.mTop;
+		mDockTongueY = dockRect.mTop;
 
-			break;
-		}
+		break;
+	}
 
 	// move dockable
-		dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
-				dockableRect.getHeight());
-		LLRect localDocableParentRect;
-		mDockableFloater->getParent()->screenRectToLocal(dockableRect,
-				&localDocableParentRect);
-		mDockableFloater->setRect(localDocableParentRect);
+	dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
+			dockableRect.getHeight());
+	LLRect localDocableParentRect;
+	mDockableFloater->getParent()->screenRectToLocal(dockableRect,
+			&localDocableParentRect);
+	mDockableFloater->setRect(localDocableParentRect);
 
-		mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY,
-				&mDockTongueX, &mDockTongueY);
+	mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY,
+			&mDockTongueX, &mDockTongueY);
 
 }
 
@@ -207,9 +207,9 @@ void LLDockControl::on()
 {
 	 if (isDockVisible())
 	{
-	mDockableFloater->setCanDrag(false);
-	mEnabled = true;
-	mRecalculateDocablePosition = true;
+		mDockableFloater->setCanDrag(false);
+		mEnabled = true;
+		mRecalculateDocablePosition = true;
 	}
 }
 
diff --git a/indra/llui/lldockcontrol.h b/indra/llui/lldockcontrol.h
index 219ddfd092..e8ffcac0ac 100644
--- a/indra/llui/lldockcontrol.h
+++ b/indra/llui/lldockcontrol.h
@@ -52,11 +52,11 @@ public:
 
 public:
 	// callback for a function getting a rect valid for control's position
-	typedef boost::function<void (LLRect& )> get_rect_callback_t;
+	typedef boost::function<void (LLRect& )> get_allowed_rect_callback_t;
 
 	LOG_CLASS(LLDockControl);
 	LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
-			const LLUIImagePtr& dockTongue, DocAt dockAt, get_rect_callback_t get_rect_callback = NULL);
+			const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_rect_callback = NULL);
 	virtual ~LLDockControl();
 
 public:
@@ -67,13 +67,13 @@ public:
 	void drawToungue();
 	bool isDockVisible();
 
-	// gets a rect that bounds possible positions for a dockable control
-	void getEnabledRect(LLRect& rect);
+	// gets a rect that bounds possible positions for a dockable control (EXT-1111)
+	void getAllowedRect(LLRect& rect);
 
 private:
 	virtual void moveDockable();
 private:
-	get_rect_callback_t mGetRectCallback;
+	get_allowed_rect_callback_t mGetAllowedRectCallback;
 	bool mEnabled;
 	bool mRecalculateDocablePosition;
 	DocAt mDockAt;
diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp
index 9fcd386c19..e9df361472 100644
--- a/indra/llui/llflatlistview.cpp
+++ b/indra/llui/llflatlistview.cpp
@@ -39,8 +39,8 @@
 
 static const LLDefaultChildRegistry::Register<LLFlatListView> flat_list_view("flat_list_view");
 
-const LLSD SELECTED_EVENT = LLSD().insert("selected", true);
-const LLSD UNSELECTED_EVENT = LLSD().insert("selected", false);
+const LLSD SELECTED_EVENT	= LLSD().insert("selected", true);
+const LLSD UNSELECTED_EVENT	= LLSD().insert("selected", false);
 
 static const std::string COMMENT_TEXTBOX = "comment_text";
 
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 8d5f277b59..39f09b297f 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -2001,6 +2001,8 @@ void LLTextEditor::cut()
 	deleteSelection( FALSE );
 
 	needsReflow();
+
+	onKeyStroke();
 }
 
 BOOL LLTextEditor::canCopy() const
@@ -2105,6 +2107,8 @@ void LLTextEditor::pasteHelper(bool is_primary)
 	deselect();
 
 	needsReflow();
+
+	onKeyStroke();
 }
 
 
@@ -2492,6 +2496,8 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask )
 		if(text_may_have_changed)
 		{
 			needsReflow();
+
+			onKeyStroke();
 		}
 		needsScroll();
 	}
@@ -2534,6 +2540,8 @@ BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char)
 		deselect();
 
 		needsReflow();
+
+		onKeyStroke();
 	}
 
 	return handled;
@@ -2588,6 +2596,8 @@ void LLTextEditor::doDelete()
 			setCursorPos(mCursorPos + 1);
 			removeChar();
 		}
+
+		onKeyStroke();
 	}
 
 	needsReflow();
@@ -2634,6 +2644,8 @@ void LLTextEditor::undo()
 		setCursorPos(pos);
 
 	needsReflow();
+
+	onKeyStroke();
 }
 
 BOOL LLTextEditor::canRedo() const
@@ -2676,6 +2688,8 @@ void LLTextEditor::redo()
 		setCursorPos(pos);
 
 	needsReflow();
+
+	onKeyStroke();
 }
 
 void LLTextEditor::onFocusReceived()
@@ -4402,6 +4416,8 @@ void LLTextEditor::updatePreedit(const LLWString &preedit_string,
 
 	// Update of the preedit should be caused by some key strokes.
 	mKeystrokeTimer.reset();
+
+	onKeyStroke();
 }
 
 BOOL LLTextEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect *bounds, LLRect *control) const
@@ -4648,3 +4664,30 @@ void LLInlineViewSegment::linkToDocument(LLTextBase* editor)
 		ed->addDocumentChild(mView);
 	}
 }
+
+BOOL LLTextEditor::isDirty() const
+{
+	if(mReadOnly)
+	{
+		return FALSE;
+	}
+
+	if( mPristineCmd )
+	{
+		return ( mPristineCmd == mLastCmd );
+	}
+	else
+	{
+		return ( NULL != mLastCmd );
+	}
+}
+
+void LLTextEditor::setKeystrokeCallback(const keystroke_signal_t::slot_type& callback)
+{
+	mKeystrokeSignal.connect(callback);
+}
+
+void LLTextEditor::onKeyStroke()
+{
+	mKeystrokeSignal(this);
+}
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 68b8f2c3b1..a04261c4be 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -139,6 +139,10 @@ public:
 
 	virtual ~LLTextEditor();
 
+	typedef boost::signals2::signal<void (LLTextEditor* caller)> keystroke_signal_t;
+
+	void	setKeystrokeCallback(const keystroke_signal_t::slot_type& callback);
+
 	void	setParseHighlights(BOOL parsing) {mParseHighlights=parsing;}
 
 	// mousehandler overrides
@@ -169,7 +173,7 @@ public:
 	virtual void	clear();
 	virtual void	setFocus( BOOL b );
 	virtual BOOL	acceptsTextInput() const;
-	virtual BOOL	isDirty() const { return isPristine(); }
+	virtual BOOL	isDirty() const;
 	virtual void 	setValue(const LLSD& value);
 
 	// LLEditMenuHandler interface
@@ -503,6 +507,8 @@ private:
 
 	S32				getFirstVisibleLine() const;
 
+	void			onKeyStroke();
+
 	//
 	// Data
 	//
@@ -568,6 +574,8 @@ private:
 	BOOL			mHandleEditKeysDirectly;  
 
 	LLCoordGL		mLastIMEPosition;		// Last position of the IME editor
+
+	keystroke_signal_t mKeystrokeSignal;
 }; // end class LLTextEditor
 
 
-- 
cgit v1.2.3