diff options
Diffstat (limited to 'indra/newview')
121 files changed, 3388 insertions, 850 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 367d3de0c9..da9a145423 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -363,6 +363,9 @@ set(viewer_SOURCE_FILES      llpanellogin.cpp      llpanelloginlistener.cpp      llpanelmaininventory.cpp +    llpanelmarketplaceinbox.cpp +    llpanelmarketplaceinboxinventory.cpp +    llpanelmarketplaceoutbox.cpp      llpanelmediasettingsgeneral.cpp      llpanelmediasettingspermissions.cpp      llpanelmediasettingssecurity.cpp @@ -913,6 +916,9 @@ set(viewer_HEADER_FILES      llpanellogin.h      llpanelloginlistener.h      llpanelmaininventory.h +    llpanelmarketplaceinbox.h +    llpanelmarketplaceinboxinventory.h +    llpanelmarketplaceoutbox.h      llpanelmediasettingsgeneral.h      llpanelmediasettingspermissions.h      llpanelmediasettingssecurity.h @@ -1470,7 +1476,7 @@ set(PACKAGE ON CACHE BOOL      "Add a package target that builds an installer package.")  if (WINDOWS) -	set_target_properties(${VIEWER_BINARY_NAME} +    set_target_properties(${VIEWER_BINARY_NAME}          PROPERTIES          # *TODO -reenable this once we get server usage sorted out          #LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /INCLUDE:\"__tcmalloc\"" diff --git a/indra/newview/app_settings/keys.xml b/indra/newview/app_settings/keys.xml index d085475c6c..6e3673e7d9 100644 --- a/indra/newview/app_settings/keys.xml +++ b/indra/newview/app_settings/keys.xml @@ -181,7 +181,7 @@      <binding key="PAD_DIVIDE" mask="CTL_ALT_SHIFT" command="start_gesture"/>    </third_person> -  # Basic editing camera control +  <!-- Basic editing camera control -->    <edit>      <binding key="A" mask="NONE" command="spin_around_cw"/>      <binding key="D" mask="NONE" command="spin_around_ccw"/> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 01daf1ceb2..4b62e376b5 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -4180,6 +4180,28 @@        <key>Value</key>        <real>1.0</real>      </map> +    <key>InventoryDisplayInbox</key> +    <map> +        <key>Comment</key> +        <string>Override received items inventory inbox display</string> +        <key>Persist</key> +        <integer>0</integer> +        <key>Type</key> +        <string>Boolean</string> +        <key>Value</key> +        <integer>0</integer> +    </map> +    <key>InventoryDisplayOutbox</key> +    <map> +        <key>Comment</key> +        <string>Override merchant inventory outbox display</string> +        <key>Persist</key> +        <integer>0</integer> +        <key>Type</key> +        <string>Boolean</string> +        <key>Value</key> +        <integer>0</integer> +    </map>  	<key>InventoryLinking</key>  	<map>  		<key>Comment</key> @@ -4422,6 +4444,17 @@        <key>Value</key>          <real>2.0</real>      </map> +    <key>LastInventoryInboxExpand</key> +    <map> +        <key>Comment</key> +        <string>The last time the received items inbox was expanded.</string> +        <key>Persist</key> +        <integer>1</integer> +        <key>Type</key> +        <string>String</string> +        <key>Value</key> +        <string /> +    </map>      <key>LCDDestination</key>      <map>        <key>Comment</key> @@ -6546,7 +6579,28 @@        <key>Value</key>        <integer>0</integer>      </map> - +   <key>PostFirstLoginIntroURL</key> +   <map> +     <key>Comment</key> +     <string>URL of intro presenatation after first time users first login</string> +     <key>Persist</key> +     <integer>1</integer> +     <key>Type</key> +     <string>String</string> +     <key>Value</key> +     <string></string> +   </map> +  <key>PostFirstLoginIntroViewed</key> +  <map> +    <key>Comment</key> +    <string>Flag indicating if user has seen intro presenatation after first time users first login</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <string>0</string> +  </map>      <key>PrecachingDelay</key>      <map>        <key>Comment</key> @@ -7182,7 +7236,7 @@      </array>    </map> -  <key>RenderAnisotropic</key> +    <key>RenderAnisotropic</key>      <map>        <key>Comment</key>        <string>Render textures using anisotropic filtering</string> @@ -9627,7 +9681,7 @@        <key>Type</key>        <string>Boolean</string>        <key>Value</key> -      <integer>0</integer> +      <integer>1</integer>      </map>      <key>ShowSnapshotButton</key>      <map> @@ -13346,5 +13400,43 @@        <key>Value</key>        <integer>1</integer>      </map> +     <key>WebProfileRect</key> +    <map> +      <key>Comment</key> +      <string>Web profile dimensions</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Rect</string> +      <key>Value</key> +      <array> +        <integer>0</integer> +        <integer>650</integer> +        <integer>490</integer> +        <integer>0</integer> +      </array>     +    </map> +   <key>HelpFloaterOpen</key> +    <map> +      <key>Comment</key> +      <string>Show Help Floater on login?</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map> +     <key>ShowHelpOnFirstLogin</key> +    <map> +      <key>Comment</key> +      <string>Show Help Floater on first login</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>  </map>  </llsd> diff --git a/indra/newview/app_settings/settings_minimal.xml b/indra/newview/app_settings/settings_minimal.xml index 70a75cb4ca..29e52ab054 100644 --- a/indra/newview/app_settings/settings_minimal.xml +++ b/indra/newview/app_settings/settings_minimal.xml @@ -459,5 +459,16 @@        <key>Value</key>        <integer>0</integer>      </map> -  </map> +    <key>ShowHelpOnFirstLogin</key> +    <map> +      <key>Comment</key> +      <string>Show Help Floater on first login</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>1</integer> +    </map> +    </map>  </llsd> diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index d426afb17c..36272f0c7c 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -33,7 +33,6 @@  #include "llagentwearablesfetch.h"  #include "llappearancemgr.h"  #include "llcallbacklist.h" -#include "llfolderview.h"  #include "llgesturemgr.h"  #include "llinventorybridge.h"  #include "llinventoryfunctions.h" @@ -45,6 +44,7 @@  #include "llsidepanelappearance.h"  #include "llsidetray.h"  #include "lltexlayer.h" +#include "lltooldraganddrop.h"  #include "llviewerregion.h"  #include "llvoavatarself.h"  #include "llwearable.h" diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 955f19c82c..8344b08bfb 100755 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -49,6 +49,7 @@  #include "llfloaterpay.h"  #include "llfloaterwebcontent.h"  #include "llfloaterworldmap.h" +#include "llfolderview.h"  #include "llgiveinventory.h"  #include "llinventorybridge.h"  #include "llinventorymodel.h"	// for gInventory.findCategoryUUIDForType @@ -69,6 +70,7 @@  #include "lltrans.h"  #include "llcallingcard.h"  #include "llslurl.h"			// IDEVO +#include "llsidepanelinventory.h"  // static  void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::string& name) @@ -312,7 +314,9 @@ static void on_avatar_name_show_profile(const LLUUID& agent_id, const LLAvatarNa  	std::string url = getProfileURL(username);  	// PROFILES: open in webkit window -	LLWeb::loadWebURLInternal(url, "", agent_id.asString()); +	const bool show_chrome = false; +	static LLCachedControl<LLRect> profile_rect(gSavedSettings, "WebProfileRect"); +	LLFloaterWebContent::create(url, "", agent_id.asString(), show_chrome, profile_rect);  }  // static @@ -444,8 +448,6 @@ void LLAvatarActions::share(const LLUUID& id)  namespace action_give_inventory  { -	typedef std::set<LLUUID> uuid_set_t; -  	/**  	 * Returns a pointer to 'Add More' inventory panel of Edit Outfit SP.  	 */ @@ -475,18 +477,16 @@ namespace action_give_inventory  	/**  	 * Checks My Inventory visibility.  	 */ +  	static bool is_give_inventory_acceptable()  	{ -		LLInventoryPanel* active_panel = get_active_inventory_panel(); -		if (!active_panel) return false; -  		// check selection in the panel -		const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList(); +		const std::set<LLUUID> inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs();  		if (inventory_selected_uuids.empty()) return false; // nothing selected  		bool acceptable = false; -		uuid_set_t::const_iterator it = inventory_selected_uuids.begin(); -		const uuid_set_t::const_iterator it_end = inventory_selected_uuids.end(); +		std::set<LLUUID>::const_iterator it = inventory_selected_uuids.begin(); +		const std::set<LLUUID>::const_iterator it_end = inventory_selected_uuids.end();  		for (; it != it_end; ++it)  		{  			LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it); @@ -529,12 +529,12 @@ namespace action_give_inventory  		}  	} -	static void build_items_string(const uuid_set_t& inventory_selected_uuids , std::string& items_string) +	static void build_items_string(const std::set<LLUUID>& inventory_selected_uuids , std::string& items_string)  	{  		llassert(inventory_selected_uuids.size() > 0);  		const std::string& separator = LLTrans::getString("words_separator"); -		for (uuid_set_t::const_iterator it = inventory_selected_uuids.begin(); ; ) +		for (std::set<LLUUID>::const_iterator it = inventory_selected_uuids.begin(); ; )  		{  			LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it);  			if (NULL != inv_cat) @@ -570,10 +570,7 @@ namespace action_give_inventory  			return;  		} -		LLInventoryPanel* active_panel = get_active_inventory_panel(); -		if (!active_panel) return; - -		const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList(); +		const std::set<LLUUID> inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs();  		if (inventory_selected_uuids.empty())  		{  			return; @@ -590,8 +587,8 @@ namespace action_give_inventory  			// We souldn't open IM session, just calculate session ID for logging purpose. See EXT-6710  			const LLUUID session_id = gIMMgr->computeSessionID(IM_NOTHING_SPECIAL, avatar_uuid); -			uuid_set_t::const_iterator it = inventory_selected_uuids.begin(); -			const uuid_set_t::const_iterator it_end = inventory_selected_uuids.end(); +			std::set<LLUUID>::const_iterator it = inventory_selected_uuids.begin(); +			const std::set<LLUUID>::const_iterator it_end = inventory_selected_uuids.end();  			const std::string& separator = LLTrans::getString("words_separator");  			std::string noncopy_item_names; @@ -654,10 +651,7 @@ namespace action_give_inventory  	{  		llassert(avatar_names.size() == avatar_uuids.size()); -		LLInventoryPanel* active_panel = get_active_inventory_panel(); -		if (!active_panel) return; - -		const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList(); +		const std::set<LLUUID> inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs();  		if (inventory_selected_uuids.empty())  		{  			return; @@ -678,6 +672,33 @@ namespace action_give_inventory  	}  } + + +//static +std::set<LLUUID> LLAvatarActions::getInventorySelectedUUIDs() +{ +	std::set<LLUUID> inventory_selected_uuids; + +	LLInventoryPanel* active_panel = action_give_inventory::get_active_inventory_panel(); +	if (active_panel) +	{ +		inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList(); +	} + +	if (inventory_selected_uuids.empty()) +	{ +		LLSidepanelInventory * sidepanel_inventory = LLSideTray::getInstance()->getPanel<LLSidepanelInventory>("sidepanel_inventory"); +		LLInventoryPanel * inbox = sidepanel_inventory->findChild<LLInventoryPanel>("inventory_inbox"); +		if (inbox) +		{ +			inventory_selected_uuids = inbox->getRootFolder()->getSelectionList(); +		} + +	} + +	return inventory_selected_uuids; +} +  //static  void LLAvatarActions::shareWithAvatars()  { @@ -705,12 +726,12 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL  	// check selection in the panel  	LLFolderView* root_folder = inv_panel->getRootFolder(); -	const uuid_set_t inventory_selected_uuids = root_folder->getSelectionList(); +	const std::set<LLUUID> inventory_selected_uuids = root_folder->getSelectionList();  	if (inventory_selected_uuids.empty()) return false; // nothing selected  	bool can_share = true; -	uuid_set_t::const_iterator it = inventory_selected_uuids.begin(); -	const uuid_set_t::const_iterator it_end = inventory_selected_uuids.end(); +	std::set<LLUUID>::const_iterator it = inventory_selected_uuids.begin(); +	const std::set<LLUUID>::const_iterator it_end = inventory_selected_uuids.end();  	for (; it != it_end; ++it)  	{  		LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it); diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h index 956fed7461..fbfd815f41 100644 --- a/indra/newview/llavataractions.h +++ b/indra/newview/llavataractions.h @@ -36,6 +36,7 @@  class LLInventoryPanel; +  /**   * Friend-related actions (add, remove, offer teleport, etc)   */ @@ -196,6 +197,8 @@ public:  	 */  	static bool canShareSelectedItems(LLInventoryPanel* inv_panel = NULL); +	static std::set<LLUUID> getInventorySelectedUUIDs(); +  private:  	static bool callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response);  	static bool handleRemove(const LLSD& notification, const LLSD& response); diff --git a/indra/newview/llfilteredwearablelist.cpp b/indra/newview/llfilteredwearablelist.cpp index cd5e779c4d..a29ccf2b6d 100644 --- a/indra/newview/llfilteredwearablelist.cpp +++ b/indra/newview/llfilteredwearablelist.cpp @@ -31,6 +31,7 @@  #include "llinventoryfunctions.h"  #include "llinventoryitemslist.h"  #include "llinventorymodel.h" +#include "llviewerinventory.h"  LLFilteredWearableListManager::LLFilteredWearableListManager(LLInventoryItemsList* list, LLInventoryCollectFunctor* collector) diff --git a/indra/newview/llfloaterhelpbrowser.cpp b/indra/newview/llfloaterhelpbrowser.cpp index 627defd006..3012638d44 100644 --- a/indra/newview/llfloaterhelpbrowser.cpp +++ b/indra/newview/llfloaterhelpbrowser.cpp @@ -71,9 +71,18 @@ void LLFloaterHelpBrowser::buildURLHistory()  	}  } +void LLFloaterHelpBrowser::onOpen(const LLSD& key) +{ +	gSavedSettings.setBOOL("HelpFloaterOpen", TRUE); +} +  //virtual  void LLFloaterHelpBrowser::onClose(bool app_quitting)  { +	if (!app_quitting) +	{ +		gSavedSettings.setBOOL("HelpFloaterOpen", FALSE); +	}  	// really really destroy the help browser when it's closed, it'll be recreated.  	destroy(); // really destroy this dialog on closure, it's relatively heavyweight.  } diff --git a/indra/newview/llfloaterhelpbrowser.h b/indra/newview/llfloaterhelpbrowser.h index 2731c81b9c..afe0f4df69 100644 --- a/indra/newview/llfloaterhelpbrowser.h +++ b/indra/newview/llfloaterhelpbrowser.h @@ -42,6 +42,7 @@ class LLFloaterHelpBrowser :  	/*virtual*/ BOOL postBuild();  	/*virtual*/ void onClose(bool app_quitting); +	/*virtual*/ void onOpen(const LLSD& key);  	// inherited from LLViewerMediaObserver  	/*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event); diff --git a/indra/newview/llfloaterwebcontent.cpp b/indra/newview/llfloaterwebcontent.cpp index 058567492b..43eecbf048 100644 --- a/indra/newview/llfloaterwebcontent.cpp +++ b/indra/newview/llfloaterwebcontent.cpp @@ -99,7 +99,7 @@ void LLFloaterWebContent::initializeURLHistory()  }  //static -void LLFloaterWebContent::create( const std::string &url, const std::string& target, const std::string& uuid ) +void LLFloaterWebContent::create( const std::string &url, const std::string& target, const std::string& uuid,  bool show_chrome, const LLRect& preferred_media_size)  {  	lldebugs << "url = " << url << ", target = " << target << ", uuid = " << uuid << llendl; @@ -155,6 +155,20 @@ void LLFloaterWebContent::create( const std::string &url, const std::string& tar  		// tell the browser instance to load the specified URL  		browser->open_media(url, target);  		LLViewerMedia::proxyWindowOpened(target, uuid); + +		browser->getChild<LLLayoutPanel>("status_bar")->setVisible(show_chrome); +		browser->getChild<LLLayoutPanel>("nav_controls")->setVisible(show_chrome); + +		if (!show_chrome) +		{ +			browser->setResizeLimits(100, 100); +		} + +		if (!preferred_media_size.isEmpty()) +		{ +			//ignore x, y for now +			browser->geometryChanged(browser->getRect().mLeft, browser->getRect().mBottom, preferred_media_size.getWidth(), preferred_media_size.getHeight()); +		}  	}  } @@ -210,7 +224,7 @@ void LLFloaterWebContent::geometryChanged(S32 x, S32 y, S32 width, S32 height)  	lldebugs << "geometry change: " << geom << llendl; -	handleReshape(geom,false); +	setShape(geom);  }  void LLFloaterWebContent::open_media(const std::string& web_url, const std::string& target) diff --git a/indra/newview/llfloaterwebcontent.h b/indra/newview/llfloaterwebcontent.h index ecc7e970d8..56b6ef12c8 100644 --- a/indra/newview/llfloaterwebcontent.h +++ b/indra/newview/llfloaterwebcontent.h @@ -46,7 +46,7 @@ public:  	void initializeURLHistory(); -	static void create(const std::string &url, const std::string& target, const std::string& uuid = LLStringUtil::null); +	static void create(const std::string &url, const std::string& target, const std::string& uuid = LLStringUtil::null, bool show_chrome = true, const LLRect& preferred_media_size = LLRect() );  	static void closeRequest(const std::string &uuid);  	static void geometryChanged(const std::string &uuid, S32 x, S32 y, S32 width, S32 height); diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index 3884b94b60..e90b6c1c3d 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -167,13 +167,23 @@ void LLCloseAllFoldersFunctor::doItem(LLFolderViewItem* item)  ///----------------------------------------------------------------------------  /// Class LLFolderView  ///---------------------------------------------------------------------------- +LLFolderView::Params::Params() +:	task_id("task_id"), +	title("title"), +	use_label_suffix("use_label_suffix"), +	allow_multiselect("allow_multiselect", true), +	show_load_status("show_load_status", true), +	use_ellipses("use_ellipses", false) +{ +} +  // Default constructor  LLFolderView::LLFolderView(const Params& p)  :	LLFolderViewFolder(p),  	mScrollContainer( NULL ),  	mPopupMenuHandle(), -	mAllowMultiSelect(TRUE), +	mAllowMultiSelect(p.allow_multiselect),  	mShowFolderHierarchy(FALSE),  	mSourceID(p.task_id),  	mRenameItem( NULL ), @@ -194,10 +204,14 @@ LLFolderView::LLFolderView(const Params& p)  	mDragAndDropThisFrame(FALSE),  	mCallbackRegistrar(NULL),  	mParentPanel(p.parent_panel), -	mUseEllipses(false), +	mUseEllipses(p.use_ellipses),  	mDraggingOverItem(NULL),  	mStatusTextBox(NULL)  { +	mRoot = this; + +	mShowLoadStatus = p.show_load_status(); +  	LLRect rect = p.rect;  	LLRect new_rect(rect.mLeft, rect.mBottom + getRect().getHeight(), rect.mLeft + getRect().getWidth(), rect.mBottom);  	setRect( rect ); @@ -263,6 +277,7 @@ LLFolderView::LLFolderView(const Params& p)  	menu->setBackgroundColor(LLUIColorTable::instance().getColor("MenuPopupBgColor"));  	mPopupMenuHandle = menu->getHandle(); +	mListener->openItem();  }  // Destroys the object @@ -308,15 +323,10 @@ void LLFolderView::setSortOrder(U32 order)  	if (order != mSortOrder)  	{  		LLFastTimer t(FTM_SORT); +		  		mSortOrder = order; -		for (folders_t::iterator iter = mFolders.begin(); -			 iter != mFolders.end();) -		{ -			folders_t::iterator fit = iter++; -			(*fit)->sortBy(order); -		} - +		sortBy(order);  		arrangeAll();  	}  } @@ -342,7 +352,7 @@ BOOL LLFolderView::addFolder( LLFolderViewFolder* folder)  	{  		recursiveIncrementNumDescendantsSelected(folder->numSelected());  	} -	folder->setShowLoadStatus(true); +	folder->setShowLoadStatus(mShowLoadStatus);  	folder->setOrigin(0, 0);  	folder->reshape(getRect().getWidth(), 0);  	folder->setVisible(FALSE); @@ -424,11 +434,7 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_gen  									(folderp->getFiltered(filter_generation) || folderp->hasFilteredDescendants(filter_generation))); // passed filter or has descendants that passed filter  		} -		// Need to call arrange regardless of visibility, since children's visibility -		// might need to be changed too (e.g. even though a folder is invisible, its -		// children also need to be set invisible for state-tracking purposes, e.g. -		// llfolderviewitem::filter). -		// if (folderp->getVisible()) +		if (folderp->getVisible())  		{  			S32 child_height = 0;  			S32 child_width = 0; @@ -764,7 +770,7 @@ void LLFolderView::sanitizeSelection()  		}  		// Don't allow invisible items (such as root folders) to be selected. -		if (item->getHidden()) +		if (item == getRoot())  		{  			items_to_remove.push_back(item);  		} @@ -787,7 +793,7 @@ void LLFolderView::sanitizeSelection()  				parent_folder;  				parent_folder = parent_folder->getParentFolder())  			{ -				if (parent_folder->potentiallyVisible() && !parent_folder->getHidden()) +				if (parent_folder->potentiallyVisible())  				{  					// give initial selection to first ancestor folder that potentially passes the filter  					if (!new_selection) @@ -806,13 +812,7 @@ void LLFolderView::sanitizeSelection()  		}  		else  		{ -			// nothing selected to start with, so pick "My Inventory" as best guess -			new_selection = getItemByID(gInventory.getRootFolderID()); -			// ... except if it's hidden from the UI. -			if (new_selection && new_selection->getHidden()) -			{ -				new_selection = NULL; -			} +			new_selection = NULL;  		}  		if (new_selection) @@ -931,14 +931,15 @@ void LLFolderView::draw()  		if (LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() || mCompletedFilterGeneration < mFilter->getMinRequiredGeneration())  		{  			mStatusText = LLTrans::getString("Searching"); -			//font->renderUTF8(mStatusText, 0, 2, 1, sSearchStatusColor, LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::NORMAL,  LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE );  		}  		else  		{ -			LLStringUtil::format_map_t args; -			args["[SEARCH_TERM]"] = LLURI::escape(getFilter()->getFilterSubStringOrig()); -			mStatusText = LLTrans::getString(getFilter()->getEmptyLookupMessage(), args); -			//font->renderUTF8(mStatusText, 0, 2, 1, sSearchStatusColor, LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::NORMAL,  LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE ); +			if (getFilter()) +			{ +				LLStringUtil::format_map_t args; +				args["[SEARCH_TERM]"] = LLURI::escape(getFilter()->getFilterSubStringOrig()); +				mStatusText = LLTrans::getString(getFilter()->getEmptyLookupMessage(), args); +			}  		}  		mStatusTextBox->setValue(mStatusText);  		mStatusTextBox->setVisible( TRUE ); @@ -962,7 +963,9 @@ void LLFolderView::draw()  	} -	LLFolderViewFolder::draw(); +	// skip over LLFolderViewFolder::draw since we don't want the folder icon, label,  +	// and arrow for the root folder +	LLView::draw();  	mDragAndDropThisFrame = FALSE;  } @@ -1642,11 +1645,7 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )  			LLFolderViewItem* parent_folder = last_selected->getParentFolder();  			if (!last_selected->isOpen() && parent_folder && parent_folder->getParentFolder())  			{ -				// Don't change selectin to hidden folder. See EXT-5328. -				if (!parent_folder->getHidden()) -				{ -					setSelection(parent_folder, FALSE, TRUE); -				} +				setSelection(parent_folder, FALSE, TRUE);  			}  			else  			{ @@ -1911,7 +1910,14 @@ BOOL LLFolderView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,  	// by the folder which is the hierarchy root.  	if (!handled && !hasVisibleChildren())  	{ -		handled = mFolders.front()->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg); +		if (mFolders.empty()) +		{ +			handled = handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg); +		} +		else +		{ +			handled = mFolders.front()->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg); +		}  	}  	if (handled) @@ -1927,8 +1933,11 @@ void LLFolderView::deleteAllChildren()  	closeRenamer();  	LLView::deleteViewByHandle(mPopupMenuHandle);  	mPopupMenuHandle = LLHandle<LLView>(); -	mRenamer = NULL; +	mScrollContainer = NULL;  	mRenameItem = NULL; +	mRenamer = NULL; +	mStatusTextBox = NULL; +	  	clearSelection();  	LLView::deleteAllChildren();  } @@ -2031,7 +2040,7 @@ void LLFolderView::removeItemID(const LLUUID& id)  LLFolderViewItem* LLFolderView::getItemByID(const LLUUID& id)  { -	if (id.isNull()) +	if (id == getListener()->getUUID())  	{  		return this;  	} @@ -2048,7 +2057,7 @@ LLFolderViewItem* LLFolderView::getItemByID(const LLUUID& id)  LLFolderViewFolder* LLFolderView::getFolderByID(const LLUUID& id)  { -	if (id.isNull()) +	if (id == getListener()->getUUID())  	{  		return this;  	} @@ -2173,7 +2182,7 @@ void LLFolderView::doIdle()  	// filter to determine visiblity before arranging  	filterFromRoot(); -	// automatically show matching items, and select first one +	// automatically show matching items, and select first one if we had a selection  	// do this every frame until user puts keyboard focus into the inventory window  	// signaling the end of the automatic update  	// only do this when mNeedsFilter is set, meaning filtered items have @@ -2183,7 +2192,7 @@ void LLFolderView::doIdle()  		LLFastTimer t3(FTM_AUTO_SELECT);  		// select new item only if a filtered item not currently selected  		LLFolderViewItem* selected_itemp = mSelectedItems.empty() ? NULL : mSelectedItems.back(); -		if ((!selected_itemp || !selected_itemp->getFiltered()) && !mAutoSelectOverride) +		if ((selected_itemp && !selected_itemp->getFiltered()) && !mAutoSelectOverride)  		{  			// select first filtered item  			LLSelectFirstFilteredItem filter; @@ -2496,11 +2505,6 @@ BOOL LLFolderView::isFilterModified()  	return mFilter->isNotDefault();  } -BOOL LLFolderView::getAllowMultiSelect() -{ -	return mAllowMultiSelect; -} -  void delete_selected_item(void* user_data)  {  	if(user_data) diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h index 1464a058d8..0b92548fd0 100644 --- a/indra/newview/llfolderview.h +++ b/indra/newview/llfolderview.h @@ -59,22 +59,6 @@ class LLUICtrl;  class LLTextBox;  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLFolderViewFunctor -// -// Simple abstract base class for applying a functor to folders and -// items in a folder view hierarchy. This is suboptimal for algorithms -// that only work folders or only work on items, but I'll worry about -// that later when it's determined to be too slow. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLFolderViewFunctor -{ -public: -	virtual ~LLFolderViewFunctor() {} -	virtual void doFolder(LLFolderViewFolder* folder) = 0; -	virtual void doItem(LLFolderViewItem* item) = 0; -}; - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  // Class LLFolderView  //  // Th LLFolderView represents the root level folder view object. It @@ -89,7 +73,12 @@ public:  		Mandatory<LLPanel*>	    parent_panel;  		Optional<LLUUID>        task_id;  		Optional<std::string>   title; -		Optional<bool>			use_label_suffix; +		Optional<bool>			use_label_suffix, +								allow_multiselect, +								show_load_status, +								use_ellipses; + +		Params();  	};  	LLFolderView(const Params&);  	virtual ~LLFolderView( void ); @@ -102,7 +91,6 @@ public:  	// and resort the items if necessary.  	void setSortOrder(U32 order);  	void setFilterPermMask(PermissionMask filter_perm_mask); -	void setAllowMultiSelect(BOOL allow) { mAllowMultiSelect = allow; }  	typedef boost::signals2::signal<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)> signal_t;  	void setSelectCallback(const signal_t::slot_type& cb) { mSelectSignal.connect(cb); } @@ -117,7 +105,6 @@ public:  	//LLInventoryFilter::EFolderShow getShowFolderState();  	U32 getSortOrder() const;  	BOOL isFilterModified(); -	BOOL getAllowMultiSelect();  	// Close all folders in the view  	void closeAllFolders(); @@ -238,7 +225,6 @@ public:  	void setShowSingleSelection(BOOL show);  	BOOL getShowSingleSelection() { return mShowSingleSelection; }  	F32  getSelectionFadeElapsedTime() { return mMultiSelectionFadeTimer.getElapsedTimeF32(); } -	void setUseEllipses(bool use_ellipses) { mUseEllipses = use_ellipses; }  	bool getUseEllipses() { return mUseEllipses; }  	void addItemID(const LLUUID& id, LLFolderViewItem* itemp); diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index e9d1ad3a9e..6e4f55fb2f 100644 --- a/indra/newview/llfolderviewitem.cpp +++ b/indra/newview/llfolderviewitem.cpp @@ -30,8 +30,10 @@  // viewer includes  #include "llfolderview.h"		// Items depend extensively on LLFolderViews  #include "llfoldervieweventlistener.h" +#include "llviewerfoldertype.h"  #include "llinventorybridge.h"	// for LLItemBridge in LLInventorySort::operator()  #include "llinventoryfilter.h" +#include "llinventoryfunctions.h"  #include "llinventorymodelbackgroundfetch.h"  #include "llpanel.h"  #include "llviewercontrol.h"	// gSavedSettings @@ -130,10 +132,14 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)  	mIconOpen(p.icon_open),  	mIconOverlay(p.icon_overlay),  	mListener(p.listener), -	mHidden(false),  	mShowLoadStatus(false)  { +} + +BOOL LLFolderViewItem::postBuild() +{  	refresh(); +	return TRUE;  }  // Destroys the object @@ -195,7 +201,7 @@ LLFolderViewItem* LLFolderViewItem::getPreviousOpenNode(BOOL include_children)  	LLFolderViewItem* itemp = mParentFolder->getPreviousFromChild( this, include_children );  	// Skip over items that are invisible or are hidden from the UI. -	while(itemp && (!itemp->getVisible() || itemp->getHidden())) +	while(itemp && !itemp->getVisible())  	{  		LLFolderViewItem* next_itemp = itemp->mParentFolder->getPreviousFromChild( itemp, include_children );  		if (itemp == next_itemp)  @@ -351,7 +357,10 @@ void LLFolderViewItem::arrangeAndSet(BOOL set_selection,  									 BOOL take_keyboard_focus)  {  	LLFolderView* root = getRoot(); +	if (getParentFolder()) +	{  	getParentFolder()->requestArrange(); +	}  	if(set_selection)  	{  		setSelectionFromRoot(this, TRUE, take_keyboard_focus); @@ -442,23 +451,20 @@ S32 LLFolderViewItem::arrange( S32* width, S32* height, S32 filter_generation)  S32 LLFolderViewItem::getItemHeight()  { -	if (getHidden()) return 0; -  	return mItemHeight;  }  void LLFolderViewItem::filter( LLInventoryFilter& filter)  {  	const BOOL previous_passed_filter = mPassedFilter; -	const BOOL passed_filter = mListener && filter.check(this); +	const BOOL passed_filter = filter.check(this);  	// If our visibility will change as a result of this filter, then  	// we need to be rearranged in our parent folder  	if (mParentFolder)  	{ -		if (getVisible() != passed_filter) -			mParentFolder->requestArrange(); -		if (passed_filter != previous_passed_filter) +		if (getVisible() != passed_filter +			||	previous_passed_filter != passed_filter )  			mParentFolder->requestArrange();  	} @@ -863,11 +869,6 @@ BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,  void LLFolderViewItem::draw()  { -	if (getHidden()) -	{ -		return; -	} -  	static LLUIColor sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);  	static LLUIColor sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);  	static LLUIColor sHighlightFgColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE); @@ -891,8 +892,8 @@ void LLFolderViewItem::draw()  	// Draw open folder arrow  	//  	const bool up_to_date = mListener && mListener->isUpToDate(); -	const bool possibly_has_children = ((up_to_date && hasVisibleChildren()) || // we fetched our children and some of them have passed the filter... -										(!up_to_date && mListener && mListener->hasChildren())); // ...or we know we have children but haven't fetched them (doesn't obey filter) +	const bool possibly_has_children = ((up_to_date && hasVisibleChildren()) // we fetched our children and some of them have passed the filter... +										|| (!up_to_date && mListener && mListener->hasChildren())); // ...or we know we have children but haven't fetched them (doesn't obey filter)  	if (possibly_has_children)  	{  		LLUIImage* arrow_image = default_params.folder_arrow_image; @@ -1054,8 +1055,11 @@ void LLFolderViewItem::draw()  	{  		root_is_loading = LLInventoryModelBackgroundFetch::instance().libraryFetchInProgress();  	} -	if ((mIsLoading && mTimeSinceRequestStart.getElapsedTimeF32() >= gSavedSettings.getF32("FolderLoadingMessageWaitTime")) || -		(LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() && root_is_loading && (mShowLoadStatus || mHidden))) +	if ((mIsLoading +		&&	mTimeSinceRequestStart.getElapsedTimeF32() >= gSavedSettings.getF32("FolderLoadingMessageWaitTime")) +			||	(LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() +				&&	root_is_loading +				&&	mShowLoadStatus))  	{  		std::string load_string = " ( " + LLTrans::getString("LoadingData") + " ) ";  		font->renderUTF8(load_string, 0, right_x, y, sSearchStatusColor, @@ -1119,7 +1123,8 @@ LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ):  	mLastCalculatedWidth(0),  	mCompletedFilterGeneration(-1),  	mMostFilteredDescendantGeneration(-1), -	mNeedsSort(false) +	mNeedsSort(false), +	mPassedFolderFilter(FALSE)  {  } @@ -1131,6 +1136,17 @@ LLFolderViewFolder::~LLFolderViewFolder( void )  	gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit()  } +void LLFolderViewFolder::setFilteredFolder(bool filtered, S32 filter_generation) +{ +	mPassedFolderFilter = filtered; +	mLastFilterGeneration = filter_generation; +} + +bool LLFolderViewFolder::getFilteredFolder(S32 filter_generation) +{ +	return mPassedFolderFilter && mLastFilterGeneration >= getRoot()->getFilter()->getMinRequiredGeneration(); +} +  // addToFolder() returns TRUE if it succeeds. FALSE otherwise  BOOL LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder, LLFolderView* root)  { @@ -1157,8 +1173,6 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)  	mHasVisibleChildren = hasFilteredDescendants(filter_generation); -	LLInventoryFilter::EFolderShow show_folder_state = getRoot()->getFilter()->getShowFolderState(); -  	// calculate height as a single item (without any children), and reshapes rectangle to match  	LLFolderViewItem::arrange( width, height, filter_generation ); @@ -1190,8 +1204,10 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)  				}  				else  				{ -					folderp->setVisible(show_folder_state == LLInventoryFilter::SHOW_ALL_FOLDERS || // always show folders? -						(folderp->getFiltered(filter_generation) || folderp->hasFilteredDescendants(filter_generation))); // passed filter or has descendants that passed filter +					folderp->setVisible( folderp->getListener() +										&&	(folderp->getFiltered(filter_generation) +											||	(folderp->getFilteredFolder(filter_generation)  +												&& folderp->hasFilteredDescendants(filter_generation)))); // passed filter or has descendants that passed filter  				}  				if (folderp->getVisible()) @@ -1311,7 +1327,9 @@ void LLFolderViewFolder::setCompletedFilterGeneration(S32 generation, BOOL recur  	mMostFilteredDescendantGeneration = llmin(mMostFilteredDescendantGeneration, generation);  	mCompletedFilterGeneration = generation;  	// only aggregate up if we are a lower (older) value -	if (recurse_up && mParentFolder && generation < mParentFolder->getCompletedFilterGeneration()) +	if (recurse_up +		&& mParentFolder +		&& generation < mParentFolder->getCompletedFilterGeneration())  	{  		mParentFolder->setCompletedFilterGeneration(generation, TRUE);  	} @@ -1336,21 +1354,19 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)  	// filter folder itself  	if (getLastFilterGeneration() < filter_generation)  	{ -		if (getLastFilterGeneration() >= must_pass_generation &&		// folder has been compared to a valid precursor filter -			!mPassedFilter)													// and did not pass the filter +		if (getLastFilterGeneration() >= must_pass_generation	// folder has been compared to a valid precursor filter +			&& !mPassedFilter)									// and did not pass the filter  		{  			// go ahead and flag this folder as done  			mLastFilterGeneration = filter_generation;			  		} -		else +		else // filter self only on first pass through  		{ -			// filter self only on first pass through +			// filter against folder rules +			filterFolder(filter); +			// and then item rules  			LLFolderViewItem::filter( filter );  		} -		if (mHidden) -		{ -			setOpen(); -		}  	}  	if (getRoot()->getDebugFilters()) @@ -1377,7 +1393,10 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)  	}  	// when applying a filter, matching folders get their contents downloaded first -	if (filter.isNotDefault() && getFiltered(filter.getMinRequiredGeneration()) && (mListener && !gInventory.isCategoryComplete(mListener->getUUID()))) +	if (filter.isNotDefault() +		&& getFiltered(filter.getMinRequiredGeneration()) +		&&	(mListener +			&& !gInventory.isCategoryComplete(mListener->getUUID())))  	{  		LLInventoryModelBackgroundFetch::instance().start(mListener->getUUID());  	} @@ -1403,6 +1422,7 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)  			if (folder->getFiltered() || folder->hasFilteredDescendants(filter.getMinRequiredGeneration()))  			{  				mMostFilteredDescendantGeneration = filter_generation; +				requestArrange();  			}  			// just skip it, it has already been filtered  			continue; @@ -1415,6 +1435,7 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)  		if (folder->getFiltered() || folder->hasFilteredDescendants(filter_generation))  		{  			mMostFilteredDescendantGeneration = filter_generation; +			requestArrange();  			if (getRoot()->needsAutoSelect() && autoopen_folders)  			{  				folder->setOpenArrangeRecursively(TRUE); @@ -1436,6 +1457,7 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)  			if (item->getFiltered())  			{  				mMostFilteredDescendantGeneration = filter_generation; +				requestArrange();  			}  			continue;  		} @@ -1454,6 +1476,7 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)  		if (item->getFiltered(filter.getMinRequiredGeneration()))  		{  			mMostFilteredDescendantGeneration = filter_generation; +			requestArrange();  		}  	} @@ -1467,6 +1490,31 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)  	}  } +void LLFolderViewFolder::filterFolder(LLInventoryFilter& filter) +{ +	const BOOL previous_passed_filter = mPassedFolderFilter; +	const BOOL passed_filter = filter.checkFolder(this); + +	// If our visibility will change as a result of this filter, then +	// we need to be rearranged in our parent folder +	if (mParentFolder) +	{ +		if (getVisible() != passed_filter +			|| previous_passed_filter != passed_filter ) +		{ +			mParentFolder->requestArrange(); +		} +	} + +	setFilteredFolder(passed_filter, filter.getCurrentGeneration()); +	filter.decrementFilterCount(); + +	if (getRoot()->getDebugFilters()) +	{ +		mStatusText = llformat("%d", mLastFilterGeneration); +	} +} +  void LLFolderViewFolder::setFiltered(BOOL filtered, S32 filter_generation)  {  	// if this folder is now filtered, but wasn't before @@ -1488,6 +1536,23 @@ void LLFolderViewFolder::dirtyFilter()  	LLFolderViewItem::dirtyFilter();  } +BOOL LLFolderViewFolder::getFiltered()  +{  +	return getFilteredFolder(getRoot()->getFilter()->getMinRequiredGeneration())  +		&& LLFolderViewItem::getFiltered();  +} + +BOOL LLFolderViewFolder::getFiltered(S32 filter_generation)  +{ +	return getFilteredFolder(filter_generation) && LLFolderViewItem::getFiltered(filter_generation); +} + +BOOL LLFolderViewFolder::hasFilteredDescendants(S32 filter_generation) +{  +	return mMostFilteredDescendantGeneration >= filter_generation;  +} + +  BOOL LLFolderViewFolder::hasFilteredDescendants()  {  	return mMostFilteredDescendantGeneration >= getRoot()->getFilter()->getCurrentGeneration(); @@ -1743,7 +1808,7 @@ void LLFolderViewFolder::destroyView()  		folderp->destroyView(); // removes entry from mFolders  	} -	deleteAllChildren(); +	//deleteAllChildren();  	if (mParentFolder)  	{ @@ -1843,8 +1908,12 @@ void LLFolderViewFolder::sortBy(U32 order)  		(*fit)->sortBy(order);  	} -	mFolders.sort(mSortFunction); -	mItems.sort(mSortFunction); +	// Don't sort the topmost folders (My Inventory and Library) +	if (mListener->getUUID().notNull()) +	{ +		mFolders.sort(mSortFunction); +		mItems.sort(mSortFunction); +	}  	if (order & LLInventoryFilter::SO_DATE)  	{ @@ -1981,6 +2050,13 @@ BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)  	item->dirtyFilter();  	requestArrange();  	requestSort(); +	LLFolderViewFolder* parentp = getParentFolder(); +	while (parentp && parentp->mSortFunction.isByDate()) +	{ +		// parent folder doesn't have a time stamp yet, so get it from us +		parentp->requestSort(); +		parentp = parentp->getParentFolder(); +	}  	return TRUE;  } @@ -2000,6 +2076,13 @@ BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)  	// rearrange all descendants too, as our indentation level might have changed  	folder->requestArrange(TRUE);  	requestSort(); +	LLFolderViewFolder* parentp = getParentFolder(); +	while (parentp && !parentp->mSortFunction.isByDate()) +	{ +		// parent folder doesn't have a time stamp yet, so get it from us +		parentp->requestSort(); +		parentp = parentp->getParentFolder(); +	}  	return TRUE;  } @@ -2059,7 +2142,9 @@ void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType r  			(*fit)->setOpenArrangeRecursively(openitem, RECURSE_DOWN);		/* Flawfinder: ignore */  		}  	} -	if (mParentFolder && (recurse == RECURSE_UP || recurse == RECURSE_UP_DOWN)) +	if (mParentFolder +		&&	(recurse == RECURSE_UP +			|| recurse == RECURSE_UP_DOWN))  	{  		mParentFolder->setOpenArrangeRecursively(openitem, RECURSE_UP);  	} @@ -2301,13 +2386,16 @@ void LLFolderViewFolder::draw()  	bool possibly_has_children = false;  	bool up_to_date = mListener && mListener->isUpToDate(); -	if(!up_to_date && mListener && mListener->hasChildren()) // we know we have children but haven't fetched them (doesn't obey filter) +	if(!up_to_date +		&& mListener->hasChildren()) // we know we have children but haven't fetched them (doesn't obey filter)  	{  		possibly_has_children = true;  	} -	BOOL loading = ( mIsOpen && possibly_has_children && !up_to_date ); +	BOOL loading = (mIsOpen +					&& possibly_has_children +					&& !up_to_date );  	if ( loading && !mIsLoading )  	{ @@ -2330,6 +2418,41 @@ void LLFolderViewFolder::draw()  time_t LLFolderViewFolder::getCreationDate() const  { +	// folders have no creation date try to create one from an item somewhere in our folder hierarchy +	if (!mCreationDate) +	{ +		for (items_t::const_iterator iit = mItems.begin(); +			 iit != mItems.end(); ++iit) +		{ +			LLFolderViewItem* itemp = (*iit); + +			const time_t item_creation_date = itemp->getCreationDate(); +			 +			if (item_creation_date) +			{ +				mCreationDate = item_creation_date; +				break; +			} +		} +		 +		if (!mCreationDate) +		{ +			for (folders_t::const_iterator fit = mFolders.begin(); +				 fit != mFolders.end(); ++fit) +			{ +				LLFolderViewFolder* folderp = (*fit); +				 +				const time_t folder_creation_date = folderp->getCreationDate(); +				 +				if (folder_creation_date) +				{ +					mCreationDate = folder_creation_date; +					break; +				} +			} +		} +	} +  	return llmax<time_t>(mCreationDate, mSubtreeCreationDate);  } @@ -2573,7 +2696,8 @@ bool LLInventorySort::operator()(const LLFolderViewItem* const& a, const LLFolde  {  	// ignore sort order for landmarks in the Favorites folder.  	// they should be always sorted as in Favorites bar. See EXT-719 -	if (a->getSortGroup() == SG_ITEM && b->getSortGroup() == SG_ITEM +	if (a->getSortGroup() == SG_ITEM +		&& b->getSortGroup() == SG_ITEM  		&& a->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK  		&& b->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK)  	{ diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h index fc941510ab..e2f94a2b63 100644 --- a/indra/newview/llfolderviewitem.h +++ b/indra/newview/llfolderviewitem.h @@ -66,6 +66,7 @@ public:  	// Returns true if order has changed  	bool updateSort(U32 order);  	U32 getSort() { return mSortOrder; } +	bool isByDate() { return mByDate; }  	bool operator()(const LLFolderViewItem* const& a, const LLFolderViewItem* const& b);  private: @@ -94,7 +95,7 @@ public:  		Optional<LLUIImage*>					icon_open;  // used for folders  		Optional<LLUIImage*>					icon_overlay;  // for links  		Optional<LLFolderView*>					root; -		Optional<LLFolderViewEventListener*>	listener; +		Mandatory<LLFolderViewEventListener*>	listener;  		Optional<LLUIImage*>					folder_arrow_image;  		Optional<S32>							folder_indentation; // pixels @@ -135,7 +136,7 @@ protected:  	std::string					mSearchableLabel;  	S32							mLabelWidth;  	bool						mLabelWidthDirty; -	time_t						mCreationDate; +	mutable time_t				mCreationDate;  	LLFolderViewFolder*			mParentFolder;  	LLFolderViewEventListener*	mListener;  	BOOL						mIsCurSelection; @@ -157,7 +158,6 @@ protected:  	BOOL						mDragAndDropTarget;  	BOOL                        mIsLoading;  	LLTimer                     mTimeSinceRequestStart; -	bool						mHidden;  	bool						mShowLoadStatus;  	// helper function to change the selection from the root. @@ -167,13 +167,15 @@ protected:  	void extendSelectionFromRoot(LLFolderViewItem* selection);  	// this is an internal method used for adding items to folders. A -	// no-op at this leve, but reimplemented in derived classes. +	// no-op at this level, but reimplemented in derived classes.  	virtual BOOL addItem(LLFolderViewItem*) { return FALSE; }  	virtual BOOL addFolder(LLFolderViewFolder*) { return FALSE; }  	static LLFontGL* getLabelFontForStyle(U8 style);  public: +	BOOL postBuild(); +  	// This function clears the currently selected item, and records  	// the specified selected item appropriately for display and use  	// in the UI. If open is TRUE, then folders are opened up along @@ -202,11 +204,6 @@ public:  	virtual S32 arrange( S32* width, S32* height, S32 filter_generation );  	virtual S32 getItemHeight(); -	// Hide the folder from the UI, such as if you want to hide the root -	// folder in an inventory panel. -	void setHidden(bool hidden) { mHidden = hidden; } -	bool getHidden() const { return mHidden; } -  	// applies filters to control visibility of inventory items  	virtual void filter( LLInventoryFilter& filter); @@ -366,6 +363,9 @@ public:  		UNKNOWN, TRASH, NOT_TRASH  	} ETrash; +	typedef std::list<LLFolderViewItem*> items_t; +	typedef std::list<LLFolderViewFolder*> folders_t; +  private:  	S32		mNumDescendantsSelected; @@ -374,8 +374,6 @@ public:		// Accessed needed by LLFolderViewItem  	S32 numSelected(void) const { return mNumDescendantsSelected + (isSelected() ? 1 : 0); }  protected: -	typedef std::list<LLFolderViewItem*> items_t; -	typedef std::list<LLFolderViewFolder*> folders_t;  	items_t mItems;  	folders_t mFolders;  	LLInventorySort	mSortFunction; @@ -392,6 +390,8 @@ protected:  	S32			mCompletedFilterGeneration;  	S32			mMostFilteredDescendantGeneration;  	bool		mNeedsSort; +	bool		mPassedFolderFilter; +  public:  	typedef enum e_recurse_type  	{ @@ -425,13 +425,21 @@ public:  	virtual void	setCompletedFilterGeneration(S32 generation, BOOL recurse_up);  	virtual S32		getCompletedFilterGeneration() { return mCompletedFilterGeneration; } -	BOOL hasFilteredDescendants(S32 filter_generation) { return mMostFilteredDescendantGeneration >= filter_generation; } +	BOOL hasFilteredDescendants(S32 filter_generation);  	BOOL hasFilteredDescendants();  	// applies filters to control visibility of inventory items  	virtual void filter( LLInventoryFilter& filter);  	virtual void setFiltered(BOOL filtered, S32 filter_generation); +	virtual BOOL getFiltered(); +	virtual BOOL getFiltered(S32 filter_generation); +  	virtual void dirtyFilter(); +	 +	// folder-specific filtering (filter status propagates top down instead of bottom up) +	void filterFolder(LLInventoryFilter& filter); +	void setFilteredFolder(bool filtered, S32 filter_generation); +	bool getFilteredFolder(S32 filter_generation);  	// Passes selection information on to children and record  	// selection information if necessary. @@ -537,6 +545,10 @@ public:  	time_t getCreationDate() const;  	bool isTrash() const;  	S32 getNumSelectedDescendants(void) const { return mNumDescendantsSelected; } + +	folders_t::const_iterator getFoldersBegin() const { return mFolders.begin(); } +	folders_t::const_iterator getFoldersEnd() const { return mFolders.end(); } +	folders_t::size_type getFoldersCount() const { return mFolders.size(); }  };  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 86c8a1a9b5..75d4c4e80d 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -40,6 +40,7 @@  #include "llfloateropenobject.h"  #include "llfloaterreg.h"  #include "llfloaterworldmap.h" +#include "llfolderview.h"  #include "llfriendcard.h"  #include "llgesturemgr.h"  #include "llgiveinventory.h"  @@ -571,8 +572,8 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,  		}  	} -	// Don't allow items to be pasted directly into the COF. -	if (!isCOFFolder()) +	// Don't allow items to be pasted directly into the COF or the inbox +	if (!isCOFFolder() && !isInboxFolder())  	{  		items.push_back(std::string("Paste"));  	} @@ -781,6 +782,18 @@ BOOL LLInvFVBridge::isCOFFolder() const  	return LLAppearanceMgr::instance().getIsInCOF(mUUID);  } +BOOL LLInvFVBridge::isInboxFolder() const +{ +	const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false); +	 +	if (inbox_id.isNull()) +	{ +		return FALSE; +	} +	 +	return gInventory.isObjectDescendentOf(mUUID, inbox_id); +} +  BOOL LLInvFVBridge::isItemPermissive() const  {  	return FALSE; @@ -1786,6 +1799,10 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,  			}  			else  			{ +				if (gInventory.isObjectDescendentOf(inv_cat->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false))) +				{ +					set_dad_inbox_object(inv_cat->getUUID()); +				}  				// Reparent the folder and restamp children if it's moving  				// into trash. @@ -2525,6 +2542,7 @@ void LLFolderBridge::folderOptionsMenu()  			{  				mItems.push_back(std::string("Add To Outfit"));  			} +  			mItems.push_back(std::string("Replace Outfit"));  		}  		if (is_ensemble) @@ -2614,15 +2632,17 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)  		// Not sure what the right thing is to do here.  		if (!isCOFFolder() && cat && (cat->getPreferredType() != LLFolderType::FT_OUTFIT))  		{ -			// Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694. -			if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat)) -				mItems.push_back(std::string("New Folder")); -			mItems.push_back(std::string("New Script")); -			mItems.push_back(std::string("New Note")); -			mItems.push_back(std::string("New Gesture")); -			mItems.push_back(std::string("New Clothes")); -			mItems.push_back(std::string("New Body Parts")); - +			if (!isInboxFolder()) // don't allow creation in inbox +			{ +				// Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694. +				if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat)) +					mItems.push_back(std::string("New Folder")); +				mItems.push_back(std::string("New Script")); +				mItems.push_back(std::string("New Note")); +				mItems.push_back(std::string("New Gesture")); +				mItems.push_back(std::string("New Clothes")); +				mItems.push_back(std::string("New Body Parts")); +			}  #if SUPPORT_ENSEMBLES  			// Changing folder types is an unfinished unsupported feature  			// and can lead to unexpected behavior if enabled. @@ -3161,6 +3181,12 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,  			// (move the item, restamp if into trash)  			else  			{ +				// set up observer to select item once drag and drop from inbox is complete  +				if (gInventory.isObjectDescendentOf(inv_item->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false))) +				{ +					set_dad_inbox_object(inv_item->getUUID()); +				} +  				LLInvFVBridge::changeItemParent(  					model,  					(LLViewerInventoryItem*)inv_item, diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 1e849c8812..15629c0c75 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -139,6 +139,7 @@ protected:  	BOOL isAgentInventory() const; // false if lost or in the inventory library  	BOOL isCOFFolder() const; // true if COF or descendent of +	BOOL isInboxFolder() const; // true if COF or descendent of marketplace inbox  	virtual BOOL isItemPermissive() const;  	static void changeItemParent(LLInventoryModel* model,  								 LLViewerInventoryItem* item, @@ -584,6 +585,9 @@ protected:  }; +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Recent Inventory Panel related classes +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  // Overridden version of the Inventory-Folder-View-Bridge for Folders  class LLRecentItemsFolderBridge : public LLFolderBridge diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index dee15a1efd..d6278a5fda 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -107,6 +107,32 @@ BOOL LLInventoryFilter::check(const LLFolderViewItem* item)  	return passed;  } +bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder) +{ +	// we're showing all folders, overriding filter +	if (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS) +	{ +		return true; +	} + +	const LLFolderViewEventListener* listener = folder->getListener(); +	const LLUUID folder_id = listener->getUUID(); + +	if (mFilterOps.mFilterTypes & FILTERTYPE_CATEGORY) +	{ +		// Can only filter categories for items in your inventory +		// (e.g. versus in-world object contents). +		const LLViewerInventoryCategory *cat = gInventory.getCategory(folder_id); +		if (!cat) +			return false; +		LLFolderType::EType cat_type = cat->getPreferredType(); +		if (cat_type != LLFolderType::FT_NONE && (1LL << cat_type & mFilterOps.mFilterCategoryTypes) == U64(0)) +			return false; +	} + +	return true; +} +  BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) const  {  	const LLFolderViewEventListener* listener = item->getListener(); @@ -137,30 +163,6 @@ BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con  		}  	} -	 -	//////////////////////////////////////////////////////////////////////////////// -	// FILTERTYPE_CATEGORY -	// Pass if this item is a category of the filter type, or -	// if its parent is a category of the filter type. -	if (filterTypes & FILTERTYPE_CATEGORY) -	{ -		// Can only filter categories for items in your inventory  -		// (e.g. versus in-world object contents). -		if (!object) return FALSE; - -		LLUUID cat_id = object_id; -		if (listener->getInventoryType() != LLInventoryType::IT_CATEGORY) -		{ -			cat_id = object->getParentUUID(); -		} -		const LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id); -		if (!cat)  -			return FALSE; -		if ((1LL << cat->getPreferredType() & mFilterOps.mFilterCategoryTypes) == U64(0)) -			return FALSE; -	} - -  	////////////////////////////////////////////////////////////////////////////////  	// FILTERTYPE_UUID  	// Pass if this item is the target UUID or if it links to the target UUID @@ -172,7 +174,6 @@ BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con  			return FALSE;  	} -  	////////////////////////////////////////////////////////////////////////////////  	// FILTERTYPE_DATE  	// Pass if this item is within the date range. @@ -293,15 +294,15 @@ BOOL LLInventoryFilter::isModifiedAndClear()  	return ret;  } -void LLInventoryFilter::setFilterObjectTypes(U64 types) +void LLInventoryFilter::updateFilterTypes(U64 types, U64& current_types)  { -	if (mFilterOps.mFilterObjectTypes != types) +	if (current_types != types)  	{  		// keep current items only if no type bits getting turned off -		BOOL fewer_bits_set = (mFilterOps.mFilterObjectTypes & ~types); -		BOOL more_bits_set = (~mFilterOps.mFilterObjectTypes & types); +		bool fewer_bits_set = (current_types & ~types) != 0; +		bool more_bits_set = (~current_types & types) != 0; -		mFilterOps.mFilterObjectTypes = types; +		current_types = types;  		if (more_bits_set && fewer_bits_set)  		{  			// neither less or more restrive, both simultaneously @@ -318,62 +319,23 @@ void LLInventoryFilter::setFilterObjectTypes(U64 types)  			setModified(FILTER_MORE_RESTRICTIVE);  		}  	} +} + +void LLInventoryFilter::setFilterObjectTypes(U64 types) +{ +	updateFilterTypes(types, mFilterOps.mFilterObjectTypes);  	mFilterOps.mFilterTypes |= FILTERTYPE_OBJECT;  }  void LLInventoryFilter::setFilterCategoryTypes(U64 types)  { -	if (mFilterOps.mFilterCategoryTypes != types) -	{ -		// keep current items only if no type bits getting turned off -		BOOL fewer_bits_set = (mFilterOps.mFilterCategoryTypes & ~types); -		BOOL more_bits_set = (~mFilterOps.mFilterCategoryTypes & types); - -		mFilterOps.mFilterCategoryTypes = types; -		if (more_bits_set && fewer_bits_set) -		{ -			// neither less or more restrive, both simultaneously -			// so we need to filter from scratch -			setModified(FILTER_RESTART); -		} -		else if (more_bits_set) -		{ -			// target is only one of all requested types so more type bits == less restrictive -			setModified(FILTER_LESS_RESTRICTIVE); -		} -		else if (fewer_bits_set) -		{ -			setModified(FILTER_MORE_RESTRICTIVE); -		} -	} -	mFilterOps.mFilterTypes |= FILTERTYPE_OBJECT; +	updateFilterTypes(types, mFilterOps.mFilterCategoryTypes); +	mFilterOps.mFilterTypes |= FILTERTYPE_CATEGORY;  }  void LLInventoryFilter::setFilterWearableTypes(U64 types)  { -	if (mFilterOps.mFilterWearableTypes != types) -	{ -		// keep current items only if no type bits getting turned off -		BOOL fewer_bits_set = (mFilterOps.mFilterWearableTypes & ~types); -		BOOL more_bits_set = (~mFilterOps.mFilterWearableTypes & types); - -		mFilterOps.mFilterWearableTypes = types; -		if (more_bits_set && fewer_bits_set) -		{ -			// neither less or more restrive, both simultaneously -			// so we need to filter from scratch -			setModified(FILTER_RESTART); -		} -		else if (more_bits_set) -		{ -			// target is only one of all requested types so more type bits == less restrictive -			setModified(FILTER_LESS_RESTRICTIVE); -		} -		else if (fewer_bits_set) -		{ -			setModified(FILTER_MORE_RESTRICTIVE); -		} -	} +	updateFilterTypes(types, mFilterOps.mFilterWearableTypes);  	mFilterOps.mFilterTypes |= FILTERTYPE_WEARABLE;  } @@ -898,11 +860,16 @@ void LLInventoryFilter::fromLLSD(LLSD& data)  	}  } -U32 LLInventoryFilter::getFilterObjectTypes() const +U64 LLInventoryFilter::getFilterObjectTypes() const  {  	return mFilterOps.mFilterObjectTypes;  } +U64 LLInventoryFilter::getFilterCategoryTypes() const +{ +	return mFilterOps.mFilterCategoryTypes; +} +  BOOL LLInventoryFilter::hasFilterString() const  {  	return mFilterSubString.size() > 0; diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h index 39e6f797a2..f9460822f7 100644 --- a/indra/newview/llinventoryfilter.h +++ b/indra/newview/llinventoryfilter.h @@ -31,6 +31,7 @@  #include "llpermissionsflags.h"  class LLFolderViewItem; +class LLFolderViewFolder;  class LLInventoryFilter  { @@ -81,11 +82,13 @@ public:  	// + Parameters  	// +-------------------------------------------------------------------+  	void 				setFilterObjectTypes(U64 types); -	U32 				getFilterObjectTypes() const; +	U64 				getFilterObjectTypes() const; +	U64					getFilterCategoryTypes() const;  	BOOL 				isFilterObjectTypesWith(LLInventoryType::EType t) const;  	void 				setFilterCategoryTypes(U64 types);  	void 				setFilterUUID(const LLUUID &object_id);  	void				setFilterWearableTypes(U64 types); +	void				updateFilterTypes(U64 types, U64& current_types);  	void 				setFilterSubString(const std::string& string);  	const std::string& 	getFilterSubString(BOOL trim = FALSE) const; @@ -110,6 +113,7 @@ public:  	// + Execution And Results  	// +-------------------------------------------------------------------+  	BOOL 				check(const LLFolderViewItem* item); +	bool				checkFolder(const LLFolderViewFolder* folder);  	BOOL 				checkAgainstFilterType(const LLFolderViewItem* item) const;  	BOOL 				checkAgainstPermissions(const LLFolderViewItem* item) const;  	BOOL 				checkAgainstFilterLinks(const LLFolderViewItem* item) const; diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index cfe1747fd4..2016b92666 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -28,9 +28,9 @@  #ifndef LL_LLINVENTORYFUNCTIONS_H  #define LL_LLINVENTORYFUNCTIONS_H -#include "llinventorytype.h" -#include "llfolderview.h" -#include "llfolderviewitem.h" +#include "llinventorymodel.h" +#include "llinventory.h" +#include "llwearabletype.h"  /********************************************************************************   **                                                                            ** @@ -417,6 +417,24 @@ public:  /**                    Inventory Collector Functions   **                                                                            **   *******************************************************************************/ +class LLFolderViewItem; +class LLFolderViewFolder; + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLFolderViewFunctor +// +// Simple abstract base class for applying a functor to folders and +// items in a folder view hierarchy. This is suboptimal for algorithms +// that only work folders or only work on items, but I'll worry about +// that later when it's determined to be too slow. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +class LLFolderViewFunctor +{ +public: +	virtual ~LLFolderViewFunctor() {} +	virtual void doFolder(LLFolderViewFolder* folder) = 0; +	virtual void doItem(LLFolderViewItem* item) = 0; +};  class LLInventoryState  { diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 318beafe65..21d5de9a5b 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -2589,7 +2589,7 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**)  		LLInventoryState::sWearNewClothing = FALSE;  	} -	if (tid == LLInventoryState::sWearNewClothingTransactionID) +	if (tid.notNull() && tid == LLInventoryState::sWearNewClothingTransactionID)  	{  		count = wearable_ids.size();  		for (i = 0; i < count; ++i) diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 7b1ff102e7..afaf660cb7 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -31,7 +31,9 @@  #include "llappviewer.h"  #include "llcallbacklist.h"  #include "llinventorypanel.h" +#include "llinventorymodel.h"  #include "llviewercontrol.h" +#include "llviewerinventory.h"  #include "llviewermessage.h"  #include "llviewerregion.h"  #include "llviewerwindow.h" diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp index 6bf19e346d..ceba4a0191 100644 --- a/indra/newview/llinventoryobserver.cpp +++ b/indra/newview/llinventoryobserver.cpp @@ -601,6 +601,34 @@ void LLInventoryAddedObserver::changed(U32 mask)  	}  } +void LLInventoryCategoryAddedObserver::changed(U32 mask) +{ +	if (!(mask & LLInventoryObserver::ADD)) +	{ +		return; +	} +	 +	const LLInventoryModel::changed_items_t& changed_ids = gInventory.getChangedIDs(); +	 +	for (LLInventoryModel::changed_items_t::const_iterator cit = changed_ids.begin(); cit != changed_ids.end(); ++cit) +	{ +		LLViewerInventoryCategory* cat = gInventory.getCategory(*cit); +		 +		if (cat) +		{ +			mAddedCategories.push_back(cat); +		} +	} +	 +	if (!mAddedCategories.empty()) +	{ +		done(); +		 +		mAddedCategories.clear(); +	} +} + +  LLInventoryTransactionObserver::LLInventoryTransactionObserver(const LLTransactionID& transaction_id) :  	mTransactionID(transaction_id)  { diff --git a/indra/newview/llinventoryobserver.h b/indra/newview/llinventoryobserver.h index 2d9021961e..aa1eae84d7 100644 --- a/indra/newview/llinventoryobserver.h +++ b/indra/newview/llinventoryobserver.h @@ -219,6 +219,28 @@ protected:  };  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLInventoryCategoryAddedObserver +// +//   Base class for doing something when a new category is created in the +//   inventory. +//   It does not watch for a certain UUID, rather it acts when anything is added +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +class LLInventoryCategoryAddedObserver : public LLInventoryObserver +{ +public: +	 +	typedef std::vector<LLViewerInventoryCategory*>	cat_vec_t; +	 +	LLInventoryCategoryAddedObserver() : mAddedCategories() {} +	/*virtual*/ void changed(U32 mask); +	 +protected: +	virtual void done() = 0; +	 +	cat_vec_t	mAddedCategories; +}; + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  // Class LLInventoryTransactionObserver  //  //   Base class for doing something when an inventory transaction completes. diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 1dcb91ad4d..702e8d5a1f 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -35,6 +35,7 @@  #include "llavataractions.h"  #include "llfloaterinventory.h"  #include "llfloaterreg.h" +#include "llfolderview.h"  #include "llimfloater.h"  #include "llimview.h"  #include "llinventorybridge.h" @@ -42,7 +43,6 @@  #include "llinventorymodelbackgroundfetch.h"  #include "llsidepanelinventory.h"  #include "llsidetray.h" -#include "llscrollcontainer.h"  #include "llviewerattachmenu.h"  #include "llviewerfoldertype.h"  #include "llvoavatarself.h" @@ -131,9 +131,8 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :  	mInventory(p.inventory),  	mAllowMultiSelect(p.allow_multi_select),  	mShowItemLinkOverlays(p.show_item_link_overlays), +	mShowLoadStatus(p.show_load_status),  	mViewsInitialized(false), -	mStartFolderString(p.start_folder),	 -	mBuildDefaultHierarchy(true),  	mInvFVBridgeBuilder(NULL)  {  	mInvFVBridgeBuilder = &INVENTORY_BRIDGE_BUILDER; @@ -146,11 +145,88 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :  	mCommitCallbackRegistrar.add("Inventory.AttachObject", boost::bind(&LLInventoryPanel::attachObject, this, _2));  	mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&LLInventoryPanel::beginIMSession, this));  	mCommitCallbackRegistrar.add("Inventory.Share",  boost::bind(&LLAvatarActions::shareWithAvatars)); + +} + +void LLInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params) +{ +	// Determine the root folder in case specified, and +	// build the views starting with that folder. +	 +	std::string start_folder_name(params.start_folder()); +	 +	const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(start_folder_name); + +	LLUUID root_id; + +	if ("LIBRARY" == params.start_folder()) +	{ +		root_id = gInventory.getLibraryRootFolderID(); +	} +	// leslie -- temporary HACK to work around sim not creating inbox and outbox with proper system folder type +	else if (preferred_type == LLFolderType::FT_INBOX) +	{ +		LLInventoryModel::cat_array_t* cats; +		LLInventoryModel::item_array_t* items; +		 +		gInventory.getDirectDescendentsOf(gInventory.getRootFolderID(), cats, items); +		 +		if (cats) +		{ +			for (LLInventoryModel::cat_array_t::const_iterator cat_it = cats->begin(); cat_it != cats->end(); ++cat_it) +			{ +				LLInventoryCategory* cat = *cat_it; +				 +				if (cat->getName() == "Received Items") +				{ +					root_id = cat->getUUID(); +				} +			} +		} +	} +	// leslie -- temporary HACK to work around sim not creating inbox and outbox with proper system folder type +	else if (preferred_type == LLFolderType::FT_OUTBOX) +	{ +		LLInventoryModel::cat_array_t* cats; +		LLInventoryModel::item_array_t* items; +		 +		gInventory.getDirectDescendentsOf(gInventory.getRootFolderID(), cats, items); +		 +		if (cats) +		{ +			for (LLInventoryModel::cat_array_t::const_iterator cat_it = cats->begin(); cat_it != cats->end(); ++cat_it) +			{ +				LLInventoryCategory* cat = *cat_it; +				 +				if (cat->getName() == "Merchant Outbox") +				{ +					root_id = cat->getUUID(); +				} +			} +		} +	} +	// leslie -- end temporary HACK +	else +	{ +		root_id = (preferred_type != LLFolderType::FT_NONE) +				? gInventory.findCategoryUUIDForType(preferred_type, false, false)  +				: LLUUID::null; +	} -	if (mStartFolderString != "") +	if ((root_id == LLUUID::null) && !start_folder_name.empty())  	{ -		mBuildDefaultHierarchy = false; +		llwarns << "No category found that matches start_folder: " << start_folder_name << llendl; +		root_id = LLUUID::generateNewID();  	} +	 +	LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY, +																	LLAssetType::AT_CATEGORY, +																	LLInventoryType::IT_CATEGORY, +																	this, +																	NULL, +																	root_id); +	 +	mFolderRoot = createFolderView(new_listener, params.use_label_suffix());  }  void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params) @@ -159,22 +235,7 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)  	mCommitCallbackRegistrar.pushScope(); // registered as a widget; need to push callback scope ourselves -	// Create root folder -	{ -		LLRect folder_rect(0, -						   0, -						   getRect().getWidth(), -						   0); -		LLFolderView::Params p; -		p.name = getName(); -		p.title = getLabel(); -		p.rect = folder_rect; -		p.parent_panel = this; -		p.tool_tip = p.name; -		p.use_label_suffix = params.use_label_suffix; -		mFolderRoot = LLUICtrlFactory::create<LLFolderView>(p); -		mFolderRoot->setAllowMultiSelect(mAllowMultiSelect); -	} +	buildFolderView(params);  	mCommitCallbackRegistrar.popScope(); @@ -184,13 +245,9 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)  	{  		LLRect scroller_view_rect = getRect();  		scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom); -		LLScrollContainer::Params p; -		p.name("Inventory Scroller"); -		p.rect(scroller_view_rect); -		p.follows.flags(FOLLOWS_ALL); -		p.reserve_scroll_corner(true); -		p.tab_stop(true); -		mScroller = LLUICtrlFactory::create<LLScrollContainer>(p); +		LLScrollContainer::Params scroller_params(params.scroll()); +		scroller_params.rect(scroller_view_rect); +		mScroller = LLUICtrlFactory::create<LLScrollContainer>(scroller_params);  		addChild(mScroller);  		mScroller->addChild(mFolderRoot);  		mFolderRoot->setScrollContainer(mScroller); @@ -206,7 +263,7 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)  	// Build view of inventory if we need default full hierarchy and inventory ready,  	// otherwise wait for idle callback. -	if (mBuildDefaultHierarchy && mInventory->isInventoryUsable() && !mViewsInitialized) +	if (mInventory->isInventoryUsable() && !mViewsInitialized)  	{  		initializeViews();  	} @@ -222,6 +279,9 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)  	}  	mFolderRoot->setSortOrder(getFilter()->getSortOrder()); +	// hide inbox +	getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_INBOX)); +  	// Initialize base class params.  	LLPanel::initFromParams(params);  } @@ -264,6 +324,15 @@ LLInventoryFilter* LLInventoryPanel::getFilter()  	return NULL;  } +const LLInventoryFilter* LLInventoryPanel::getFilter() const +{ +	if (mFolderRoot) +	{ +		return mFolderRoot->getFilter(); +	} +	return NULL; +} +  void LLInventoryPanel::setFilterTypes(U64 types, LLInventoryFilter::EFilterType filter_type)  {  	if (filter_type == LLInventoryFilter::FILTERTYPE_OBJECT) @@ -272,6 +341,17 @@ void LLInventoryPanel::setFilterTypes(U64 types, LLInventoryFilter::EFilterType  		getFilter()->setFilterCategoryTypes(types);  } +U32 LLInventoryPanel::getFilterObjectTypes() const  +{  +	return mFolderRoot->getFilterObjectTypes();  +} + +U32 LLInventoryPanel::getFilterPermMask() const  +{  +	return mFolderRoot->getFilterPermissions();  +} + +  void LLInventoryPanel::setFilterPermMask(PermissionMask filter_perm_mask)  {  	getFilter()->setFilterPermissions(filter_perm_mask); @@ -287,6 +367,12 @@ void LLInventoryPanel::setFilterSubString(const std::string& string)  	getFilter()->setFilterSubString(string);  } +const std::string LLInventoryPanel::getFilterSubString()  +{  +	return mFolderRoot->getFilterSubString();  +} + +  void LLInventoryPanel::setSortOrder(U32 order)  {  	getFilter()->setSortOrder(order); @@ -298,6 +384,12 @@ void LLInventoryPanel::setSortOrder(U32 order)  	}  } +U32 LLInventoryPanel::getSortOrder() const  +{  +	return mFolderRoot->getSortOrder();  +} + +  void LLInventoryPanel::setSinceLogoff(BOOL sl)  {  	getFilter()->setDateRangeLastLogoff(sl); @@ -379,7 +471,8 @@ void LLInventoryPanel::modelChanged(U32 mask)  			{  				view_item->destroyView();  			} -			buildNewViews(item_id); +			view_item = buildNewViews(item_id); +			view_folder = dynamic_cast<LLFolderViewFolder *>(view_item);  		}  		////////////////////////////// @@ -432,11 +525,10 @@ void LLInventoryPanel::modelChanged(U32 mask)  			//////////////////////////////  			// STRUCTURE Operation  			// This item already exists in both memory and UI.  It was probably reparented. -			if (model_item && view_item) +			else if (model_item && view_item)  			{ -				// Don't process the item if it's hanging from the root, since its -				// model_item's parent will be NULL. -				if (view_item->getRoot() != view_item->getParent()) +				// Don't process the item if it is the root +				if (view_item->getRoot() != view_item)  				{  					LLFolderViewFolder* new_parent = (LLFolderViewFolder*)mFolderRoot->getItemByID(model_item->getParentUUID());  					// Item has been moved. @@ -461,7 +553,7 @@ void LLInventoryPanel::modelChanged(U32 mask)  			//////////////////////////////  			// REMOVE Operation  			// This item has been removed from memory, but its associated UI element still exists. -			if (!model_item && view_item) +			else if (!model_item && view_item)  			{  				// Remove the item's UI.  				view_item->destroyView(); @@ -470,6 +562,12 @@ void LLInventoryPanel::modelChanged(U32 mask)  	}  } +LLFolderView* LLInventoryPanel::getRootFolder()  +{  +	return mFolderRoot;  +} + +  // static  void LLInventoryPanel::onIdle(void *userdata)  { @@ -488,23 +586,16 @@ void LLInventoryPanel::onIdle(void *userdata)  	}  } +const LLUUID& LLInventoryPanel::getRootFolderID() const +{ +	return mFolderRoot->getListener()->getUUID(); +} +  void LLInventoryPanel::initializeViews()  {  	if (!gInventory.isInventoryUsable()) return; -	// Determine the root folder in case specified, and -	// build the views starting with that folder. -	const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(mStartFolderString); - -	if ("LIBRARY" == mStartFolderString) -	{ -		mStartFolderID = gInventory.getLibraryRootFolderID(); -	} -	else -	{ -		mStartFolderID = (preferred_type != LLFolderType::FT_NONE ? gInventory.findCategoryUUIDForType(preferred_type) : LLUUID::null); -	} -	rebuildViewsFor(mStartFolderID); +	rebuildViewsFor(getRootFolderID());  	mViewsInitialized = true; @@ -529,132 +620,155 @@ void LLInventoryPanel::initializeViews()  	}  } -void LLInventoryPanel::rebuildViewsFor(const LLUUID& id) +LLFolderViewItem* LLInventoryPanel::rebuildViewsFor(const LLUUID& id)  {  	// Destroy the old view for this ID so we can rebuild it.  	LLFolderViewItem* old_view = mFolderRoot->getItemByID(id); -	if (old_view && id.notNull()) +	if (old_view)  	{  		old_view->destroyView();  	} -	buildNewViews(id); +	return buildNewViews(id);  } -void LLInventoryPanel::buildNewViews(const LLUUID& id) +LLFolderView * LLInventoryPanel::createFolderView(LLInvFVBridge * bridge, bool useLabelSuffix)  { -	LLMemType mt(LLMemType::MTYPE_INVENTORY_BUILD_NEW_VIEWS); -	LLFolderViewItem* itemp = NULL; -	LLInventoryObject* objectp = gInventory.getObject(id); -	if (objectp) +	LLRect folder_rect(0, +					   0, +					   getRect().getWidth(), +					   0); + +	LLFolderView::Params p; +	 +	p.name = getName(); +	p.title = getLabel(); +	p.rect = folder_rect; +	p.parent_panel = this; +	p.tool_tip = p.name; +	p.listener =  bridge; +	p.use_label_suffix = useLabelSuffix; +	p.allow_multiselect = mAllowMultiSelect; +	p.show_load_status = mShowLoadStatus; + +	return LLUICtrlFactory::create<LLFolderView>(p); +} + +LLFolderViewFolder * LLInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge) +{ +	LLFolderViewFolder::Params params; + +	params.name = bridge->getDisplayName(); +	params.icon = bridge->getIcon(); +	params.icon_open = bridge->getOpenIcon(); + +	if (mShowItemLinkOverlays) // if false, then links show up just like normal items  	{ -		const LLUUID &parent_id = objectp->getParentUUID(); -		LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)mFolderRoot->getItemByID(parent_id); -		if (id == mStartFolderID) -		{ -			parent_folder = mFolderRoot; -		} -		else if ((mStartFolderID != LLUUID::null) && (!gInventory.isObjectDescendentOf(id, mStartFolderID))) -		{ -			// This item exists outside the inventory's hierarchy, so don't add it. -			return; -		} -		 -		if (objectp->getType() <= LLAssetType::AT_NONE || -			objectp->getType() >= LLAssetType::AT_COUNT) -		{ -			llwarns << "LLInventoryPanel::buildNewViews called with invalid objectp->mType : " -					<< ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID()  -					<< llendl; -			return; -		} -		 -		if ((objectp->getType() == LLAssetType::AT_CATEGORY) && -			(objectp->getActualType() != LLAssetType::AT_LINK_FOLDER)) -		{ -			LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(objectp->getType(), -																			objectp->getType(), -																			LLInventoryType::IT_CATEGORY, -																			this, -																			mFolderRoot, -																			objectp->getUUID()); -			if (new_listener) -			{ -				LLFolderViewFolder::Params params; -				params.name = new_listener->getDisplayName(); -				params.icon = new_listener->getIcon(); -				params.icon_open = new_listener->getOpenIcon(); -				if (mShowItemLinkOverlays) // if false, then links show up just like normal items -				{ -					params.icon_overlay = LLUI::getUIImage("Inv_Link"); -				} -				params.root = mFolderRoot; -				params.listener = new_listener; -				params.tool_tip = params.name; -				LLFolderViewFolder* folderp = LLUICtrlFactory::create<LLFolderViewFolder>(params); -				folderp->setItemSortOrder(mFolderRoot->getSortOrder()); -				itemp = folderp; - -				// Hide the root folder, so we can show the contents of a folder flat -				// but still have the parent folder present for listener-related operations. -				if (id == mStartFolderID) -				{ -					folderp->setHidden(TRUE); -				} -				const LLViewerInventoryCategory *cat = dynamic_cast<LLViewerInventoryCategory *>(objectp); -				if (cat && getIsHiddenFolderType(cat->getPreferredType())) -				{ -					folderp->setHidden(TRUE); -				} -			} -		} -		else  -		{ -			// Build new view for item. -			LLInventoryItem* item = (LLInventoryItem*)objectp; -			LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(item->getType(), -																			item->getActualType(), -																			item->getInventoryType(), -																			this, -																			mFolderRoot, -																			item->getUUID(), -																			item->getFlags()); - -			if (new_listener) -			{ -				LLFolderViewItem::Params params; -				params.name = new_listener->getDisplayName(); -				params.icon = new_listener->getIcon(); -				params.icon_open = new_listener->getOpenIcon(); -				if (mShowItemLinkOverlays) // if false, then links show up just like normal items -				{ -					params.icon_overlay = LLUI::getUIImage("Inv_Link"); -				} -				params.creation_date = new_listener->getCreationDate(); -				params.root = mFolderRoot; -				params.listener = new_listener; -				params.rect = LLRect (0, 0, 0, 0); -				params.tool_tip = params.name; -				itemp = LLUICtrlFactory::create<LLFolderViewItem> (params); -			} -		} +		params.icon_overlay = LLUI::getUIImage("Inv_Link"); +	} +	 +	params.root = mFolderRoot; +	params.listener = bridge; +	params.tool_tip = params.name; -		if (itemp) -		{ -			itemp->addToFolder(parent_folder, mFolderRoot); +	return LLUICtrlFactory::create<LLFolderViewFolder>(params); +} -			// Don't add children of hidden folders unless this is the panel's root folder. -			if (itemp->getHidden() && (id != mStartFolderID)) -			{ -				return; -			} +LLFolderViewItem * LLInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge) +{ +	LLFolderViewItem::Params params; +	 +	params.name = bridge->getDisplayName(); +	params.icon = bridge->getIcon(); +	params.icon_open = bridge->getOpenIcon(); + +	if (mShowItemLinkOverlays) // if false, then links show up just like normal items +	{ +		params.icon_overlay = LLUI::getUIImage("Inv_Link"); +	} + +	params.creation_date = bridge->getCreationDate(); +	params.root = mFolderRoot; +	params.listener = bridge; +	params.rect = LLRect (0, 0, 0, 0); +	params.tool_tip = params.name; +	 +	return LLUICtrlFactory::create<LLFolderViewItem>(params); +} + +LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id) +{ + 	LLInventoryObject const* objectp = gInventory.getObject(id); + 	LLUUID root_id = mFolderRoot->getListener()->getUUID(); + 	LLFolderViewFolder* parent_folder = NULL; +	LLFolderViewItem* itemp = NULL; +	 + 	if (id == root_id) + 	{ + 		parent_folder = mFolderRoot; + 	} + 	else if (objectp) + 	{ + 		const LLUUID &parent_id = objectp->getParentUUID(); + 		parent_folder = (LLFolderViewFolder*)mFolderRoot->getItemByID(parent_id); +  		 +  		if (parent_folder) +  		{ +  			if (objectp->getType() <= LLAssetType::AT_NONE || +  				objectp->getType() >= LLAssetType::AT_COUNT) +  			{ +  				llwarns << "LLInventoryPanel::buildNewViews called with invalid objectp->mType : " +  						<< ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID() +  						<< llendl; +  				return NULL; +  			} +  		 +  			if ((objectp->getType() == LLAssetType::AT_CATEGORY) && +  				(objectp->getActualType() != LLAssetType::AT_LINK_FOLDER)) +  			{ +  				LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(objectp->getType(), +  																				objectp->getType(), +  																				LLInventoryType::IT_CATEGORY, +  																				this, +  																				mFolderRoot, +  																				objectp->getUUID()); +  				if (new_listener) +  				{ +					LLFolderViewFolder* folderp = createFolderViewFolder(new_listener); +  					folderp->setItemSortOrder(mFolderRoot->getSortOrder()); +  					itemp = folderp; +  				} +  			} +  			else +  			{ +  				// Build new view for item. +  				LLInventoryItem* item = (LLInventoryItem*)objectp; +  				LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(item->getType(), +  																				item->getActualType(), +  																				item->getInventoryType(), +  																				this, +  																				mFolderRoot, +  																				item->getUUID(), +  																				item->getFlags()); +  +  				if (new_listener) +  				{ +					itemp = createFolderViewItem(new_listener); +  				} +  			} +  +  			if (itemp) +  			{ +  				itemp->addToFolder(parent_folder, mFolderRoot); +   			}  		}  	}  	// If this is a folder, add the children of the folder and recursively add any   	// child folders. -	if ((id == mStartFolderID) || -		(objectp && objectp->getType() == LLAssetType::AT_CATEGORY)) +	if (id.isNull() +		||	(objectp +			&& objectp->getType() == LLAssetType::AT_CATEGORY))  	{  		LLViewerInventoryCategory::cat_array_t* categories;  		LLViewerInventoryItem::item_array_t* items; @@ -671,7 +785,7 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)  			}  		} -		if(items) +		if(items && parent_folder)  		{  			for (LLViewerInventoryItem::item_array_t::const_iterator item_iter = items->begin();  				 item_iter != items->end(); @@ -683,28 +797,25 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)  		}  		mInventory->unlockDirectDescendentArrays(id);  	} +	 +	return itemp;  }  // bit of a hack to make sure the inventory is open.  void LLInventoryPanel::openStartFolderOrMyInventory()  { -	if (mStartFolderString != "") +	// Find My Inventory folder and open it up by name +	for (LLView *child = mFolderRoot->getFirstChild(); child; child = mFolderRoot->findNextSibling(child))  	{ -		mFolderRoot->openFolder(mStartFolderString); -	} -	else -	{ -		// Find My Inventory folder and open it up by name -		for (LLView *child = mFolderRoot->getFirstChild(); child; child = mFolderRoot->findNextSibling(child)) +		LLFolderViewFolder *fchild = dynamic_cast<LLFolderViewFolder*>(child); +		if (fchild +			&& fchild->getListener() +				&& fchild->getListener()->getUUID() == gInventory.getRootFolderID())  		{ -			LLFolderViewFolder *fchild = dynamic_cast<LLFolderViewFolder*>(child); -			if (fchild && fchild->getListener() && -				(fchild->getListener()->getUUID() == gInventory.getRootFolderID())) -			{ -				const std::string& child_name = child->getName(); -				mFolderRoot->openFolder(child_name); -				break; -			} +			const std::string& child_name = child->getName(); +			mFolderRoot->openFolder(child_name); +			mFolderRoot->clearSelection();	// No need to keep it selected though! +			break;  		}  	}  } @@ -723,6 +834,12 @@ void LLInventoryPanel::openSelected()  	bridge->openItem();  } +void LLInventoryPanel::unSelectAll()	 +{  +	mFolderRoot->setSelection(NULL, FALSE, FALSE);  +} + +  BOOL LLInventoryPanel::handleHover(S32 x, S32 y, MASK mask)  {  	BOOL handled = LLView::handleHover(x, y, mask); @@ -802,7 +919,7 @@ void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_foc  	mFolderRoot->setSelectionByID(obj_id, take_keyboard_focus);  } -void LLInventoryPanel::setSelectCallback(const LLFolderView::signal_t::slot_type& cb)  +void LLInventoryPanel::setSelectCallback(const boost::function<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb)   {   	if (mFolderRoot)   	{ @@ -1067,15 +1184,12 @@ LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel(BOOL auto_open)  void LLInventoryPanel::addHideFolderType(LLFolderType::EType folder_type)  { -	if (!getIsHiddenFolderType(folder_type)) -	{ -		mHiddenFolderTypes.push_back(folder_type); -	} +	getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() & ~(1ULL << folder_type));  }  BOOL LLInventoryPanel::getIsHiddenFolderType(LLFolderType::EType folder_type) const  { -	return (std::find(mHiddenFolderTypes.begin(), mHiddenFolderTypes.end(), folder_type) != mHiddenFolderTypes.end()); +	return !(getFilter()->getFilterCategoryTypes() & (1ULL << folder_type));  } @@ -1092,6 +1206,13 @@ public:  	struct Params :	public LLInitParam::Block<Params, LLInventoryPanel::Params>  	{}; +	void initFromParams(const Params& p) +	{ +		LLInventoryPanel::initFromParams(p); +		// turn on inbox for recent items +		getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() | (1ULL << LLFolderType::FT_INBOX)); +	} +  protected:  	LLInventoryRecentItemsPanel (const Params&);  	friend class LLUICtrlFactory; diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index 9da9f7d8ba..a4287a438e 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -33,11 +33,13 @@  #include "llfloater.h"  #include "llinventory.h"  #include "llinventoryfilter.h" -#include "llfolderview.h"  #include "llinventorymodel.h" +#include "llscrollcontainer.h"  #include "lluictrlfactory.h"  #include <set> +class LLFolderView; +class LLFolderViewFolder;  class LLFolderViewItem;  class LLInventoryFilter;  class LLInventoryModel; @@ -46,7 +48,6 @@ class LLInventoryFVBridgeBuilder;  class LLMenuBarGL;  class LLCheckBoxCtrl;  class LLSpinCtrl; -class LLScrollContainer;  class LLTextBox;  class LLIconCtrl;  class LLSaveFolderState; @@ -83,6 +84,8 @@ public:  		Optional<Filter>					filter;  		Optional<std::string>               start_folder;  		Optional<bool>						use_label_suffix; +		Optional<bool>						show_load_status; +		Optional<LLScrollContainer::Params>	scroll;  		Params()  		:	sort_order_setting("sort_order_setting"), @@ -91,7 +94,9 @@ public:  			show_item_link_overlays("show_item_link_overlays", false),  			filter("filter"),  			start_folder("start_folder"), -			use_label_suffix("use_label_suffix", true) +			use_label_suffix("use_label_suffix", true), +			show_load_status("show_load_status"), +			scroll("scroll")  		{}  	}; @@ -123,16 +128,17 @@ public:  	// Call this method to set the selection.  	void openAllFolders();  	void setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus); -	void setSelectCallback(const LLFolderView::signal_t::slot_type& cb); +	void setSelectCallback(const boost::function<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb);  	void clearSelection();  	LLInventoryFilter* getFilter(); +	const LLInventoryFilter* getFilter() const;  	void setFilterTypes(U64 filter, LLInventoryFilter::EFilterType = LLInventoryFilter::FILTERTYPE_OBJECT); -	U32 getFilterObjectTypes() const { return mFolderRoot->getFilterObjectTypes(); } +	U32 getFilterObjectTypes() const;  	void setFilterPermMask(PermissionMask filter_perm_mask); -	U32 getFilterPermMask() const { return mFolderRoot->getFilterPermissions(); } +	U32 getFilterPermMask() const;  	void setFilterWearableTypes(U64 filter);  	void setFilterSubString(const std::string& string); -	const std::string getFilterSubString() { return mFolderRoot->getFilterSubString(); } +	const std::string getFilterSubString();  	void setSinceLogoff(BOOL sl);  	void setHoursAgo(U32 hours);  	BOOL getSinceLogoff(); @@ -140,10 +146,9 @@ public:  	void setShowFolderState(LLInventoryFilter::EFolderShow show);  	LLInventoryFilter::EFolderShow getShowFolderState(); -	void setAllowMultiSelect(BOOL allow) { mFolderRoot->setAllowMultiSelect(allow); }  	// This method is called when something has changed about the inventory.  	void modelChanged(U32 mask); -	LLFolderView* getRootFolder() { return mFolderRoot; } +	LLFolderView* getRootFolder();  	LLScrollContainer* getScrollableContainer() { return mScroller; }  	void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action); @@ -158,7 +163,7 @@ public:  	static void dumpSelectionInformation(void* user_data);  	void openSelected(); -	void unSelectAll()	{ mFolderRoot->setSelection(NULL, FALSE, FALSE); } +	void unSelectAll();  	static void onIdle(void* user_data); @@ -175,6 +180,7 @@ protected:  	LLInvPanelComplObserver*	mCompletionObserver;  	BOOL 						mAllowMultiSelect;  	BOOL 						mShowItemLinkOverlays; // Shows link graphic over inventory item icons +	BOOL						mShowLoadStatus;  	LLFolderView*				mFolderRoot;  	LLScrollContainer*			mScroller; @@ -198,7 +204,7 @@ public:  	static const std::string INHERIT_SORT_ORDER;  	void setSortOrder(U32 order); -	U32 getSortOrder() const { return mFolderRoot->getSortOrder(); } +	U32 getSortOrder() const;  private:  	std::string					mSortOrderSetting; @@ -207,29 +213,27 @@ private:  	//--------------------------------------------------------------------  public:  	void addHideFolderType(LLFolderType::EType folder_type); -protected: -	BOOL getIsHiddenFolderType(LLFolderType::EType folder_type) const; -private: -	std::vector<LLFolderType::EType> mHiddenFolderTypes; -	//-------------------------------------------------------------------- -	// Initialization routines for building up the UI ("views") -	//--------------------------------------------------------------------  public:  	BOOL 				getIsViewsInitialized() const { return mViewsInitialized; } -	const LLUUID&		getStartFolderID() const { return mStartFolderID; } -	const std::string&  getStartFolderString() { return mStartFolderString; } +	const LLUUID&		getRootFolderID() const;  protected:  	// Builds the UI.  Call this once the inventory is usable.  	void 				initializeViews(); -	void rebuildViewsFor(const LLUUID& id); // Given the id and the parent, build all of the folder views. -	virtual void buildNewViews(const LLUUID& id); +	LLFolderViewItem*	rebuildViewsFor(const LLUUID& id); // Given the id and the parent, build all of the folder views. + +	virtual void		buildFolderView(const LLInventoryPanel::Params& params); +	LLFolderViewItem*	buildNewViews(const LLUUID& id); +	BOOL				getIsHiddenFolderType(LLFolderType::EType folder_type) const; +	 +	virtual LLFolderView*		createFolderView(LLInvFVBridge * bridge, bool useLabelSuffix); +	virtual LLFolderViewFolder*	createFolderViewFolder(LLInvFVBridge * bridge); +	virtual LLFolderViewItem*	createFolderViewItem(LLInvFVBridge * bridge);  private:  	BOOL				mBuildDefaultHierarchy; // default inventory hierarchy should be created in postBuild()  	BOOL				mViewsInitialized; // Views have been generated  	// UUID of category from which hierarchy should be built.  Set with the   	// "start_folder" xml property.  Default is LLUUID::null that means total Inventory hierarchy.  -	std::string         mStartFolderString;  	LLUUID				mStartFolderID;  }; diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index b3ad9efeb2..03ccabc994 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -38,6 +38,7 @@  #include "llviewermedia.h"  #include "llviewertexture.h"  #include "llviewerwindow.h" +#include "lldebugmessagebox.h"  #include "llweb.h"  #include "llrender.h"  #include "llpluginclassmedia.h" @@ -708,6 +709,8 @@ LLPluginClassMedia* LLMediaCtrl::getMediaPlugin()  //  void LLMediaCtrl::draw()  { +	F32 alpha = getDrawContext().mAlpha; +  	if ( gRestoreGL == 1 )  	{  		LLRect r = getRect(); @@ -746,21 +749,11 @@ void LLMediaCtrl::draw()  		}  	} -//	if(mHidingInitialLoad) -//	{ -//		// If we're hiding loading, don't draw at all. -//		draw_media = false; -//	} -	  	bool background_visible = isBackgroundVisible();  	bool background_opaque = isBackgroundOpaque();  	if(draw_media)  	{ -		// alpha off for this -		LLGLSUIDefault gls_ui; -		LLGLDisable gls_alphaTest( GL_ALPHA_TEST ); -  		gGL.pushUIMatrix();  		{  			if (mIgnoreUIScale) @@ -775,7 +768,8 @@ void LLMediaCtrl::draw()  			// scale texture to fit the space using texture coords  			gGL.getTexUnit(0)->bind(media_texture); -			gGL.color4fv( LLColor4::white.mV ); +			LLColor4 media_color = LLColor4::white % alpha; +			gGL.color4fv( media_color.mV );  			F32 max_u = ( F32 )media_plugin->getWidth() / ( F32 )media_plugin->getTextureWidth();  			F32 max_v = ( F32 )media_plugin->getHeight() / ( F32 )media_plugin->getTextureHeight(); @@ -827,7 +821,6 @@ void LLMediaCtrl::draw()  			}  			// draw the browser -			gGL.setSceneBlendType(LLRender::BT_REPLACE);  			gGL.begin( LLRender::QUADS );  			if (! media_plugin->getTextureCoordsOpenGL())  			{ @@ -860,7 +853,6 @@ void LLMediaCtrl::draw()  				gGL.vertex2i( x_offset + width, y_offset );  			}  			gGL.end(); -			gGL.setSceneBlendType(LLRender::BT_ALPHA);  		}  		gGL.popUIMatrix(); diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 6435126fc0..10887aa53a 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -364,8 +364,8 @@ LLOutfitsList::~LLOutfitsList()  	if (gInventory.containsObserver(mCategoriesObserver))  	{  		gInventory.removeObserver(mCategoriesObserver); -		delete mCategoriesObserver;  	} +	delete mCategoriesObserver;  }  BOOL LLOutfitsList::postBuild() diff --git a/indra/newview/llpanelappearancetab.cpp b/indra/newview/llpanelappearancetab.cpp index 9910a3a2ac..8fa8867c69 100644 --- a/indra/newview/llpanelappearancetab.cpp +++ b/indra/newview/llpanelappearancetab.cpp @@ -31,6 +31,7 @@  #include "llinventoryfunctions.h"  #include "llinventorymodel.h" +#include "llviewerinventory.h"  //virtual  bool LLPanelAppearanceTab::canTakeOffSelected() diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp index 0cc5dcda82..e370f2f622 100644 --- a/indra/newview/llpanelimcontrolpanel.cpp +++ b/indra/newview/llpanelimcontrolpanel.cpp @@ -71,7 +71,7 @@ void LLPanelChatControlPanel::onChange(EStatusType status, const std::string &ch  void LLPanelChatControlPanel::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)  { -	updateButtons(new_state >= LLVoiceChannel::STATE_CALL_STARTED); +	updateButtons(new_state);  }  void LLPanelChatControlPanel::updateCallButton() @@ -96,11 +96,15 @@ void LLPanelChatControlPanel::updateCallButton()  	getChildView("call_btn")->setEnabled(enable_connect);  } -void LLPanelChatControlPanel::updateButtons(bool is_call_started) +void LLPanelChatControlPanel::updateButtons(LLVoiceChannel::EState state)  { +	bool is_call_started = state >= LLVoiceChannel::STATE_CALL_STARTED;  	getChildView("end_call_btn_panel")->setVisible( is_call_started); -	getChildView("voice_ctrls_btn_panel")->setVisible( is_call_started); +	getChildView("voice_ctrls_btn_panel")->setVisible( is_call_started && findChild<LLView>("voice_ctrls_btn_panel"));  	getChildView("call_btn_panel")->setVisible( ! is_call_started); +	 +	getChildView("volume_ctrl_panel")->setVisible(state == LLVoiceChannel::STATE_CONNECTED); +	  	updateCallButton();  } @@ -135,7 +139,7 @@ void LLPanelChatControlPanel::setSessionId(const LLUUID& session_id)  		mVoiceChannelStateChangeConnection = voice_channel->setStateChangedCallback(boost::bind(&LLPanelChatControlPanel::onVoiceChannelStateChanged, this, _1, _2));  		//call (either p2p, group or ad-hoc) can be already in started state -		updateButtons(voice_channel->getState() >= LLVoiceChannel::STATE_CALL_STARTED); +		updateButtons(voice_channel->getState());  	}  } @@ -156,6 +160,13 @@ BOOL LLPanelIMControlPanel::postBuild()  	childSetAction("share_btn", boost::bind(&LLPanelIMControlPanel::onShareButtonClicked, this));  	childSetAction("teleport_btn", boost::bind(&LLPanelIMControlPanel::onTeleportButtonClicked, this));  	childSetAction("pay_btn", boost::bind(&LLPanelIMControlPanel::onPayButtonClicked, this)); + +	childSetAction("mute_btn", boost::bind(&LLPanelIMControlPanel::onClickMuteVolume, this)); +	childSetAction("block_btn", boost::bind(&LLPanelIMControlPanel::onClickBlock, this)); +	childSetAction("unblock_btn", boost::bind(&LLPanelIMControlPanel::onClickUnblock, this)); +	 +	getChild<LLUICtrl>("volume_slider")->setCommitCallback(boost::bind(&LLPanelIMControlPanel::onVolumeChange, this, _2)); +  	getChildView("add_friend_btn")->setEnabled(!LLAvatarActions::isFriend(getChild<LLAvatarIconCtrl>("avatar_icon")->getAvatarId()));  	setFocusReceivedCallback(boost::bind(&LLPanelIMControlPanel::onFocusReceived, this)); @@ -163,6 +174,79 @@ BOOL LLPanelIMControlPanel::postBuild()  	return LLPanelChatControlPanel::postBuild();  } +void LLPanelIMControlPanel::draw() +{ +	bool is_muted = LLMuteList::getInstance()->isMuted(mAvatarID); + +	getChild<LLUICtrl>("block_btn_panel")->setVisible(!is_muted); +	getChild<LLUICtrl>("unblock_btn_panel")->setVisible(is_muted); + +	if (getChildView("volume_ctrl_panel")->getVisible()) +	{ + +		bool is_muted_voice = LLMuteList::getInstance()->isMuted(mAvatarID, LLMute::flagVoiceChat); + +		LLUICtrl* mute_btn = getChild<LLUICtrl>("mute_btn"); +		mute_btn->setValue( is_muted_voice ); + +		LLUICtrl* volume_slider = getChild<LLUICtrl>("volume_slider"); +		volume_slider->setEnabled( !is_muted_voice ); + +		F32 volume; + +		if (is_muted_voice) +		{ +			// it's clearer to display their volume as zero +			volume = 0.f; +		} +		else +		{ +			// actual volume +			volume = LLVoiceClient::getInstance()->getUserVolume(mAvatarID); +		} +		volume_slider->setValue( (F64)volume ); +	} + +	LLPanelChatControlPanel::draw(); +} + +void LLPanelIMControlPanel::onClickMuteVolume() +{ +	// By convention, we only display and toggle voice mutes, not all mutes +	LLMuteList* mute_list = LLMuteList::getInstance(); +	bool is_muted = mute_list->isMuted(mAvatarID, LLMute::flagVoiceChat); + +	LLMute mute(mAvatarID, getChild<LLTextBox>("avatar_name")->getText(), LLMute::AGENT); +	if (!is_muted) +	{ +		mute_list->add(mute, LLMute::flagVoiceChat); +	} +	else +	{ +		mute_list->remove(mute, LLMute::flagVoiceChat); +	} +} + +void LLPanelIMControlPanel::onClickBlock() +{ +	LLMute mute(mAvatarID, getChild<LLTextBox>("avatar_name")->getText(), LLMute::AGENT); +	 +	LLMuteList::getInstance()->add(mute); +} + +void LLPanelIMControlPanel::onClickUnblock() +{ +	LLMute mute(mAvatarID, getChild<LLTextBox>("avatar_name")->getText(), LLMute::AGENT); + +	LLMuteList::getInstance()->remove(mute); +} + +void LLPanelIMControlPanel::onVolumeChange(const LLSD& data) +{ +	F32 volume = (F32)data.asReal(); +	LLVoiceClient::getInstance()->setUserVolume(mAvatarID, volume); +} +  void LLPanelIMControlPanel::onTeleportButtonClicked()  {  	LLAvatarActions::offerTeleport(mAvatarID); @@ -262,6 +346,9 @@ void LLPanelIMControlPanel::onNameCache(const LLUUID& id, const std::string& ful  		std::string avatar_name = full_name;  		getChild<LLTextBox>("avatar_name")->setValue(avatar_name);  		getChild<LLTextBox>("avatar_name")->setToolTip(avatar_name); + +		bool is_linden = LLStringUtil::endsWith(full_name, " Linden"); +		getChild<LLUICtrl>("mute_btn")->setEnabled( !is_linden);  	}  } diff --git a/indra/newview/llpanelimcontrolpanel.h b/indra/newview/llpanelimcontrolpanel.h index 3bbe24ecb9..bba847b5d4 100644 --- a/indra/newview/llpanelimcontrolpanel.h +++ b/indra/newview/llpanelimcontrolpanel.h @@ -54,7 +54,7 @@ public:  	virtual void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state); -	void updateButtons(bool is_call_started); +	void updateButtons(LLVoiceChannel::EState state);  	// Enables/disables call button depending on voice availability  	void updateCallButton(); @@ -94,6 +94,12 @@ private:  	void onPayButtonClicked();  	void onFocusReceived(); +	void onClickMuteVolume(); +	void onClickBlock(); +	void onClickUnblock(); +	/*virtual*/ void draw(); +	void onVolumeChange(const LLSD& data); +  	LLUUID mAvatarID;  }; diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index c2729fa19b..a9cc247d1b 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -46,6 +46,7 @@  #include "llfolderviewitem.h"  #include "llinventorymodelbackgroundfetch.h"  #include "llinventorypanel.h" +#include "llinventoryfunctions.h"  #include "lllandmarkactions.h"  #include "llmenubutton.h"  #include "llplacesinventorybridge.h" @@ -529,7 +530,7 @@ void LLLandmarksPanel::setParcelID(const LLUUID& parcel_id)  // virtual  void LLLandmarksPanel::setErrorStatus(U32 status, const std::string& reason)  { -	llerrs<< "Can't handle remote parcel request."<< " Http Status: "<< status << ". Reason : "<< reason<<llendl; +	llwarns << "Can't handle remote parcel request."<< " Http Status: "<< status << ". Reason : "<< reason<<llendl;  } @@ -645,7 +646,7 @@ void LLLandmarksPanel::onAccordionExpandedCollapsed(const LLSD& param, LLPlacesI  	// Start background fetch, mostly for My Inventory and Library  	if (expanded)  	{ -		const LLUUID &cat_id = inventory_list->getStartFolderID(); +		const LLUUID &cat_id = inventory_list->getRootFolderID();  		// Just because the category itself has been fetched, doesn't mean its child folders have.  		/*  		  if (!gInventory.isCategoryComplete(cat_id)) @@ -1414,7 +1415,7 @@ static void filter_list(LLPlacesInventoryPanel* inventory_list, const std::strin  static bool category_has_descendents(LLPlacesInventoryPanel* inventory_list)  { -	LLViewerInventoryCategory* category = gInventory.getCategory(inventory_list->getStartFolderID()); +	LLViewerInventoryCategory* category = gInventory.getCategory(inventory_list->getRootFolderID());  	if (category)  	{  		return category->getDescendentCount() > 0; diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index bc4998dd0c..1920cc2940 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -1,6 +1,6 @@  /**  - * @file llsidepanelmaininventory.cpp - * @brief Implementation of llsidepanelmaininventory. + * @file llpanelmaininventory.cpp + * @brief Implementation of llpanelmaininventory.   *   * $LicenseInfo:firstyear=2001&license=viewerlgpl$   * Second Life Viewer Source Code @@ -95,8 +95,8 @@ private:  /// LLPanelMainInventory  ///---------------------------------------------------------------------------- -LLPanelMainInventory::LLPanelMainInventory() -	: LLPanel(), +LLPanelMainInventory::LLPanelMainInventory(const LLPanel::Params& p) +	: LLPanel(p),  	  mActivePanel(NULL),  	  mSavedFolderState(NULL),  	  mFilterText(""), @@ -193,6 +193,9 @@ BOOL LLPanelMainInventory::postBuild()  	mMenuAdd->getChild<LLMenuItemGL>("Upload Animation")->setLabelArg("[COST]", upload_cost);  	mMenuAdd->getChild<LLMenuItemGL>("Bulk Upload")->setLabelArg("[COST]", upload_cost); +	// Trigger callback for focus received so we can deselect items in inbox/outbox +	LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLPanelMainInventory::onFocusReceived, this)); +  	return TRUE;  } @@ -572,6 +575,27 @@ void LLPanelMainInventory::updateItemcountText()  	getChild<LLUICtrl>("ItemcountText")->setValue(text);  } +void LLPanelMainInventory::onFocusReceived() +{ +	LLSidepanelInventory * sidepanel_inventory = LLSideTray::getInstance()->getPanel<LLSidepanelInventory>("sidepanel_inventory"); + +	LLInventoryPanel * inbox_panel = sidepanel_inventory->findChild<LLInventoryPanel>("inventory_inbox"); + +	if (inbox_panel) +	{ +		inbox_panel->clearSelection(); +	} + +	LLInventoryPanel * outbox_panel = sidepanel_inventory->findChild<LLInventoryPanel>("inventory_outbox"); + +	if (outbox_panel) +	{ +		outbox_panel->clearSelection(); +	} + +	sidepanel_inventory->updateVerbs(); +} +  void LLPanelMainInventory::setFilterTextFromFilter()   {   	mFilterText = mActivePanel->getFilter()->getFilterText();  diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h index 2b2ee1c0c9..899931aa89 100644 --- a/indra/newview/llpanelmaininventory.h +++ b/indra/newview/llpanelmaininventory.h @@ -57,7 +57,7 @@ class LLPanelMainInventory : public LLPanel, LLInventoryObserver  public:  	friend class LLFloaterInventoryFinder; -	LLPanelMainInventory(); +	LLPanelMainInventory(const LLPanel::Params& p = getDefaultParams());  	~LLPanelMainInventory();  	BOOL postBuild(); @@ -114,6 +114,8 @@ protected:  	bool isSaveTextureEnabled(const LLSD& userdata);  	void updateItemcountText(); +	void onFocusReceived(); +  private:  	LLFloaterInventoryFinder* getFinder(); diff --git a/indra/newview/llpanelmarketplaceinbox.cpp b/indra/newview/llpanelmarketplaceinbox.cpp new file mode 100644 index 0000000000..af74f8f261 --- /dev/null +++ b/indra/newview/llpanelmarketplaceinbox.cpp @@ -0,0 +1,248 @@ +/** 
 + * @file llpanelmarketplaceinbox.cpp
 + * @brief Panel for marketplace inbox
 + *
 +* $LicenseInfo:firstyear=2011&license=viewerlgpl$
 + * Second Life Viewer Source Code
 + * Copyright (C) 2010, Linden Research, Inc.
 + * 
 + * This library is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU Lesser General Public
 + * License as published by the Free Software Foundation;
 + * version 2.1 of the License only.
 + * 
 + * This library is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 + * Lesser General Public License for more details.
 + * 
 + * You should have received a copy of the GNU Lesser General Public
 + * License along with this library; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 + * 
 + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 + * $/LicenseInfo$
 + */
 +
 +#include "llviewerprecompiledheaders.h"
 +
 +#include "llpanelmarketplaceinbox.h"
 +
 +#include "llappviewer.h"
 +#include "llbutton.h"
 +#include "llinventorypanel.h"
 +#include "llfolderview.h"
 +#include "llsidepanelinventory.h"
 +
 +
 +#define SUPPORTING_FRESH_ITEM_COUNT	0
 +
 +
 +static LLRegisterPanelClassWrapper<LLPanelMarketplaceInbox> t_panel_marketplace_inbox("panel_marketplace_inbox");
 +
 +const LLPanelMarketplaceInbox::Params& LLPanelMarketplaceInbox::getDefaultParams() 
 +{ 
 +	return LLUICtrlFactory::getDefaultParams<LLPanelMarketplaceInbox>(); 
 +}
 +
 +// protected
 +LLPanelMarketplaceInbox::LLPanelMarketplaceInbox(const Params& p)
 +	: LLPanel(p)
 +	, mInventoryPanel(NULL)
 +{
 +}
 +
 +LLPanelMarketplaceInbox::~LLPanelMarketplaceInbox()
 +{
 +}
 +
 +// virtual
 +BOOL LLPanelMarketplaceInbox::postBuild()
 +{
 +	LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLPanelMarketplaceInbox::handleLoginComplete, this));
 +
 +	LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLPanelMarketplaceInbox::onFocusReceived, this));
 +	
 +	return TRUE;
 +}
 +
 +void LLPanelMarketplaceInbox::onSelectionChange()
 +{
 +	LLSidepanelInventory* sidepanel_inventory = dynamic_cast<LLSidepanelInventory*>(LLSideTray::getInstance()->getPanel("sidepanel_inventory"));
 +		
 +	sidepanel_inventory->updateVerbs();
 +}
 +
 +
 +void LLPanelMarketplaceInbox::handleLoginComplete()
 +{
 +	// Set us up as the class to drive the badge value for the sidebar_inventory button
 +	LLSideTray::getInstance()->setTabButtonBadgeDriver("sidebar_inventory", this);
 +}
 +
 +void LLPanelMarketplaceInbox::setupInventoryPanel()
 +{
 +	LLView * inbox_inventory_placeholder = getChild<LLView>("inbox_inventory_placeholder");
 +	LLView * inbox_inventory_parent = inbox_inventory_placeholder->getParent();
 +
 +	mInventoryPanel = 
 +		LLUICtrlFactory::createFromFile<LLInventoryPanel>("panel_inbox_inventory.xml",
 +														  inbox_inventory_parent,
 +														  LLInventoryPanel::child_registry_t::instance());
 +	
 +	// Reshape the inventory to the proper size
 +	LLRect inventory_placeholder_rect = inbox_inventory_placeholder->getRect();
 +	mInventoryPanel->setShape(inventory_placeholder_rect);
 +	
 +	// Set the sort order newest to oldest, and a selection change callback
 +	mInventoryPanel->setSortOrder(LLInventoryFilter::SO_DATE);	
 +	mInventoryPanel->setSelectCallback(boost::bind(&LLPanelMarketplaceInbox::onSelectionChange, this));
 +
 +	// Set up the note to display when the inbox is empty
 +	mInventoryPanel->getFilter()->setEmptyLookupMessage("InventoryInboxNoItems");
 +	
 +	// Hide the placeholder text
 +	inbox_inventory_placeholder->setVisible(FALSE);
 +}
 +
 +void LLPanelMarketplaceInbox::onFocusReceived()
 +{
 +	LLSidepanelInventory * sidepanel_inventory = LLSideTray::getInstance()->getPanel<LLSidepanelInventory>("sidepanel_inventory");
 +
 +	if (sidepanel_inventory)
 +	{
 +		LLInventoryPanel * inv_panel = sidepanel_inventory->getActivePanel();
 +
 +		if (inv_panel)
 +		{
 +			inv_panel->clearSelection();
 +		}
 +	
 +		LLInventoryPanel * outbox_panel = sidepanel_inventory->findChild<LLInventoryPanel>("inventory_outbox");
 +
 +		if (outbox_panel)
 +		{
 +			outbox_panel->clearSelection();
 +		}
 +		
 +		sidepanel_inventory->updateVerbs();
 +	}
 +}
 +
 +BOOL LLPanelMarketplaceInbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string& tooltip_msg)
 +{
 +	*accept = ACCEPT_NO;
 +	return TRUE;
 +}
 +
 +U32 LLPanelMarketplaceInbox::getFreshItemCount() const
 +{
 +#if SUPPORTING_FRESH_ITEM_COUNT
 +	
 +	//
 +	// NOTE: When turning this on, be sure to test the no inbox/outbox case because this code probably
 +	//       will return "2" for the Inventory and LIBRARY top-levels when that happens.
 +	//
 +	
 +	U32 fresh_item_count = 0;
 +
 +	if (mInventoryPanel)
 +	{
 +		const LLFolderViewFolder * inbox_folder = mInventoryPanel->getRootFolder();
 +		
 +		if (inbox_folder)
 +		{
 +			LLFolderViewFolder::folders_t::const_iterator folders_it = inbox_folder->getFoldersBegin();
 +			LLFolderViewFolder::folders_t::const_iterator folders_end = inbox_folder->getFoldersEnd();
 +
 +			for (; folders_it != folders_end; ++folders_it)
 +			{
 +				const LLFolderViewFolder * folder = *folders_it;
 +
 +				// TODO: Replace this check with new "fresh" flag
 +				if (folder->getCreationDate() > 1500)
 +				{
 +					fresh_item_count++;
 +				}
 +			}
 +		}
 +	}
 +
 +	return fresh_item_count;
 +#else
 +	return getTotalItemCount();
 +#endif
 +}
 +
 +U32 LLPanelMarketplaceInbox::getTotalItemCount() const
 +{
 +	U32 item_count = 0;
 +	
 +	if (mInventoryPanel)
 +	{
 +		const LLFolderViewFolder * inbox_folder = mInventoryPanel->getRootFolder();
 +		
 +		if (inbox_folder)
 +		{
 +			item_count += inbox_folder->getFoldersCount();
 +		}
 +	}
 +	
 +	return item_count;
 +}
 +
 +std::string LLPanelMarketplaceInbox::getBadgeString() const
 +{
 +	std::string item_count_str("");
 +
 +	// If the inbox is visible, and the side panel is collapsed or expanded and not the inventory panel
 +	if (getParent()->getVisible() &&
 +		(LLSideTray::getInstance()->getCollapsed() || !LLSideTray::getInstance()->isPanelActive("sidepanel_inventory")))
 +	{
 +		U32 item_count = getFreshItemCount();
 +
 +		if (item_count)
 +		{
 +			item_count_str = llformat("%d", item_count);
 +		}
 +	}
 +
 +	return item_count_str;
 +}
 +
 +void LLPanelMarketplaceInbox::draw()
 +{
 +	U32 item_count = getTotalItemCount();
 +
 +	LLView * fresh_new_count_view = getChildView("inbox_fresh_new_count");
 +
 +	if (item_count > 0)
 +	{
 +		std::string item_count_str = llformat("%d", item_count);
 +
 +		LLStringUtil::format_map_t args;
 +		args["[NUM]"] = item_count_str;
 +		getChild<LLButton>("inbox_btn")->setLabel(getString("InboxLabelWithArg", args));
 +
 +#if SUPPORTING_FRESH_ITEM_COUNT
 +		// set green text to fresh item count
 +		U32 fresh_item_count = getFreshItemCount();
 +		fresh_new_count_view->setVisible((fresh_item_count > 0));
 +
 +		if (fresh_item_count > 0)
 +		{
 +			getChild<LLUICtrl>("inbox_fresh_new_count")->setTextArg("[NUM]", llformat("%d", fresh_item_count));
 +		}
 +#else
 +		fresh_new_count_view->setVisible(FALSE);
 +#endif
 +	}
 +	else
 +	{
 +		getChild<LLButton>("inbox_btn")->setLabel(getString("InboxLabelNoArg"));
 +
 +		fresh_new_count_view->setVisible(FALSE);
 +	}
 +		
 +	LLPanel::draw();
 +}
 diff --git a/indra/newview/llpanelmarketplaceinbox.h b/indra/newview/llpanelmarketplaceinbox.h new file mode 100644 index 0000000000..4ecea29304 --- /dev/null +++ b/indra/newview/llpanelmarketplaceinbox.h @@ -0,0 +1,78 @@ +/**  + * @file llpanelmarketplaceinbox.h + * @brief Panel for marketplace inbox + * +* $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLPANELMARKETPLACEINBOX_H +#define LL_LLPANELMARKETPLACEINBOX_H + +#include "llpanel.h" +#include "llsidetray.h" + +class LLInventoryPanel; + +class LLPanelMarketplaceInbox : public LLPanel, public LLSideTrayTabBadgeDriver +{ +public: + +	struct Params :	public LLInitParam::Block<Params, LLPanel::Params> +	{ +		Params() {} +	}; + +	LOG_CLASS(LLPanelMarketplaceInbox); + +	// RN: for some reason you can't just use LLUICtrlFactory::getDefaultParams as a default argument in VC8 +	static const LLPanelMarketplaceInbox::Params& getDefaultParams(); + +	LLPanelMarketplaceInbox(const Params& p = getDefaultParams()); +	~LLPanelMarketplaceInbox(); + +	/*virtual*/ BOOL postBuild(); +	 +	/*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string& tooltip_msg); + +	/*virtual*/ void draw(); +	 +	void setupInventoryPanel(); + +	U32 getFreshItemCount() const; +	U32 getTotalItemCount() const; + +	std::string getBadgeString() const; + +private: +	void handleLoginComplete(); + +	void onSelectionChange(); + +	void onFocusReceived(); + +private: +	LLInventoryPanel* mInventoryPanel; +}; + + +#endif //LL_LLPANELMARKETPLACEINBOX_H + diff --git a/indra/newview/llpanelmarketplaceinboxinventory.cpp b/indra/newview/llpanelmarketplaceinboxinventory.cpp new file mode 100644 index 0000000000..b644f0e5cb --- /dev/null +++ b/indra/newview/llpanelmarketplaceinboxinventory.cpp @@ -0,0 +1,167 @@ +/**  + * @file llpanelmarketplaceinboxinventory.cpp + * @brief LLInboxInventoryPanel  class definition + * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llpanelmarketplaceinboxinventory.h" + +#include "llfolderview.h" +#include "llfoldervieweventlistener.h" +#include "llinventorybridge.h" +#include "llinventoryfunctions.h" +#include "llpanellandmarks.h" +#include "llplacesinventorybridge.h" +#include "llviewerfoldertype.h" + + +// +// statics +// + +static LLDefaultChildRegistry::Register<LLInboxInventoryPanel> r1("inbox_inventory_panel"); +static LLDefaultChildRegistry::Register<LLInboxFolderViewFolder> r2("inbox_folder_view_folder"); + + +// +// LLInboxInventoryPanel Implementation +// + +LLInboxInventoryPanel::LLInboxInventoryPanel(const LLInboxInventoryPanel::Params& p) +	: LLInventoryPanel(p) +{ +} + +LLInboxInventoryPanel::~LLInboxInventoryPanel() +{ +} + +// virtual +void LLInboxInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params) +{ +	// Determine the root folder in case specified, and +	// build the views starting with that folder. +	 +	LLUUID root_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false); +	 +	// leslie -- temporary HACK to work around sim not creating inbox and outbox with proper system folder type +	if (root_id.isNull()) +	{ +		std::string start_folder_name(params.start_folder()); +		 +		LLInventoryModel::cat_array_t* cats; +		LLInventoryModel::item_array_t* items; +		 +		gInventory.getDirectDescendentsOf(gInventory.getRootFolderID(), cats, items); +		 +		if (cats) +		{ +			for (LLInventoryModel::cat_array_t::const_iterator cat_it = cats->begin(); cat_it != cats->end(); ++cat_it) +			{ +				LLInventoryCategory* cat = *cat_it; +				 +				if (cat->getName() == start_folder_name) +				{ +					root_id = cat->getUUID(); +					break; +				} +			} +		} +		 +		if (root_id == LLUUID::null) +		{ +			llwarns << "No category found that matches inbox inventory panel start_folder: " << start_folder_name << llendl; +		} +	} +	// leslie -- end temporary HACK +	 +	if (root_id == LLUUID::null) +	{ +		llwarns << "Inbox inventory panel has no root folder!" << llendl; +		root_id = LLUUID::generateNewID(); +	} +	 +	LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY, +																	LLAssetType::AT_CATEGORY, +																	LLInventoryType::IT_CATEGORY, +																	this, +																	NULL, +																	root_id); +	 +	mFolderRoot = createFolderView(new_listener, params.use_label_suffix()); +} + +LLFolderViewFolder * LLInboxInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge) +{ +	LLInboxFolderViewFolder::Params params; +	 +	params.name = bridge->getDisplayName(); +	params.icon = bridge->getIcon(); +	params.icon_open = bridge->getOpenIcon(); +	 +	if (mShowItemLinkOverlays) // if false, then links show up just like normal items +	{ +		params.icon_overlay = LLUI::getUIImage("Inv_Link"); +	} +	 +	params.root = mFolderRoot; +	params.listener = bridge; +	params.tool_tip = params.name; +	 +	return LLUICtrlFactory::create<LLInboxFolderViewFolder>(params); +} + + +// +// LLInboxFolderViewFolder Implementation +// + +LLInboxFolderViewFolder::LLInboxFolderViewFolder(const Params& p) +	: LLFolderViewFolder(p) +	, LLBadgeOwner(getHandle()) +	, mFresh(false) +{ +	initBadgeParams(p.new_badge()); +} + +LLInboxFolderViewFolder::~LLInboxFolderViewFolder() +{ +} + +// virtual +void LLInboxFolderViewFolder::draw() +{ +	if (!badgeHasParent()) +	{ +		addBadgeToParentPanel(); +	} +	 +	setBadgeVisibility(mFresh); + +	LLFolderViewFolder::draw(); +} + + +// eof diff --git a/indra/newview/llpanelmarketplaceinboxinventory.h b/indra/newview/llpanelmarketplaceinboxinventory.h new file mode 100644 index 0000000000..8f198c41c1 --- /dev/null +++ b/indra/newview/llpanelmarketplaceinboxinventory.h @@ -0,0 +1,77 @@ +/**  + * @file llpanelmarketplaceinboxinventory.h + * @brief LLInboxInventoryPanel class declaration + * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_INBOXINVENTORYPANEL_H +#define LL_INBOXINVENTORYPANEL_H + + +#include "llbadgeowner.h" +#include "llinventorypanel.h" +#include "llfolderviewitem.h" + +class LLInboxInventoryPanel : public LLInventoryPanel +{ +public: +	struct Params : public LLInitParam::Block<Params, LLInventoryPanel::Params> +	{ +		Params() {} +	}; +	 +	LLInboxInventoryPanel(const Params& p); +	~LLInboxInventoryPanel(); + +	// virtual +	void buildFolderView(const LLInventoryPanel::Params& params); + +	// virtual +	class LLFolderViewFolder*	createFolderViewFolder(LLInvFVBridge * bridge); +}; + + +class LLInboxFolderViewFolder : public LLFolderViewFolder, public LLBadgeOwner +{ +public: +	struct Params : public LLInitParam::Block<Params, LLFolderViewFolder::Params> +	{ +		Optional<LLBadge::Params>	new_badge; +		 +		Params() +		: new_badge("new_badge") +		{ +		} +	}; +	 +	LLInboxFolderViewFolder(const Params& p); +	~LLInboxFolderViewFolder(); +	 +	void draw(); +	 +protected: +	bool	mFresh; +}; + + +#endif //LL_INBOXINVENTORYPANEL_H diff --git a/indra/newview/llpanelmarketplaceoutbox.cpp b/indra/newview/llpanelmarketplaceoutbox.cpp new file mode 100644 index 0000000000..74d0de3b30 --- /dev/null +++ b/indra/newview/llpanelmarketplaceoutbox.cpp @@ -0,0 +1,209 @@ +/**  + * @file llpanelmarketplaceoutbox.cpp + * @brief Panel for marketplace outbox + * +* $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llpanelmarketplaceoutbox.h" + +#include "llappviewer.h" +#include "llbutton.h" +#include "llcoros.h" +#include "lleventcoro.h" +#include "llinventorypanel.h" +#include "llloadingindicator.h" +#include "llpanelmarketplaceinbox.h" +#include "llsidepanelinventory.h" +#include "llsidetray.h" +#include "lltimer.h" + + +static LLRegisterPanelClassWrapper<LLPanelMarketplaceOutbox> t_panel_marketplace_outbox("panel_marketplace_outbox"); + +const LLPanelMarketplaceOutbox::Params& LLPanelMarketplaceOutbox::getDefaultParams()  +{  +	return LLUICtrlFactory::getDefaultParams<LLPanelMarketplaceOutbox>();  +} + +// protected +LLPanelMarketplaceOutbox::LLPanelMarketplaceOutbox(const Params& p) +	: LLPanel(p) +	, mInventoryPanel(NULL) +	, mSyncButton(NULL) +	, mSyncIndicator(NULL) +	, mSyncInProgress(false) +{ +} + +LLPanelMarketplaceOutbox::~LLPanelMarketplaceOutbox() +{ +} + +// virtual +BOOL LLPanelMarketplaceOutbox::postBuild() +{ +	LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLPanelMarketplaceOutbox::handleLoginComplete, this)); +	 +	LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLPanelMarketplaceOutbox::onFocusReceived, this)); + +	return TRUE; +} + +void LLPanelMarketplaceOutbox::handleLoginComplete() +{ +	mSyncButton = getChild<LLButton>("outbox_sync_btn"); +	mSyncButton->setCommitCallback(boost::bind(&LLPanelMarketplaceOutbox::onSyncButtonClicked, this)); +	mSyncButton->setEnabled(!isOutboxEmpty()); +	 +	mSyncIndicator = getChild<LLLoadingIndicator>("outbox_sync_indicator"); +} + +void LLPanelMarketplaceOutbox::onFocusReceived() +{ +	LLSidepanelInventory * sidepanel_inventory = LLSideTray::getInstance()->getPanel<LLSidepanelInventory>("sidepanel_inventory"); + +	if (sidepanel_inventory) +	{ +		LLInventoryPanel * inv_panel = sidepanel_inventory->getActivePanel(); + +		if (inv_panel) +		{ +			inv_panel->clearSelection(); +		} + +		LLInventoryPanel * inbox_panel = sidepanel_inventory->findChild<LLInventoryPanel>("inventory_inbox"); + +		if (inbox_panel) +		{ +			inbox_panel->clearSelection(); +		} +		 +		sidepanel_inventory->updateVerbs(); +	} +} + +void LLPanelMarketplaceOutbox::onSelectionChange() +{ +	LLSidepanelInventory* sidepanel_inventory = dynamic_cast<LLSidepanelInventory*>(LLSideTray::getInstance()->getPanel("sidepanel_inventory")); +	 +	sidepanel_inventory->updateVerbs(); +} + +void LLPanelMarketplaceOutbox::setupInventoryPanel() +{ +	LLView * outbox_inventory_placeholder = getChild<LLView>("outbox_inventory_placeholder"); +	LLView * outbox_inventory_parent = outbox_inventory_placeholder->getParent(); +	 +	mInventoryPanel =  +		LLUICtrlFactory::createFromFile<LLInventoryPanel>("panel_outbox_inventory.xml", +														  outbox_inventory_parent, +														  LLInventoryPanel::child_registry_t::instance()); +	 +	// Reshape the inventory to the proper size +	LLRect inventory_placeholder_rect = outbox_inventory_placeholder->getRect(); +	mInventoryPanel->setShape(inventory_placeholder_rect); +	 +	// Set the sort order newest to oldest, and a selection change callback +	mInventoryPanel->setSortOrder(LLInventoryFilter::SO_DATE);	 +	mInventoryPanel->setSelectCallback(boost::bind(&LLPanelMarketplaceOutbox::onSelectionChange, this)); +	 +	// Set up the note to display when the outbox is empty +	mInventoryPanel->getFilter()->setEmptyLookupMessage("InventoryOutboxNoItems"); +	 +	// Hide the placeholder text +	outbox_inventory_placeholder->setVisible(FALSE); +} + +bool LLPanelMarketplaceOutbox::isOutboxEmpty() const +{ +	// TODO: Check for contents of outbox + +	return false; +} + +bool LLPanelMarketplaceOutbox::isSyncInProgress() const +{ +	return mSyncInProgress; +} + + +std::string gTimeDelayDebugFunc = ""; + +void timeDelay(LLCoros::self& self, LLPanelMarketplaceOutbox* outboxPanel) +{ +	waitForEventOn(self, "mainloop"); + +	LLTimer delayTimer; +	delayTimer.reset(); +	delayTimer.setTimerExpirySec(5.0f); + +	while (!delayTimer.hasExpired()) +	{ +		waitForEventOn(self, "mainloop"); +	} + +	outboxPanel->onSyncComplete(); + +	gTimeDelayDebugFunc = ""; +} + +void LLPanelMarketplaceOutbox::onSyncButtonClicked() +{ +	// TODO: Actually trigger sync to marketplace + +	mSyncInProgress = true; +	updateSyncButtonStatus(); + +	// Set a timer (for testing only) + +    gTimeDelayDebugFunc = LLCoros::instance().launch("LLPanelMarketplaceOutbox timeDelay", boost::bind(&timeDelay, _1, this)); +} + +void LLPanelMarketplaceOutbox::onSyncComplete() +{ +	mSyncInProgress = false; + +	updateSyncButtonStatus(); +} + +void LLPanelMarketplaceOutbox::updateSyncButtonStatus() +{ +	if (isSyncInProgress()) +	{ +		mSyncButton->setVisible(false); + +		mSyncIndicator->setVisible(true); +		mSyncIndicator->reset(); +		mSyncIndicator->start(); +	} +	else +	{ +		mSyncIndicator->stop(); +		mSyncIndicator->setVisible(false); + +		mSyncButton->setVisible(true); +		mSyncButton->setEnabled(!isOutboxEmpty()); +	} +} diff --git a/indra/newview/llpanelmarketplaceoutbox.h b/indra/newview/llpanelmarketplaceoutbox.h new file mode 100644 index 0000000000..1b502127ef --- /dev/null +++ b/indra/newview/llpanelmarketplaceoutbox.h @@ -0,0 +1,82 @@ +/**  + * @file llpanelmarketplaceoutbox.h + * @brief Panel for marketplace outbox + * +* $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLPANELMARKETPLACEOUTBOX_H +#define LL_LLPANELMARKETPLACEOUTBOX_H + +#include "llpanel.h" + + +class LLButton; +class LLInventoryPanel; +class LLLoadingIndicator; + + +class LLPanelMarketplaceOutbox : public LLPanel +{ +public: +	 +	struct Params :	public LLInitParam::Block<Params, LLPanel::Params> +	{ +		Params() {} +	}; +	 +	LOG_CLASS(LLPanelMarketplaceOutbox); + +	// RN: for some reason you can't just use LLUICtrlFactory::getDefaultParams as a default argument in VC8 +	static const LLPanelMarketplaceOutbox::Params& getDefaultParams(); +	 +	LLPanelMarketplaceOutbox(const Params& p = getDefaultParams()); +	~LLPanelMarketplaceOutbox(); + +	/*virtual*/ BOOL postBuild(); + +	void setupInventoryPanel(); + +	bool isOutboxEmpty() const; +	bool isSyncInProgress() const; + +	void onSyncComplete(); + +protected: +	void onSyncButtonClicked(); +	void updateSyncButtonStatus(); + +	void handleLoginComplete(); +	void onFocusReceived(); +	void onSelectionChange(); + +private: +	LLInventoryPanel *		mInventoryPanel; + +	LLButton *				mSyncButton; +	LLLoadingIndicator *	mSyncIndicator; +	bool					mSyncInProgress; +}; + + +#endif //LL_LLPANELMARKETPLACEOUTBOX_H + diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index bfe6cab52f..e3b61f695a 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -44,6 +44,7 @@  #include "llcallbacklist.h"  #include "llbuycurrencyhtml.h"  #include "llfloaterreg.h" +#include "llfolderview.h"  #include "llinventorybridge.h"  #include "llinventorydefines.h"  #include "llinventoryfilter.h" @@ -58,8 +59,10 @@  #include "llselectmgr.h"  #include "llsidetray.h"  #include "llstatusbar.h" +#include "lltooldraganddrop.h"  #include "lltrans.h"  #include "llviewerassettype.h" +#include "llviewerinventory.h"  #include "llviewerregion.h"  #include "llviewerobjectlist.h"  #include "llviewermessage.h" @@ -761,7 +764,7 @@ void LLTaskCategoryBridge::openItem()  BOOL LLTaskCategoryBridge::startDrag(EDragAndDropType* type, LLUUID* id) const  {  	//llinfos << "LLTaskInvFVBridge::startDrag()" << llendl; -	if(mPanel) +	if(mPanel && mUUID.notNull())  	{  		LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());  		if(object) @@ -1349,79 +1352,81 @@ LLTaskInvFVBridge* LLTaskInvFVBridge::createObjectBridge(LLPanelObjectInventory*  	LLTaskInvFVBridge* new_bridge = NULL;  	const LLInventoryItem* item = dynamic_cast<LLInventoryItem*>(object);  	const U32 itemflags = ( NULL == item ? 0 : item->getFlags() ); -	LLAssetType::EType type = object->getType(); +	LLAssetType::EType type = object ? object->getType() : LLAssetType::AT_CATEGORY; +	LLUUID object_id = object ? object->getUUID() : LLUUID::null; +	std::string object_name = object ? object->getName() : std::string();  	switch(type)  	{  	case LLAssetType::AT_TEXTURE:  		new_bridge = new LLTaskTextureBridge(panel, -						     object->getUUID(), -						     object->getName()); +						     object_id, +						     object_name);  		break;  	case LLAssetType::AT_SOUND:  		new_bridge = new LLTaskSoundBridge(panel, -						   object->getUUID(), -						   object->getName()); +						   object_id, +						   object_name);  		break;  	case LLAssetType::AT_LANDMARK:  		new_bridge = new LLTaskLandmarkBridge(panel, -						      object->getUUID(), -						      object->getName()); +						      object_id, +						      object_name);  		break;  	case LLAssetType::AT_CALLINGCARD:  		new_bridge = new LLTaskCallingCardBridge(panel, -							 object->getUUID(), -							 object->getName()); +							 object_id, +							 object_name);  		break;  	case LLAssetType::AT_SCRIPT:  		// OLD SCRIPTS DEPRECATED - JC  		llwarns << "Old script" << llendl;  		//new_bridge = new LLTaskOldScriptBridge(panel, -		//									   object->getUUID(), -		//									   object->getName()); +		//									   object_id, +		//									   object_name);  		break;  	case LLAssetType::AT_OBJECT:  		new_bridge = new LLTaskObjectBridge(panel, -						    object->getUUID(), -						    object->getName(), +						    object_id, +						    object_name,  						    itemflags);  		break;  	case LLAssetType::AT_NOTECARD:  		new_bridge = new LLTaskNotecardBridge(panel, -						      object->getUUID(), -						      object->getName()); +						      object_id, +						      object_name);  		break;  	case LLAssetType::AT_ANIMATION:  		new_bridge = new LLTaskAnimationBridge(panel, -						       object->getUUID(), -						       object->getName()); +						       object_id, +						       object_name);  		break;  	case LLAssetType::AT_GESTURE:  		new_bridge = new LLTaskGestureBridge(panel, -						     object->getUUID(), -						     object->getName()); +						     object_id, +						     object_name);  		break;  	case LLAssetType::AT_CLOTHING:  	case LLAssetType::AT_BODYPART:  		new_bridge = new LLTaskWearableBridge(panel, -						      object->getUUID(), -						      object->getName(), +						      object_id, +						      object_name,  						      itemflags);  		break;  	case LLAssetType::AT_CATEGORY:  		new_bridge = new LLTaskCategoryBridge(panel, -						      object->getUUID(), -						      object->getName()); +						      object_id, +						      object_name);  		break;  	case LLAssetType::AT_LSL_TEXT:  		new_bridge = new LLTaskLSLBridge(panel, -						 object->getUUID(), -						 object->getName()); +						 object_id, +						 object_name);  		break;  	case LLAssetType::AT_MESH:  		new_bridge = new LLTaskMeshBridge(panel, -										  object->getUUID(), -										  object->getName()); +										  object_id, +										  object_name);  		break;  	default:  		llinfos << "Unhandled inventory type (llassetstorage.h): " @@ -1521,6 +1526,7 @@ void LLPanelObjectInventory::reset()  	p.task_id = getTaskUUID();  	p.parent_panel = this;  	p.tool_tip= LLTrans::getString("PanelContentsTooltip"); +	p.listener = LLTaskInvFVBridge::createObjectBridge(this, NULL);  	mFolders = LLUICtrlFactory::create<LLFolderView>(p);  	// this ensures that we never say "searching..." or "no items found"  	mFolders->getFilter()->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS); diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index 62f582c343..35e2e96bab 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -36,7 +36,7 @@  #include "lloutfitobserver.h"  #include "llcofwearables.h"  #include "llfilteredwearablelist.h" -#include "llfolderviewitem.h" +#include "llfolderview.h"  #include "llinventory.h"  #include "llinventoryitemslist.h"  #include "llviewercontrol.h" diff --git a/indra/newview/llpanelwearing.cpp b/indra/newview/llpanelwearing.cpp index 911a9e5dda..0645fd8a54 100644 --- a/indra/newview/llpanelwearing.cpp +++ b/indra/newview/llpanelwearing.cpp @@ -174,8 +174,8 @@ LLPanelWearing::~LLPanelWearing()  	if (gInventory.containsObserver(mCategoriesObserver))  	{  		gInventory.removeObserver(mCategoriesObserver); -		delete mCategoriesObserver;  	} +	delete mCategoriesObserver;  }  BOOL LLPanelWearing::postBuild() diff --git a/indra/newview/llplacesinventorypanel.cpp b/indra/newview/llplacesinventorypanel.cpp index 29e262199e..f7823f4fe8 100644 --- a/indra/newview/llplacesinventorypanel.cpp +++ b/indra/newview/llplacesinventorypanel.cpp @@ -35,6 +35,7 @@  #include "llinventoryfunctions.h"  #include "llpanellandmarks.h"  #include "llplacesinventorybridge.h" +#include "llviewerfoldertype.h"  static LLDefaultChildRegistry::Register<LLPlacesInventoryPanel> r("places_inventory_panel"); @@ -56,72 +57,44 @@ LLPlacesInventoryPanel::~LLPlacesInventoryPanel()  	delete mSavedFolderState;  } -BOOL LLPlacesInventoryPanel::postBuild() +void LLPlacesInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)  { -	LLInventoryPanel::postBuild(); +	// Determine the root folder in case specified, and +	// build the views starting with that folder. +	const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(params.start_folder); -	// clear Contents(); -	{ -		mFolderRoot->destroyView(); -		mFolderRoot->getParent()->removeChild(mFolderRoot); -		mFolderRoot->die(); - -		if( mScroller ) -		{ -			removeChild( mScroller ); -			mScroller->die(); -			mScroller = NULL; -		} -		mFolderRoot = NULL; -	} - - -	mCommitCallbackRegistrar.pushScope(); // registered as a widget; need to push callback scope ourselves +	LLUUID root_id; -	// create root folder +	if ("LIBRARY" == params.start_folder())  	{ -		LLRect folder_rect(0, -			0, -			getRect().getWidth(), -			0); -		LLPlacesFolderView::Params p; -		p.name = getName(); -		p.title = getLabel(); -		p.rect = folder_rect; -		p.parent_panel = this; -		mFolderRoot = (LLFolderView*)LLUICtrlFactory::create<LLPlacesFolderView>(p); -		mFolderRoot->setAllowMultiSelect(mAllowMultiSelect); +		root_id = gInventory.getLibraryRootFolderID();  	} - -	mCommitCallbackRegistrar.popScope(); - -	mFolderRoot->setCallbackRegistrar(&mCommitCallbackRegistrar); - -	// scroller +	else  	{ -		LLRect scroller_view_rect = getRect(); -		scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom); -		LLScrollContainer::Params p; -		p.name("Inventory Scroller"); -		p.rect(scroller_view_rect); -		p.follows.flags(FOLLOWS_ALL); -		p.reserve_scroll_corner(true); -		p.tab_stop(true); -		mScroller = LLUICtrlFactory::create<LLScrollContainer>(p); +		root_id = (preferred_type != LLFolderType::FT_NONE ? gInventory.findCategoryUUIDForType(preferred_type) : LLUUID::null);  	} -	addChild(mScroller); -	mScroller->addChild(mFolderRoot); - -	mFolderRoot->setScrollContainer(mScroller); -	mFolderRoot->addChild(mFolderRoot->mStatusTextBox); - -	// cut subitems -	mFolderRoot->setUseEllipses(true); - -	return TRUE; +	LLRect folder_rect(0, +		0, +		getRect().getWidth(), +		0); +	LLPlacesFolderView::Params p; +	p.name = getName(); +	p.title = getLabel(); +	p.rect = folder_rect; +	p.listener =  mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY, +													LLAssetType::AT_CATEGORY, +													LLInventoryType::IT_CATEGORY, +													this, +													NULL, +													root_id); +	p.parent_panel = this; +	p.allow_multiselect = mAllowMultiSelect; +	p.use_ellipses = true;	// truncate inventory item text so remove horizontal scroller +	mFolderRoot = (LLFolderView*)LLUICtrlFactory::create<LLPlacesFolderView>(p);  } +  // save current folder open state  void LLPlacesInventoryPanel::saveFolderState()  { diff --git a/indra/newview/llplacesinventorypanel.h b/indra/newview/llplacesinventorypanel.h index 6641871a0b..f647e7f970 100644 --- a/indra/newview/llplacesinventorypanel.h +++ b/indra/newview/llplacesinventorypanel.h @@ -46,7 +46,7 @@ public:  	LLPlacesInventoryPanel(const Params& p);  	~LLPlacesInventoryPanel(); -	/*virtual*/ BOOL postBuild(); +	/*virtual*/ void buildFolderView(const LLInventoryPanel::Params& params);  	void saveFolderState();  	void restoreFolderState(); diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index 9f5c55bad1..f47928b131 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -42,6 +42,7 @@  #include "llinventoryfunctions.h"  #include "llinventorymodel.h"  #include "llinventorymodelbackgroundfetch.h" +#include "llkeyboard.h"  #include "llmultigesture.h"  #include "llnotificationsutil.h"  #include "llradiogroup.h" diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp index 31fde5d58a..028891a90e 100644 --- a/indra/newview/llprogressview.cpp +++ b/indra/newview/llprogressview.cpp @@ -55,23 +55,18 @@ LLProgressView* LLProgressView::sInstance = NULL;  S32 gStartImageWidth = 1;  S32 gStartImageHeight = 1; -const F32 FADE_IN_TIME = 1.f; - -const std::string ANIMATION_FILENAME = "Login Sequence "; -const std::string ANIMATION_SUFFIX = ".jpg"; -const F32 TOTAL_LOGIN_TIME = 10.f;	// seconds, wild guess at time from GL context to actual world view -S32 gLastStartAnimationFrame = 0;	// human-style indexing, first image = 1 -const S32 ANIMATION_FRAMES = 1; //13; +const F32 FADE_TO_WORLD_TIME = 1.0f;  static LLRegisterPanelClassWrapper<LLProgressView> r("progress_view"); -  // XUI: Translate  LLProgressView::LLProgressView()   :	LLPanel(),  	mPercentDone( 0.f ), +	mMediaCtrl( NULL ),  	mMouseDownInActiveArea( false ), -	mUpdateEvents("LLProgressView") +	mUpdateEvents("LLProgressView"), +	mFadeToWorldTimer()  {  	mUpdateEvents.listen("self", boost::bind(&LLProgressView::handleUpdate, this, _1));  } @@ -80,9 +75,14 @@ BOOL LLProgressView::postBuild()  {  	mProgressBar = getChild<LLProgressBar>("login_progress_bar"); +	// media control that is used to play intro video +	mMediaCtrl = getChild<LLMediaCtrl>("login_media_panel"); +	mMediaCtrl->setVisible( false );		// hidden initially +	mMediaCtrl->addObserver( this );		// watch events +  	mCancelBtn = getChild<LLButton>("cancel_btn");  	mCancelBtn->setClickedCallback(  LLProgressView::onCancelButtonClicked, NULL ); -	mFadeTimer.stop(); +	mFadeToWorldTimer.stop();  	getChild<LLTextBox>("title_text")->setText(LLStringExplicit(LLAppViewer::instance()->getSecondLifeTitle())); @@ -125,24 +125,43 @@ BOOL LLProgressView::handleKeyHere(KEY key, MASK mask)  	return TRUE;  } +void LLProgressView::revealIntroPanel() +{ +	// if user hasn't yet seen intro video +	std::string intro_url = gSavedSettings.getString("PostFirstLoginIntroURL"); +	if ( intro_url.length() > 0 &&  +			gSavedSettings.getBOOL("PostFirstLoginIntroViewed" ) == FALSE ) +	{ +		// navigate to intro URL and reveal widget  +		mMediaCtrl->navigateTo( intro_url );	 +		mMediaCtrl->setVisible( TRUE ); + +		// flag as having seen the new user post login intro +		gSavedSettings.setBOOL("PostFirstLoginIntroViewed", TRUE ); +	} +	else +	{ +		// start the timer that will control the fade through to the world view  +		mFadeToWorldTimer.start(); +	} +} +  void LLProgressView::setVisible(BOOL visible)  {  	// hiding progress view  	if (getVisible() && !visible)  	{ -		mFadeTimer.start(); +		LLPanel::setVisible(FALSE);  	}  	// showing progress view -	else if (visible && (!getVisible() || mFadeTimer.getStarted())) +	else if (visible && (!getVisible() || mFadeToWorldTimer.getStarted()))  	{  		setFocus(TRUE); -		mFadeTimer.stop(); -		mProgressTimer.start(); +		mFadeToWorldTimer.stop();  		LLPanel::setVisible(TRUE);  	}   } -  void LLProgressView::draw()  {  	static LLTimer timer; @@ -153,7 +172,7 @@ void LLProgressView::draw()  	{  		LLGLSUIDefault gls_ui;  		gGL.getTexUnit(0)->bind(gStartTexture.get()); -		gGL.color4f(1.f, 1.f, 1.f, mFadeTimer.getStarted() ? clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, FADE_IN_TIME, 1.f, 0.f) : 1.f); +		gGL.color4f(1.f, 1.f, 1.f, 1.f);  		F32 image_aspect = (F32)gStartImageWidth / (F32)gStartImageHeight;  		S32 width = getRect().getWidth();  		S32 height = getRect().getHeight(); @@ -180,16 +199,36 @@ void LLProgressView::draw()  	}  	glPopMatrix(); -	// Handle fade-in animation -	if (mFadeTimer.getStarted()) +	// handle fade out to world view when we're asked to +	if (mFadeToWorldTimer.getStarted())  	{ +		// draw fading panel +		F32 alpha = clamp_rescale(mFadeToWorldTimer.getElapsedTimeF32(), 0.f, FADE_TO_WORLD_TIME, 1.f, 0.f); +		LLViewDrawContext context(alpha);  		LLPanel::draw(); -		if (mFadeTimer.getElapsedTimeF32() > FADE_IN_TIME) + +		// faded out completely - remove panel and reveal world +		if (mFadeToWorldTimer.getElapsedTimeF32() > FADE_TO_WORLD_TIME )  		{ +			mFadeToWorldTimer.stop(); +  			// Fade is complete, release focus  			gFocusMgr.releaseFocusIfNeeded( this ); + +			// turn off panel that hosts intro so we see the world  			LLPanel::setVisible(FALSE); -			mFadeTimer.stop(); + +			// stop observing events since we no longer care +			mMediaCtrl->remObserver( this ); + +			// hide the intro +			mMediaCtrl->setVisible( false ); + +			// navigate away from intro page to something innocuous since 'unload' is broken right now +			//mMediaCtrl->navigateTo( "about:blank" ); + +			// FIXME: this causes a crash that i haven't been able to fix +			mMediaCtrl->unloadMediaSource();	  			gStartTexture = NULL;  		} @@ -307,3 +346,12 @@ bool LLProgressView::onAlertModal(const LLSD& notify)  	}  	return false;  } + +void LLProgressView::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) +{ +	if( event == MEDIA_EVENT_CLOSE_REQUEST ) +	{ +		// the intro web content calls javascript::window.close() when it's done +		mFadeToWorldTimer.start(); +	} +} diff --git a/indra/newview/llprogressview.h b/indra/newview/llprogressview.h index be1744f08a..73dd478e98 100644 --- a/indra/newview/llprogressview.h +++ b/indra/newview/llprogressview.h @@ -28,6 +28,7 @@  #define LL_LLPROGRESSVIEW_H  #include "llpanel.h" +#include "llmediactrl.h"  #include "llframetimer.h"  #include "llevents.h" @@ -35,7 +36,10 @@ class LLImageRaw;  class LLButton;  class LLProgressBar; -class LLProgressView : public LLPanel +class LLProgressView :  +	public LLPanel, +	public LLViewerMediaObserver +  {  public:  	LLProgressView(); @@ -49,25 +53,35 @@ public:  	/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);  	/*virtual*/ void setVisible(BOOL visible); +	// inherited from LLViewerMediaObserver +	/*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event); +  	void setText(const std::string& text);  	void setPercent(const F32 percent);  	// Set it to NULL when you want to eliminate the message.  	void setMessage(const std::string& msg); +	// turns on (under certain circumstances) the into video after login +	void revealIntroPanel(); +  	void setCancelButtonVisible(BOOL b, const std::string& label);  	static void onCancelButtonClicked( void* );  	static void onClickMessage(void*);  	bool onAlertModal(const LLSD& sd); +	// note - this is not just hiding the intro panel - it also hides the parent panel +	// and is used when the intro is finished and we want to show the world +	void removeIntroPanel(); +  protected:  	LLProgressBar* mProgressBar; +	LLMediaCtrl* mMediaCtrl;  	F32 mPercentDone;  	std::string mMessage;  	LLButton*	mCancelBtn; -	LLFrameTimer	mFadeTimer; -	LLFrameTimer mProgressTimer; +	LLFrameTimer mFadeToWorldTimer;  	LLRect mOutlineRect;  	bool mMouseDownInActiveArea; diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index 16729f045a..28ec11d1c7 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -32,6 +32,7 @@  #include "llagentcamera.h"  #include "llagentwearables.h"  #include "llappearancemgr.h" +#include "llfolderview.h"  #include "llinventorypanel.h"  #include "llfiltereditor.h"  #include "llfloaterreg.h" diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp index 31ea542743..65655f82cd 100644 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -29,33 +29,147 @@  #include "llagent.h"  #include "llappearancemgr.h" +#include "llappviewer.h"  #include "llavataractions.h"  #include "llbutton.h" +#include "lldate.h"  #include "llfirstuse.h" +#include "llfoldertype.h" +#include "llhttpclient.h"  #include "llinventorybridge.h"  #include "llinventoryfunctions.h" +#include "llinventorymodel.h" +#include "llinventorymodelbackgroundfetch.h" +#include "llinventoryobserver.h"  #include "llinventorypanel.h" +#include "lllayoutstack.h"  #include "lloutfitobserver.h"  #include "llpanelmaininventory.h" +#include "llpanelmarketplaceinbox.h" +#include "llpanelmarketplaceoutbox.h" +#include "llselectmgr.h"  #include "llsidepaneliteminfo.h"  #include "llsidepaneltaskinfo.h" +#include "llstring.h"  #include "lltabcontainer.h" -#include "llselectmgr.h" +#include "llviewermedia.h"  #include "llweb.h"  static LLRegisterPanelClassWrapper<LLSidepanelInventory> t_inventory("sidepanel_inventory"); -LLSidepanelInventory::LLSidepanelInventory() -	:	LLPanel(), -		mItemPanel(NULL), -		mPanelMainInventory(NULL) +// +// Constants +// + +static const char * const INBOX_EXPAND_TIME_SETTING = "LastInventoryInboxExpand"; + +static const char * const INBOX_BUTTON_NAME = "inbox_btn"; +static const char * const OUTBOX_BUTTON_NAME = "outbox_btn"; + +static const char * const INBOX_LAYOUT_PANEL_NAME = "inbox_layout_panel"; +static const char * const OUTBOX_LAYOUT_PANEL_NAME = "outbox_layout_panel"; +static const char * const MAIN_INVENTORY_LAYOUT_PANEL_NAME = "main_inventory_layout_panel"; + +static const char * const INBOX_INVENTORY_PANEL = "inventory_inbox"; +static const char * const OUTBOX_INVENTORY_PANEL = "inventory_outbox"; + +static const char * const INVENTORY_LAYOUT_STACK_NAME = "inventory_layout_stack"; + +static const char * const MARKETPLACE_INBOX_PANEL = "marketplace_inbox"; +static const char * const MARKETPLACE_OUTBOX_PANEL = "marketplace_outbox"; + +// +// Helpers +// + +class LLInboxOutboxAddedObserver : public LLInventoryCategoryAddedObserver  { +public: +	LLInboxOutboxAddedObserver(LLSidepanelInventory * sidepanelInventory) +		: LLInventoryCategoryAddedObserver() +		, mSidepanelInventory(sidepanelInventory) +	{ +	} +	 +	void done() +	{ +		for (cat_vec_t::iterator it = mAddedCategories.begin(); it != mAddedCategories.end(); ++it) +		{ +			LLViewerInventoryCategory* added_category = *it; +			 +			LLFolderType::EType added_category_type = added_category->getPreferredType(); +			 +			switch (added_category_type) +			{ +				case LLFolderType::FT_INBOX: +					mSidepanelInventory->observeInboxModifications(added_category->getUUID()); +					break; +				case LLFolderType::FT_OUTBOX: +					mSidepanelInventory->observeOutboxModifications(added_category->getUUID()); +					break; +				case LLFolderType::FT_NONE: +					// HACK until sim update to properly create folder with system type +					if (added_category->getName() == "Received Items") +					{ +						mSidepanelInventory->observeInboxModifications(added_category->getUUID()); +					} +					else if (added_category->getName() == "Merchant Outbox") +					{ +						mSidepanelInventory->observeOutboxModifications(added_category->getUUID()); +					} +				default: +					break; +			} +		} +	} +	 +private: +	LLSidepanelInventory * mSidepanelInventory; +}; +// +// Implementation +// + +LLSidepanelInventory::LLSidepanelInventory() +	: LLPanel() +	, mItemPanel(NULL) +	, mPanelMainInventory(NULL) +	, mInboxEnabled(false) +	, mOutboxEnabled(false) +	, mCategoriesObserver(NULL) +	, mInboxOutboxAddedObserver(NULL) +{  	//buildFromFile( "panel_inventory.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder()  }  LLSidepanelInventory::~LLSidepanelInventory()  { +	if (mCategoriesObserver && gInventory.containsObserver(mCategoriesObserver)) +	{ +		gInventory.removeObserver(mCategoriesObserver); +	} +	delete mCategoriesObserver; +	 +	if (mInboxOutboxAddedObserver && gInventory.containsObserver(mInboxOutboxAddedObserver)) +	{ +		gInventory.removeObserver(mInboxOutboxAddedObserver); +	} +	delete mInboxOutboxAddedObserver; +} + +void handleInventoryDisplayInboxChanged() +{ +	LLSidepanelInventory* sidepanel_inventory = dynamic_cast<LLSidepanelInventory*>(LLSideTray::getInstance()->getPanel("sidepanel_inventory")); + +	sidepanel_inventory->enableInbox(gSavedSettings.getBOOL("InventoryDisplayInbox")); +} + +void handleInventoryDisplayOutboxChanged() +{ +	LLSidepanelInventory* sidepanel_inventory = dynamic_cast<LLSidepanelInventory*>(LLSideTray::getInstance()->getPanel("sidepanel_inventory")); + +	sidepanel_inventory->enableOutbox(gSavedSettings.getBOOL("InventoryDisplayOutbox"));  }  BOOL LLSidepanelInventory::postBuild() @@ -85,7 +199,7 @@ BOOL LLSidepanelInventory::postBuild()  		mOverflowBtn = mInventoryPanel->getChild<LLButton>("overflow_btn");  		mOverflowBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onOverflowButtonClicked, this)); -		mPanelMainInventory = mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory"); +		mPanelMainInventory = mInventoryPanel->getChild<LLPanelMainInventory>("panel_main_inventory");  		mPanelMainInventory->setSelectCallback(boost::bind(&LLSidepanelInventory::onSelectionChange, this, _1, _2));  		LLTabContainer* tabs = mPanelMainInventory->getChild<LLTabContainer>("inventory filter tabs");  		tabs->setCommitCallback(boost::bind(&LLSidepanelInventory::updateVerbs, this)); @@ -103,7 +217,7 @@ BOOL LLSidepanelInventory::postBuild()  	// UI elements from item panel  	{ -		mItemPanel = findChild<LLSidepanelItemInfo>("sidepanel__item_panel"); +		mItemPanel = getChild<LLSidepanelItemInfo>("sidepanel__item_panel");  		LLButton* back_btn = mItemPanel->getChild<LLButton>("back_btn");  		back_btn->setClickedCallback(boost::bind(&LLSidepanelInventory::onBackButtonClicked, this)); @@ -119,13 +233,263 @@ BOOL LLSidepanelInventory::postBuild()  		}  	} +	// Marketplace inbox/outbox setup +	{ +		LLLayoutStack* stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME); + +		// Disable user_resize on main inventory panel by default +		stack->setPanelUserResize(MAIN_INVENTORY_LAYOUT_PANEL_NAME, false); +		stack->setPanelUserResize(INBOX_LAYOUT_PANEL_NAME, false); +		stack->setPanelUserResize(OUTBOX_LAYOUT_PANEL_NAME, false); + +		// Collapse both inbox and outbox panels +		stack->collapsePanel(getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME), true); +		stack->collapsePanel(getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME), true); +		 +		// Set up button states and callbacks +		LLButton * inbox_button = getChild<LLButton>(INBOX_BUTTON_NAME); +		LLButton * outbox_button = getChild<LLButton>(OUTBOX_BUTTON_NAME); + +		inbox_button->setToggleState(false); +		outbox_button->setToggleState(false); + +		inbox_button->setCommitCallback(boost::bind(&LLSidepanelInventory::onToggleInboxBtn, this)); +		outbox_button->setCommitCallback(boost::bind(&LLSidepanelInventory::onToggleOutboxBtn, this)); + +		// Set the inbox and outbox visible based on debug settings (final setting comes from http request below) +		enableInbox(gSavedSettings.getBOOL("InventoryDisplayInbox")); +		enableOutbox(gSavedSettings.getBOOL("InventoryDisplayOutbox")); + +		// Trigger callback for after login so we can setup to track inbox and outbox changes after initial inventory load +		LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLSidepanelInventory::handleLoginComplete, this)); +	} + +	gSavedSettings.getControl("InventoryDisplayInbox")->getCommitSignal()->connect(boost::bind(&handleInventoryDisplayInboxChanged)); +	gSavedSettings.getControl("InventoryDisplayOutbox")->getCommitSignal()->connect(boost::bind(&handleInventoryDisplayOutboxChanged)); +  	return TRUE;  } +void LLSidepanelInventory::handleLoginComplete() +{ +	// +	// Track inbox and outbox folder changes +	// + +	const bool do_not_create_folder = false; +	const bool do_not_find_in_library = false; + +	const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, do_not_create_folder, do_not_find_in_library); +	const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, do_not_create_folder, do_not_find_in_library); +	 +	// Set up observer to listen for creation of inbox and outbox if at least one of them doesn't exist +	if (inbox_id.isNull() || outbox_id.isNull()) +	{ +		observeInboxOutboxCreation(); +	} + +	// Set up observer for inbox changes, if we have an inbox already +	if (!inbox_id.isNull()) +	{ +		observeInboxModifications(inbox_id); + +		// Enable the display of the inbox if it exists +		enableInbox(true); +	} +	 +	// Set up observer for outbox changes, if we have an outbox already +	if (!outbox_id.isNull()) +	{ +		observeOutboxModifications(outbox_id); + +		// Enable the display of the outbox if it exists +		//enableOutbox(true); +		// leslie NOTE: Disabling outbox until we support it officially. +	} +} + +void LLSidepanelInventory::observeInboxOutboxCreation() +{ +	// +	// Set up observer to track inbox and outbox folder creation +	// +	 +	if (mInboxOutboxAddedObserver == NULL) +	{ +		mInboxOutboxAddedObserver = new LLInboxOutboxAddedObserver(this); +		 +		gInventory.addObserver(mInboxOutboxAddedObserver); +	} +} + +void LLSidepanelInventory::observeInboxModifications(const LLUUID& inboxID) +{ +	// +	// Track inbox and outbox folder changes +	// +	 +	if (inboxID.isNull()) +	{ +		llwarns << "Attempting to track modifications to non-existant inbox" << llendl; +		return; +	} +	 +	if (mCategoriesObserver == NULL) +	{ +		mCategoriesObserver = new LLInventoryCategoriesObserver(); +		gInventory.addObserver(mCategoriesObserver); +	} +	 +	mCategoriesObserver->addCategory(inboxID, boost::bind(&LLSidepanelInventory::onInboxChanged, this, inboxID)); +	 +	// +	// Trigger a load for the entire contents of the Inbox +	// +	 +	LLInventoryModelBackgroundFetch::instance().start(inboxID); +	 +	// +	// Set up the inbox inventory view +	// +	 +	LLPanelMarketplaceInbox * inbox = getChild<LLPanelMarketplaceInbox>(MARKETPLACE_INBOX_PANEL); +	inbox->setupInventoryPanel(); +} + + +void LLSidepanelInventory::observeOutboxModifications(const LLUUID& outboxID) +{ +	// +	// Track outbox folder changes +	// +	 +	if (outboxID.isNull()) +	{ +		llwarns << "Attempting to track modifications to non-existant outbox" << llendl; +		return; +	} +	 +	if (mCategoriesObserver == NULL) +	{ +		mCategoriesObserver = new LLInventoryCategoriesObserver(); +		gInventory.addObserver(mCategoriesObserver); +	} +	 +	mCategoriesObserver->addCategory(outboxID, boost::bind(&LLSidepanelInventory::onOutboxChanged, this, outboxID)); +	 +	// +	// Set up the outbox inventory view +	// +	 +	LLPanelMarketplaceOutbox * outbox = getChild<LLPanelMarketplaceOutbox>(MARKETPLACE_OUTBOX_PANEL); +	outbox->setupInventoryPanel(); +} + +void LLSidepanelInventory::enableInbox(bool enabled) +{ +	mInboxEnabled = enabled; +	getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME)->setVisible(enabled); +} + +void LLSidepanelInventory::enableOutbox(bool enabled) +{ +	mOutboxEnabled = enabled; +	getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME)->setVisible(enabled); +} + +void LLSidepanelInventory::onInboxChanged(const LLUUID& inbox_id) +{ +	// Trigger a load of the entire inbox so we always know the contents and their creation dates for sorting +	LLInventoryModelBackgroundFetch::instance().start(inbox_id); +	 +	// Expand the inbox since we have fresh items +	LLPanelMarketplaceInbox * inbox = findChild<LLPanelMarketplaceInbox>(MARKETPLACE_INBOX_PANEL); +	if (inbox && (inbox->getFreshItemCount() > 0)) +	{ +		getChild<LLButton>(INBOX_BUTTON_NAME)->setToggleState(true); +		onToggleInboxBtn(); +	}	 +} + +void LLSidepanelInventory::onOutboxChanged(const LLUUID& outbox_id) +{ +	// Perhaps use this to track outbox changes? +} + +bool manageInboxOutboxPanels(LLLayoutStack * stack, +							 LLButton * pressedButton, LLLayoutPanel * pressedPanel, +							 LLButton * otherButton, LLLayoutPanel * otherPanel) +{ +	bool expand = pressedButton->getToggleState(); +	bool otherExpanded = otherButton->getToggleState(); + +	// +	// NOTE: Ideally we could have two panel sizes stored for a collapsed and expanded minimum size. +	//       For now, leave this code disabled because it creates some bad artifacts when expanding +	//       and collapsing the inbox/outbox. +	// +	//S32 smallMinSize = (expand ? pressedPanel->getMinDim() : otherPanel->getMinDim()); +	//S32 pressedMinSize = (expand ? 2 * smallMinSize : smallMinSize); +	//otherPanel->setMinDim(smallMinSize); +	//pressedPanel->setMinDim(pressedMinSize); + +	if (expand && otherExpanded) +	{ +		// Reshape pressedPanel to the otherPanel's height so we preserve the marketplace panel size +		pressedPanel->reshape(pressedPanel->getRect().getWidth(), otherPanel->getRect().getHeight()); + +		stack->collapsePanel(otherPanel, true); +		otherButton->setToggleState(false); +	} + +	stack->collapsePanel(pressedPanel, !expand); + +	// Enable user_resize on main inventory panel only when a marketplace box is expanded +	stack->setPanelUserResize(MAIN_INVENTORY_LAYOUT_PANEL_NAME, expand); + +	return expand; +} + +void LLSidepanelInventory::onToggleInboxBtn() +{ +	LLLayoutStack* stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME); +	LLButton* pressedButton = getChild<LLButton>(INBOX_BUTTON_NAME); +	LLLayoutPanel* pressedPanel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME); +	LLButton* otherButton = getChild<LLButton>(OUTBOX_BUTTON_NAME); +	LLLayoutPanel* otherPanel = getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME); + +	bool inboxExpanded = manageInboxOutboxPanels(stack, pressedButton, pressedPanel, otherButton, otherPanel); + +	if (inboxExpanded) +	{ +		// Save current time as a setting for future new-ness tests +		gSavedSettings.setString(INBOX_EXPAND_TIME_SETTING, LLDate::now().asString()); +	} +} + +void LLSidepanelInventory::onToggleOutboxBtn() +{ +	LLLayoutStack* stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME); +	LLButton* pressedButton = getChild<LLButton>(OUTBOX_BUTTON_NAME); +	LLLayoutPanel* pressedPanel = getChild<LLLayoutPanel>(OUTBOX_LAYOUT_PANEL_NAME); +	LLButton* otherButton = getChild<LLButton>(INBOX_BUTTON_NAME); +	LLLayoutPanel* otherPanel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME); + +	manageInboxOutboxPanels(stack, pressedButton, pressedPanel, otherButton, otherPanel); +} +  void LLSidepanelInventory::onOpen(const LLSD& key)  {  	LLFirstUse::newInventory(false); +	// Expand the inbox if we have fresh items +	LLPanelMarketplaceInbox * inbox = findChild<LLPanelMarketplaceInbox>(MARKETPLACE_INBOX_PANEL); +	if (inbox && (inbox->getFreshItemCount() > 0)) +	{ +		getChild<LLButton>(INBOX_BUTTON_NAME)->setToggleState(true); +		onToggleInboxBtn(); +	} +  	if(key.size() == 0)  		return; @@ -171,26 +535,29 @@ void LLSidepanelInventory::onShopButtonClicked()  void LLSidepanelInventory::performActionOnSelection(const std::string &action)  { -	LLPanelMainInventory *panel_main_inventory = mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory"); +	LLPanelMainInventory *panel_main_inventory = mInventoryPanel->getChild<LLPanelMainInventory>("panel_main_inventory");  	LLFolderViewItem* current_item = panel_main_inventory->getActivePanel()->getRootFolder()->getCurSelectedItem();  	if (!current_item)  	{ -		return; +		LLInventoryPanel* inbox = findChild<LLInventoryPanel>("inventory_inbox"); +		if (inbox) +		{ +			current_item = inbox->getRootFolder()->getCurSelectedItem(); +		} + +		if (!current_item) +		{ +			return; +		}  	} +  	current_item->getListener()->performAction(panel_main_inventory->getActivePanel()->getModel(), action);  }  void LLSidepanelInventory::onWearButtonClicked()  { -	LLPanelMainInventory *panel_main_inventory = mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory"); -	if (!panel_main_inventory) -	{ -		llassert(panel_main_inventory != NULL); -		return; -	} -  	// Get selected items set. -	const std::set<LLUUID> selected_uuids_set = panel_main_inventory->getActivePanel()->getRootFolder()->getSelectionList(); +	const std::set<LLUUID> selected_uuids_set = LLAvatarActions::getInventorySelectedUUIDs();  	if (selected_uuids_set.empty()) return; // nothing selected  	// Convert the set to a vector. @@ -329,31 +696,28 @@ bool LLSidepanelInventory::canShare()  	LLPanelMainInventory* panel_main_inventory =  		mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory"); -	if (!panel_main_inventory) +	LLInventoryPanel* inbox = findChild<LLInventoryPanel>("inventory_inbox"); + +	// Avoid flicker in the Recent tab while inventory is being loaded. +	if ( (!inbox || inbox->getRootFolder()->getSelectionList().empty()) +		&& (panel_main_inventory && !panel_main_inventory->getActivePanel()->getRootFolder()->hasVisibleChildren()) )  	{ -		llwarns << "Failed to get the main inventory panel" << llendl;  		return false;  	} -	LLInventoryPanel* active_panel = panel_main_inventory->getActivePanel(); -	// Avoid flicker in the Recent tab while inventory is being loaded. -	if (!active_panel->getRootFolder()->hasVisibleChildren()) return false; - -	return LLAvatarActions::canShareSelectedItems(active_panel); +	return ( (panel_main_inventory ? LLAvatarActions::canShareSelectedItems(panel_main_inventory->getActivePanel()) : false) +			|| (inbox ? LLAvatarActions::canShareSelectedItems(inbox) : false) );  } +  bool LLSidepanelInventory::canWearSelected()  { -	LLPanelMainInventory* panel_main_inventory = -		mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory"); -	if (!panel_main_inventory) -	{ -		llassert(panel_main_inventory != NULL); +	std::set<LLUUID> selected_uuids = LLAvatarActions::getInventorySelectedUUIDs(); + +	if (selected_uuids.empty())  		return false; -	} -	std::set<LLUUID> selected_uuids = panel_main_inventory->getActivePanel()->getRootFolder()->getSelectionList();  	for (std::set<LLUUID>::const_iterator it = selected_uuids.begin();  		it != selected_uuids.end();  		++it) @@ -366,11 +730,20 @@ bool LLSidepanelInventory::canWearSelected()  LLInventoryItem *LLSidepanelInventory::getSelectedItem()  { -	LLPanelMainInventory *panel_main_inventory = mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory"); +	LLPanelMainInventory *panel_main_inventory = mInventoryPanel->getChild<LLPanelMainInventory>("panel_main_inventory");  	LLFolderViewItem* current_item = panel_main_inventory->getActivePanel()->getRootFolder()->getCurSelectedItem();  	if (!current_item)  	{ -		return NULL; +		LLInventoryPanel* inbox = findChild<LLInventoryPanel>("inventory_inbox"); +		if (inbox) +		{ +			current_item = inbox->getRootFolder()->getCurSelectedItem(); +		} + +		if (!current_item) +		{ +			return NULL; +		}  	}  	const LLUUID &item_id = current_item->getListener()->getUUID();  	LLInventoryItem *item = gInventory.getItem(item_id); @@ -379,9 +752,20 @@ LLInventoryItem *LLSidepanelInventory::getSelectedItem()  U32 LLSidepanelInventory::getSelectedCount()  { -	LLPanelMainInventory *panel_main_inventory = mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory"); +	int count = 0; + +	LLPanelMainInventory *panel_main_inventory = mInventoryPanel->getChild<LLPanelMainInventory>("panel_main_inventory");  	std::set<LLUUID> selection_list = panel_main_inventory->getActivePanel()->getRootFolder()->getSelectionList(); -	return selection_list.size(); +	count += selection_list.size(); + +	LLInventoryPanel* inbox = findChild<LLInventoryPanel>("inventory_inbox"); +	if (inbox) +	{ +		selection_list = inbox->getRootFolder()->getSelectionList(); +		count += selection_list.size(); +	} + +	return count;  }  LLInventoryPanel *LLSidepanelInventory::getActivePanel() diff --git a/indra/newview/llsidepanelinventory.h b/indra/newview/llsidepanelinventory.h index 32c98bc034..9117e3bf27 100644 --- a/indra/newview/llsidepanelinventory.h +++ b/indra/newview/llsidepanelinventory.h @@ -30,6 +30,8 @@  #include "llpanel.h"  class LLFolderViewItem; +class LLInboxOutboxAddedObserver; +class LLInventoryCategoriesObserver;  class LLInventoryItem;  class LLInventoryPanel;  class LLPanelMainInventory; @@ -42,6 +44,14 @@ public:  	LLSidepanelInventory();  	virtual ~LLSidepanelInventory(); +private: +	void handleLoginComplete(); +	 +public: +	void observeInboxOutboxCreation(); +	void observeInboxModifications(const LLUUID& inboxID); +	void observeOutboxModifications(const LLUUID& outboxID); +  	/*virtual*/ BOOL postBuild();  	/*virtual*/ void onOpen(const LLSD& key); @@ -56,6 +66,17 @@ public:  	// checks can share selected item(s)  	bool canShare(); +	void onToggleInboxBtn(); +	void onToggleOutboxBtn(); + +	void enableInbox(bool enabled); +	void enableOutbox(bool enabled); + +	bool isInboxEnabled() const { return mInboxEnabled; } +	bool isOutboxEnabled() const { return mOutboxEnabled; } + +	void updateVerbs(); +  protected:  	// Tracks highlighted (selected) item in inventory panel.  	LLInventoryItem *getSelectedItem(); @@ -63,10 +84,12 @@ protected:  	void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);  	// "wear", "teleport", etc.  	void performActionOnSelection(const std::string &action); -	void updateVerbs();  	bool canWearSelected(); // check whether selected items can be worn +	void onInboxChanged(const LLUUID& inbox_id); +	void onOutboxChanged(const LLUUID& outbox_id); +  	//  	// UI Elements  	// @@ -85,6 +108,7 @@ protected:  	void 						onTeleportButtonClicked();  	void 						onOverflowButtonClicked();  	void 						onBackButtonClicked(); +  private:  	LLButton*					mInfoBtn;  	LLButton*					mShareBtn; @@ -94,6 +118,11 @@ private:  	LLButton*					mOverflowBtn;  	LLButton*					mShopBtn; +	bool						mInboxEnabled; +	bool						mOutboxEnabled; + +	LLInventoryCategoriesObserver* 			mCategoriesObserver; +	LLInboxOutboxAddedObserver*				mInboxOutboxAddedObserver;  };  #endif //LL_LLSIDEPANELINVENTORY_H diff --git a/indra/newview/llsidepanelinventorysubpanel.cpp b/indra/newview/llsidepanelinventorysubpanel.cpp index 37b10b592f..2918bb388a 100644 --- a/indra/newview/llsidepanelinventorysubpanel.cpp +++ b/indra/newview/llsidepanelinventorysubpanel.cpp @@ -46,8 +46,8 @@  ///----------------------------------------------------------------------------  // Default constructor -LLSidepanelInventorySubpanel::LLSidepanelInventorySubpanel() -  : LLPanel(), +LLSidepanelInventorySubpanel::LLSidepanelInventorySubpanel(const LLPanel::Params& p) +  : LLPanel(p),  	mIsDirty(TRUE),  	mIsEditing(FALSE),  	mCancelBtn(NULL), diff --git a/indra/newview/llsidepanelinventorysubpanel.h b/indra/newview/llsidepanelinventorysubpanel.h index b2de7d3b0b..b5cf3aaf17 100644 --- a/indra/newview/llsidepanelinventorysubpanel.h +++ b/indra/newview/llsidepanelinventorysubpanel.h @@ -40,7 +40,7 @@ class LLInventoryItem;  class LLSidepanelInventorySubpanel : public LLPanel  {  public: -	LLSidepanelInventorySubpanel(); +	LLSidepanelInventorySubpanel(const LLPanel::Params& p = getDefaultParams());  	virtual ~LLSidepanelInventorySubpanel();  	/*virtual*/ void setVisible(BOOL visible); diff --git a/indra/newview/llsidepaneliteminfo.cpp b/indra/newview/llsidepaneliteminfo.cpp index fbd2f7ca83..1ce05da849 100644 --- a/indra/newview/llsidepaneliteminfo.cpp +++ b/indra/newview/llsidepaneliteminfo.cpp @@ -130,9 +130,10 @@ void LLObjectInventoryObserver::inventoryChanged(LLViewerObject* object,  static LLRegisterPanelClassWrapper<LLSidepanelItemInfo> t_item_info("sidepanel_item_info");  // Default constructor -LLSidepanelItemInfo::LLSidepanelItemInfo() -  : mItemID(LLUUID::null) -  , mObjectInventoryObserver(NULL) +LLSidepanelItemInfo::LLSidepanelItemInfo(const LLPanel::Params& p) +	: LLSidepanelInventorySubpanel(p) +	, mItemID(LLUUID::null) +	, mObjectInventoryObserver(NULL)  {  	mPropertiesObserver = new LLItemPropertiesObserver(this);  } diff --git a/indra/newview/llsidepaneliteminfo.h b/indra/newview/llsidepaneliteminfo.h index 25be145f64..12aaca923e 100644 --- a/indra/newview/llsidepaneliteminfo.h +++ b/indra/newview/llsidepaneliteminfo.h @@ -44,7 +44,7 @@ class LLPermissions;  class LLSidepanelItemInfo : public LLSidepanelInventorySubpanel  {  public: -	LLSidepanelItemInfo(); +	LLSidepanelItemInfo(const LLPanel::Params& p = getDefaultParams());  	virtual ~LLSidepanelItemInfo();  	/*virtual*/ BOOL postBuild(); diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp index 631b244785..651897a217 100644 --- a/indra/newview/llsidetray.cpp +++ b/indra/newview/llsidetray.cpp @@ -30,6 +30,7 @@  #include "llagentcamera.h"  #include "llappviewer.h" +#include "llbadge.h"  #include "llbottomtray.h"  #include "llfloaterreg.h"  #include "llfirstuse.h" @@ -40,6 +41,7 @@  #include "llfocusmgr.h"  #include "llrootview.h"  #include "llnavigationbar.h" +#include "llpanelmarketplaceinbox.h"  #include "llaccordionctrltab.h" @@ -113,11 +115,14 @@ public:  		Optional<std::string>		image_selected;  		Optional<std::string>		tab_title;  		Optional<std::string>		description; +		Optional<LLBadge::Params>	badge; +		  		Params()  		:	image("image"),  			image_selected("image_selected"),  			tab_title("tab_title","no title"), -			description("description","no description") +			description("description","no description"), +			badge("badge")  		{};  	};  protected: @@ -140,7 +145,6 @@ public:  	static LLSideTrayTab*  createInstance	();  	const std::string& getDescription () const { return mDescription;} -	const std::string& getTabTitle() const { return mTabTitle;}  	void			onOpen		(const LLSD& key); @@ -150,7 +154,10 @@ public:  	BOOL			handleScrollWheel(S32 x, S32 y, S32 clicks); -	LLPanel *getPanel(); +	LLPanel*		getPanel(); + +	LLButton*		createButton(bool allowTearOff, LLUICtrl::commit_callback_t callback); +  private:  	std::string mTabTitle;  	std::string mImage; @@ -158,6 +165,9 @@ private:  	std::string	mDescription;  	LLView*	mMainPanel; + +	bool			mHasBadge; +	LLBadge::Params	mBadgeParams;  };  LLSideTrayTab::LLSideTrayTab(const Params& p) @@ -166,8 +176,10 @@ LLSideTrayTab::LLSideTrayTab(const Params& p)  	mImage(p.image),  	mImageSelected(p.image_selected),  	mDescription(p.description), -	mMainPanel(NULL) +	mMainPanel(NULL), +	mBadgeParams(p.badge)  { +	mHasBadge = p.badge.isProvided();  }  LLSideTrayTab::~LLSideTrayTab() @@ -182,8 +194,6 @@ bool LLSideTrayTab::addChild(LLView* view, S32 tab_group)  	//return res;  } - -  //virtual   BOOL LLSideTrayTab::postBuild()  { @@ -196,7 +206,7 @@ BOOL LLSideTrayTab::postBuild()  	getChild<LLButton>("undock")->setCommitCallback(boost::bind(&LLSideTrayTab::setDocked, this, false));  	getChild<LLButton>("dock")->setCommitCallback(boost::bind(&LLSideTrayTab::setDocked, this, true)); -	return true; +	return LLPanel::postBuild();  }  static const S32 splitter_margin = 1; @@ -523,18 +533,36 @@ public:  		return FALSE;  	} +	void setBadgeDriver(LLSideTrayTabBadgeDriver* driver) +	{ +		mBadgeDriver = driver; +	} +  protected:  	LLSideTrayButton(const LLButton::Params& p) -	: LLButton(p) -	, mDragLastScreenX(0) -	, mDragLastScreenY(0) +		: LLButton(p) +		, mDragLastScreenX(0) +		, mDragLastScreenY(0) +		, mBadgeDriver(NULL)  	{}  	friend class LLUICtrlFactory; +	void draw() +	{ +		if (mBadgeDriver) +		{ +			setBadgeLabel(mBadgeDriver->getBadgeString()); +		} + +		LLButton::draw(); +	} +  private:  	S32		mDragLastScreenX;  	S32		mDragLastScreenY; + +	LLSideTrayTabBadgeDriver*	mBadgeDriver;  };  ////////////////////////////////////////////////////////////////////////////// @@ -615,11 +643,31 @@ BOOL LLSideTray::postBuild()  	return true;  } +void LLSideTray::setTabButtonBadgeDriver(std::string tabName, LLSideTrayTabBadgeDriver* driver) +{ +	mTabButtonBadgeDrivers[tabName] = driver; +} +  void LLSideTray::handleLoginComplete()  {  	//reset tab to "home" tab if it was changesd during login process  	selectTabByName("sidebar_home"); +	for (badge_map_t::iterator it = mTabButtonBadgeDrivers.begin(); it != mTabButtonBadgeDrivers.end(); ++it) +	{ +		LLButton* button = mTabButtons[it->first]; +		LLSideTrayButton* side_button = dynamic_cast<LLSideTrayButton*>(button); + +		if (side_button) +		{ +			side_button->setBadgeDriver(it->second); +		} +		else +		{ +			llwarns << "Unable to find button " << it->first << " to set the badge driver. " << llendl; +		} +	} +  	detachTabs();  } @@ -766,51 +814,6 @@ bool LLSideTray::selectTabByName(const std::string& name, bool keep_prev_visible  	return true;  } -LLButton* LLSideTray::createButton	(const std::string& name,const std::string& image,const std::string& tooltip, -									 LLUICtrl::commit_callback_t callback) -{ -	static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams<LLSideTray>());	 -	 -	LLButton::Params bparams; - -	LLRect rect; -	rect.setOriginAndSize(0, 0, sidetray_params.default_button_width, sidetray_params.default_button_height);  - -	bparams.name(name); -	bparams.follows.flags (FOLLOWS_LEFT | FOLLOWS_TOP); -	bparams.rect (rect); -	bparams.tab_stop(false); -	bparams.image_unselected(sidetray_params.tab_btn_image_normal); -	bparams.image_selected(sidetray_params.tab_btn_image_selected); -	bparams.image_disabled(sidetray_params.tab_btn_image_normal); -	bparams.image_disabled_selected(sidetray_params.tab_btn_image_selected); - -	LLButton* button; -	if (name == "sidebar_openclose") -	{ -		// "Open/Close" button shouldn't allow "tear off" -		// hence it is created as LLButton instance. -		button = LLUICtrlFactory::create<LLButton>(bparams); -	} -	else -	{ -		button = LLUICtrlFactory::create<LLSideTrayButton>(bparams); -	} - -	button->setClickedCallback(callback); - -	button->setToolTip(tooltip); -	 -	if(image.length()) -	{ -		button->setImageOverlay(image); -	} - -	mButtonsPanel->addChildInBack(button); - -	return button; -} -  bool LLSideTray::addChild(LLView* view, S32 tab_group)  {  	LLSideTrayTab* tab_panel = dynamic_cast<LLSideTrayTab*>(view); @@ -938,7 +941,56 @@ bool LLSideTray::addTab(LLSideTrayTab* tab)  	return true;  } -void	LLSideTray::createButtons	() +LLButton* LLSideTrayTab::createButton(bool allowTearOff, LLUICtrl::commit_callback_t callback) +{ +	static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams<LLSideTray>());	 + +	LLRect rect; +	rect.setOriginAndSize(0, 0, sidetray_params.default_button_width, sidetray_params.default_button_height);  + +	LLButton::Params bparams; + +	// Append "_button" to the side tray tab name +	std::string button_name = getName() + "_button"; +	bparams.name(button_name); +	bparams.follows.flags (FOLLOWS_LEFT | FOLLOWS_TOP); +	bparams.rect (rect); +	bparams.tab_stop(false); +	bparams.image_unselected(sidetray_params.tab_btn_image_normal); +	bparams.image_selected(sidetray_params.tab_btn_image_selected); +	bparams.image_disabled(sidetray_params.tab_btn_image_normal); +	bparams.image_disabled_selected(sidetray_params.tab_btn_image_selected); + +	if (mHasBadge) +	{ +		bparams.badge = mBadgeParams; +	} + +	LLButton* button; +	if (allowTearOff) +	{ +		button = LLUICtrlFactory::create<LLSideTrayButton>(bparams); +	} +	else +	{ +		// "Open/Close" button shouldn't allow "tear off" +		// hence it is created as LLButton instance. +		button = LLUICtrlFactory::create<LLButton>(bparams); +	} + +	button->setClickedCallback(callback); + +	button->setToolTip(mTabTitle); + +	if(mImage.length()) +	{ +		button->setImageOverlay(mImage); +	} + +	return button; +} + +void LLSideTray::createButtons()  {  	//create buttons for tabs  	child_vector_const_iter_t child_it = mTabs.begin(); @@ -951,17 +1003,22 @@ void	LLSideTray::createButtons	()  		// The "OpenClose" button will open/close the whole panel  		if (name == "sidebar_openclose")  		{ -			mCollapseButton = createButton(name,sidebar_tab->mImage,sidebar_tab->getTabTitle(), -				boost::bind(&LLSideTray::onToggleCollapse, this)); +			mCollapseButton = sidebar_tab->createButton(false, boost::bind(&LLSideTray::onToggleCollapse, this)); + +			mButtonsPanel->addChildInBack(mCollapseButton); +  			LLHints::registerHintTarget("side_panel_btn", mCollapseButton->getHandle());  		}  		else  		{ -			LLButton* button = createButton(name,sidebar_tab->mImage,sidebar_tab->getTabTitle(), -				boost::bind(&LLSideTray::onTabButtonClick, this, name)); +			LLButton* button = sidebar_tab->createButton(true, boost::bind(&LLSideTray::onTabButtonClick, this, name)); + +			mButtonsPanel->addChildInBack(button); +  			mTabButtons[name] = button;  		}  	} +  	LLHints::registerHintTarget("inventory_btn", mTabButtons["sidebar_inventory"]->getHandle());  } diff --git a/indra/newview/llsidetray.h b/indra/newview/llsidetray.h index 24882411f4..17158329dc 100644 --- a/indra/newview/llsidetray.h +++ b/indra/newview/llsidetray.h @@ -33,6 +33,13 @@  class LLAccordionCtrl;  class LLSideTrayTab; +// Define an interface for side tab button badge values +class LLSideTrayTabBadgeDriver +{ +public: +	virtual std::string getBadgeString() const = 0; +}; +  // Deal with LLSideTrayTab being opaque. Generic do-nothing cast...  template <class T>  T tab_cast(LLSideTrayTab* tab) { return tab; } @@ -166,6 +173,8 @@ public:  	bool		getCollapsed() { return mCollapsed; } +	void		setTabButtonBadgeDriver(std::string tabName, LLSideTrayTabBadgeDriver* driver); +  public:  	virtual ~LLSideTray(){}; @@ -204,8 +213,6 @@ protected:  	void		createButtons	(); -	LLButton*	createButton	(const std::string& name,const std::string& image,const std::string& tooltip, -									LLUICtrl::commit_callback_t callback);  	void		arrange			();  	void		detachTabs		();  	void		reflectCollapseChange(); @@ -234,6 +241,8 @@ private:  	LLPanel*						mButtonsPanel;  	typedef std::map<std::string,LLButton*> button_map_t;  	button_map_t					mTabButtons; +	typedef std::map<std::string,LLSideTrayTabBadgeDriver*> badge_map_t; +	badge_map_t						mTabButtonBadgeDrivers;  	child_vector_t					mTabs;  	child_vector_t					mDetachedTabs;  	tab_order_vector_t				mOriginalTabOrder; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 3c2ef37bb8..4dfcb85295 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -76,6 +76,7 @@  #include "lluserrelations.h"  #include "llversioninfo.h"  #include "llviewercontrol.h" +#include "llviewerhelp.h"  #include "llvfs.h"  #include "llxorcipher.h"	// saved password, MAC address  #include "llwindow.h" @@ -1689,11 +1690,22 @@ bool idle_startup()  				gViewerThrottle.setMaxBandwidth(FAST_RATE_BPS / 1024.f);  			} +			if (gSavedSettings.getBOOL("ShowHelpOnFirstLogin")) +			{ +				gSavedSettings.setBOOL("HelpFloaterOpen", TRUE); +			} +  			// Set the show start location to true, now that the user has logged  			// on with this install.  			gSavedSettings.setBOOL("ShowStartLocation", TRUE);  		} +		if (gSavedSettings.getBOOL("HelpFloaterOpen")) +		{ +			// show default topic +			LLViewerHelp::instance().showTopic(""); +		} +  		// We're successfully logged in.  		gSavedSettings.setBOOL("FirstLoginThisInstall", FALSE); @@ -1950,7 +1962,8 @@ bool idle_startup()  		gViewerWindow->getWindow()->resetBusyCount();  		gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);  		LL_DEBUGS("AppInit") << "Done releasing bitmap" << LL_ENDL; -		gViewerWindow->setShowProgress(FALSE); +		gViewerWindow->revealIntroPanel(); +		//gViewerWindow->setShowProgress(FALSE);  // reveal intro video now handles this  		gViewerWindow->setProgressCancelButtonVisible(FALSE);  		// We're not away from keyboard, even though login might have taken diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 5b76537804..de22f2ae6b 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -420,7 +420,6 @@ BOOL LLFloaterTexturePicker::postBuild()  		mInventoryPanel->setFilterPermMask(mImmediateFilterPermMask);  		mInventoryPanel->setSelectCallback(boost::bind(&LLFloaterTexturePicker::onSelectionChange, this, _1, _2));  		mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); -		mInventoryPanel->setAllowMultiSelect(FALSE);  		// Disable auto selecting first filtered item because it takes away  		// selection from the item set by LLTextureCtrl owning this floater. diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp index 42f780a8a3..9101222393 100644 --- a/indra/newview/llviewerfoldertype.cpp +++ b/indra/newview/llviewerfoldertype.cpp @@ -128,8 +128,10 @@ LLViewerFolderDictionary::LLViewerFolderDictionary()  	addEntry(LLFolderType::FT_MY_OUTFITS, 			new ViewerFolderEntry("My Outfits",				"Inv_SysOpen",			"Inv_SysClosed",		TRUE));  	addEntry(LLFolderType::FT_MESH, 				new ViewerFolderEntry("Meshes",					"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); -  	addEntry(LLFolderType::FT_INBOX, 				new ViewerFolderEntry("Inbox",					"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); +	addEntry(LLFolderType::FT_OUTBOX, 				new ViewerFolderEntry("Outbox",					"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); + +	addEntry(LLFolderType::FT_BASIC_ROOT, 			new ViewerFolderEntry("Basic Root",				"Inv_SysOpen",			"Inv_SysClosed",		FALSE));  	addEntry(LLFolderType::FT_NONE, 				new ViewerFolderEntry("New Folder",				"Inv_FolderOpen",		"Inv_FolderClosed",		FALSE, "default")); diff --git a/indra/newview/llviewerhelp.cpp b/indra/newview/llviewerhelp.cpp index 9fe8c142b9..3a3d4f3881 100644 --- a/indra/newview/llviewerhelp.cpp +++ b/indra/newview/llviewerhelp.cpp @@ -101,8 +101,9 @@ void LLViewerHelp::showTopic(const std::string &topic)  	// work out the URL for this topic and display it   	showHelp(); +	  	std::string helpURL = LLViewerHelpUtil::buildHelpURL( help_topic ); -	setRawURL( helpURL ); +	setRawURL(helpURL);  }  std::string LLViewerHelp::defaultTopic() @@ -148,18 +149,7 @@ std::string LLViewerHelp::getTopicFromFocus()  // static   void LLViewerHelp::showHelp()  { -	LLFloaterHelpBrowser* helpbrowser = dynamic_cast<LLFloaterHelpBrowser*>(LLFloaterReg::getInstance("help_browser")); -	if (helpbrowser) -	{ -		BOOL visible = TRUE; -		BOOL take_focus = TRUE; -		helpbrowser->setVisible(visible); -		helpbrowser->setFrontmost(take_focus); -	} -	else -	{ -		llwarns << "Eep, help_browser floater not found" << llendl; -	} +	LLFloaterReg::showInstance("help_browser");  }  // static diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 9e58acdcd3..22666cec0d 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -1269,7 +1269,7 @@ void menu_create_inventory_item(LLFolderView* root, LLFolderBridge *bridge, cons  {  	std::string type_name = userdata.asString(); -	if (("category" == type_name) || ("current" == type_name) || ("outfit" == type_name) || ("my_otfts" == type_name)) +	if (("inbox" == type_name) || ("outbox" == type_name) || ("category" == type_name) || ("current" == type_name) || ("outfit" == type_name) || ("my_otfts" == type_name))  	{  		LLFolderType::EType preferred_type = LLFolderType::lookup(type_name); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 1e53274cd6..1be58eae45 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -64,8 +64,10 @@  #include "llappviewer.h"  #include "lllogininstance.h"   //#include "llfirstuse.h" +#include "llviewernetwork.h"  #include "llwindow.h" +  #include "llfloatermediabrowser.h"	// for handling window close requests and geometry change requests in media browser windows.  #include "llfloaterwebcontent.h"	// for handling window close requests and geometry change requests in media browser windows. @@ -1360,6 +1362,34 @@ void LLViewerMedia::removeCookie(const std::string &name, const std::string &dom  } +class LLInventoryUserStatusResponder : public LLHTTPClient::Responder +{ +public: +	LLInventoryUserStatusResponder() +		: LLCurl::Responder() +	{ +	} + +	void completed(U32 status, const std::string& reason, const LLSD& content) +	{ +		if (isGoodStatus(status)) +		{ +			// Complete success +			gSavedSettings.setBOOL("InventoryDisplayInbox", true); +		} +		else if (status == 401) +		{ +			// API is available for use but OpenID authorization failed +			gSavedSettings.setBOOL("InventoryDisplayInbox", true); +		} +		else +		{ +			// API in unavailable +			llinfos << "Marketplace API is unavailable -- Inbox may be disabled, status = " << status << ", reason = " << reason << llendl; +		} +	} +}; +  /////////////////////////////////////////////////////////////////////////////////////////  // static  void LLViewerMedia::setOpenIDCookie() @@ -1406,6 +1436,25 @@ void LLViewerMedia::setOpenIDCookie()  		LLHTTPClient::get(profile_url,    			new LLViewerMediaWebProfileResponder(raw_profile_url.getAuthority()),  			headers); + +		std::string url = "https://marketplace.secondlife.com/"; + +		if (!LLGridManager::getInstance()->isInProductionGrid()) +		{ +			std::string gridLabel = LLGridManager::getInstance()->getGridLabel(); +			url = llformat("https://marketplace.%s.lindenlab.com/", utf8str_tolower(gridLabel).c_str()); +		} +	 +		url += "api/1/users/"; +		url += gAgent.getID().getString(); +		url += "/user_status"; + +		headers = LLSD::emptyMap(); +		headers["Accept"] = "*/*"; +		headers["Cookie"] = sOpenIDCookie; +		headers["User-Agent"] = getCurrentUserAgent(); + +		LLHTTPClient::get(url, new LLInventoryUserStatusResponder(), headers);  	}  } @@ -2349,15 +2398,13 @@ void LLViewerMediaImpl::updateJavascriptObject()  	if ( mMediaSource )  	{  		// flag to expose this information to internal browser or not. -		bool expose_javascript_object = gSavedSettings.getBOOL("BrowserEnableJSObject"); -		mMediaSource->jsExposeObjectEvent( expose_javascript_object ); +		bool enable = gSavedSettings.getBOOL("BrowserEnableJSObject"); +		mMediaSource->jsEnableObject( enable ); -		// indicate if the values we have are valid (currently do this blanket-fashion for -		// everything depending on whether you are logged in or not - this may require a  -		// more granular approach once variables are added that ARE valid before login +		// these values are only menaingful after login so don't set them before  		bool logged_in = LLLoginInstance::getInstance()->authSuccess(); -		mMediaSource->jsValuesValidEvent( logged_in ); - +		if ( logged_in ) +		{  		// current location within a region  		LLVector3 agent_pos = gAgent.getPositionAgent();  		double x = agent_pos.mV[ VX ]; @@ -2386,6 +2433,7 @@ void LLViewerMediaImpl::updateJavascriptObject()  			region_name = region->getName();  		};  		mMediaSource->jsAgentRegionEvent( region_name ); +		}  		// language code the viewer is set to  		mMediaSource->jsAgentLanguageEvent( LLUI::getLanguage() ); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 55eea8fc69..a37f8ad0d8 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -108,6 +108,7 @@  #include "lltrans.h"  #include "lleconomy.h"  #include "lltoolgrab.h" +#include "llwindow.h"  #include "boost/unordered_map.hpp"  using namespace LLVOAvatarDefines; diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 9f7559ad15..44b3a85f25 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -37,6 +37,7 @@  #include "lleconomy.h"  #include "lleventtimer.h"  #include "llfloaterreg.h" +#include "llfolderview.h"  #include "llfollowcamparams.h"  #include "llinventorydefines.h"  #include "lllslconstants.h" @@ -87,6 +88,7 @@  #include "lluri.h"  #include "llviewergenericmessage.h"  #include "llviewermenu.h" +#include "llviewerinventory.h"  #include "llviewerjoystick.h"  #include "llviewerobjectlist.h"  #include "llviewerparcelmgr.h" @@ -694,7 +696,7 @@ bool join_group_response(const LLSD& notification, const LLSD& response)  	return false;  } -static void highlight_inventory_items_in_panel(const std::vector<LLUUID>& items, LLInventoryPanel *inventory_panel) +static void highlight_inventory_objects_in_panel(const std::vector<LLUUID>& items, LLInventoryPanel *inventory_panel)  {  	if (NULL == inventory_panel) return; @@ -708,7 +710,7 @@ static void highlight_inventory_items_in_panel(const std::vector<LLUUID>& items,  			continue;  		} -		LLInventoryItem* item = gInventory.getItem(item_id); +		LLInventoryObject* item = gInventory.getObject(item_id);  		llassert(item);  		if (!item) {  			continue; @@ -787,7 +789,6 @@ class LLViewerInventoryMoveFromWorldObserver : public LLInventoryAddItemByAssetO  public:  	LLViewerInventoryMoveFromWorldObserver()  		: LLInventoryAddItemByAssetObserver() -		, mActivePanel(NULL)  	{  	} @@ -798,13 +799,16 @@ private:  	/*virtual */void onAssetAdded(const LLUUID& asset_id)  	{  		// Store active Inventory panel. -		mActivePanel = LLInventoryPanel::getActiveInventoryPanel(); +		if (LLInventoryPanel::getActiveInventoryPanel()) +		{ +			mActivePanel = LLInventoryPanel::getActiveInventoryPanel()->getHandle(); +		}  		// Store selected items (without destination folder)  		mSelectedItems.clear(); -		if (mActivePanel) +		if (LLInventoryPanel::getActiveInventoryPanel())  		{ -			mSelectedItems = mActivePanel->getRootFolder()->getSelectionList(); +			mSelectedItems = LLInventoryPanel::getActiveInventoryPanel()->getRootFolder()->getSelectionList();  		}  		mSelectedItems.erase(mMoveIntoFolderID);  	} @@ -815,12 +819,14 @@ private:  	 */  	void done()  	{ +		LLInventoryPanel* active_panel = dynamic_cast<LLInventoryPanel*>(mActivePanel.get()); +  		// if selection is not changed since watch started lets hightlight new items. -		if (mActivePanel && !isSelectionChanged()) +		if (active_panel && !isSelectionChanged())  		{  			LL_DEBUGS("Inventory_Move") << "Selecting new items..." << LL_ENDL; -			mActivePanel->clearSelection(); -			highlight_inventory_items_in_panel(mAddedItems, mActivePanel); +			active_panel->clearSelection(); +			highlight_inventory_objects_in_panel(mAddedItems, active_panel);  		}  	} @@ -828,16 +834,16 @@ private:  	 * Returns true if selected inventory items were changed since moved inventory items were started to watch.  	 */  	bool isSelectionChanged() -	{ -		const LLInventoryPanel * const current_active_panel = LLInventoryPanel::getActiveInventoryPanel(); +	{	 +		LLInventoryPanel* active_panel = dynamic_cast<LLInventoryPanel*>(mActivePanel.get()); -		if (NULL == mActivePanel || current_active_panel != mActivePanel) +		if (NULL == active_panel)  		{  			return true;  		}  		// get selected items (without destination folder) -		selected_items_t selected_items = mActivePanel->getRootFolder()->getSelectionList(); +		selected_items_t selected_items = active_panel->getRootFolder()->getSelectionList();  		selected_items.erase(mMoveIntoFolderID);  		// compare stored & current sets of selected items @@ -851,7 +857,7 @@ private:  		return different_items.size() > 0;  	} -	LLInventoryPanel *mActivePanel; +	LLHandle<LLPanel> mActivePanel;  	typedef std::set<LLUUID> selected_items_t;  	selected_items_t mSelectedItems; @@ -880,6 +886,75 @@ void set_dad_inventory_item(LLInventoryItem* inv_item, const LLUUID& into_folder  	gInventoryMoveObserver->watchAsset(inv_item->getAssetUUID());  } + +/** + * Class to observe moving of items and to select them in inventory. + * + * Used currently for dragging from inbox to regular inventory folders + */ + +class LLViewerInventoryMoveObserver : public LLInventoryObserver +{ +public: + +	LLViewerInventoryMoveObserver(const LLUUID& object_id) +		: LLInventoryObserver() +		, mObjectID(object_id) +	{ +		if (LLInventoryPanel::getActiveInventoryPanel()) +		{ +			mActivePanel = LLInventoryPanel::getActiveInventoryPanel()->getHandle(); +		} +	} + +	virtual ~LLViewerInventoryMoveObserver() {} +	virtual void changed(U32 mask); +	 +private: +	LLUUID mObjectID; +	LLHandle<LLPanel> mActivePanel; + +}; + +void LLViewerInventoryMoveObserver::changed(U32 mask) +{ +	LLInventoryPanel* active_panel = dynamic_cast<LLInventoryPanel*>(mActivePanel.get()); + +	if (NULL == active_panel) +	{ +		gInventory.removeObserver(this); +		return; +	} + +	if((mask & (LLInventoryObserver::STRUCTURE)) != 0) +	{ +		const std::set<LLUUID>& changed_items = gInventory.getChangedIDs(); + +		std::set<LLUUID>::const_iterator id_it = changed_items.begin(); +		std::set<LLUUID>::const_iterator id_end = changed_items.end(); +		for (;id_it != id_end; ++id_it) +		{ +			if ((*id_it) == mObjectID) +			{ +				active_panel->clearSelection();			 +				std::vector<LLUUID> items; +				items.push_back(mObjectID); +				highlight_inventory_objects_in_panel(items, active_panel); +				active_panel->getRootFolder()->scrollToShowSelection(); +				 +				gInventory.removeObserver(this); +				break; +			} +		} +	} +} + +void set_dad_inbox_object(const LLUUID& object_id) +{ +	LLViewerInventoryMoveObserver* move_observer = new LLViewerInventoryMoveObserver(object_id); +	gInventory.addObserver(move_observer); +} +  //unlike the FetchObserver for AgentOffer, we only make one   //instance of the AddedObserver for TaskOffers  //and it never dies.  We do this because we don't know the UUID of  @@ -936,7 +1011,6 @@ protected:  //one global instance to bind them  LLOpenTaskOffer* gNewInventoryObserver=NULL; -  class LLNewInventoryHintObserver : public LLInventoryAddedObserver  {  protected: @@ -946,6 +1020,8 @@ protected:  	}  }; +LLNewInventoryHintObserver* gNewInventoryHintObserver=NULL; +  void start_new_inventory_observer()  {  	if (!gNewInventoryObserver) //task offer observer  @@ -962,7 +1038,12 @@ void start_new_inventory_observer()  		gInventory.addObserver(gInventoryMoveObserver);  	} -	gInventory.addObserver(new LLNewInventoryHintObserver()); +	if (!gNewInventoryHintObserver) +	{ +		// Observer is deleted by gInventory +		gNewInventoryHintObserver = new LLNewInventoryHintObserver(); +		gInventory.addObserver(gNewInventoryHintObserver); +	}  }  class LLDiscardAgentOffer : public LLInventoryFetchItemsObserver @@ -4324,7 +4405,7 @@ void process_sound_trigger(LLMessageSystem *msg, void **)  	{  		return;  	} - +		  	// Don't play sounds from gestures if they are not enabled.  	if (object_id == owner_id && !gSavedSettings.getBOOL("EnableGestureSounds"))  	{ @@ -6499,7 +6580,7 @@ void process_script_dialog(LLMessageSystem* msg, void**)      LLUUID owner_id;  	if (gMessageSystem->getNumberOfBlocks("OwnerData") > 0)  	{ -		msg->getUUID("OwnerData", "OwnerID", owner_id); +    msg->getUUID("OwnerData", "OwnerID", owner_id);  	}  	if (LLMuteList::getInstance()->isMuted(object_id) || LLMuteList::getInstance()->isMuted(owner_id)) diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h index b4a9b8e677..9d09d9c01a 100644 --- a/indra/newview/llviewermessage.h +++ b/indra/newview/llviewermessage.h @@ -203,6 +203,8 @@ void open_inventory_offer(const uuid_vec_t& items, const std::string& from_name)  bool highlight_offered_object(const LLUUID& obj_id);  void set_dad_inventory_item(LLInventoryItem* inv_item, const LLUUID& into_folder_uuid); +void set_dad_inbox_object(const LLUUID& object_id); +  class LLOfferInfo : public LLNotificationResponderInterface  { diff --git a/indra/newview/llviewerprecompiledheaders.h b/indra/newview/llviewerprecompiledheaders.h index faa86d43dd..252183b6d7 100644 --- a/indra/newview/llviewerprecompiledheaders.h +++ b/indra/newview/llviewerprecompiledheaders.h @@ -33,6 +33,8 @@  // in viewer.  // It is used to precompile headers for improved build speed. +#include <boost/coroutine/coroutine.hpp> +  #include "linden_common.h"  // Work around stupid Microsoft STL warning @@ -118,8 +120,8 @@  // Library includes from llvfs  #include "lldir.h" - -// Library includes from llmessage project +
 +// Library includes from llmessage project
  #include "llcachename.h"  #endif diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index b1441cc281..cff166b825 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1979,7 +1979,10 @@ void LLViewerWindow::shutdownViews()  	// destroy the nav bar, not currently part of gViewerWindow  	// *TODO: Make LLNavigationBar part of gViewerWindow +	if (LLNavigationBar::instanceExists()) +	{  	delete LLNavigationBar::getInstance(); +	}  	// destroy menus after instantiating navbar above, as it needs  	// access to gMenuHolder @@ -4512,6 +4515,14 @@ void LLViewerWindow::setup3DViewport(S32 x_offset, S32 y_offset)  	glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);  } +void LLViewerWindow::revealIntroPanel() +{ +	if (mProgressView) +	{ +		mProgressView->revealIntroPanel(); +	} +} +  void LLViewerWindow::setShowProgress(const BOOL show)  {  	if (mProgressView) diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index df6928aa1d..ff49ed1f62 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -271,6 +271,7 @@ public:  	void			setProgressMessage(const std::string& msg);  	void			setProgressCancelButtonVisible( BOOL b, const std::string& label = LLStringUtil::null );  	LLProgressView *getProgressView() const; +	void			revealIntroPanel();  	void			updateObjectUnderCursor(); diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index b0628dfe67..76965ad14b 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -133,6 +133,15 @@       name="AvatarListItemIconVoiceLeftColor"       reference="AvatarListItemIconOfflineColor" />      <color +     name="BadgeImageColor" +     value="0.44 0.69 0.56 1.0" /> +    <color +     name="BadgeBorderColor" +     value="0.9 0.9 0.9 1.0" /> +    <color +     name="BadgeLabelColor" +     reference="White" /> +    <color       name="ButtonBorderColor"       reference="Unused?" />      <color @@ -760,7 +769,7 @@      <color       name="MenuBarProjectBgColor"       reference="MdBlue" /> - +        <color        name="MeshImportTableNormalColor"        value="1 1 1 1"/> diff --git a/indra/newview/skins/default/textures/icons/Inv_Gift.png b/indra/newview/skins/default/textures/icons/Inv_Gift.png Binary files differnew file mode 100644 index 0000000000..5afe85d72d --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Gift.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Disabled.png b/indra/newview/skins/default/textures/icons/OutboxPush_Disabled.png Binary files differnew file mode 100644 index 0000000000..be58114aa1 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Disabled.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Off.png b/indra/newview/skins/default/textures/icons/OutboxPush_Off.png Binary files differnew file mode 100644 index 0000000000..e6b9480ab1 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Off.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_On.png b/indra/newview/skins/default/textures/icons/OutboxPush_On.png Binary files differnew file mode 100644 index 0000000000..ffda2e92d4 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_On.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_On_Over.png b/indra/newview/skins/default/textures/icons/OutboxPush_On_Over.png Binary files differnew file mode 100644 index 0000000000..6b5911014f --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_On_Over.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_On_Selected.png b/indra/newview/skins/default/textures/icons/OutboxPush_On_Selected.png Binary files differnew file mode 100644 index 0000000000..0e60b417b0 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_On_Selected.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Over.png b/indra/newview/skins/default/textures/icons/OutboxPush_Over.png Binary files differnew file mode 100644 index 0000000000..9c26b92e73 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Over.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Press.png b/indra/newview/skins/default/textures/icons/OutboxPush_Press.png Binary files differnew file mode 100644 index 0000000000..3b5d462975 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Press.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_1.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_1.png Binary files differnew file mode 100644 index 0000000000..f85be047b0 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_1.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_2.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_2.png Binary files differnew file mode 100644 index 0000000000..cd4e482216 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_2.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_3.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_3.png Binary files differnew file mode 100644 index 0000000000..d212a871ce --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_3.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_4.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_4.png Binary files differnew file mode 100644 index 0000000000..e5b6023e36 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_4.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_5.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_5.png Binary files differnew file mode 100644 index 0000000000..e1911a092f --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_5.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Progress_6.png b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_6.png Binary files differnew file mode 100644 index 0000000000..9e59f7843a --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Progress_6.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Selected.png b/indra/newview/skins/default/textures/icons/OutboxPush_Selected.png Binary files differnew file mode 100644 index 0000000000..51e8bff646 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Selected.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Disabled.png b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Disabled.png Binary files differnew file mode 100644 index 0000000000..300e2e69e1 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Disabled.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Over.png b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Over.png Binary files differnew file mode 100644 index 0000000000..32fb236381 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Over.png diff --git a/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Press.png b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Press.png Binary files differnew file mode 100644 index 0000000000..827f343b1e --- /dev/null +++ b/indra/newview/skins/default/textures/icons/OutboxPush_Selected_Press.png diff --git a/indra/newview/skins/default/textures/icons/Sync_Disabled.png b/indra/newview/skins/default/textures/icons/Sync_Disabled.png Binary files differnew file mode 100644 index 0000000000..ca2e8def97 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Sync_Disabled.png diff --git a/indra/newview/skins/default/textures/icons/Sync_Enabled.png b/indra/newview/skins/default/textures/icons/Sync_Enabled.png Binary files differnew file mode 100644 index 0000000000..bc236c8b98 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Sync_Enabled.png diff --git a/indra/newview/skins/default/textures/icons/Sync_Progress_1.png b/indra/newview/skins/default/textures/icons/Sync_Progress_1.png Binary files differnew file mode 100644 index 0000000000..624e556376 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Sync_Progress_1.png diff --git a/indra/newview/skins/default/textures/icons/Sync_Progress_2.png b/indra/newview/skins/default/textures/icons/Sync_Progress_2.png Binary files differnew file mode 100644 index 0000000000..5769803b3f --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Sync_Progress_2.png diff --git a/indra/newview/skins/default/textures/icons/Sync_Progress_3.png b/indra/newview/skins/default/textures/icons/Sync_Progress_3.png Binary files differnew file mode 100644 index 0000000000..92d4bfb020 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Sync_Progress_3.png diff --git a/indra/newview/skins/default/textures/icons/Sync_Progress_4.png b/indra/newview/skins/default/textures/icons/Sync_Progress_4.png Binary files differnew file mode 100644 index 0000000000..6d43eb3a9f --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Sync_Progress_4.png diff --git a/indra/newview/skins/default/textures/icons/Sync_Progress_5.png b/indra/newview/skins/default/textures/icons/Sync_Progress_5.png Binary files differnew file mode 100644 index 0000000000..766d063c99 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Sync_Progress_5.png diff --git a/indra/newview/skins/default/textures/icons/Sync_Progress_6.png b/indra/newview/skins/default/textures/icons/Sync_Progress_6.png Binary files differnew file mode 100644 index 0000000000..dfe7f68b72 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Sync_Progress_6.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index cc7cce99c9..c2757f2c94 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -72,8 +72,11 @@ with the same filename but different name    <texture name="BackButton_Over" file_name="icons/back_arrow_over.png" preload="false" scale.left="22" scale.top="12" scale.right="25" scale.bottom="12" />    <texture name="BackButton_Press" file_name="icons/back_arrow_press.png" preload="false" scale.left="22" scale.top="12" scale.right="25" scale.bottom="12" /> +  <texture name="Badge_Background" file_name="widgets/Badge_Background.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" /> +  <texture name="Badge_Border" file_name="widgets/Badge_Border.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" /> +    <texture name="Blank" file_name="Blank.png" preload="false" /> -	 +    <texture name="BreadCrumbBtn_Left_Disabled" file_name="widgets/BreadCrumbBtn_Left_Disabled.png" preload="false"/>    <texture name="BreadCrumbBtn_Left_Off" file_name="widgets/BreadCrumbBtn_Left_Off.png" preload="false"/>    <texture name="BreadCrumbBtn_Left_Over" file_name="widgets/BreadCrumbBtn_Left_Over.png" preload="false"/> @@ -88,7 +91,6 @@ with the same filename but different name    <texture name="BreadCrumbBtn_Right_Off" file_name="widgets/BreadCrumbBtn_Right_Off.png" preload="false"/>    <texture name="BreadCrumbBtn_Right_Over" file_name="widgets/BreadCrumbBtn_Right_Over.png" preload="false"/>    <texture name="BreadCrumbBtn_Right_Press" file_name="widgets/BreadCrumbBtn_Right_Press.png" preload="false"/> -     <texture name="BuyArrow_Over" file_name="navbar/BuyArrow_Over.png" preload="true" scale.left="0" scale.top="1" scale.right="0" scale.bottom="0"  />    <texture name="BuyArrow_Press" file_name="navbar/BuyArrow_Press.png" preload="true" scale.left="1" scale.top="1" scale.right="0" scale.bottom="0"  /> @@ -266,6 +268,8 @@ with the same filename but different name    <texture name="Locked_Icon" file_name="icons/Locked_Icon.png" preload="false" /> +  <texture name="MarketplaceBtn_Off" file_name="widgets/MarketplaceBtn_Off.png" preload="true" scale.left="30" scale.top="19" scale.right="35" scale.bottom="4" /> +  <texture name="MarketplaceBtn_Selected" file_name="widgets/MarketplaceBtn_Selected.png" preload="true" scale.left="30" scale.top="19" scale.right="35" scale.bottom="4" />    <texture name="Microphone_On" file_name="icons/Microphone_On.png" preload="false" /> @@ -349,6 +353,23 @@ with the same filename but different name    <texture name="OptionsMenu_Off" file_name="icons/OptionsMenu_Off.png" preload="false" />    <texture name="OptionsMenu_Press" file_name="icons/OptionsMenu_Press.png" preload="false" /> +  <texture name="OutboxPush_Disabled" file_name="icons/OutboxPush_Disabled.png" preload="true" /> +  <texture name="OutboxPush_Off" file_name="icons/OutboxPush_Off.png" preload="true" /> +  <texture name="OutboxPush_On" file_name="icons/OutboxPush_On.png" preload="true" /> +  <texture name="OutboxPush_On_Over" file_name="icons/OutboxPush_On_Over.png" preload="true" /> +  <texture name="OutboxPush_Over" file_name="icons/OutboxPush_Over.png" preload="true" /> +  <texture name="OutboxPush_Press" file_name="icons/OutboxPush_Press.png" preload="true" /> +  <texture name="OutboxPush_Progress_1" file_name="icons/OutboxPush_Progress_1.png" preload="true" /> +  <texture name="OutboxPush_Progress_2" file_name="icons/OutboxPush_Progress_2.png" preload="true" /> +  <texture name="OutboxPush_Progress_3" file_name="icons/OutboxPush_Progress_3.png" preload="true" /> +  <texture name="OutboxPush_Progress_4" file_name="icons/OutboxPush_Progress_4.png" preload="true" /> +  <texture name="OutboxPush_Progress_5" file_name="icons/OutboxPush_Progress_5.png" preload="true" /> +  <texture name="OutboxPush_Progress_6" file_name="icons/OutboxPush_Progress_6.png" preload="true" /> +  <texture name="OutboxPush_Selected" file_name="icons/OutboxPush_Selected.png" preload="true" /> +  <texture name="OutboxPush_Selected_Disabled" file_name="icons/OutboxPush_Selected_Disabled.png" preload="true" /> +  <texture name="OutboxPush_Selected_Over" file_name="icons/OutboxPush_Selected_Over.png" preload="true" /> +  <texture name="OutboxPush_Selected_Press" file_name="icons/OutboxPush_Selected_Press.png" preload="true" /> +    <texture name="PanOrbit_Off" file_name="bottomtray/PanOrbit_Off.png" preload="false" />    <texture name="Parcel_Exp_Color" file_name="icons/Parcel_Exp_Color.png" preload="false" /> @@ -496,6 +517,15 @@ with the same filename but different name    <texture name="StopReload_Off" file_name="icons/StopReload_Off.png" preload="false" />    <texture name="StopReload_Over" file_name="icons/StopReload_Over.png" preload="false" /> +  <texture name="Sync_Disabled" file_name="icons/Sync_Disabled.png" preload="true" /> +  <texture name="Sync_Enabled" file_name="icons/Sync_Enabled.png" preload="true" /> +  <texture name="Sync_Progress_1" file_name="icons/Sync_Progress_1.png" preload="true" /> +  <texture name="Sync_Progress_2" file_name="icons/Sync_Progress_2.png" preload="true" /> +  <texture name="Sync_Progress_3" file_name="icons/Sync_Progress_3.png" preload="true" /> +  <texture name="Sync_Progress_4" file_name="icons/Sync_Progress_4.png" preload="true" /> +  <texture name="Sync_Progress_5" file_name="icons/Sync_Progress_5.png" preload="true" /> +  <texture name="Sync_Progress_6" file_name="icons/Sync_Progress_6.png" preload="true" /> +    <texture name="TabIcon_Appearance_Off" file_name="taskpanel/TabIcon_Appearance_Off.png" preload="false" />    <texture name="TabIcon_Appearance_Selected" file_name="taskpanel/TabIcon_Appearance_Selected.png" preload="false" />    <texture name="TabIcon_Close_Off" file_name="taskpanel/TabIcon_Close_Off.png" preload="false" /> @@ -649,6 +679,7 @@ with the same filename but different name    <texture name="inv_folder_mesh.tga"/>    <texture name="inv_item_mesh.tga"/> +    <texture name="lag_status_critical.tga" />    <texture name="lag_status_good.tga" />    <texture name="lag_status_warning.tga" /> diff --git a/indra/newview/skins/default/textures/widgets/Badge_Background.png b/indra/newview/skins/default/textures/widgets/Badge_Background.png Binary files differnew file mode 100644 index 0000000000..5089c30312 --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/Badge_Background.png diff --git a/indra/newview/skins/default/textures/widgets/Badge_Border.png b/indra/newview/skins/default/textures/widgets/Badge_Border.png Binary files differnew file mode 100644 index 0000000000..4b086a63fb --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/Badge_Border.png diff --git a/indra/newview/skins/default/textures/widgets/MarketplaceBtn_Off.png b/indra/newview/skins/default/textures/widgets/MarketplaceBtn_Off.png Binary files differnew file mode 100644 index 0000000000..e603c44384 --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/MarketplaceBtn_Off.png diff --git a/indra/newview/skins/default/textures/widgets/MarketplaceBtn_Selected.png b/indra/newview/skins/default/textures/widgets/MarketplaceBtn_Selected.png Binary files differnew file mode 100644 index 0000000000..fbc164123f --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/MarketplaceBtn_Selected.png diff --git a/indra/newview/skins/default/xui/en/floater_help_browser.xml b/indra/newview/skins/default/xui/en/floater_help_browser.xml index 02e50ee584..de6d586f72 100644 --- a/indra/newview/skins/default/xui/en/floater_help_browser.xml +++ b/indra/newview/skins/default/xui/en/floater_help_browser.xml @@ -2,6 +2,8 @@  <floater   legacy_header_height="18"   can_resize="true" + left="10000" + bottom="10000"   height="600"   layout="topleft"   min_height="150" diff --git a/indra/newview/skins/default/xui/en/floater_media_browser.xml b/indra/newview/skins/default/xui/en/floater_media_browser.xml index 43729d7c9f..5a1f920398 100644 --- a/indra/newview/skins/default/xui/en/floater_media_browser.xml +++ b/indra/newview/skins/default/xui/en/floater_media_browser.xml @@ -5,7 +5,7 @@   height="440"   layout="topleft"   min_height="140" - min_width="467" + min_width="0"   name="floater_about"   help_topic="floater_about"   save_rect="true" diff --git a/indra/newview/skins/default/xui/en/floater_web_content.xml b/indra/newview/skins/default/xui/en/floater_web_content.xml index e04a72cbc0..69e6057556 100644 --- a/indra/newview/skins/default/xui/en/floater_web_content.xml +++ b/indra/newview/skins/default/xui/en/floater_web_content.xml @@ -18,6 +18,7 @@      follows="left|right|top|bottom"      layout="topleft"      left="5" +    animate="false"      name="stack1"      orientation="vertical"      top="20" @@ -156,14 +157,20 @@        name="external_controls"        top_delta="0"        user_resize="false" +      auto_resize="true"        width="585">        <web_browser -        bottom="-22" +        bottom="-2"          follows="all"          layout="topleft"          left="0"          name="webbrowser"          top="0"/> +    </layout_panel> +    <layout_panel name="status_bar"  +                  height="23" +                  auto_resize="false" +                  user_resize="false">        <text          type="string"          length="200" @@ -174,7 +181,7 @@          name="statusbartext"          parse_urls="false"          text_color="0.4 0.4 0.4 1" -        top_pad="5" +        top_pad="3"          width="495"/>        <progress_bar          color_bar="0.3 1.0 0.3 1" diff --git a/indra/newview/skins/default/xui/en/menu_inventory_add.xml b/indra/newview/skins/default/xui/en/menu_inventory_add.xml index b36b82ebd8..e0ccb18c08 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory_add.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory_add.xml @@ -42,7 +42,7 @@                      <menu_item_call.on_enable                       function="File.EnableUpload" />                  </menu_item_call> -		<menu_item_call +                <menu_item_call                   label="Model..."                   layout="topleft"                   name="Upload Model"> @@ -263,4 +263,4 @@                       parameter="eyes" />                  </menu_item_call>              </menu> -</menu> +</menu>
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/panel_inbox_inventory.xml b/indra/newview/skins/default/xui/en/panel_inbox_inventory.xml new file mode 100644 index 0000000000..d06190ec54 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_inbox_inventory.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<inbox_inventory_panel +    name="inventory_inbox" +    start_folder="Received Items" +    follows="all" layout="topleft" +    top="0" left="0" height="165" width="308" +	top_pad="0" +    bg_opaque_color="DkGray2" +    bg_alpha_color="DkGray2" +    background_visible="true" +    background_opaque="true" +    border="false" +    bevel_style="none" +    show_item_link_overlays="true" +    > +    <scroll reserve_scroll_corner="false" /> +</inbox_inventory_panel> diff --git a/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml new file mode 100644 index 0000000000..af32056428 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<inventory_panel +    name="inventory_outbox" +    start_folder="Outbox" +    follows="all" layout="topleft" +    top="0" left="0" height="165" width="308" +	top_pad="0" +    bg_opaque_color="DkGray2" +    bg_alpha_color="DkGray2" +    background_visible="true" +    background_opaque="true" +    border="false" +    bevel_style="none" +    show_item_link_overlays="true" +    > +    <scroll reserve_scroll_corner="false" /> +</inventory_panel> diff --git a/indra/newview/skins/default/xui/en/panel_progress.xml b/indra/newview/skins/default/xui/en/panel_progress.xml index 2868d91cc7..4535c56339 100644 --- a/indra/newview/skins/default/xui/en/panel_progress.xml +++ b/indra/newview/skins/default/xui/en/panel_progress.xml @@ -132,4 +132,12 @@       name="cancel_btn"       top="700"       width="90" /> +  <web_browser +   follows="all" +   layout="topleft" +   left="0" +   name="login_media_panel" +   width="1024" +   height="768" +   top="0"/>  </panel> diff --git a/indra/newview/skins/default/xui/en/panel_side_tray.xml b/indra/newview/skins/default/xui/en/panel_side_tray.xml index 6ef93406ec..0f330a7b98 100644 --- a/indra/newview/skins/default/xui/en/panel_side_tray.xml +++ b/indra/newview/skins/default/xui/en/panel_side_tray.xml @@ -142,6 +142,7 @@      mouse_opaque="false"      background_visible="true"    > +      <badge location="top_left" location_percent_vcenter="50" location_percent_hcenter="95" />        <panel          class="sidepanel_inventory"          name="sidepanel_inventory" diff --git a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml index 8997c1a6d7..79a0ec7c72 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml @@ -9,7 +9,7 @@  	  min_width="240"  	  name="objects panel"  	  width="333"> -	 <panel +    <panel  		 follows="all"  		 layout="topleft"  		 left="0" @@ -19,24 +19,226 @@  		 height="570"  		 visible="true"  		 width="330"> -		<panel -			 class="panel_main_inventory" -			 filename="panel_main_inventory.xml" -			 follows="all" -			 layout="topleft" -			 left="0" -			 name="panel_main_inventory" -			 top="0" -			 label="" -			 height="545" -			 width="330" /> +         <layout_stack +              follows="left|right|top|bottom" +              layout="topleft" +              left="0" +              top="0" +              orientation="vertical" +              name="inventory_layout_stack" +              height="535" +              width="330"> +             <layout_panel +                 name="main_inventory_layout_panel" +                 min_dim="150" +                 width="330" +                 follows="bottom|left|right" +                 user_resize="false" +                 height="480"> +                 <panel +                      class="panel_main_inventory" +                      filename="panel_main_inventory.xml" +                      follows="all" +                      layout="topleft" +                      left="0" +                      name="panel_main_inventory" +                      top="0" +                      label="" +                      height="480" +                      width="330" /> +             </layout_panel> +             <layout_panel +                 width="330" +                 auto_resize="true" +                 user_resize="false" +                 follows="bottom|left|right" +                 name="inbox_layout_panel" +                 visible="false" +                 min_dim="35" +                 max_dim="200" +                 expanded_min_dim="90" +                 height="200"> +                 <panel +                      follows="all" +                      layout="topleft" +                      left="0" +                      name="marketplace_inbox" +                      class="panel_marketplace_inbox" +                      top="0" +                      label="" +                      height="200" +                      width="330"> +                     <string name="InboxLabelWithArg">Received Items ([NUM])</string> +                     <string name="InboxLabelNoArg">Received Items</string> +                     <button +                        label="Received Items" +                        name="inbox_btn" +                        height="35" +                        width="308" +                        image_unselected="MarketplaceBtn_Off" +                        image_selected="MarketplaceBtn_Selected" +                        halign="left" +                        handle_right_mouse="false" +                        follows="top|left|right" +                        is_toggle="true" +                        tab_stop="false" +                        pad_left="35" +                        top="0" +                        left="10" /> +                     <text +                        type="string" +                        length="1" +                        follows="right|top" +                        layout="topleft" +                        height="13" +                        top="10" +                        right="-20" +                        name="inbox_fresh_new_count" +                        font="SansSerifMedium" +                        halign="right" +                        text_color="EmphasisColor" +                        top_pad="0" +                        width="300"> +                        [NUM] New +                     </text> +                     <panel +                        follows="all" +                        left="10" +                        bottom="200" +                        width="308" +                        top="35" +                        bg_opaque_color="InventoryBackgroundColor" +                        background_visible="true" +                        background_opaque="true" +                        tool_tip="Drag and drop items to your inventory to manage and use them" +                        > +                        <text +							name="inbox_inventory_placeholder" +							type="string" +							follows="all" +							layout="topleft" +							top="0" +							left="0" +							width="308" +							height="165" +							wrap="true" +							halign="center"> +							Purchases from the marketplace will be delivered here. +						</text> +                    </panel> +                 </panel> +             </layout_panel> +             <layout_panel +                width="330" +                auto_resize="true" +                user_resize="false" +                follows="bottom|left|right" +                name="outbox_layout_panel" +                visible="false" +                min_dim="35" +                max_dim="200" +                expanded_min_dim="90" +                height="200"> +                 <panel +                      follows="all" +                      layout="topleft" +                      left="10" +                      name="marketplace_outbox" +                      class="panel_marketplace_outbox" +                      top="0" +                      label="" +                      height="200" +                      width="310"> +                     <button +                        label="Merchant Outbox" +                        is_toggle="true" +                        handle_right_mouse="false" +                        name="outbox_btn" +                        follows="top|left|right" +                        image_unselected="MarketplaceBtn_Off" +                        image_selected="MarketplaceBtn_Selected" +                        height="35" +                        tab_stop="false" +                        width="308" +                        halign="left" +                        pad_left="35" +                        top="0" +                        left="0" /> +                     <button +                         image_unselected="OutboxPush_Off" +                         image_selected="OutboxPush_Selected" +                         image_hover_selected="OutboxPush_Selected_Over" +                         image_hover_unselected="OutboxPush_Over" +                         image_disabled_selected="OutboxPush_Selected_Disabled" +                         image_disabled="OutboxPush_Disabled" +                         image_pressed="OutboxPush_Press" +                         image_pressed_selected="OutboxPush_Selected_Press" +                         label="" +                         tool_tip="Push to my Marketplace Storefront" +                         is_toggle="false" +                         name="outbox_sync_btn" +                         follows="top|right" +                         tab_stop="false" +                         halign="center" +                         top="6" +                         left="-50" +                         height="23" +                         width="32" +                         enabled="false" /> +                     <loading_indicator +                        follows="top|right" +                        name="outbox_sync_indicator" +                        top="6" +                        left="-50" +                        height="23" +                        width="32" +                        images_per_sec="1.15" +                        tab_stop="false" +                        visible="false"> +                         <images> +                             <image name="OutboxPush_Progress_1"/> +                             <image name="OutboxPush_Progress_2"/> +                             <image name="OutboxPush_Progress_3"/> +                             <image name="OutboxPush_Progress_4"/> +                             <image name="OutboxPush_Progress_5"/> +                             <image name="OutboxPush_Progress_6"/> +                         </images> +                     </loading_indicator> +                     <panel +                        follows="all" +                        left="10" +                        bottom="200" +                        width="308" +                        top="35" +                        bg_opaque_color="InventoryBackgroundColor" +                        background_visible="true" +                        background_opaque="true" +                        tool_tip="Drag and drop items here to prepare them for sale on your storefront" +                        > +                        <text +							name="outbox_inventory_placeholder" +							type="string" +							follows="all" +							layout="topleft" +							top="0" +							left="0" +							width="308" +							height="165" +							wrap="true" +							halign="center"> +							Set up your merchant account to use this feature. +						</text> +                    </panel> +                 </panel> +             </layout_panel> +         </layout_stack>  		<panel  		     follows="bottom|left|right" -			 height="25" +			 height="30"  			 layout="topleft"  			 name="button_panel"  			 left="9" -			 top_pad="-2" +             top_pad="7"  			 width="308">  			<layout_stack       	         follows="bottom|left|right" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 09bff0a46c..def4079ba9 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2021,6 +2021,8 @@ Returns a string with the requested data about the region  	<string name="PlacesNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/places/[SEARCH_TERM] Search].</string>  	<string name="FavoritesNoMatchingItems">Drag a landmark here to add it to your favorites.</string>  	<string name="InventoryNoTexture">You do not have a copy of this texture in your inventory</string> +	<string name="InventoryInboxNoItems">Items purchased through the marketplace will be delivered here.</string> +	<string name="InventoryOutboxNoItems">Drag items here in preparation for listing on your marketplace storefront.</string>      <!-- use value="" because they have preceding spaces -->  	<string name="no_transfer" value=" (no transfer)" />  	<string name="no_modify"   value=" (no modify)" /> diff --git a/indra/newview/skins/default/xui/en/widgets/badge.xml b/indra/newview/skins/default/xui/en/widgets/badge.xml new file mode 100644 index 0000000000..f77c4b7178 --- /dev/null +++ b/indra/newview/skins/default/xui/en/widgets/badge.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<!-- Additional attributes: +   --> +<badge border_image="Badge_Border" +       border_color="BadgeBorderColor" +       font="SansSerifSmall" +       image="Badge_Background" +       image_color="BadgeImageColor" +       label_color="BadgeLabelColor" +       location="top_left" +       location_percent_hcenter="85" +       location_percent_vcenter="85" +       padding_horiz="7" +       padding_vert="4" +       requests_front="true" +       > +</badge> diff --git a/indra/newview/skins/default/xui/en/widgets/button.xml b/indra/newview/skins/default/xui/en/widgets/button.xml index 16241ed84e..302014eb24 100644 --- a/indra/newview/skins/default/xui/en/widgets/button.xml +++ b/indra/newview/skins/default/xui/en/widgets/button.xml @@ -25,5 +25,6 @@          pad_bottom="3"           height="23"          scale_image="true" +        handle_right_mouse="true"          use_draw_context_alpha="true">  </button> diff --git a/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml b/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml new file mode 100644 index 0000000000..2c987b158d --- /dev/null +++ b/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<inbox_folder_view_folder +  folder_arrow_image="Folder_Arrow" +  folder_indentation="8" +  item_height="20"  +  item_top_pad="4" +  selection_image="Rounded_Square" +  > +	<new_badge label="New" location="right" location_percent_hcenter="70" /> +</inbox_folder_view_folder> diff --git a/indra/newview/skins/default/xui/en/widgets/inbox_inventory_panel.xml b/indra/newview/skins/default/xui/en/widgets/inbox_inventory_panel.xml new file mode 100644 index 0000000000..830c27bdac --- /dev/null +++ b/indra/newview/skins/default/xui/en/widgets/inbox_inventory_panel.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<inbox_inventory_panel show_load_status="false" /> diff --git a/indra/newview/skins/default/xui/en/widgets/inventory_panel.xml b/indra/newview/skins/default/xui/en/widgets/inventory_panel.xml index 93875d66e6..00f4c43915 100644 --- a/indra/newview/skins/default/xui/en/widgets/inventory_panel.xml +++ b/indra/newview/skins/default/xui/en/widgets/inventory_panel.xml @@ -3,4 +3,12 @@    bg_opaque_color="InventoryBackgroundColor"    background_visible="true"    background_opaque="true" -  /> +  show_load_status="true" +  > +    <scroll +		name="Inventory Scroller" +        follows="all" +		reserve_scroll_corner="true" +        tab_stop="true" +        /> +</panel> diff --git a/indra/newview/skins/default/xui/en/widgets/panel.xml b/indra/newview/skins/default/xui/en/widgets/panel.xml index 9bf99fa363..47a210d9b7 100644 --- a/indra/newview/skins/default/xui/en/widgets/panel.xml +++ b/indra/newview/skins/default/xui/en/widgets/panel.xml @@ -10,4 +10,5 @@         bg_alpha_image_overlay="White"         background_visible="false"         background_opaque="false" -       chrome="false"/>
\ No newline at end of file +       chrome="false" +       accepts_badge="true"/>
\ No newline at end of file diff --git a/indra/newview/skins/minimal/xui/en/floater_help_browser.xml b/indra/newview/skins/minimal/xui/en/floater_help_browser.xml index cc551f7d58..477f210352 100644 --- a/indra/newview/skins/minimal/xui/en/floater_help_browser.xml +++ b/indra/newview/skins/minimal/xui/en/floater_help_browser.xml @@ -3,14 +3,13 @@   legacy_header_height="18"   can_resize="true"   can_minimize="false"  - height="360" + height="460"   layout="topleft"   min_height="360" - left="645" + left="10000"   top="10"  - min_width="345" + min_width="335"   name="floater_help_browser" - save_rect="true"   single_instance="true"   title="HOW TO"   width="335"> @@ -22,7 +21,7 @@       name="done_text">      </floater.string>      <layout_stack -     bottom="360" +     bottom="460"       follows="left|right|top|bottom"       layout="topleft"       left="5" @@ -38,7 +37,7 @@           user_resize="false"           width="325">              <web_browser -              trusted_content="true"  +              trusted_content="true"                 bottom="-5"               follows="left|right|top|bottom"               layout="topleft" diff --git a/indra/newview/skins/minimal/xui/en/floater_web_content.xml b/indra/newview/skins/minimal/xui/en/floater_web_content.xml index 50cb5b14ce..1d9a967d5a 100644 --- a/indra/newview/skins/minimal/xui/en/floater_web_content.xml +++ b/indra/newview/skins/minimal/xui/en/floater_web_content.xml @@ -17,6 +17,7 @@      follows="left|right|top|bottom"      layout="topleft"      left="5" +    animate="false"      name="stack1"      orientation="vertical"      top="20" @@ -155,14 +156,20 @@        name="external_controls"        top_delta="0"        user_resize="false" +      auto_resize="true"        width="585">        <web_browser -        bottom="-22" +        bottom="-2"          follows="all"          layout="topleft"          left="0"          name="webbrowser"          top="0"/> +      </layout_panel> +    <layout_panel name="status_bar"  +                  height="23" +                  auto_resize="false" +                  user_resize="false">        <text          type="string"          length="200" @@ -173,7 +180,7 @@          name="statusbartext"          parse_urls="false"          text_color="0.4 0.4 0.4 1" -        top_pad="5" +        top_pad="3"          width="495"/>        <progress_bar          color_bar="0.3 1.0 0.3 1" diff --git a/indra/newview/skins/minimal/xui/en/panel_im_control_panel.xml b/indra/newview/skins/minimal/xui/en/panel_im_control_panel.xml index be13bc1bb7..2cb77bcdf3 100644 --- a/indra/newview/skins/minimal/xui/en/panel_im_control_panel.xml +++ b/indra/newview/skins/minimal/xui/en/panel_im_control_panel.xml @@ -23,102 +23,172 @@       orientation="vertical"       top_pad="5"       width="145"> -      <layout_panel -       auto_resize="false" -       follows="top|left|right" -       height="20" -       layout="topleft" -       left="2" -       min_height="20" -       width="140" -       name="view_profile_btn_panel" -       top="0" -       user_resize="false"> -        <button -         follows="left|top|right" -         height="23" -         label="Profile" -         name="view_profile_btn" +        <layout_panel +         auto_resize="false" +         follows="top|left|right" +         height="20" +         layout="topleft" +         left="2" +         min_height="20" +         width="140" +         name="view_profile_btn_panel"           top="0" -         width="140" /> -      </layout_panel> -      <layout_panel -       auto_resize="false" -       follows="top|left|right" -       height="25" -       layout="topleft" -       min_height="25" -       width="140" -       name="add_friend_btn_panel" -       user_resize="false"> -        <button -         follows="left|top|right" -         height="23" -         label="Add Friend" -         name="add_friend_btn" -         top="5" -         width="140" /> -      </layout_panel> -      <layout_panel -       auto_resize="false" -       follows="top|left|right" -       height="25" -       layout="topleft" -       min_height="25" -       width="140" -       name="teleport_btn_panel" -       user_resize="false"> -        <button -             auto_resize="false" +         user_resize="false"> +            <button +             follows="left|top|right" +             height="23" +             label="Profile" +             name="view_profile_btn" +             top="0" +             width="140" /> +        </layout_panel> +        <layout_panel +         auto_resize="false" +         follows="top|left|right" +         height="25" +         layout="topleft" +         min_height="25" +         width="140" +         name="add_friend_btn_panel" +         user_resize="false"> +            <button               follows="left|top|right"               height="23" -             label="Teleport" -             name="teleport_btn" -             tool_tip = "Offer to teleport this person" +             label="Add Friend" +             name="add_friend_btn" +             top="5"               width="140" /> -      </layout_panel> -      <layout_panel +        </layout_panel> +        <layout_panel           auto_resize="false"           follows="top|left|right"           height="25"           layout="topleft"           min_height="25"           width="140" -         name="call_btn_panel" +         name="teleport_btn_panel"           user_resize="false"> -        <button -         follows="left|top|right" -         height="23" -         label="Call" -         name="call_btn" -         width="140" /> -      </layout_panel> -      <layout_panel -       auto_resize="false" -       follows="top|left|right" -       height="25" -       layout="topleft" -       min_height="25" -       width="140" -       name="end_call_btn_panel" -       user_resize="false" -       visible="false"> -        <button -         follows="left|top|right" -         height="23" -         label="End Call" -         name="end_call_btn" -         width="140" /> -      </layout_panel> -      <layout_panel -       mouse_opaque="false" -       auto_resize="true" -       follows="top|left" -       height="0" -       layout="topleft" -       min_height="0" -       width="140" -       name="spacer" -       user_resize="false" /> +            <button +                 auto_resize="false" +                 follows="left|top|right" +                 height="23" +                 label="Teleport" +                 name="teleport_btn" +                 tool_tip = "Offer to teleport this person" +                 width="140" /> +        </layout_panel> +        <layout_panel +           auto_resize="false" +           follows="top|left|right" +           height="25" +           layout="topleft" +           min_height="25" +           width="140" +           name="call_btn_panel" +           user_resize="false"> +            <button +             follows="left|top|right" +             height="23" +             label="Call" +             name="call_btn" +             width="140" /> +        </layout_panel> +        <layout_panel +         auto_resize="false" +         follows="top|left|right" +         height="25" +         layout="topleft" +         min_height="25" +         width="140" +         name="end_call_btn_panel" +         user_resize="false" +         visible="false"> +            <button +             follows="left|top|right" +             height="23" +             label="End Call" +             name="end_call_btn" +             width="140" /> +        </layout_panel> +        <layout_panel +         auto_resize="false" +         follows="top|left|right" +         height="25" +         layout="topleft" +         min_height="25" +         width="140" +         name="block_btn_panel" +         user_resize="false"> +            <button +             follows="left|top|right" +             height="23" +             label="Block" +             name="block_btn" +             width="140" /> +        </layout_panel> +        <layout_panel +         auto_resize="false" +         follows="top|left|right" +         height="25" +         layout="topleft" +         min_height="25" +         width="140" +         name="unblock_btn_panel" +         user_resize="false" +         visible="false"> +            <button +             follows="left|top|right" +             height="23" +             label="Unblock" +             name="unblock_btn" +             width="140" /> +        </layout_panel> +        <layout_panel +         auto_resize="false" +         follows="top|left|right" +         height="25" +         layout="topleft" +         min_height="54" +         width="140" +         name="volume_ctrl_panel" +         visible="false"  +         user_resize="false"> +            <slider +             follows="top|left" +             height="23" +             increment="0.01" +             left="0" +             max_val="0.95" +             min_val="0.05" +             name="volume_slider" +             show_text="false" +             tool_tip="Call Volume" +             top_pad="32" +             value="0.5" +             width="125" /> +            <button +             follows="top|left" +             height="16" +             image_disabled="Audio_Off" +             image_disabled_selected="AudioMute_Off" +             image_hover_selected="AudioMute_Over" +             image_selected="AudioMute_Off" +             image_unselected="Audio_Off" +             is_toggle="true" +             left_pad="0" +             top_delta="4" +             name="mute_btn" +             width="16" /> +        </layout_panel> +        <layout_panel +         mouse_opaque="false" +         auto_resize="true" +         follows="top|left" +         height="0" +         layout="topleft" +         min_height="0" +         width="140" +         name="spacer" +         user_resize="false" />      </layout_stack>  </panel>  | 
