From cd467cc34f876920b35d3570f50dbad54ce4a42c Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 3 Oct 2011 16:27:24 -0700
Subject: EXP-1286 : First pass at Drag and Drop of tools. Not functional. Most
 hooks into the LLToolDragAndDrop system in to support the new AT_WIDGET and
 SOURCE_VIEWER

---
 indra/llcommon/llassettype.cpp        |   3 +-
 indra/llcommon/llassettype.h          |   8 +-
 indra/llcommon/stdenums.h             |   5 +-
 indra/llinventory/llinventorytype.cpp |   5 +-
 indra/llinventory/llinventorytype.h   |   3 +-
 indra/llui/CMakeLists.txt             |   5 +-
 indra/llui/llclipboard.cpp            |   6 +
 indra/llui/llclipboard.h              |   9 +-
 indra/llui/lltoolbar.cpp              |  55 +++++
 indra/llui/lltoolbar.h                |  32 ++-
 indra/llui/lltoolbarview.cpp          | 311 ---------------------------
 indra/llui/lltoolbarview.h            |  96 ---------
 indra/newview/CMakeLists.txt          |   2 +
 indra/newview/lltoolbarview.cpp       | 390 ++++++++++++++++++++++++++++++++++
 indra/newview/lltoolbarview.h         | 102 +++++++++
 indra/newview/lltooldraganddrop.cpp   |   5 +
 indra/newview/lltooldraganddrop.h     |   3 +-
 indra/newview/llviewerassettype.cpp   |   4 +-
 18 files changed, 621 insertions(+), 423 deletions(-)
 delete mode 100644 indra/llui/lltoolbarview.cpp
 delete mode 100644 indra/llui/lltoolbarview.h
 create mode 100644 indra/newview/lltoolbarview.cpp
 create mode 100644 indra/newview/lltoolbarview.h

diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp
index 145dddd543..5e566d6c7c 100644
--- a/indra/llcommon/llassettype.cpp
+++ b/indra/llcommon/llassettype.cpp
@@ -93,7 +93,8 @@ LLAssetDictionary::LLAssetDictionary()
 
 	addEntry(LLAssetType::AT_LINK, 				new AssetEntry("LINK",				"link",		"sym link",			false,		false,		true));
 	addEntry(LLAssetType::AT_LINK_FOLDER, 		new AssetEntry("FOLDER_LINK",		"link_f", 	"sym folder link",	false,		false,		true));
-	addEntry(LLAssetType::AT_MESH,              new AssetEntry("MESH",              "mesh",     "mesh",             false, false, false));
+	addEntry(LLAssetType::AT_MESH,              new AssetEntry("MESH",              "mesh",     "mesh",             false,      false,      false));
+	addEntry(LLAssetType::AT_WIDGET,            new AssetEntry("WIDGET",            "widget",   "widget",           false,      false,      false));
 	addEntry(LLAssetType::AT_NONE, 				new AssetEntry("NONE",				"-1",		NULL,		  		FALSE,		FALSE,		FALSE));
 
 };
diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h
index 74ccd00324..d538accbf7 100644
--- a/indra/llcommon/llassettype.h
+++ b/indra/llcommon/llassettype.h
@@ -108,9 +108,13 @@ public:
 
 		AT_LINK_FOLDER = 25,
 			// Inventory folder link
+		
+		AT_WIDGET = 40,
+			// UI Widget: this is *not* an inventory asset type, only a viewer side asset (e.g. button, other ui items...)
+		
 		AT_MESH = 49,
-		    // Mesh data in our proprietary SLM format
-
+			// Mesh data in our proprietary SLM format
+		
 		AT_COUNT = 50,
 
 			// +*********************************************************+
diff --git a/indra/llcommon/stdenums.h b/indra/llcommon/stdenums.h
index 556eff8370..40b3364b36 100644
--- a/indra/llcommon/stdenums.h
+++ b/indra/llcommon/stdenums.h
@@ -49,8 +49,9 @@ enum EDragAndDropType
 	DAD_ANIMATION		= 12,
 	DAD_GESTURE			= 13,
 	DAD_LINK			= 14,
-	DAD_MESH           		= 15,
-	DAD_COUNT			= 16,   // number of types in this enum
+	DAD_MESH            = 15,
+	DAD_WIDGET          = 16,
+	DAD_COUNT           = 17,   // number of types in this enum
 };
 
 // Reasons for drags to be denied.
diff --git a/indra/llinventory/llinventorytype.cpp b/indra/llinventory/llinventorytype.cpp
index d2bba21648..8282d79b67 100644
--- a/indra/llinventory/llinventorytype.cpp
+++ b/indra/llinventory/llinventorytype.cpp
@@ -84,6 +84,7 @@ LLInventoryDictionary::LLInventoryDictionary()
 	addEntry(LLInventoryType::IT_ANIMATION,           new InventoryEntry("animation", "animation",     1, LLAssetType::AT_ANIMATION));  
 	addEntry(LLInventoryType::IT_GESTURE,             new InventoryEntry("gesture",   "gesture",       1, LLAssetType::AT_GESTURE)); 
 	addEntry(LLInventoryType::IT_MESH,                new InventoryEntry("mesh",      "mesh",          1, LLAssetType::AT_MESH));
+	addEntry(LLInventoryType::IT_WIDGET,              new InventoryEntry("widget",    "widget",        1, LLAssetType::AT_WIDGET));
 }
 
 
@@ -134,7 +135,7 @@ DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] =
 	LLInventoryType::IT_NONE,			// 37	AT_NONE
 	LLInventoryType::IT_NONE,			// 38	AT_NONE
 	LLInventoryType::IT_NONE,			// 39	AT_NONE
-	LLInventoryType::IT_NONE,			// 40	AT_NONE
+	LLInventoryType::IT_WIDGET,			// 40	AT_WIDGET
 	LLInventoryType::IT_NONE,			// 41	AT_NONE
 	LLInventoryType::IT_NONE,			// 42	AT_NONE
 	LLInventoryType::IT_NONE,			// 43	AT_NONE
@@ -143,7 +144,7 @@ DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] =
 	LLInventoryType::IT_NONE,			// 46	AT_NONE
 	LLInventoryType::IT_NONE,			// 47	AT_NONE
 	LLInventoryType::IT_NONE,			// 48	AT_NONE
-	LLInventoryType::IT_MESH            // 49	AT_MESH
+	LLInventoryType::IT_MESH,			// 49	AT_MESH
 };
 
 // static
diff --git a/indra/llinventory/llinventorytype.h b/indra/llinventory/llinventorytype.h
index 1a24e351ad..4d1e0db040 100644
--- a/indra/llinventory/llinventorytype.h
+++ b/indra/llinventory/llinventorytype.h
@@ -62,7 +62,8 @@ public:
 		IT_ANIMATION = 19,
 		IT_GESTURE = 20,
 		IT_MESH = 22,
-		IT_COUNT = 23,
+		IT_WIDGET = 23,
+		IT_COUNT = 24,
 
 		IT_NONE = -1
 	};
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 4212812558..dded8ab661 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -5,6 +5,7 @@ project(llui)
 include(00-Common)
 include(LLCommon)
 include(LLImage)
+include(LLInventory)
 include(LLMath)
 include(LLMessage)
 include(LLRender)
@@ -16,6 +17,7 @@ include(LLXUIXML)
 include_directories(
     ${LLCOMMON_INCLUDE_DIRS}
     ${LLIMAGE_INCLUDE_DIRS}
+    ${LLINVENTORY_INCLUDE_DIRS}
     ${LLMATH_INCLUDE_DIRS}
     ${LLMESSAGE_INCLUDE_DIRS}
     ${LLRENDER_INCLUDE_DIRS}
@@ -101,7 +103,6 @@ set(llui_SOURCE_FILES
     lltransutil.cpp
     lltoggleablemenu.cpp
     lltoolbar.cpp
-    lltoolbarview.cpp
     lltooltip.cpp
     llui.cpp
     lluicolortable.cpp
@@ -205,7 +206,6 @@ set(llui_HEADER_FILES
     lltimectrl.h
     lltoggleablemenu.h
     lltoolbar.h
-    lltoolbarview.h
     lltooltip.h
     lltransutil.h
     lluicolortable.h
@@ -251,6 +251,7 @@ target_link_libraries(llui
     ${LLRENDER_LIBRARIES}
     ${LLWINDOW_LIBRARIES}
     ${LLIMAGE_LIBRARIES}
+    ${LLINVENTORY_LIBRARIES}
     ${LLVFS_LIBRARIES}    # ugh, just for LLDir
     ${LLXUIXML_LIBRARIES}
     ${LLXML_LIBRARIES}
diff --git a/indra/llui/llclipboard.cpp b/indra/llui/llclipboard.cpp
index 984c4ec5fb..6910b962a1 100644
--- a/indra/llui/llclipboard.cpp
+++ b/indra/llui/llclipboard.cpp
@@ -40,6 +40,7 @@ LLClipboard gClipboard;
 
 LLClipboard::LLClipboard()
 {
+	mSourceItem = NULL;
 }
 
 
@@ -134,3 +135,8 @@ BOOL LLClipboard::canPastePrimaryString() const
 {
 	return LLView::getWindow()->isPrimaryTextAvailable();
 }
+
+void LLClipboard::setSourceObject(const LLUUID& source_id, LLAssetType::EType type) 
+{
+	mSourceItem = new LLInventoryObject (source_id, LLUUID::null, type, "");
+}
diff --git a/indra/llui/llclipboard.h b/indra/llui/llclipboard.h
index 24cb46c3f4..9371b94284 100644
--- a/indra/llui/llclipboard.h
+++ b/indra/llui/llclipboard.h
@@ -30,6 +30,8 @@
 
 #include "llstring.h"
 #include "lluuid.h"
+#include "stdenums.h"
+#include "llinventory.h"
 
 
 class LLClipboard
@@ -52,9 +54,14 @@ public:
 	BOOL		canPastePrimaryString() const;
 	const LLWString&	getPastePrimaryWString(LLUUID* source_id = NULL);	
 
+	// Support clipboard for object known only by their uuid and asset type
+	void		  setSourceObject(const LLUUID& source_id, LLAssetType::EType type);
+	const LLInventoryObject* getSourceObject() { return mSourceItem; }
+	
 private:
-	LLUUID		mSourceID;
+	LLUUID      mSourceID;
 	LLWString	mString;
+	LLInventoryObject* mSourceItem;
 };
 
 
diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp
index 75c7d91f8a..5300de38a0 100644
--- a/indra/llui/lltoolbar.cpp
+++ b/indra/llui/lltoolbar.cpp
@@ -113,6 +113,7 @@ LLToolBar::LLToolBar(const LLToolBar::Params& p)
 {
 	mButtonParams[LLToolBarEnums::BTNTYPE_ICONS_WITH_TEXT] = p.button_icon_and_text;
 	mButtonParams[LLToolBarEnums::BTNTYPE_ICONS_ONLY] = p.button_icon;
+	mUUID = LLUUID::LLUUID::generateNewID(p.name);
 }
 
 LLToolBar::~LLToolBar()
@@ -534,6 +535,8 @@ void LLToolBar::createButton(const LLCommandId& id)
 		cbParam.function_name = commandp->functionName();
 		cbParam.parameter = commandp->parameter();
 		button->setCommitCallback(cbParam);
+		button->setStartDragCallback(mStartDragItemCallback);
+		button->setHandleDragCallback(mHandleDragItemCallback);
 	}
 
 	mButtons.push_back(button);
@@ -541,3 +544,55 @@ void LLToolBar::createButton(const LLCommandId& id)
 
 	mNeedsLayout = true;
 }
+
+BOOL LLToolBar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+										EDragAndDropType cargo_type,
+										void* cargo_data,
+										EAcceptance* accept,
+										std::string& tooltip_msg)
+{
+	llinfos << "Merov debug : handleDragAndDrop. drop = " << drop << ", tooltip = " << tooltip_msg << llendl;
+	// If we have a drop callback, that means that we can handle the drop
+	BOOL handled = (mHandleDropCallback ? TRUE : FALSE);
+	
+	// if drop, time to call the drop callback to get the operation done
+	if (handled && drop)
+	{
+		handled = mHandleDropCallback(cargo_type,cargo_data,mUUID);
+	}
+	
+	// We accept multi drop by default
+	*accept = (handled ? ACCEPT_YES_MULTI : ACCEPT_NO);
+	
+	// We'll use that flag to change the visual aspect of the target on draw()
+	mDragAndDropTarget = handled;
+	
+	return handled;
+}
+
+LLToolBarButton::LLToolBarButton(const Params& p) : LLButton(p)
+{
+	mUUID = LLUUID::LLUUID::generateNewID(p.name);
+}
+
+BOOL LLToolBarButton::handleHover( S32 x, S32 y, MASK mask )
+{
+//	llinfos << "Merov debug: handleHover, x = " << x << ", y = " << y << ", mouse = " << hasMouseCapture() << llendl;
+	BOOL handled = FALSE;
+		
+	if (hasMouseCapture() && mStartDragItemCallback && mHandleDragItemCallback)
+	{
+		if (!mIsDragged)
+		{
+			mStartDragItemCallback(x,y,mUUID);
+			mIsDragged = true;
+			handled = TRUE;
+		}
+		else 
+		{
+			handled = mHandleDragItemCallback(x,y,mUUID,LLAssetType::AT_WIDGET);
+		}
+	}
+	return handled;
+}
+
diff --git a/indra/llui/lltoolbar.h b/indra/llui/lltoolbar.h
index 03b1756988..6dcf620861 100644
--- a/indra/llui/lltoolbar.h
+++ b/indra/llui/lltoolbar.h
@@ -33,7 +33,11 @@
 #include "lllayoutstack.h"
 #include "lluictrl.h"
 #include "llcommandmanager.h"
+#include "llassettype.h"
 
+typedef boost::function<void (S32 x, S32 y, const LLUUID& uuid)> startdrag_callback_t;
+typedef boost::function<BOOL (S32 x, S32 y, const LLUUID& uuid, LLAssetType::EType type)> handledrag_callback_t;
+typedef boost::function<BOOL (EDragAndDropType type, void* data, const LLUUID& uuid)> handledrop_callback_t;
 
 class LLToolBarButton : public LLButton
 {
@@ -42,7 +46,17 @@ public:
 	{
 	};
 
-	LLToolBarButton(const Params& p) : LLButton(p) {}
+	LLToolBarButton(const Params& p);
+
+	virtual BOOL handleHover( S32 x, S32 y, MASK mask );
+	
+	void setStartDragCallback(startdrag_callback_t cb) { mStartDragItemCallback = cb; }
+	void setHandleDragCallback(handledrag_callback_t cb) { mHandleDragItemCallback = cb; }
+protected:
+	bool						mIsDragged;
+	startdrag_callback_t		mStartDragItemCallback;
+	handledrag_callback_t		mHandleDragItemCallback;
+	LLUUID						mUUID;
 };
 
 
@@ -86,7 +100,6 @@ class LLToolBar
 :	public LLUICtrl
 {
 public:
-
 	struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
 	{
 		Mandatory<LLToolBarEnums::ButtonType>	button_display_mode;
@@ -119,10 +132,18 @@ public:
 	void draw();
 	void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
 	BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
-
+	virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+								   EDragAndDropType cargo_type,
+								   void* cargo_data,
+								   EAcceptance* accept,
+								   std::string& tooltip_msg);
+	
 	bool addCommand(const LLCommandId& commandId);
 	bool hasCommand(const LLCommandId& commandId) const;
 	bool enableCommand(const LLCommandId& commandId, bool enabled);
+	void setStartDragCallback(startdrag_callback_t cb) { mStartDragItemCallback = cb; }
+	void setHandleDragCallback(handledrag_callback_t cb) { mHandleDragItemCallback = cb; }
+	void setHandleDropCallback(handledrop_callback_t cb) { mHandleDropCallback = cb; }
 
 protected:
 	friend class LLUICtrlFactory;
@@ -130,6 +151,10 @@ protected:
 	~LLToolBar();
 
 	void initFromParams(const Params&);
+	startdrag_callback_t		mStartDragItemCallback;
+	handledrag_callback_t		mHandleDragItemCallback;
+	handledrop_callback_t		mHandleDropCallback;
+	bool						mDragAndDropTarget;
 
 public:
 	// Methods used in loading and saving toolbar settings
@@ -147,6 +172,7 @@ private:
 	BOOL isSettingChecked(const LLSD& userdata);
 	void onSettingEnable(const LLSD& userdata);
 
+	LLUUID							mUUID;
 	const bool						mReadOnly;
 
 	std::list<LLToolBarButton*>		mButtons;
diff --git a/indra/llui/lltoolbarview.cpp b/indra/llui/lltoolbarview.cpp
deleted file mode 100644
index 1c6cf3230b..0000000000
--- a/indra/llui/lltoolbarview.cpp
+++ /dev/null
@@ -1,311 +0,0 @@
-/** 
- * @file lltoolbarview.cpp
- * @author Merov Linden
- * @brief User customizable toolbar class
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, 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 "linden_common.h"
-
-#include "lltoolbarview.h"
-
-#include "lldir.h"
-#include "llxmlnode.h"
-#include "lltoolbar.h"
-#include "llbutton.h"
-
-#include <boost/foreach.hpp>
-
-LLToolBarView* gToolBarView = NULL;
-
-static LLDefaultChildRegistry::Register<LLToolBarView> r("toolbar_view");
-
-LLToolBarView::Toolbar::Toolbar()
-:	button_display_mode("button_display_mode"),
-	commands("command")
-{}
-
-LLToolBarView::ToolbarSet::ToolbarSet()
-:	left_toolbar("left_toolbar"),
-	right_toolbar("right_toolbar"),
-	bottom_toolbar("bottom_toolbar")
-{}
-
-
-LLToolBarView::LLToolBarView(const LLToolBarView::Params& p)
-:	LLUICtrl(p),
-	mToolbarLeft(NULL),
-	mToolbarRight(NULL),
-	mToolbarBottom(NULL)
-{
-}
-
-void LLToolBarView::initFromParams(const LLToolBarView::Params& p)
-{
-	// Initialize the base object
-	LLUICtrl::initFromParams(p);
-}
-
-LLToolBarView::~LLToolBarView()
-{
-	saveToolbars();
-}
-
-BOOL LLToolBarView::postBuild()
-{
-	mToolbarLeft   = getChild<LLToolBar>("toolbar_left");
-	mToolbarRight  = getChild<LLToolBar>("toolbar_right");
-	mToolbarBottom = getChild<LLToolBar>("toolbar_bottom");
-
-	return TRUE;
-}
-
-bool LLToolBarView::hasCommand(const LLCommandId& commandId) const
-{
-	bool has_command = false;
-	if (mToolbarLeft && !has_command)
-	{
-		has_command = mToolbarLeft->hasCommand(commandId);
-	}
-	if (mToolbarRight && !has_command)
-	{
-		has_command = mToolbarRight->hasCommand(commandId);
-	}
-	if (mToolbarBottom && !has_command)
-	{
-		has_command = mToolbarBottom->hasCommand(commandId);
-	}
-	return has_command;
-}
-
-bool LLToolBarView::addCommand(const LLCommandId& command, LLToolBar* toolbar)
-{
-	LLCommandManager& mgr = LLCommandManager::instance();
-	if (mgr.getCommand(command))
-	{
-		toolbar->addCommand(command);
-	}
-	else 
-	{
-		llwarns	<< "Toolbars creation : the command " << command.name() << " cannot be found in the command manager" << llendl;
-		return false;
-	}
-	return true;
-}
-
-bool LLToolBarView::loadToolbars(bool force_default)
-{	
-	LLToolBarView::ToolbarSet toolbar_set;
-	
-	// Load the toolbars.xml file
-	std::string toolbar_file = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "toolbars.xml");
-	if (force_default)
-	{
-		toolbar_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "toolbars.xml");
-	}
-	else if (!gDirUtilp->fileExists(toolbar_file)) 
-	{
-		llwarns << "User toolbars def not found -> use default" << llendl;
-		toolbar_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "toolbars.xml");
-	}
-	
-	LLXMLNodePtr root;
-	if(!LLXMLNode::parseFile(toolbar_file, root, NULL))
-	{
-		llerrs << "Unable to load toolbars from file: " << toolbar_file << llendl;
-		return false;
-	}
-	if(!root->hasName("toolbars"))
-	{
-		llwarns << toolbar_file << " is not a valid toolbars definition file" << llendl;
-		return false;
-	}
-	
-	// Parse the toolbar settings
-	LLXUIParser parser;
-	parser.readXUI(root, toolbar_set, toolbar_file);
-	if (!toolbar_set.validateBlock())
-	{
-		llerrs << "Unable to validate toolbars from file: " << toolbar_file << llendl;
-		return false;
-	}
-	
-	// Clear the toolbars now before adding the loaded commands and settings
-	if (mToolbarLeft)
-	{
-		mToolbarLeft->clearCommandsList();
-	}
-	if (mToolbarRight)
-	{
-		mToolbarRight->clearCommandsList();
-	}
-	if (mToolbarBottom)
-	{
-		mToolbarBottom->clearCommandsList();
-	}
-	
-	// Add commands to each toolbar
-	if (toolbar_set.left_toolbar.isProvided() && mToolbarLeft)
-	{
-		if (toolbar_set.left_toolbar.button_display_mode.isProvided())
-		{
-			U32 button_type = toolbar_set.left_toolbar.button_display_mode;
-			mToolbarLeft->setButtonType((LLToolBarEnums::ButtonType)(button_type));
-		}
-		BOOST_FOREACH(LLCommandId::Params& command, toolbar_set.left_toolbar.commands)
-		{
-			addCommand(LLCommandId(command),mToolbarLeft);
-		}
-	}
-	if (toolbar_set.right_toolbar.isProvided() && mToolbarRight)
-	{
-		if (toolbar_set.right_toolbar.button_display_mode.isProvided())
-		{
-			U32 button_type = toolbar_set.right_toolbar.button_display_mode;
-			mToolbarRight->setButtonType((LLToolBarEnums::ButtonType)(button_type));
-		}
-		BOOST_FOREACH(LLCommandId::Params& command, toolbar_set.right_toolbar.commands)
-		{
-			addCommand(LLCommandId(command),mToolbarRight);
-		}
-	}
-	if (toolbar_set.bottom_toolbar.isProvided() && mToolbarBottom)
-	{
-		if (toolbar_set.bottom_toolbar.button_display_mode.isProvided())
-		{
-			U32 button_type = toolbar_set.bottom_toolbar.button_display_mode;
-			mToolbarBottom->setButtonType((LLToolBarEnums::ButtonType)(button_type));
-		}
-		BOOST_FOREACH(LLCommandId::Params& command, toolbar_set.bottom_toolbar.commands)
-		{
-			addCommand(LLCommandId(command),mToolbarBottom);
-		}
-	}
-	return true;
-}
-
-void LLToolBarView::saveToolbars() const
-{
-	// Build the parameter tree from the toolbar data
-	LLToolBarView::ToolbarSet toolbar_set;
-	if (mToolbarLeft)
-	{
-		toolbar_set.left_toolbar.button_display_mode = (int)(mToolbarLeft->getButtonType());
-		addToToolset(mToolbarLeft->getCommandsList(),toolbar_set.left_toolbar);
-	}
-	if (mToolbarRight)
-	{
-		toolbar_set.right_toolbar.button_display_mode = (int)(mToolbarRight->getButtonType());
-		addToToolset(mToolbarRight->getCommandsList(),toolbar_set.right_toolbar);
-	}
-	if (mToolbarBottom)
-	{
-		toolbar_set.bottom_toolbar.button_display_mode = (int)(mToolbarBottom->getButtonType());
-		addToToolset(mToolbarBottom->getCommandsList(),toolbar_set.bottom_toolbar);
-	}
-	
-	// Serialize the parameter tree
-	LLXMLNodePtr output_node = new LLXMLNode("toolbars", false);
-	LLXUIParser parser;
-	parser.writeXUI(output_node, toolbar_set);
-	
-	// Write the resulting XML to file
-	if(!output_node->isNull())
-	{
-		const std::string& filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "toolbars.xml");
-		LLFILE *fp = LLFile::fopen(filename, "w");
-		if (fp != NULL)
-		{
-			LLXMLNode::writeHeaderToFile(fp);
-			output_node->writeToFile(fp);
-			fclose(fp);
-		}
-	}
-}
-
-// Enumerate the commands in command_list and add them as Params to the toolbar
-void LLToolBarView::addToToolset(command_id_list_t& command_list, Toolbar& toolbar) const
-{
-	for (command_id_list_t::const_iterator it = command_list.begin();
-		 it != command_list.end();
-		 ++it)
-	{
-		LLCommandId::Params command;
-		command.name = it->name();		
-		toolbar.commands.add(command);
-	}
-}
-
-void LLToolBarView::draw()
-{
-	static bool debug_print = true;
-	static S32 old_width = 0;
-	static S32 old_height = 0;
-
-	//LLPanel* sizer_left = getChild<LLPanel>("sizer_left");
-	
-	LLRect bottom_rect, left_rect, right_rect;
-
-	if (mToolbarBottom) 
-	{
-		mToolbarBottom->getParent()->reshape(mToolbarBottom->getParent()->getRect().getWidth(), mToolbarBottom->getRect().getHeight());
-		mToolbarBottom->localRectToOtherView(mToolbarBottom->getLocalRect(), &bottom_rect, this);
-	}
-	if (mToolbarLeft)   
-	{
-		mToolbarLeft->getParent()->reshape(mToolbarLeft->getRect().getWidth(), mToolbarLeft->getParent()->getRect().getHeight());
-		mToolbarLeft->localRectToOtherView(mToolbarLeft->getLocalRect(), &left_rect, this);
-	}
-	if (mToolbarRight)  
-	{
-		mToolbarRight->getParent()->reshape(mToolbarRight->getRect().getWidth(), mToolbarRight->getParent()->getRect().getHeight());
-		mToolbarRight->localRectToOtherView(mToolbarRight->getLocalRect(), &right_rect, this);
-	}
-	
-	if ((old_width != getRect().getWidth()) || (old_height != getRect().getHeight()))
-		debug_print = true;
-	if (debug_print)
-	{
-		LLRect ctrl_rect = getRect();
-		llinfos << "Merov debug : draw control rect = " << ctrl_rect.mLeft << ", " << ctrl_rect.mTop << ", " << ctrl_rect.mRight << ", " << ctrl_rect.mBottom << llendl; 
-		llinfos << "Merov debug : draw bottom  rect = " << bottom_rect.mLeft << ", " << bottom_rect.mTop << ", " << bottom_rect.mRight << ", " << bottom_rect.mBottom << llendl; 
-		llinfos << "Merov debug : draw left    rect = " << left_rect.mLeft << ", " << left_rect.mTop << ", " << left_rect.mRight << ", " << left_rect.mBottom << llendl; 
-		llinfos << "Merov debug : draw right   rect = " << right_rect.mLeft << ", " << right_rect.mTop << ", " << right_rect.mRight << ", " << right_rect.mBottom << llendl; 
-		old_width = ctrl_rect.getWidth();
-		old_height = ctrl_rect.getHeight();
-		debug_print = false;
-	}
-	// Debug draw
-	LLColor4 back_color = LLColor4::blue;
-	LLColor4 back_color_vert = LLColor4::red;
-	LLColor4 back_color_hori = LLColor4::yellow;
-	back_color[VALPHA] = 0.5f;
-	back_color_hori[VALPHA] = 0.5f;
-	back_color_vert[VALPHA] = 0.5f;
-	//gl_rect_2d(getLocalRect(), back_color, TRUE);
-	//gl_rect_2d(bottom_rect, back_color_hori, TRUE);
-	//gl_rect_2d(left_rect, back_color_vert, TRUE);
-	//gl_rect_2d(right_rect, back_color_vert, TRUE);
-	
-	LLUICtrl::draw();
-}
diff --git a/indra/llui/lltoolbarview.h b/indra/llui/lltoolbarview.h
deleted file mode 100644
index efe6920db8..0000000000
--- a/indra/llui/lltoolbarview.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/** 
- * @file lltoolbarview.h
- * @author Merov Linden
- * @brief User customizable toolbar class
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLTOOLBARVIEW_H
-#define LL_LLTOOLBARVIEW_H
-
-#include "lluictrl.h"
-#include "lltoolbar.h"
-#include "llcommandmanager.h"
-
-class LLUICtrlFactory;
-
-// Parent of all LLToolBar
-
-class LLToolBarView : public LLUICtrl
-{
-public:
-	// Xui structure of the toolbar panel
-	struct Params : public LLInitParam::Block<Params, LLUICtrl::Params> {};
-
-	// Note: valid children for LLToolBarView are stored in this registry
-	typedef LLDefaultChildRegistry child_registry_t;
-	
-	// Xml structure of the toolbars.xml setting
-	// Those live in a toolbars.xml found in app_settings (for the default) and in
-	// the user folder for the user specific (saved) settings
-	struct Toolbar : public LLInitParam::Block<Toolbar>
-	{
-		Mandatory<U32>                button_display_mode;
-		Multiple<LLCommandId::Params> commands;
-		Toolbar();
-	};
-	struct ToolbarSet : public LLInitParam::Block<ToolbarSet>
-	{
-		Optional<Toolbar>	left_toolbar,
-							right_toolbar,
-							bottom_toolbar;
-		ToolbarSet();
-	};
-
-	// Derived methods
-	virtual ~LLToolBarView();
-	virtual BOOL postBuild();
-	virtual void draw();
-
-	// Toolbar view interface with the rest of the world
-	// Checks if the commandId is being used somewhere in one of the toolbars
-	bool hasCommand(const LLCommandId& commandId) const;
-	// Loads the toolbars from the existing user or default settings
-	bool loadToolbars(bool force_default = false);	// return false if load fails
-	bool loadDefaultToolbars() { return loadToolbars(true); }
-	
-protected:
-	friend class LLUICtrlFactory;
-	LLToolBarView(const Params&);
-
-	void initFromParams(const Params&);
-
-private:
-	void	saveToolbars() const;
-	bool	addCommand(const LLCommandId& commandId, LLToolBar*	toolbar);
-	void	addToToolset(command_id_list_t& command_list, Toolbar& toolbar) const;
-
-	// Pointers to the toolbars handled by the toolbar view
-	LLToolBar*	mToolbarLeft;
-	LLToolBar*	mToolbarRight;
-	LLToolBar*	mToolbarBottom;
-};
-
-extern LLToolBarView* gToolBarView;
-
-#endif  // LL_LLTOOLBARVIEW_H
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index c488d51ba5..ce47cca16f 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -481,6 +481,7 @@ set(viewer_SOURCE_FILES
     lltoastpanel.cpp
     lltoastscripttextbox.cpp
     lltool.cpp
+    lltoolbarview.cpp
     lltoolbrush.cpp
     lltoolcomp.cpp
     lltooldraganddrop.cpp
@@ -1039,6 +1040,7 @@ set(viewer_HEADER_FILES
     lltoastpanel.h
     lltoastscripttextbox.h
     lltool.h
+    lltoolbarview.h
     lltoolbrush.h
     lltoolcomp.h
     lltooldraganddrop.h
diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp
new file mode 100644
index 0000000000..929486a185
--- /dev/null
+++ b/indra/newview/lltoolbarview.cpp
@@ -0,0 +1,390 @@
+/** 
+ * @file lltoolbarview.cpp
+ * @author Merov Linden
+ * @brief User customizable toolbar class
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, 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 "linden_common.h"
+
+#include "lltoolbarview.h"
+
+#include "lldir.h"
+#include "llxmlnode.h"
+#include "lltoolbar.h"
+#include "llbutton.h"
+#include "lltooldraganddrop.h"
+#include "llclipboard.h"
+
+#include <boost/foreach.hpp>
+
+LLToolBarView* gToolBarView = NULL;
+
+static LLDefaultChildRegistry::Register<LLToolBarView> r("toolbar_view");
+bool LLToolBarView::sDragStarted = false;
+
+LLToolBarView::Toolbar::Toolbar()
+:	button_display_mode("button_display_mode"),
+	commands("command")
+{}
+
+LLToolBarView::ToolbarSet::ToolbarSet()
+:	left_toolbar("left_toolbar"),
+	right_toolbar("right_toolbar"),
+	bottom_toolbar("bottom_toolbar")
+{}
+
+
+LLToolBarView::LLToolBarView(const LLToolBarView::Params& p)
+:	LLUICtrl(p),
+	mToolbarLeft(NULL),
+	mToolbarRight(NULL),
+	mToolbarBottom(NULL)
+{
+}
+
+void LLToolBarView::initFromParams(const LLToolBarView::Params& p)
+{
+	// Initialize the base object
+	LLUICtrl::initFromParams(p);
+}
+
+LLToolBarView::~LLToolBarView()
+{
+	saveToolbars();
+}
+
+BOOL LLToolBarView::postBuild()
+{
+	mToolbarLeft   = getChild<LLToolBar>("toolbar_left");
+	mToolbarRight  = getChild<LLToolBar>("toolbar_right");
+	mToolbarBottom = getChild<LLToolBar>("toolbar_bottom");
+
+	mToolbarLeft->setStartDragCallback(boost::bind(LLToolBarView::startDragItem,_1,_2,_3));
+	mToolbarLeft->setHandleDragCallback(boost::bind(LLToolBarView::handleDragItem,_1,_2,_3,_4));
+	mToolbarLeft->setHandleDropCallback(boost::bind(LLToolBarView::handleDrop,_1,_2,_3));
+	
+	mToolbarRight->setStartDragCallback(boost::bind(LLToolBarView::startDragItem,_1,_2,_3));
+	mToolbarRight->setHandleDragCallback(boost::bind(LLToolBarView::handleDragItem,_1,_2,_3,_4));
+	mToolbarRight->setHandleDropCallback(boost::bind(LLToolBarView::handleDrop,_1,_2,_3));
+	
+	mToolbarBottom->setStartDragCallback(boost::bind(LLToolBarView::startDragItem,_1,_2,_3));
+	mToolbarBottom->setHandleDragCallback(boost::bind(LLToolBarView::handleDragItem,_1,_2,_3,_4));
+	mToolbarBottom->setHandleDropCallback(boost::bind(LLToolBarView::handleDrop,_1,_2,_3));
+	
+	return TRUE;
+}
+
+bool LLToolBarView::hasCommand(const LLCommandId& commandId) const
+{
+	bool has_command = false;
+	if (mToolbarLeft && !has_command)
+	{
+		has_command = mToolbarLeft->hasCommand(commandId);
+	}
+	if (mToolbarRight && !has_command)
+	{
+		has_command = mToolbarRight->hasCommand(commandId);
+	}
+	if (mToolbarBottom && !has_command)
+	{
+		has_command = mToolbarBottom->hasCommand(commandId);
+	}
+	return has_command;
+}
+
+bool LLToolBarView::addCommand(const LLCommandId& command, LLToolBar* toolbar)
+{
+	LLCommandManager& mgr = LLCommandManager::instance();
+	if (mgr.getCommand(command))
+	{
+		toolbar->addCommand(command);
+	}
+	else 
+	{
+		llwarns	<< "Toolbars creation : the command " << command.name() << " cannot be found in the command manager" << llendl;
+		return false;
+	}
+	return true;
+}
+
+bool LLToolBarView::loadToolbars(bool force_default)
+{	
+	LLToolBarView::ToolbarSet toolbar_set;
+	
+	// Load the toolbars.xml file
+	std::string toolbar_file = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "toolbars.xml");
+	if (force_default)
+	{
+		toolbar_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "toolbars.xml");
+	}
+	else if (!gDirUtilp->fileExists(toolbar_file)) 
+	{
+		llwarns << "User toolbars def not found -> use default" << llendl;
+		toolbar_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "toolbars.xml");
+	}
+	
+	LLXMLNodePtr root;
+	if(!LLXMLNode::parseFile(toolbar_file, root, NULL))
+	{
+		llerrs << "Unable to load toolbars from file: " << toolbar_file << llendl;
+		return false;
+	}
+	if(!root->hasName("toolbars"))
+	{
+		llwarns << toolbar_file << " is not a valid toolbars definition file" << llendl;
+		return false;
+	}
+	
+	// Parse the toolbar settings
+	LLXUIParser parser;
+	parser.readXUI(root, toolbar_set, toolbar_file);
+	if (!toolbar_set.validateBlock())
+	{
+		llerrs << "Unable to validate toolbars from file: " << toolbar_file << llendl;
+		return false;
+	}
+	
+	// Clear the toolbars now before adding the loaded commands and settings
+	if (mToolbarLeft)
+	{
+		mToolbarLeft->clearCommandsList();
+	}
+	if (mToolbarRight)
+	{
+		mToolbarRight->clearCommandsList();
+	}
+	if (mToolbarBottom)
+	{
+		mToolbarBottom->clearCommandsList();
+	}
+	
+	// Add commands to each toolbar
+	if (toolbar_set.left_toolbar.isProvided() && mToolbarLeft)
+	{
+		if (toolbar_set.left_toolbar.button_display_mode.isProvided())
+		{
+			U32 button_type = toolbar_set.left_toolbar.button_display_mode;
+			mToolbarLeft->setButtonType((LLToolBarEnums::ButtonType)(button_type));
+		}
+		BOOST_FOREACH(LLCommandId::Params& command, toolbar_set.left_toolbar.commands)
+		{
+			addCommand(LLCommandId(command),mToolbarLeft);
+		}
+	}
+	if (toolbar_set.right_toolbar.isProvided() && mToolbarRight)
+	{
+		if (toolbar_set.right_toolbar.button_display_mode.isProvided())
+		{
+			U32 button_type = toolbar_set.right_toolbar.button_display_mode;
+			mToolbarRight->setButtonType((LLToolBarEnums::ButtonType)(button_type));
+		}
+		BOOST_FOREACH(LLCommandId::Params& command, toolbar_set.right_toolbar.commands)
+		{
+			addCommand(LLCommandId(command),mToolbarRight);
+		}
+	}
+	if (toolbar_set.bottom_toolbar.isProvided() && mToolbarBottom)
+	{
+		if (toolbar_set.bottom_toolbar.button_display_mode.isProvided())
+		{
+			U32 button_type = toolbar_set.bottom_toolbar.button_display_mode;
+			mToolbarBottom->setButtonType((LLToolBarEnums::ButtonType)(button_type));
+		}
+		BOOST_FOREACH(LLCommandId::Params& command, toolbar_set.bottom_toolbar.commands)
+		{
+			addCommand(LLCommandId(command),mToolbarBottom);
+		}
+	}
+	return true;
+}
+
+void LLToolBarView::saveToolbars() const
+{
+	// Build the parameter tree from the toolbar data
+	LLToolBarView::ToolbarSet toolbar_set;
+	if (mToolbarLeft)
+	{
+		toolbar_set.left_toolbar.button_display_mode = (int)(mToolbarLeft->getButtonType());
+		addToToolset(mToolbarLeft->getCommandsList(),toolbar_set.left_toolbar);
+	}
+	if (mToolbarRight)
+	{
+		toolbar_set.right_toolbar.button_display_mode = (int)(mToolbarRight->getButtonType());
+		addToToolset(mToolbarRight->getCommandsList(),toolbar_set.right_toolbar);
+	}
+	if (mToolbarBottom)
+	{
+		toolbar_set.bottom_toolbar.button_display_mode = (int)(mToolbarBottom->getButtonType());
+		addToToolset(mToolbarBottom->getCommandsList(),toolbar_set.bottom_toolbar);
+	}
+	
+	// Serialize the parameter tree
+	LLXMLNodePtr output_node = new LLXMLNode("toolbars", false);
+	LLXUIParser parser;
+	parser.writeXUI(output_node, toolbar_set);
+	
+	// Write the resulting XML to file
+	if(!output_node->isNull())
+	{
+		const std::string& filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "toolbars.xml");
+		LLFILE *fp = LLFile::fopen(filename, "w");
+		if (fp != NULL)
+		{
+			LLXMLNode::writeHeaderToFile(fp);
+			output_node->writeToFile(fp);
+			fclose(fp);
+		}
+	}
+}
+
+// Enumerate the commands in command_list and add them as Params to the toolbar
+void LLToolBarView::addToToolset(command_id_list_t& command_list, Toolbar& toolbar) const
+{
+	for (command_id_list_t::const_iterator it = command_list.begin();
+		 it != command_list.end();
+		 ++it)
+	{
+		LLCommandId::Params command;
+		command.name = it->name();		
+		toolbar.commands.add(command);
+	}
+}
+
+void LLToolBarView::draw()
+{
+	static bool debug_print = true;
+	static S32 old_width = 0;
+	static S32 old_height = 0;
+
+	//LLPanel* sizer_left = getChild<LLPanel>("sizer_left");
+	
+	LLRect bottom_rect, left_rect, right_rect;
+
+	if (mToolbarBottom) 
+	{
+		mToolbarBottom->getParent()->reshape(mToolbarBottom->getParent()->getRect().getWidth(), mToolbarBottom->getRect().getHeight());
+		mToolbarBottom->localRectToOtherView(mToolbarBottom->getLocalRect(), &bottom_rect, this);
+	}
+	if (mToolbarLeft)   
+	{
+		mToolbarLeft->getParent()->reshape(mToolbarLeft->getRect().getWidth(), mToolbarLeft->getParent()->getRect().getHeight());
+		mToolbarLeft->localRectToOtherView(mToolbarLeft->getLocalRect(), &left_rect, this);
+	}
+	if (mToolbarRight)  
+	{
+		mToolbarRight->getParent()->reshape(mToolbarRight->getRect().getWidth(), mToolbarRight->getParent()->getRect().getHeight());
+		mToolbarRight->localRectToOtherView(mToolbarRight->getLocalRect(), &right_rect, this);
+	}
+	
+	if ((old_width != getRect().getWidth()) || (old_height != getRect().getHeight()))
+		debug_print = true;
+	if (debug_print)
+	{
+		LLRect ctrl_rect = getRect();
+		llinfos << "Merov debug : draw control rect = " << ctrl_rect.mLeft << ", " << ctrl_rect.mTop << ", " << ctrl_rect.mRight << ", " << ctrl_rect.mBottom << llendl; 
+		llinfos << "Merov debug : draw bottom  rect = " << bottom_rect.mLeft << ", " << bottom_rect.mTop << ", " << bottom_rect.mRight << ", " << bottom_rect.mBottom << llendl; 
+		llinfos << "Merov debug : draw left    rect = " << left_rect.mLeft << ", " << left_rect.mTop << ", " << left_rect.mRight << ", " << left_rect.mBottom << llendl; 
+		llinfos << "Merov debug : draw right   rect = " << right_rect.mLeft << ", " << right_rect.mTop << ", " << right_rect.mRight << ", " << right_rect.mBottom << llendl; 
+		old_width = ctrl_rect.getWidth();
+		old_height = ctrl_rect.getHeight();
+		debug_print = false;
+	}
+	// Debug draw
+	LLColor4 back_color = LLColor4::blue;
+	LLColor4 back_color_vert = LLColor4::red;
+	LLColor4 back_color_hori = LLColor4::yellow;
+	back_color[VALPHA] = 0.5f;
+	back_color_hori[VALPHA] = 0.5f;
+	back_color_vert[VALPHA] = 0.5f;
+	//gl_rect_2d(getLocalRect(), back_color, TRUE);
+	//gl_rect_2d(bottom_rect, back_color_hori, TRUE);
+	//gl_rect_2d(left_rect, back_color_vert, TRUE);
+	//gl_rect_2d(right_rect, back_color_vert, TRUE);
+	
+	LLUICtrl::draw();
+}
+
+
+// ----------------------------------------
+// Drag and Drop hacks (under construction)
+// ----------------------------------------
+
+
+void LLToolBarView::startDragItem( S32 x, S32 y, const LLUUID& uuid)
+{
+	llinfos << "Merov debug: startDragItem() : x = " << x << ", y = " << y << llendl;
+	LLToolDragAndDrop::getInstance()->setDragStart( x, y );
+	sDragStarted = false;
+}
+
+BOOL LLToolBarView::handleDragItem( S32 x, S32 y, const LLUUID& uuid, LLAssetType::EType type)
+{
+//	llinfos << "Merov debug: handleDragItem() : x = " << x << ", y = " << y << ", uuid = " << uuid << llendl;
+	if (LLToolDragAndDrop::getInstance()->isOverThreshold( x, y ))
+	{
+		if (!sDragStarted)
+		{
+			std::vector<EDragAndDropType> types;
+			uuid_vec_t cargo_ids;
+			types.push_back(DAD_WIDGET);
+			cargo_ids.push_back(uuid);
+			gClipboard.setSourceObject(uuid,LLAssetType::AT_WIDGET);
+			LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_VIEWER;
+			LLUUID srcID;
+			llinfos << "Merov debug: handleDragItem() :  beginMultiDrag()" << llendl;
+			LLToolDragAndDrop::getInstance()->beginMultiDrag(types, cargo_ids, src, srcID);
+			sDragStarted = true;
+			return TRUE;
+		}
+		else
+		{
+			MASK mask = 0;
+			return LLToolDragAndDrop::getInstance()->handleHover( x, y, mask );
+		}
+	}
+	return FALSE;
+}
+
+BOOL LLToolBarView::handleDrop( EDragAndDropType cargo_type, void* cargo_data, const LLUUID& toolbar_id)
+{
+	LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data;
+	llinfos << "Merov debug : handleDrop. Drop " << inv_item->getUUID() << " named " << inv_item->getName() << " of type " << inv_item->getType() << " to toolbar " << toolbar_id << " under cargo type " << cargo_type << llendl;
+		
+	LLAssetType::EType type = inv_item->getType();
+	if (type == LLAssetType::AT_WIDGET)
+	{
+		llinfos << "Merov debug : handleDrop. Drop source is a widget -> that's where we'll get code in..." << llendl;
+		// Find out if he command is in one of the toolbar
+		// If it is, pull it out of the toolbar
+		// Now insert it in the toolbar in the correct spot...
+	}
+	else
+	{
+		llinfos << "Merov debug : handleDrop. Drop source is not a widget -> nothing to do" << llendl;
+	}
+	
+	return TRUE;
+}
+
+
diff --git a/indra/newview/lltoolbarview.h b/indra/newview/lltoolbarview.h
new file mode 100644
index 0000000000..4e1b855e3d
--- /dev/null
+++ b/indra/newview/lltoolbarview.h
@@ -0,0 +1,102 @@
+/** 
+ * @file lltoolbarview.h
+ * @author Merov Linden
+ * @brief User customizable toolbar class
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLTOOLBARVIEW_H
+#define LL_LLTOOLBARVIEW_H
+
+#include "lluictrl.h"
+#include "lltoolbar.h"
+#include "llcommandmanager.h"
+
+class LLUICtrlFactory;
+
+// Parent of all LLToolBar
+
+class LLToolBarView : public LLUICtrl
+{
+public:
+	// Xui structure of the toolbar panel
+	struct Params : public LLInitParam::Block<Params, LLUICtrl::Params> {};
+
+	// Note: valid children for LLToolBarView are stored in this registry
+	typedef LLDefaultChildRegistry child_registry_t;
+	
+	// Xml structure of the toolbars.xml setting
+	// Those live in a toolbars.xml found in app_settings (for the default) and in
+	// the user folder for the user specific (saved) settings
+	struct Toolbar : public LLInitParam::Block<Toolbar>
+	{
+		Mandatory<U32>                button_display_mode;
+		Multiple<LLCommandId::Params> commands;
+		Toolbar();
+	};
+	struct ToolbarSet : public LLInitParam::Block<ToolbarSet>
+	{
+		Optional<Toolbar>	left_toolbar,
+							right_toolbar,
+							bottom_toolbar;
+		ToolbarSet();
+	};
+
+	// Derived methods
+	virtual ~LLToolBarView();
+	virtual BOOL postBuild();
+	virtual void draw();
+
+	// Toolbar view interface with the rest of the world
+	// Checks if the commandId is being used somewhere in one of the toolbars
+	bool hasCommand(const LLCommandId& commandId) const;
+	// Loads the toolbars from the existing user or default settings
+	bool loadToolbars(bool force_default = false);	// return false if load fails
+	bool loadDefaultToolbars() { return loadToolbars(true); }
+	
+	static void startDragItem( S32 x, S32 y, const LLUUID& uuid);
+	static BOOL handleDragItem( S32 x, S32 y, const LLUUID& uuid, LLAssetType::EType type);
+	static BOOL handleDrop(	EDragAndDropType cargo_type, void* cargo_data, const LLUUID& folder_id);
+
+protected:
+	friend class LLUICtrlFactory;
+	LLToolBarView(const Params&);
+
+	void initFromParams(const Params&);
+
+private:
+	void	saveToolbars() const;
+	bool	addCommand(const LLCommandId& commandId, LLToolBar*	toolbar);
+	void	addToToolset(command_id_list_t& command_list, Toolbar& toolbar) const;
+
+	// Pointers to the toolbars handled by the toolbar view
+	LLToolBar*	mToolbarLeft;
+	LLToolBar*	mToolbarRight;
+	LLToolBar*	mToolbarBottom;
+	
+	static bool			sDragStarted;
+};
+
+extern LLToolBarView* gToolBarView;
+
+#endif  // LL_LLTOOLBARVIEW_H
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 3e5ce427a8..a8014b8cde 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -57,6 +57,7 @@
 #include "llviewerwindow.h"
 #include "llvoavatarself.h"
 #include "llworld.h"
+#include "llclipboard.h"
 
 // syntactic sugar
 #define callMemberFunction(object,ptrToMember)  ((object).*(ptrToMember))
@@ -2495,6 +2496,10 @@ LLInventoryObject* LLToolDragAndDrop::locateInventory(
 			item = (LLViewerInventoryItem*)preview->getDragItem();
 		}
 	}
+	else if(mSource == SOURCE_VIEWER)
+	{
+		item = (LLViewerInventoryItem*)gClipboard.getSourceObject();
+	}
 	if(item) return item;
 	if(cat) return cat;
 	return NULL;
diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h
index 7b8cce3dc7..92f007a251 100644
--- a/indra/newview/lltooldraganddrop.h
+++ b/indra/newview/lltooldraganddrop.h
@@ -66,7 +66,8 @@ public:
 		SOURCE_AGENT,
 		SOURCE_WORLD,
 		SOURCE_NOTECARD,
-		SOURCE_LIBRARY
+		SOURCE_LIBRARY,
+		SOURCE_VIEWER
 	};
 
 	void beginDrag(EDragAndDropType type,
diff --git a/indra/newview/llviewerassettype.cpp b/indra/newview/llviewerassettype.cpp
index b103f11597..a4b1c2155f 100644
--- a/indra/newview/llviewerassettype.cpp
+++ b/indra/newview/llviewerassettype.cpp
@@ -80,7 +80,9 @@ LLViewerAssetDictionary::LLViewerAssetDictionary()
 	addEntry(LLViewerAssetType::AT_LINK_FOLDER, 		new ViewerAssetEntry(DAD_LINK));
 
 	addEntry(LLViewerAssetType::AT_MESH, 				new ViewerAssetEntry(DAD_MESH));
-
+	
+	addEntry(LLViewerAssetType::AT_WIDGET, 				new ViewerAssetEntry(DAD_WIDGET));
+	
 	addEntry(LLViewerAssetType::AT_NONE, 				new ViewerAssetEntry(DAD_NONE));
 };
 
-- 
cgit v1.2.3