diff options
Diffstat (limited to 'indra')
23 files changed, 559 insertions, 270 deletions
| diff --git a/indra/llcommon/llfoldertype.cpp b/indra/llcommon/llfoldertype.cpp index f6d0f5bce8..9c38349cf7 100755 --- a/indra/llcommon/llfoldertype.cpp +++ b/indra/llcommon/llfoldertype.cpp @@ -92,8 +92,9 @@ LLFolderDictionary::LLFolderDictionary()  	addEntry(LLFolderType::FT_MESH, 				new FolderEntry("mesh",	TRUE)); -	addEntry(LLFolderType::FT_INBOX, 				new FolderEntry("inbox",	TRUE)); -	addEntry(LLFolderType::FT_OUTBOX, 				new FolderEntry("outbox",	TRUE)); +	addEntry(LLFolderType::FT_INBOX, 				new FolderEntry("inbox",	FALSE)); +	addEntry(LLFolderType::FT_OUTBOX, 				new FolderEntry("outbox",	FALSE)); +	  	addEntry(LLFolderType::FT_BASIC_ROOT,			new FolderEntry("basic_rt", TRUE));  	addEntry(LLFolderType::FT_NONE, 				new FolderEntry("-1",		FALSE)); diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp index f32a52e6c6..704e03a605 100755 --- a/indra/llui/llfolderview.cpp +++ b/indra/llui/llfolderview.cpp @@ -167,13 +167,14 @@ LLFolderView::LLFolderView(const Params& p)  	mMinWidth(0),  	mDragAndDropThisFrame(FALSE),  	mCallbackRegistrar(NULL), -	mParentPanel(p.parent_panel),  	mUseEllipses(p.use_ellipses),  	mDraggingOverItem(NULL),  	mStatusTextBox(NULL),  	mShowItemLinkOverlays(p.show_item_link_overlays),  	mViewModel(p.view_model)  { +    LLPanel* panel = p.parent_panel; +    mParentPanel = panel->getHandle();  	mViewModel->setFolderView(this);  	mRoot = this; @@ -264,6 +265,7 @@ LLFolderView::~LLFolderView( void )  	mItems.clear();  	mFolders.clear(); +	//mViewModel->setFolderView(NULL);  	mViewModel = NULL;  } @@ -325,7 +327,7 @@ void LLFolderView::filter( LLFolderViewFilter& filter )  {      // Entry point of inventory filtering (CHUI-849)  	LLFastTimer t2(FTM_FILTER); -    filter.resetTime(llclamp(LLUI::sSettingGroups["config"]->getS32(mParentPanel->getVisible() ? "FilterItemsMaxTimePerFrameVisible" : "FilterItemsMaxTimePerFrameUnvisible"), 1, 100)); +    filter.resetTime(llclamp(LLUI::sSettingGroups["config"]->getS32(mParentPanel.get()->getVisible() ? "FilterItemsMaxTimePerFrameVisible" : "FilterItemsMaxTimePerFrameUnvisible"), 1, 100));      // Note: we filter the model, not the view  	getViewModelItem()->filter(filter); @@ -419,7 +421,7 @@ BOOL LLFolderView::setSelection(LLFolderViewItem* selection, BOOL openitem,  	if( selection && take_keyboard_focus)  	{ -		mParentPanel->setFocus(TRUE); +		mParentPanel.get()->setFocus(TRUE);  	}  	// clear selection down here because change of keyboard focus can potentially @@ -757,7 +759,7 @@ void LLFolderView::removeSelectedItems()  				if (item_to_delete->remove())  				{  					// change selection on successful delete -					setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel->hasFocus()); +					setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel.get()->hasFocus());  				}  			}  			arrangeAll(); @@ -767,7 +769,7 @@ void LLFolderView::removeSelectedItems()  			LLDynamicArray<LLFolderViewModelItem*> listeners;  			LLFolderViewModelItem* listener; -			setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel->hasFocus()); +			setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel.get()->hasFocus());  			for(S32 i = 0; i < count; ++i)  			{ @@ -947,7 +949,7 @@ void LLFolderView::cut()  		}  		// Update the selection -		setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel->hasFocus()); +		setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel.get()->hasFocus());  	}  	mSearchString.clear();  } @@ -1289,7 +1291,7 @@ BOOL LLFolderView::handleUnicodeCharHere(llwchar uni_char)  	}  	BOOL handled = FALSE; -	if (mParentPanel->hasFocus()) +	if (mParentPanel.get()->hasFocus())  	{  		// SL-51858: Key presses are not being passed to the Popup menu.  		// A proper fix is non-trivial so instead just close the menu. @@ -1323,7 +1325,7 @@ BOOL LLFolderView::handleMouseDown( S32 x, S32 y, MASK mask )  	mKeyboardSelection = FALSE;  	mSearchString.clear(); -	mParentPanel->setFocus(TRUE); +	mParentPanel.get()->setFocus(TRUE);  	LLEditMenuHandler::gEditMenuHandler = this; @@ -1406,7 +1408,7 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )  {  	// all user operations move keyboard focus to inventory  	// this way, we know when to stop auto-updating a search -	mParentPanel->setFocus(TRUE); +	mParentPanel.get()->setFocus(TRUE);  	BOOL handled = childrenHandleRightMouseDown(x, y, mask) != NULL;  	S32 count = mSelectedItems.size(); @@ -1598,6 +1600,12 @@ void LLFolderView::update()  	// If this is associated with the user's inventory, don't do anything  	// until that inventory is loaded up.  	LLFastTimer t2(FTM_INVENTORY); +     +    // If there's no model, the view is in suspended state (being deleted) and shouldn't be updated +    if (getFolderViewModel() == NULL) +    { +        return; +    }  	if (getFolderViewModel()->getFilter().isModified() && getFolderViewModel()->getFilter().isNotDefault())  	{ @@ -1644,8 +1652,8 @@ void LLFolderView::update()  	BOOL filter_finished = getViewModelItem()->passedFilter()  						&& mViewModel->contentsReady();  	if (filter_finished  -		|| gFocusMgr.childHasKeyboardFocus(mParentPanel) -		|| gFocusMgr.childHasMouseCapture(mParentPanel)) +		|| gFocusMgr.childHasKeyboardFocus(mParentPanel.get()) +		|| gFocusMgr.childHasMouseCapture(mParentPanel.get()))  	{  		// finishing the filter process, giving focus to the folder view, or dragging the scrollbar all stop the auto select process  		mNeedsAutoSelect = FALSE; diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h index 11fccdace4..5b83049e5c 100755 --- a/indra/llui/llfolderview.h +++ b/indra/llui/llfolderview.h @@ -229,7 +229,7 @@ public:  	void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; } -	LLPanel* getParentPanel() { return mParentPanel; } +	LLPanel* getParentPanel() { return mParentPanel.get(); }  	// DEBUG only  	void dumpSelectionInformation(); @@ -238,6 +238,9 @@ public:  	bool useLabelSuffix() { return mUseLabelSuffix; }  	void updateMenu(); +    // Note: We may eventually have to move that method up the hierarchy to LLFolderViewItem. +	LLHandle<LLFolderView>	getHandle() const { return getDerivedHandle<LLFolderView>(); } +      private:  	void updateMenuOptions(LLMenuGL* menu);  	void updateRenamerPosition(); @@ -295,7 +298,7 @@ protected:  	S32								mMinWidth;  	BOOL							mDragAndDropThisFrame; -	LLPanel*						mParentPanel; +	LLHandle<LLPanel>               mParentPanel;  	LLFolderViewModelInterface*		mViewModel; diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index d39bf6c3c2..de11309394 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -4655,6 +4655,17 @@  		<key>Value</key>  		<integer>0</integer>  	</map> +	<key>InventoryOutboxMakeVisible</key> +	<map> +		<key>Comment</key> +		<string>Enable making the Merchant Outbox and Inbox visible in the inventory for debug purposes.</string> +		<key>Persist</key> +		<integer>1</integer> +		<key>Type</key> +		<string>Boolean</string> +		<key>Value</key> +		<integer>0</integer> +	</map>      <key>InventoryOutboxMaxFolderCount</key>      <map>        <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl index c98e7d1cd3..bc63d07d72 100755 --- a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl @@ -33,8 +33,8 @@ mat4 getSkinnedTransform()  	mat4 ret;  	int i = int(floor(weight.x));  	float x = fract(weight.x); -	 -	ret[0] = mix(matrixPalette[i+0], matrixPalette[i+1],  x); +		 +	ret[0] = mix(matrixPalette[i+0], matrixPalette[i+1], x);  	ret[1] = mix(matrixPalette[i+15],matrixPalette[i+16], x);  	ret[2] = mix(matrixPalette[i+30],matrixPalette[i+31], x);  	ret[3] = vec4(0,0,0,1); diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 70cc48f12b..307e72fe18 100755 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -868,6 +868,10 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL  	// check selection in the panel  	LLFolderView* root_folder = inv_panel->getRootFolder(); +    if (!root_folder) +    { +        return false; +    }  	const std::set<LLFolderViewItem*> inventory_selected = root_folder->getSelectionList();  	if (inventory_selected.empty()) return false; // nothing selected diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp index 29a3e6ac3a..de96f75602 100755 --- a/indra/newview/llfloateroutbox.cpp +++ b/indra/newview/llfloateroutbox.cpp @@ -95,7 +95,7 @@ public:  			if (added_category_type == LLFolderType::FT_OUTBOX)  			{ -				mOutboxFloater->setupOutbox(added_category->getUUID()); +				mOutboxFloater->initializeMarketPlace();  			}  		}  	} @@ -120,7 +120,6 @@ LLFloaterOutbox::LLFloaterOutbox(const LLSD& key)  	, mInventoryText(NULL)  	, mInventoryTitle(NULL)  	, mOutboxId(LLUUID::null) -	, mOutboxInventoryPanel(NULL)  	, mOutboxItemCount(0)  	, mOutboxTopLevelDropZone(NULL)  	, mWindowShade(NULL) @@ -157,9 +156,24 @@ BOOL LLFloaterOutbox::postBuild()  	LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLFloaterOutbox::onFocusReceived, this)); +	// Observe category creation to catch outbox creation (moot if already existing) +	mCategoryAddedObserver = new LLOutboxAddedObserver(this); +	gInventory.addObserver(mCategoryAddedObserver); +	  	return TRUE;  } +void LLFloaterOutbox::cleanOutbox() +{ +    // Note: we cannot delete the mOutboxInventoryPanel as that point +    // as this is called through callback observers of the panel itself. +    // Doing so would crash rapidly. +	 +	// Invalidate the outbox data +    mOutboxId.setNull(); +    mOutboxItemCount = 0; +} +  void LLFloaterOutbox::onClose(bool app_quitting)  {  	if (mWindowShade) @@ -173,33 +187,25 @@ void LLFloaterOutbox::onClose(bool app_quitting)  void LLFloaterOutbox::onOpen(const LLSD& key)  {  	// -	// Look for an outbox and set up the inventory API +	// Initialize the Market Place or go update the outbox  	// -	 -	if (mOutboxId.isNull()) +	if (LLMarketplaceInventoryImporter::getInstance()->getMarketPlaceStatus() == MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED)  	{ -		const bool do_not_create_folder = false; -		 -		const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, do_not_create_folder); -		 -		if (outbox_id.isNull()) -		{ -			// Observe category creation to catch outbox creation -			mCategoryAddedObserver = new LLOutboxAddedObserver(this); -			gInventory.addObserver(mCategoryAddedObserver); -		} -		else -		{ -			setupOutbox(outbox_id); -		} +		initializeMarketPlace(); +	} +	else  +	{ +		setupOutbox();  	} +	// +	// Update the floater view +	//  	updateView();  	//  	// Trigger fetch of outbox contents  	// -	  	fetchOutboxContents();  } @@ -216,14 +222,34 @@ void LLFloaterOutbox::fetchOutboxContents()  	}  } -void LLFloaterOutbox::setupOutbox(const LLUUID& outboxId) +void LLFloaterOutbox::setupOutbox()  { -	llassert(outboxId.notNull()); -	llassert(mOutboxId.isNull()); -	llassert(mCategoriesObserver == NULL); -	 -	mOutboxId = outboxId; -	 +	if (LLMarketplaceInventoryImporter::getInstance()->getMarketPlaceStatus() != MarketplaceStatusCodes::MARKET_PLACE_MERCHANT) +	{ +		// If we are *not* a merchant or we have no market place connection established yet, do nothing +		return; +	} +		 +	// We are a merchant. Get the outbox, create it if needs be. +	LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, true); +	if (outbox_id.isNull()) +	{ +		// We should never get there unless the inventory fails badly +		llerrs << "Inventory problem: failure to create the outbox for a merchant!" << llendl; +		return; +	} +     +    // Consolidate Merchant Outbox +    // We shouldn't have to do that but with a client/server system relying on a "well known folder" convention, things get messy and conventions get broken down eventually +    gInventory.consolidateForType(outbox_id, LLFolderType::FT_OUTBOX); +     +    if (outbox_id == mOutboxId) +    { +        llwarns << "Inventory warning: Merchant outbox already set" << llendl; +        return; +    } +    mOutboxId = outbox_id; +  	// No longer need to observe new category creation  	if (mCategoryAddedObserver && gInventory.containsObserver(mCategoryAddedObserver))  	{ @@ -231,45 +257,55 @@ void LLFloaterOutbox::setupOutbox(const LLUUID& outboxId)  		delete mCategoryAddedObserver;  		mCategoryAddedObserver = NULL;  	} +	llassert(!mCategoryAddedObserver); -	// Create observer for outbox modifications -	mCategoriesObserver = new LLInventoryCategoriesObserver(); -	gInventory.addObserver(mCategoriesObserver); -	 -	mCategoriesObserver->addCategory(mOutboxId, boost::bind(&LLFloaterOutbox::onOutboxChanged, this)); +	// Create observer for outbox modifications : clear the old one and create a new one +	if (mCategoriesObserver && gInventory.containsObserver(mCategoriesObserver)) +	{ +		gInventory.removeObserver(mCategoriesObserver); +		delete mCategoriesObserver; +	} +    mCategoriesObserver = new LLInventoryCategoriesObserver(); +    gInventory.addObserver(mCategoriesObserver); +    mCategoriesObserver->addCategory(mOutboxId, boost::bind(&LLFloaterOutbox::onOutboxChanged, this)); +	llassert(mCategoriesObserver); -	//  	// Set up the outbox inventory view -	// -	 -	mOutboxInventoryPanel =  -		LLUICtrlFactory::createFromFile<LLInventoryPanel>("panel_outbox_inventory.xml", -														  mInventoryPlaceholder->getParent(), -														  LLInventoryPanel::child_registry_t::instance()); -	 -	llassert(mOutboxInventoryPanel); +	LLInventoryPanel* inventory_panel = mOutboxInventoryPanel.get(); +    if (inventory_panel) +    { +        delete inventory_panel; +    } +    inventory_panel = LLUICtrlFactory::createFromFile<LLInventoryPanel>("panel_outbox_inventory.xml", mInventoryPlaceholder->getParent(), LLInventoryPanel::child_registry_t::instance()); +    mOutboxInventoryPanel = inventory_panel->getInventoryPanelHandle(); +	llassert(mOutboxInventoryPanel.get() != NULL);  	// Reshape the inventory to the proper size  	LLRect inventory_placeholder_rect = mInventoryPlaceholder->getRect(); -	mOutboxInventoryPanel->setShape(inventory_placeholder_rect); +	inventory_panel->setShape(inventory_placeholder_rect);  	// Set the sort order newest to oldest - -	mOutboxInventoryPanel->getFolderViewModel()->setSorter(LLInventoryFilter::SO_FOLDERS_BY_NAME);	 -	mOutboxInventoryPanel->getFilter().markDefault(); -	 +	inventory_panel->getFolderViewModel()->setSorter(LLInventoryFilter::SO_FOLDERS_BY_NAME);	 +	inventory_panel->getFilter().markDefault(); +     +	// Get the content of the outbox  	fetchOutboxContents(); -	 +} + +void LLFloaterOutbox::initializeMarketPlace() +{  	//  	// Initialize the marketplace import API  	// -	  	LLMarketplaceInventoryImporter& importer = LLMarketplaceInventoryImporter::instance(); -	importer.setInitializationErrorCallback(boost::bind(&LLFloaterOutbox::initializationReportError, this, _1, _2)); -	importer.setStatusChangedCallback(boost::bind(&LLFloaterOutbox::importStatusChanged, this, _1)); -	importer.setStatusReportCallback(boost::bind(&LLFloaterOutbox::importReportResults, this, _1, _2)); -	importer.initialize(); +    if (!importer.isInitialized()) +    { +        importer.setInitializationErrorCallback(boost::bind(&LLFloaterOutbox::initializationReportError, this, _1, _2)); +        importer.setStatusChangedCallback(boost::bind(&LLFloaterOutbox::importStatusChanged, this, _1)); +        importer.setStatusReportCallback(boost::bind(&LLFloaterOutbox::importReportResults, this, _1, _2)); +        importer.initialize(); +    }  }  void LLFloaterOutbox::setStatusString(const std::string& statusString) @@ -281,18 +317,26 @@ void LLFloaterOutbox::setStatusString(const std::string& statusString)  void LLFloaterOutbox::updateFolderCount()  { -	S32 item_count = 0; - -	if (mOutboxId.notNull()) +	if (mOutboxInventoryPanel.get() && mOutboxId.notNull())  	{ -		LLInventoryModel::cat_array_t * cats; -		LLInventoryModel::item_array_t * items; -		gInventory.getDirectDescendentsOf(mOutboxId, cats, items); +        S32 item_count = 0; -		item_count = cats->count() + items->count(); -	} +        if (mOutboxId.notNull()) +        { +            LLInventoryModel::cat_array_t * cats; +            LLInventoryModel::item_array_t * items; +            gInventory.getDirectDescendentsOf(mOutboxId, cats, items); + +            item_count = cats->count() + items->count(); +        } -	mOutboxItemCount = item_count; +        mOutboxItemCount = item_count; +    } +    else +    { +        // If there's no outbox, the number of items in it should be set to 0 for consistency +        mOutboxItemCount = 0; +    }  	if (!mImportBusy)  	{ @@ -302,7 +346,7 @@ void LLFloaterOutbox::updateFolderCount()  void LLFloaterOutbox::updateFolderCountStatus()  { -	if (mOutboxInventoryPanel) +	if (mOutboxInventoryPanel.get() && mOutboxId.notNull())  	{  		switch (mOutboxItemCount)  		{ @@ -327,18 +371,23 @@ void LLFloaterOutbox::updateFolderCountStatus()  void LLFloaterOutbox::updateView()  {  	updateFolderCount(); +	LLInventoryPanel* panel = mOutboxInventoryPanel.get();  	if (mOutboxItemCount > 0)  	{ -		mOutboxInventoryPanel->setVisible(TRUE); +		panel->setVisible(TRUE);  		mInventoryPlaceholder->setVisible(FALSE); +		mOutboxTopLevelDropZone->setVisible(TRUE);  	}  	else  	{ -		if (mOutboxInventoryPanel) +		if (panel)  		{ -			mOutboxInventoryPanel->setVisible(FALSE); +			panel->setVisible(FALSE);  		} +		 +		// Show the drop zone if there is an outbox folder +		mOutboxTopLevelDropZone->setVisible(mOutboxId.notNull());  		mInventoryPlaceholder->setVisible(TRUE); @@ -347,19 +396,41 @@ void LLFloaterOutbox::updateView()  		std::string outbox_tooltip;  		const LLSD& subs = getMarketplaceStringSubstitutions(); +		U32 mkt_status = LLMarketplaceInventoryImporter::getInstance()->getMarketPlaceStatus();  		if (mOutboxId.notNull())  		{ +            // Does the outbox needs recreation? +            if ((mOutboxInventoryPanel.get() == NULL) || !gInventory.getCategory(mOutboxId)) +            { +                setupOutbox(); +            } +			// "Outbox is empty!" message strings  			outbox_text = LLTrans::getString("InventoryOutboxNoItems", subs);  			outbox_title = LLTrans::getString("InventoryOutboxNoItemsTitle");  			outbox_tooltip = LLTrans::getString("InventoryOutboxNoItemsTooltip");  		} -		else +		else if (mkt_status <= MarketplaceStatusCodes::MARKET_PLACE_INITIALIZING) +		{ +			// "Initializing!" message strings +			outbox_text = LLTrans::getString("InventoryOutboxInitializing", subs); +			outbox_title = LLTrans::getString("InventoryOutboxInitializingTitle"); +			outbox_tooltip = LLTrans::getString("InventoryOutboxInitializingTooltip"); +		} +		else if (mkt_status == MarketplaceStatusCodes::MARKET_PLACE_NOT_MERCHANT)  		{ +			// "Not a merchant!" message strings  			outbox_text = LLTrans::getString("InventoryOutboxNotMerchant", subs);  			outbox_title = LLTrans::getString("InventoryOutboxNotMerchantTitle");  			outbox_tooltip = LLTrans::getString("InventoryOutboxNotMerchantTooltip");  		} +		else +		{ +			// "Errors!" message strings +			outbox_text = LLTrans::getString("InventoryOutboxError", subs); +			outbox_title = LLTrans::getString("InventoryOutboxErrorTitle"); +			outbox_tooltip = LLTrans::getString("InventoryOutboxErrorTooltip"); +		}  		mInventoryText->setValue(outbox_text);  		mInventoryTitle->setValue(outbox_title); @@ -378,9 +449,10 @@ BOOL LLFloaterOutbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,  										EAcceptance* accept,  										std::string& tooltip_msg)  { -	if ((mOutboxInventoryPanel == NULL) || +	if ((mOutboxInventoryPanel.get() == NULL) ||  		(mWindowShade && mWindowShade->isShown()) || -		LLMarketplaceInventoryImporter::getInstance()->isImportInProgress()) +		LLMarketplaceInventoryImporter::getInstance()->isImportInProgress() || +        mOutboxId.isNull())  	{  		return FALSE;  	} @@ -391,15 +463,16 @@ BOOL LLFloaterOutbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,  	// Determine if the mouse is inside the inventory panel itself or just within the floater  	bool pointInInventoryPanel = false;  	bool pointInInventoryPanelChild = false; -	LLFolderView* root_folder = mOutboxInventoryPanel->getRootFolder(); -	if (mOutboxInventoryPanel->getVisible()) +	LLInventoryPanel* panel = mOutboxInventoryPanel.get(); +	LLFolderView* root_folder = panel->getRootFolder(); +	if (panel->getVisible())  	{  		S32 inv_x, inv_y; -		localPointToOtherView(x, y, &inv_x, &inv_y, mOutboxInventoryPanel); +		localPointToOtherView(x, y, &inv_x, &inv_y, panel); -		pointInInventoryPanel = mOutboxInventoryPanel->getRect().pointInRect(inv_x, inv_y); +		pointInInventoryPanel = panel->getRect().pointInRect(inv_x, inv_y); -		LLView * inventory_panel_child_at_point = mOutboxInventoryPanel->childFromPoint(inv_x, inv_y, true); +		LLView * inventory_panel_child_at_point = panel->childFromPoint(inv_x, inv_y, true);  		pointInInventoryPanelChild = (inventory_panel_child_at_point != root_folder);  	} @@ -439,23 +512,26 @@ void LLFloaterOutbox::onMouseLeave(S32 x, S32 y, MASK mask)  void LLFloaterOutbox::onImportButtonClicked()  { -	mOutboxInventoryPanel->clearSelection(); +    if (mOutboxInventoryPanel.get()) +    { +        mOutboxInventoryPanel.get()->clearSelection(); +    }  	mImportBusy = LLMarketplaceInventoryImporter::instance().triggerImport();  }  void LLFloaterOutbox::onOutboxChanged()  { -	llassert(!mOutboxId.isNull()); -	 -	//if (mOutboxInventoryPanel) -	//{ -	//	mOutboxInventoryPanel->requestSort(); -	//} - -	fetchOutboxContents(); - -	updateView(); +    LLViewerInventoryCategory* category = gInventory.getCategory(mOutboxId); +	if (mOutboxId.notNull() && category) +    { +        fetchOutboxContents(); +        updateView(); +    } +    else +    { +        cleanOutbox(); +    }  }  void LLFloaterOutbox::importReportResults(U32 status, const LLSD& content) @@ -486,6 +562,11 @@ void LLFloaterOutbox::importReportResults(U32 status, const LLSD& content)  void LLFloaterOutbox::importStatusChanged(bool inProgress)  { +	if (mOutboxId.isNull() && (LLMarketplaceInventoryImporter::getInstance()->getMarketPlaceStatus() == MarketplaceStatusCodes::MARKET_PLACE_MERCHANT)) +	{ +		setupOutbox(); +	} +	  	if (inProgress)  	{  		if (mImportBusy) @@ -503,6 +584,7 @@ void LLFloaterOutbox::importStatusChanged(bool inProgress)  	}  	else  	{ +		setStatusString("");  		mImportBusy = false;  		mImportButton->setEnabled(mOutboxItemCount > 0);  		mInventoryImportInProgress->setVisible(false); @@ -513,7 +595,7 @@ void LLFloaterOutbox::importStatusChanged(bool inProgress)  void LLFloaterOutbox::initializationReportError(U32 status, const LLSD& content)  { -	if (status != MarketplaceErrorCodes::IMPORT_DONE) +	if (status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST)  	{  		char status_string[16];  		sprintf(status_string, "%d", status); diff --git a/indra/newview/llfloateroutbox.h b/indra/newview/llfloateroutbox.h index a91d8c1139..40519c8fd2 100755 --- a/indra/newview/llfloateroutbox.h +++ b/indra/newview/llfloateroutbox.h @@ -54,7 +54,7 @@ public:  	LLFloaterOutbox(const LLSD& key);  	~LLFloaterOutbox(); -	void setupOutbox(const LLUUID& outboxId); +	void initializeMarketPlace();  	// virtuals  	BOOL postBuild(); @@ -70,6 +70,8 @@ public:  	void onMouseLeave(S32 x, S32 y, MASK mask);  protected: +	void setupOutbox(); +    void cleanOutbox();  	void fetchOutboxContents();  	void importReportResults(U32 status, const LLSD& content); @@ -104,7 +106,7 @@ private:  	LLTextBox *		mInventoryTitle;  	LLUUID				mOutboxId; -	LLInventoryPanel *	mOutboxInventoryPanel; +	LLHandle<LLInventoryPanel> mOutboxInventoryPanel;  	U32					mOutboxItemCount;  	LLPanel *			mOutboxTopLevelDropZone; diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp index c28657dbcd..aac3a41b9e 100755 --- a/indra/newview/llfolderviewmodelinventory.cpp +++ b/indra/newview/llfolderviewmodelinventory.cpp @@ -232,16 +232,16 @@ bool LLFolderViewModelItemInventory::filter( LLFolderViewFilter& filter)      return continue_filtering;  } -LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel() -{ -	return &mInventoryViewModel; -} - - -const LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel() const -{ -	return &mInventoryViewModel; -} +//LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel() +//{ +//	return &mInventoryViewModel; +//} +// +// +//const LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel() const +//{ +//	return &mInventoryViewModel; +//}  bool LLInventorySort::operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b) const  { diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 935fe2b4d0..ed7fd3cd34 100755 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -369,15 +369,74 @@ void LLInventoryModel::unlockDirectDescendentArrays(const LLUUID& cat_id)  	mItemLock[cat_id] = false;  } +void LLInventoryModel::consolidateForType(const LLUUID& main_id, LLFolderType::EType type) +{ +    // Make a list of folders that are not "main_id" and are of "type" +    std::vector<LLUUID> folder_ids; +    for (cat_map_t::iterator cit = mCategoryMap.begin(); cit != mCategoryMap.end(); ++cit) +    { +        LLViewerInventoryCategory* cat = cit->second; +        if ((cat->getPreferredType() == type) && (cat->getUUID() != main_id)) +        { +            folder_ids.push_back(cat->getUUID()); +        } +    } + +    // Iterate through those folders +	for (std::vector<LLUUID>::iterator folder_ids_it = folder_ids.begin(); folder_ids_it != folder_ids.end(); ++folder_ids_it) +	{ +		LLUUID folder_id = (*folder_ids_it); +         +        // Get the content of this folder +        cat_array_t* cats; +        item_array_t* items; +        getDirectDescendentsOf(folder_id, cats, items); +         +        // Move all items to the main folder +        // Note : we get the list of UUIDs and iterate on them instead of iterating directly on item_array_t +        // elements. This is because moving elements modify the maps and, consequently, invalidate iterators on them. +        // This "gather and iterate" method is verbose but resilient. +        std::vector<LLUUID> list_uuids; +        for (item_array_t::const_iterator it = items->begin(); it != items->end(); ++it) +        { +            list_uuids.push_back((*it)->getUUID()); +        } +        for (std::vector<LLUUID>::const_iterator it = list_uuids.begin(); it != list_uuids.end(); ++it) +        { +            LLViewerInventoryItem* item = getItem(*it); +            changeItemParent(item, main_id, TRUE); +        } + +        // Move all folders to the main folder +        list_uuids.clear(); +        for (cat_array_t::const_iterator it = cats->begin(); it != cats->end(); ++it) +        { +            list_uuids.push_back((*it)->getUUID()); +        } +        for (std::vector<LLUUID>::const_iterator it = list_uuids.begin(); it != list_uuids.end(); ++it) +        { +            LLViewerInventoryCategory* cat = getCategory(*it); +            changeCategoryParent(cat, main_id, TRUE); +        } +         +        // Purge the emptied folder +        // Note: we'd like to use purgeObject() but it doesn't cleanly eliminate the folder +        // which leads to issues further down the road when the folder is found again +        //purgeObject(folder_id); +        // We remove the folder and empty the trash instead which seems to work +		removeCategory(folder_id); +        gInventory.emptyFolderType("", LLFolderType::FT_TRASH); +	} +} +  // findCategoryUUIDForType() returns the uuid of the category that  // specifies 'type' as what it defaults to containing. The category is  // not necessarily only for that type. *NOTE: This will create a new  // inventory category on the fly if one does not exist. -const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType preferred_type, bool create_folder/*,  +const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType preferred_type, bool create_folder/*,  					  bool find_in_library*/)  {  	LLUUID rv = LLUUID::null; -	  	const LLUUID &root_id = /*(find_in_library) ? gInventory.getLibraryRootFolderID() :*/ gInventory.getRootFolderID();  	if(LLFolderType::FT_ROOT_INVENTORY == preferred_type)  	{ @@ -392,9 +451,9 @@ const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType prefe  			S32 count = cats->count();  			for(S32 i = 0; i < count; ++i)  			{ -				if(cats->get(i)->getPreferredType() == preferred_type) +				if (cats->get(i)->getPreferredType() == preferred_type)  				{ -					rv = cats->get(i)->getUUID(); +                    rv = cats->get(i)->getUUID();  					break;  				}  			} @@ -587,7 +646,7 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id,  	return id;  } -// Starting with the object specified, add it's descendents to the +// Starting with the object specified, add its descendents to the  // array provided, but do not add the inventory object specified by  // id. There is no guaranteed order. Neither array will be erased  // before adding objects to it. Do not store a copy of the pointers @@ -1003,7 +1062,7 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat)  		new_cat->copyViewerCategory(cat);  		addCategory(new_cat); -		// make sure this category is correctly referenced by it's parent. +		// make sure this category is correctly referenced by its parent.  		cat_array_t* cat_array;  		cat_array = getUnlockedCatArray(cat->getParentUUID());  		if(cat_array) @@ -1209,12 +1268,6 @@ void LLInventoryModel::updateLinkedObjectsFromPurge(const LLUUID &baseobj_id)  // folders, items, etc in a fairly efficient manner.  void LLInventoryModel::purgeDescendentsOf(const LLUUID& id)  { -	EHasChildren children = categoryHasChildren(id); -	if(children == CHILDREN_NO) -	{ -		llinfos << "Not purging descendents of " << id << llendl; -		return; -	}  	LLPointer<LLViewerInventoryCategory> cat = getCategory(id);  	if (cat.notNull())  	{ @@ -1225,7 +1278,7 @@ void LLInventoryModel::purgeDescendentsOf(const LLUUID& id)  			<< " iterate and purge non hidden items" << llendl;  			cat_array_t* categories;  			item_array_t* items; -			// Get the list of direct descendants in tha categoy passed as argument +			// Get the list of direct descendants in that category passed as argument  			getDirectDescendentsOf(id, categories, items);  			std::vector<LLUUID> list_uuids;  			// Make a unique list with all the UUIDs of the direct descendants (items and categories are not treated differently) diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 8aac879a93..544ca5e5dc 100755 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -263,6 +263,11 @@ public:  	// Get the inventoryID or item that this item points to, else just return object_id  	const LLUUID& getLinkedItemID(const LLUUID& object_id) const;  	LLViewerInventoryItem* getLinkedItem(const LLUUID& object_id) const; +     +    // Copy content of all folders of type "type" into folder "id" and delete/purge the empty folders +    // Note : This method has been designed for FT_OUTBOX (aka Merchant Outbox) but can be used for other categories +    void consolidateForType(const LLUUID& id, LLFolderType::EType type); +      private:  	mutable LLPointer<LLViewerInventoryItem> mLastItem; // cache recent lookups	 diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp index 9db175ec2e..16427f2016 100755 --- a/indra/newview/llinventoryobserver.cpp +++ b/indra/newview/llinventoryobserver.cpp @@ -690,15 +690,24 @@ void LLInventoryCategoriesObserver::changed(U32 mask)  	if (!mCategoryMap.size())  		return; +	std::vector<LLUUID> deleted_categories_ids; +  	for (category_map_t::iterator iter = mCategoryMap.begin();  		 iter != mCategoryMap.end();  		 ++iter)  	{  		const LLUUID& cat_id = (*iter).first; - +		LLCategoryData& cat_data = (*iter).second; +          		LLViewerInventoryCategory* category = gInventory.getCategory(cat_id);  		if (!category) +        { +            llwarns << "Category : Category id = " << cat_id << " disappeared" << llendl; +			cat_data.mCallback(); +            // Keep track of those deleted categories so we can remove them +            deleted_categories_ids.push_back(cat_id);  			continue; +        }  		const S32 version = category->getVersion();  		const S32 expected_num_descendents = category->getDescendentCount(); @@ -726,8 +735,6 @@ void LLInventoryCategoriesObserver::changed(U32 mask)  		const S32 current_num_known_descendents = cats->count() + items->count(); -		LLCategoryData& cat_data = (*iter).second; -  		bool cat_changed = false;  		// If category version or descendents count has changed @@ -757,6 +764,12 @@ void LLInventoryCategoriesObserver::changed(U32 mask)  		if (cat_changed)  			cat_data.mCallback();  	} +     +    // Remove deleted categories from the list + 	for (std::vector<LLUUID>::iterator deleted_id = deleted_categories_ids.begin(); deleted_id != deleted_categories_ids.end(); ++deleted_id) +	{ +		removeCategory(*deleted_id); +    }  }  bool LLInventoryCategoriesObserver::addCategory(const LLUUID& cat_id, callback_t cb) diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index e5b9e11d48..81ee7ac07e 100755 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -137,7 +137,6 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :  	LLPanel(p),  	mInventoryObserver(NULL),  	mCompletionObserver(NULL), -	mFolderRoot(NULL),  	mScroller(NULL),  	mSortOrderSetting(p.sort_order_setting),  	mInventory(p.inventory), @@ -196,6 +195,32 @@ LLFolderView * LLInventoryPanel::createFolderRoot(LLUUID root_id )      return LLUICtrlFactory::create<LLFolderView>(p);  } +void LLInventoryPanel::clearFolderRoot() +{ +	gIdleCallbacks.deleteFunction(idle, this); +    gIdleCallbacks.deleteFunction(onIdle, this); +     +    if (mInventoryObserver) +    { +        mInventory->removeObserver(mInventoryObserver); +        delete mInventoryObserver; +        mInventoryObserver = NULL; +    } +    if (mCompletionObserver) +    { +        mInventory->removeObserver(mCompletionObserver); +        delete mCompletionObserver; +        mCompletionObserver = NULL; +    } +     +    if (mScroller) +    { +        removeChild(mScroller); +        delete mScroller; +        mScroller = NULL; +    } +} +  void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)  {  	// save off copy of params @@ -203,23 +228,23 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)  	// Clear up the root view  	// Note: This needs to be done *before* we build the new folder view   	LLUUID root_id = getRootFolderID(); -	if (mFolderRoot) +	if (mFolderRoot.get())  	{  		removeItemID(root_id); -		mFolderRoot->destroyView(); -		mFolderRoot = NULL; +		mFolderRoot.get()->destroyView();  	}  	mCommitCallbackRegistrar.pushScope(); // registered as a widget; need to push callback scope ourselves  	{  		// Determine the root folder in case specified, and  		// build the views starting with that folder. -		mFolderRoot = createFolderRoot(root_id); +        LLFolderView* folder_view = createFolderRoot(root_id); +		mFolderRoot = folder_view->getHandle(); -		addItemID(root_id, mFolderRoot); +		addItemID(root_id, mFolderRoot.get());  	}  	mCommitCallbackRegistrar.popScope(); -	mFolderRoot->setCallbackRegistrar(&mCommitCallbackRegistrar); +	mFolderRoot.get()->setCallbackRegistrar(&mCommitCallbackRegistrar);  	// Scroller  		LLRect scroller_view_rect = getRect(); @@ -228,10 +253,10 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)  		scroller_params.rect(scroller_view_rect);  		mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params);  		addChild(mScroller); -		mScroller->addChild(mFolderRoot); -		mFolderRoot->setScrollContainer(mScroller); -		mFolderRoot->setFollowsAll(); -		mFolderRoot->addChild(mFolderRoot->mStatusTextBox); +		mScroller->addChild(mFolderRoot.get()); +		mFolderRoot.get()->setScrollContainer(mScroller); +		mFolderRoot.get()->setFollowsAll(); +		mFolderRoot.get()->addChild(mFolderRoot.get()->mStatusTextBox);  	// Set up the callbacks from the inventory we're viewing, and then build everything.  	mInventoryObserver = new LLInventoryPanelObserver(this); @@ -259,8 +284,11 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)  	}  	// hide inbox -	getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_INBOX)); -	getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_OUTBOX)); +	if (!gSavedSettings.getBOOL("InventoryOutboxMakeVisible")) +	{ +		getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_INBOX)); +		getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_OUTBOX)); +	}  	// set the filter for the empty folder if the debug setting is on  	if (gSavedSettings.getBOOL("DebugHideEmptySystemFolders")) @@ -277,23 +305,13 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)  LLInventoryPanel::~LLInventoryPanel()  { -	gIdleCallbacks.deleteFunction(idle, this); -  	U32 sort_order = getFolderViewModel()->getSorter().getSortOrder(); -		if (mSortOrderSetting != INHERIT_SORT_ORDER) -		{ -			gSavedSettings.setU32(mSortOrderSetting, sort_order); -		} - -	gIdleCallbacks.deleteFunction(onIdle, this); - -	// LLView destructor will take care of the sub-views. -	mInventory->removeObserver(mInventoryObserver); -	mInventory->removeObserver(mCompletionObserver); -	delete mInventoryObserver; -	delete mCompletionObserver; - -	mScroller = NULL; +    if (mSortOrderSetting != INHERIT_SORT_ORDER) +    { +        gSavedSettings.setU32(mSortOrderSetting, sort_order); +    } +     +    clearFolderRoot();  }  void LLInventoryPanel::draw() @@ -360,9 +378,9 @@ void LLInventoryPanel::setSortOrder(U32 order)  	if (order != getFolderViewModel()->getSorter().getSortOrder())  	{  		getFolderViewModel()->setSorter(sorter); -		mFolderRoot->arrangeAll(); +		mFolderRoot.get()->arrangeAll();  		// try to keep selection onscreen, even if it wasn't to start with -		mFolderRoot->scrollToShowSelection(); +		mFolderRoot.get()->scrollToShowSelection();  	}  } @@ -505,7 +523,7 @@ void LLInventoryPanel::modelChanged(U32 mask)  				// Add the UI element for this item.  				buildNewViews(item_id);  				// Select any newly created object that has the auto rename at top of folder root set. -				if(mFolderRoot->getRoot()->needsAutoRename()) +				if(mFolderRoot.get()->getRoot()->needsAutoRename())  				{  					setSelection(item_id, FALSE);  				} @@ -556,17 +574,11 @@ void LLInventoryPanel::modelChanged(U32 mask)  	}  } -LLFolderView* LLInventoryPanel::getRootFolder()  -{  -	return mFolderRoot;  -} -  LLUUID LLInventoryPanel::getRootFolderID()  { -	if (mFolderRoot && mFolderRoot->getViewModelItem()) +	if (mFolderRoot.get() && mFolderRoot.get()->getViewModelItem())  	{ -		return static_cast<LLFolderViewModelItemInventory*>(mFolderRoot->getViewModelItem())->getUUID(); - +		return static_cast<LLFolderViewModelItemInventory*>(mFolderRoot.get()->getViewModelItem())->getUUID();  	}  	else  	{ @@ -587,6 +599,9 @@ LLUUID LLInventoryPanel::getRootFolderID()  			}  			else if (preferred_type != LLFolderType::FT_NONE)  			{ +                LLStringExplicit label(mParams.start_folder.name()); +                setLabel(label); +                  				root_id = gInventory.findCategoryUUIDForType(preferred_type, false);  				if (root_id.isNull())  				{ @@ -646,24 +661,33 @@ void LLInventoryPanel::idle(void* user_data)  	} -	panel->mFolderRoot->update(); -	// while dragging, update selection rendering to reflect single/multi drag status -	if (LLToolDragAndDrop::getInstance()->hasMouseCapture()) -	{ -		EAcceptance last_accept = LLToolDragAndDrop::getInstance()->getLastAccept(); -		if (last_accept == ACCEPT_YES_SINGLE || last_accept == ACCEPT_YES_COPY_SINGLE) -		{ -			panel->mFolderRoot->setShowSingleSelection(TRUE); -		} -		else -		{ -			panel->mFolderRoot->setShowSingleSelection(FALSE); -		} -} -	else -	{ -		panel->mFolderRoot->setShowSingleSelection(FALSE); -	} +    // Take into account the fact that the root folder might be invalidated +    if (panel->mFolderRoot.get()) +    { +        panel->mFolderRoot.get()->update(); +        // while dragging, update selection rendering to reflect single/multi drag status +        if (LLToolDragAndDrop::getInstance()->hasMouseCapture()) +        { +            EAcceptance last_accept = LLToolDragAndDrop::getInstance()->getLastAccept(); +            if (last_accept == ACCEPT_YES_SINGLE || last_accept == ACCEPT_YES_COPY_SINGLE) +            { +                panel->mFolderRoot.get()->setShowSingleSelection(TRUE); +            } +            else +            { +                panel->mFolderRoot.get()->setShowSingleSelection(FALSE); +            } +        } +        else +        { +            panel->mFolderRoot.get()->setShowSingleSelection(FALSE); +        } +    } +    else +    { +        llwarns << "Inventory : Deleted folder root detected on panel" << llendl; +        panel->clearFolderRoot(); +    }  } @@ -714,7 +738,7 @@ LLFolderViewFolder * LLInventoryPanel::createFolderViewFolder(LLInvFVBridge * br  	LLFolderViewFolder::Params params(mParams.folder);  	params.name = bridge->getDisplayName(); -	params.root = mFolderRoot; +	params.root = mFolderRoot.get();  	params.listener = bridge;  	params.tool_tip = params.name; @@ -730,7 +754,7 @@ LLFolderViewItem * LLInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge  	params.name = bridge->getDisplayName();  	params.creation_date = bridge->getCreationDate(); -	params.root = mFolderRoot; +	params.root = mFolderRoot.get();  	params.listener = bridge;  	params.rect = LLRect (0, 0, 0, 0);  	params.tool_tip = params.name; @@ -771,7 +795,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)    																				LLInventoryType::IT_CATEGORY,    																				this,  																			&mInventoryViewModel, -  																				mFolderRoot, +  																				mFolderRoot.get(),    																				objectp->getUUID());    				if (new_listener)    				{ @@ -787,7 +811,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)    																				item->getInventoryType(),    																				this,  																			&mInventoryViewModel, -  																				mFolderRoot, +  																				mFolderRoot.get(),    																				item->getUUID(),    																				item->getFlags()); @@ -844,7 +868,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)  void LLInventoryPanel::openStartFolderOrMyInventory()  {  	// Find My Inventory folder and open it up by name -	for (LLView *child = mFolderRoot->getFirstChild(); child; child = mFolderRoot->findNextSibling(child)) +	for (LLView *child = mFolderRoot.get()->getFirstChild(); child; child = mFolderRoot.get()->findNextSibling(child))  	{  		LLFolderViewFolder *fchild = dynamic_cast<LLFolderViewFolder*>(child);  		if (fchild @@ -859,12 +883,12 @@ void LLInventoryPanel::openStartFolderOrMyInventory()  void LLInventoryPanel::onItemsCompletion()  { -	if (mFolderRoot) mFolderRoot->updateMenu(); +	if (mFolderRoot.get()) mFolderRoot.get()->updateMenu();  }  void LLInventoryPanel::openSelected()  { -	LLFolderViewItem* folder_item = mFolderRoot->getCurSelectedItem(); +	LLFolderViewItem* folder_item = mFolderRoot.get()->getCurSelectedItem();  	if(!folder_item) return;  	LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getViewModelItem();  	if(!bridge) return; @@ -873,7 +897,7 @@ void LLInventoryPanel::openSelected()  void LLInventoryPanel::unSelectAll()	  {  -	mFolderRoot->setSelection(NULL, FALSE, FALSE);  +	mFolderRoot.get()->setSelection(NULL, FALSE, FALSE);  } @@ -911,14 +935,14 @@ BOOL LLInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,  		// If folder view is empty the (x, y) point won't be in its rect  		// so the handler must be called explicitly.  		// but only if was not handled before. See EXT-6746. -		if (!handled && !mFolderRoot->hasVisibleChildren()) +		if (!handled && !mFolderRoot.get()->hasVisibleChildren())  		{ -			handled = mFolderRoot->handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg); +			handled = mFolderRoot.get()->handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);  		}  		if (handled)  		{ -			mFolderRoot->setDragAndDropThisFrame(); +			mFolderRoot.get()->setDragAndDropThisFrame();  		}  	} @@ -928,7 +952,7 @@ BOOL LLInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,  void LLInventoryPanel::onFocusLost()  {  	// inventory no longer handles cut/copy/paste/delete -	if (LLEditMenuHandler::gEditMenuHandler == mFolderRoot) +	if (LLEditMenuHandler::gEditMenuHandler == mFolderRoot.get())  	{  		LLEditMenuHandler::gEditMenuHandler = NULL;  	} @@ -939,7 +963,7 @@ void LLInventoryPanel::onFocusLost()  void LLInventoryPanel::onFocusReceived()  {  	// inventory now handles cut/copy/paste/delete -	LLEditMenuHandler::gEditMenuHandler = mFolderRoot; +	LLEditMenuHandler::gEditMenuHandler = mFolderRoot.get();  	LLPanel::onFocusReceived();  } @@ -950,7 +974,7 @@ bool LLInventoryPanel::addBadge(LLBadge * badge)  	if (acceptsBadge())  	{ -		badge_added = badge->addToView(mFolderRoot); +		badge_added = badge->addToView(mFolderRoot.get());  	}  	return badge_added; @@ -958,8 +982,8 @@ bool LLInventoryPanel::addBadge(LLBadge * badge)  void LLInventoryPanel::openAllFolders()  { -	mFolderRoot->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_DOWN); -	mFolderRoot->arrangeAll(); +	mFolderRoot.get()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_DOWN); +	mFolderRoot.get()->arrangeAll();  }  void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus) @@ -975,9 +999,9 @@ void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_foc  void LLInventoryPanel::setSelectCallback(const boost::function<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb)   {  -	if (mFolderRoot)  +	if (mFolderRoot.get())  	{ -		mFolderRoot->setSelectCallback(cb); +		mFolderRoot.get()->setSelectCallback(cb);  	}  } @@ -1001,7 +1025,7 @@ void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& it  		}  	} -	LLFolderView* fv = getRootFolder(); +	LLFolderView* fv = mFolderRoot.get();  	if (fv->needsAutoRename()) // auto-selecting a new user-created asset and preparing to rename  	{  		fv->setNeedsAutoRename(FALSE); @@ -1020,7 +1044,7 @@ void LLInventoryPanel::doCreate(const LLSD& userdata)  bool LLInventoryPanel::beginIMSession()  { -	std::set<LLFolderViewItem*> selected_items =   mFolderRoot->getSelectionList(); +	std::set<LLFolderViewItem*> selected_items =   mFolderRoot.get()->getSelectionList();  	std::string name; @@ -1114,7 +1138,7 @@ bool LLInventoryPanel::beginIMSession()  bool LLInventoryPanel::attachObject(const LLSD& userdata)  {  	// Copy selected item UUIDs to a vector. -	std::set<LLFolderViewItem*> selected_items = mFolderRoot->getSelectionList(); +	std::set<LLFolderViewItem*> selected_items = mFolderRoot.get()->getSelectionList();  	uuid_vec_t items;  	for (std::set<LLFolderViewItem*>::const_iterator set_iter = selected_items.begin();  		 set_iter != selected_items.end();  @@ -1141,7 +1165,7 @@ BOOL LLInventoryPanel::getSinceLogoff()  void LLInventoryPanel::dumpSelectionInformation(void* user_data)  {  	LLInventoryPanel* iv = (LLInventoryPanel*)user_data; -	iv->mFolderRoot->dumpSelectionInformation(); +	iv->mFolderRoot.get()->dumpSelectionInformation();  }  BOOL is_inventorysp_active() @@ -1343,7 +1367,7 @@ void LLInventoryPanel::updateSelection()  void LLInventoryPanel::doToSelected(const LLSD& userdata)  { -	LLInventoryAction::doToSelected(mInventory, mFolderRoot, userdata.asString()); +	LLInventoryAction::doToSelected(mInventory, mFolderRoot.get(), userdata.asString());  	return;  } @@ -1357,7 +1381,7 @@ BOOL LLInventoryPanel::handleKeyHere( KEY key, MASK mask )  		// Open selected items if enter key hit on the inventory panel  		if (mask == MASK_NONE)  		{ -			LLInventoryAction::doToSelected(mInventory, mFolderRoot, "open"); +			LLInventoryAction::doToSelected(mInventory, mFolderRoot.get(), "open");  			handled = TRUE;  		}  		break; @@ -1367,7 +1391,7 @@ BOOL LLInventoryPanel::handleKeyHere( KEY key, MASK mask )  		// Note: on Mac laptop keyboards, backspace and delete are one and the same  		if (isSelectionRemovable() && (mask == MASK_NONE))  		{ -			LLInventoryAction::doToSelected(mInventory, mFolderRoot, "delete"); +			LLInventoryAction::doToSelected(mInventory, mFolderRoot.get(), "delete");  			handled = TRUE;  		}  		break; @@ -1378,9 +1402,9 @@ BOOL LLInventoryPanel::handleKeyHere( KEY key, MASK mask )  bool LLInventoryPanel::isSelectionRemovable()  {  	bool can_delete = false; -	if (mFolderRoot) +	if (mFolderRoot.get())  	{ -		std::set<LLFolderViewItem*> selection_set = mFolderRoot->getSelectionList(); +		std::set<LLFolderViewItem*> selection_set = mFolderRoot.get()->getSelectionList();  		if (!selection_set.empty())   		{  			can_delete = true; diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index 00a90325ad..c0ce513694 100755 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -181,7 +181,7 @@ public:  	LLInventoryFilter::EFolderShow getShowFolderState();  	// This method is called when something has changed about the inventory.  	void modelChanged(U32 mask); -	LLFolderView* getRootFolder(); +	LLFolderView* getRootFolder() { return mFolderRoot.get(); }  	LLUUID getRootFolderID();  	LLScrollContainer* getScrollableContainer() { return mScroller; } @@ -217,8 +217,11 @@ public:  	void setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus);  	void updateSelection(); -	LLFolderViewModelInventory* getFolderViewModel(); -	const LLFolderViewModelInventory* getFolderViewModel() const; +	LLFolderViewModelInventory* getFolderViewModel() { return &mInventoryViewModel; } +	const LLFolderViewModelInventory* getFolderViewModel() const { return &mInventoryViewModel; } +     +    // Clean up stuff when the folder root gets deleted +    void clearFolderRoot();  protected:  	void openStartFolderOrMyInventory(); // open the first level of inventory @@ -233,7 +236,7 @@ protected:  	bool 						mShowItemLinkOverlays; // Shows link graphic over inventory item icons  	bool						mShowEmptyMessage; -	LLFolderView*				mFolderRoot; +	LLHandle<LLFolderView>      mFolderRoot;  	LLScrollContainer*			mScroller;  	LLFolderViewModelInventory	mInventoryViewModel; diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index 0b009b68f7..05c9d76810 100755 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -30,6 +30,7 @@  #include "llagent.h"  #include "llhttpclient.h" +#include "llsdserialize.h"  #include "lltimer.h"  #include "lltrans.h"  #include "llviewercontrol.h" @@ -135,19 +136,25 @@ namespace LLMarketplaceImport  				llinfos << " SLM POST status: " << status << llendl;  				llinfos << " SLM POST reason: " << reason << llendl;  				llinfos << " SLM POST content: " << content.asString() << llendl; -  				llinfos << " SLM POST timer: " << slmPostTimer.getElapsedTimeF32() << llendl;  			} -			if ((status == MarketplaceErrorCodes::IMPORT_REDIRECT) || -				(status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) || -				(status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT)) +			// MAINT-2301 : we determined we can safely ignore that error in that context +			if (status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT)  			{  				if (gSavedSettings.getBOOL("InventoryOutboxLogging"))  				{ -					llinfos << " SLM POST clearing marketplace cookie due to authentication failure or timeout" << llendl; +					llinfos << " SLM POST : Ignoring time out status and treating it as success" << llendl; +				} +				status = MarketplaceErrorCodes::IMPORT_DONE; +			} +			 +			if (status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST) +			{ +				if (gSavedSettings.getBOOL("InventoryOutboxLogging")) +				{ +					llinfos << " SLM POST clearing marketplace cookie due to client or server error" << llendl;  				} -  				sMarketplaceCookie.clear();  			} @@ -182,20 +189,25 @@ namespace LLMarketplaceImport  				llinfos << " SLM GET status: " << status << llendl;  				llinfos << " SLM GET reason: " << reason << llendl;  				llinfos << " SLM GET content: " << content.asString() << llendl; -  				llinfos << " SLM GET timer: " << slmGetTimer.getElapsedTimeF32() << llendl;  			} -			if ((status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) || -				(status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT)) +            // MAINT-2452 : Do not clear the cookie on IMPORT_DONE_WITH_ERRORS : Happens when trying to import objects with wrong permissions +            // ACME-1221 : Do not clear the cookie on IMPORT_NOT_FOUND : Happens for newly created Merchant accounts that are initally empty +			if ((status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST) && +                (status != MarketplaceErrorCodes::IMPORT_DONE_WITH_ERRORS) && +                (status != MarketplaceErrorCodes::IMPORT_NOT_FOUND))  			{  				if (gSavedSettings.getBOOL("InventoryOutboxLogging"))  				{ -					llinfos << " SLM GET clearing marketplace cookie due to authentication failure or timeout" << llendl; +					llinfos << " SLM GET clearing marketplace cookie due to client or server error" << llendl;  				} -  				sMarketplaceCookie.clear();  			} +            else if (gSavedSettings.getBOOL("InventoryOutboxLogging") && (status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST)) +            { +                llinfos << " SLM GET : Got error status = " << status << ", but marketplace cookie not cleared." << llendl; +            }  			sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_PROCESSING);  			sImportGetPending = false; @@ -256,7 +268,12 @@ namespace LLMarketplaceImport  		if (gSavedSettings.getBOOL("InventoryOutboxLogging"))  		{ -			llinfos << " SLM GET: " << url << llendl; +            llinfos << " SLM GET: establishMarketplaceSessionCookie, LLHTTPClient::get, url = " << url << llendl; +            LLSD headers = LLViewerMedia::getHeaders(); +            std::stringstream str; +            LLSDSerialize::toPrettyXML(headers, str); +            llinfos << " SLM GET: headers " << llendl; +            llinfos << str.str() << llendl;  		}  		slmGetTimer.start(); @@ -287,7 +304,11 @@ namespace LLMarketplaceImport  		if (gSavedSettings.getBOOL("InventoryOutboxLogging"))  		{ -			llinfos << " SLM GET: " << url << llendl; +            llinfos << " SLM GET: pollStatus, LLHTTPClient::get, url = " << url << llendl; +            std::stringstream str; +            LLSDSerialize::toPrettyXML(headers, str); +            llinfos << " SLM GET: headers " << llendl; +            llinfos << str.str() << llendl;  		}  		slmGetTimer.start(); @@ -321,11 +342,15 @@ namespace LLMarketplaceImport  		if (gSavedSettings.getBOOL("InventoryOutboxLogging"))  		{ -			llinfos << " SLM POST: " << url << llendl; +            llinfos << " SLM POST: triggerImport, LLHTTPClient::post, url = " << url << llendl; +            std::stringstream str; +            LLSDSerialize::toPrettyXML(headers, str); +            llinfos << " SLM POST: headers " << llendl; +            llinfos << str.str() << llendl;  		}  		slmPostTimer.start(); -		LLHTTPClient::post(url, LLSD(), new LLImportPostResponder(), headers); +        LLHTTPClient::post(url, LLSD(), new LLImportPostResponder(), headers);  		return true;  	} @@ -356,6 +381,7 @@ LLMarketplaceInventoryImporter::LLMarketplaceInventoryImporter()  	: mAutoTriggerImport(false)  	, mImportInProgress(false)  	, mInitialized(false) +	, mMarketPlaceStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED)  	, mErrorInitSignal(NULL)  	, mStatusChangedSignal(NULL)  	, mStatusReportSignal(NULL) @@ -394,20 +420,27 @@ boost::signals2::connection LLMarketplaceInventoryImporter::setStatusReportCallb  void LLMarketplaceInventoryImporter::initialize()  { -	llassert(!mInitialized); +    if (mInitialized) +    { +        return; +    }  	if (!LLMarketplaceImport::hasSessionCookie())  	{ +		mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_INITIALIZING;  		LLMarketplaceImport::establishMarketplaceSessionCookie();  	} +	else +	{ +		mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_MERCHANT; +	}  }  void LLMarketplaceInventoryImporter::reinitializeAndTriggerImport()  {  	mInitialized = false; - +	mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED;  	initialize(); -  	mAutoTriggerImport = true;  } @@ -459,17 +492,30 @@ void LLMarketplaceInventoryImporter::updateImport()  				if (mInitialized)  				{ +					mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_MERCHANT;  					// Follow up with auto trigger of import  					if (mAutoTriggerImport)  					{  						mAutoTriggerImport = false; -  						mImportInProgress = triggerImport();  					}  				} -				else if (mErrorInitSignal) +				else  				{ -					(*mErrorInitSignal)(LLMarketplaceImport::getResultStatus(), LLMarketplaceImport::getResults()); +					U32 status = LLMarketplaceImport::getResultStatus(); +					if ((status == MarketplaceErrorCodes::IMPORT_FORBIDDEN) || +						(status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR)) +					{ +						mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_NOT_MERCHANT; +					} +					else  +					{ +						mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE; +					} +					if (mErrorInitSignal && (mMarketPlaceStatus == MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE)) +					{ +						(*mErrorInitSignal)(LLMarketplaceImport::getResultStatus(), LLMarketplaceImport::getResults()); +					}  				}  			}  		} diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h index 4b8f7a1ac7..abe60890a3 100755 --- a/indra/newview/llmarketplacefunctions.h +++ b/indra/newview/llmarketplacefunctions.h @@ -47,10 +47,27 @@ namespace MarketplaceErrorCodes  		IMPORT_DONE = 200,  		IMPORT_PROCESSING = 202,  		IMPORT_REDIRECT = 302, +		IMPORT_BAD_REQUEST = 400,  		IMPORT_AUTHENTICATION_ERROR = 401, +		IMPORT_FORBIDDEN = 403, +		IMPORT_NOT_FOUND = 404,  		IMPORT_DONE_WITH_ERRORS = 409,  		IMPORT_JOB_FAILED = 410,  		IMPORT_JOB_TIMEOUT = 499, +		IMPORT_SERVER_SITE_DOWN = 500, +		IMPORT_SERVER_API_DISABLED = 503, +	}; +} + +namespace MarketplaceStatusCodes +{ +	enum sCode +	{ +		MARKET_PLACE_NOT_INITIALIZED = 0, +		MARKET_PLACE_INITIALIZING = 1, +		MARKET_PLACE_CONNECTION_FAILURE = 2, +		MARKET_PLACE_MERCHANT = 3, +		MARKET_PLACE_NOT_MERCHANT = 4,  	};  } @@ -73,6 +90,8 @@ public:  	void initialize();  	bool triggerImport();  	bool isImportInProgress() const { return mImportInProgress; } +	bool isInitialized() const { return mInitialized; } +	U32 getMarketPlaceStatus() const { return mMarketPlaceStatus; }  protected:  	void reinitializeAndTriggerImport(); @@ -82,6 +101,7 @@ private:  	bool mAutoTriggerImport;  	bool mImportInProgress;  	bool mInitialized; +	U32  mMarketPlaceStatus;  	status_report_signal_t *	mErrorInitSignal;  	status_changed_signal_t *	mStatusChangedSignal; diff --git a/indra/newview/llpanelmarketplaceinboxinventory.cpp b/indra/newview/llpanelmarketplaceinboxinventory.cpp index adfb2dee86..da938712d7 100755 --- a/indra/newview/llpanelmarketplaceinboxinventory.cpp +++ b/indra/newview/llpanelmarketplaceinboxinventory.cpp @@ -69,7 +69,7 @@ LLFolderViewFolder * LLInboxInventoryPanel::createFolderViewFolder(LLInvFVBridge  	LLInboxFolderViewFolder::Params params;  	params.name = bridge->getDisplayName(); -	params.root = mFolderRoot; +	params.root = mFolderRoot.get();  	params.listener = bridge;  	params.tool_tip = params.name;  	params.font_color = item_color; @@ -86,7 +86,7 @@ LLFolderViewItem * LLInboxInventoryPanel::createFolderViewItem(LLInvFVBridge * b  	params.name = bridge->getDisplayName();  	params.creation_date = bridge->getCreationDate(); -	params.root = mFolderRoot; +	params.root = mFolderRoot.get();  	params.listener = bridge;  	params.rect = LLRect (0, 0, 0, 0);  	params.tool_tip = params.name; diff --git a/indra/newview/llplacesinventorypanel.cpp b/indra/newview/llplacesinventorypanel.cpp index 4c2213c198..5eadd65884 100755 --- a/indra/newview/llplacesinventorypanel.cpp +++ b/indra/newview/llplacesinventorypanel.cpp @@ -91,17 +91,17 @@ LLFolderView * LLPlacesInventoryPanel::createFolderRoot(LLUUID root_id )  void LLPlacesInventoryPanel::saveFolderState()  {  	mSavedFolderState->setApply(FALSE); -	mFolderRoot->applyFunctorRecursively(*mSavedFolderState); +	mFolderRoot.get()->applyFunctorRecursively(*mSavedFolderState);  }  // re-open folders which state was saved  void LLPlacesInventoryPanel::restoreFolderState()  {  	mSavedFolderState->setApply(TRUE); -	mFolderRoot->applyFunctorRecursively(*mSavedFolderState); +	mFolderRoot.get()->applyFunctorRecursively(*mSavedFolderState);  	LLOpenFoldersWithSelection opener; -	mFolderRoot->applyFunctorRecursively(opener); -	mFolderRoot->scrollToShowSelection(); +	mFolderRoot.get()->applyFunctorRecursively(opener); +	mFolderRoot.get()->scrollToShowSelection();  }  S32	LLPlacesInventoryPanel::notify(const LLSD& info)  @@ -111,11 +111,11 @@ S32	LLPlacesInventoryPanel::notify(const LLSD& info)  		std::string str_action = info["action"];  		if(str_action == "select_first")  		{ -			return mFolderRoot->notify(info); +			return mFolderRoot.get()->notify(info);  		}  		else if(str_action == "select_last")  		{ -			return mFolderRoot->notify(info); +			return mFolderRoot.get()->notify(info);  		}  	}  	return 0; diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp index 2e91ceee2e..040cbc22a6 100755 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -119,7 +119,6 @@ private:  LLSidepanelInventory::LLSidepanelInventory()  	: LLPanel()  	, mItemPanel(NULL) -	, mInventoryPanelInbox(NULL)  	, mPanelMainInventory(NULL)  	, mInboxEnabled(false)  	, mCategoriesObserver(NULL) @@ -299,7 +298,7 @@ void LLSidepanelInventory::observeInboxModifications(const LLUUID& inboxID)  	// (this can happen multiple times on the initial session that creates the inbox)  	// -	if (mInventoryPanelInbox != NULL) +	if (mInventoryPanelInbox.get() != NULL)  	{  		return;  	} @@ -333,7 +332,8 @@ void LLSidepanelInventory::observeInboxModifications(const LLUUID& inboxID)  	//  	LLPanelMarketplaceInbox * inbox = getChild<LLPanelMarketplaceInbox>(MARKETPLACE_INBOX_PANEL); -	mInventoryPanelInbox = inbox->setupInventoryPanel(); +    LLInventoryPanel* inventory_panel = inbox->setupInventoryPanel(); +	mInventoryPanelInbox = inventory_panel->getInventoryPanelHandle();  }  void LLSidepanelInventory::enableInbox(bool enabled) @@ -461,9 +461,9 @@ void LLSidepanelInventory::performActionOnSelection(const std::string &action)  	LLFolderViewItem* current_item = mPanelMainInventory->getActivePanel()->getRootFolder()->getCurSelectedItem();  	if (!current_item)  	{ -		if (mInventoryPanelInbox) +		if (mInventoryPanelInbox.get() && mInventoryPanelInbox.get()->getRootFolder())  		{ -			current_item = mInventoryPanelInbox->getRootFolder()->getCurSelectedItem(); +			current_item = mInventoryPanelInbox.get()->getRootFolder()->getCurSelectedItem();  		}  		if (!current_item) @@ -614,10 +614,10 @@ void LLSidepanelInventory::updateVerbs()  bool LLSidepanelInventory::canShare()  { -	LLInventoryPanel* inbox = mInventoryPanelInbox; +	LLInventoryPanel* inbox = mInventoryPanelInbox.get();  	// Avoid flicker in the Recent tab while inventory is being loaded. -	if ( (!inbox || inbox->getRootFolder()->getSelectionList().empty()) +	if ( (!inbox || !inbox->getRootFolder() || inbox->getRootFolder()->getSelectionList().empty())  		&& (mPanelMainInventory && !mPanelMainInventory->getActivePanel()->getRootFolder()->hasVisibleChildren()) )  	{  		return false; @@ -652,9 +652,9 @@ LLInventoryItem *LLSidepanelInventory::getSelectedItem()  	if (!current_item)  	{ -		if (mInventoryPanelInbox) +		if (mInventoryPanelInbox.get() && mInventoryPanelInbox.get()->getRootFolder())  		{ -			current_item = mInventoryPanelInbox->getRootFolder()->getCurSelectedItem(); +			current_item = mInventoryPanelInbox.get()->getRootFolder()->getCurSelectedItem();  		}  		if (!current_item) @@ -671,12 +671,12 @@ U32 LLSidepanelInventory::getSelectedCount()  {  	int count = 0; -	std::set<LLFolderViewItem*> selection_list =    mPanelMainInventory->getActivePanel()->getRootFolder()->getSelectionList(); +	std::set<LLFolderViewItem*> selection_list = mPanelMainInventory->getActivePanel()->getRootFolder()->getSelectionList();  	count += selection_list.size(); -	if ((count == 0) && mInboxEnabled && (mInventoryPanelInbox != NULL)) +	if ((count == 0) && mInboxEnabled && mInventoryPanelInbox.get() && mInventoryPanelInbox.get()->getRootFolder())  	{ -		selection_list = mInventoryPanelInbox->getRootFolder()->getSelectionList(); +		selection_list = mInventoryPanelInbox.get()->getRootFolder()->getSelectionList();  		count += selection_list.size();  	} @@ -714,9 +714,9 @@ void LLSidepanelInventory::clearSelections(bool clearMain, bool clearInbox)  		}  	} -	if (clearInbox && mInboxEnabled && (mInventoryPanelInbox != NULL)) +	if (clearInbox && mInboxEnabled && mInventoryPanelInbox.get())  	{ -		mInventoryPanelInbox->clearSelection(); +		mInventoryPanelInbox.get()->clearSelection();  	}  	updateVerbs(); @@ -726,9 +726,9 @@ std::set<LLFolderViewItem*> LLSidepanelInventory::getInboxSelectionList()  {  	std::set<LLFolderViewItem*> inventory_selected_uuids; -	if (mInboxEnabled && (mInventoryPanelInbox != NULL)) +	if (mInboxEnabled && mInventoryPanelInbox.get() && mInventoryPanelInbox.get()->getRootFolder())  	{ -		inventory_selected_uuids = mInventoryPanelInbox->getRootFolder()->getSelectionList(); +		inventory_selected_uuids = mInventoryPanelInbox.get()->getRootFolder()->getSelectionList();  	}  	return inventory_selected_uuids; diff --git a/indra/newview/llsidepanelinventory.h b/indra/newview/llsidepanelinventory.h index e8b2808d4f..17a3098db9 100755 --- a/indra/newview/llsidepanelinventory.h +++ b/indra/newview/llsidepanelinventory.h @@ -57,7 +57,7 @@ public:  	/*virtual*/ void onOpen(const LLSD& key);  	LLInventoryPanel* getActivePanel(); // Returns an active inventory panel, if any. -	LLInventoryPanel* getInboxPanel() const { return mInventoryPanelInbox; } +	LLInventoryPanel* getInboxPanel() const { return mInventoryPanelInbox.get(); }  	LLPanelMainInventory* getMainInventoryPanel() const { return mPanelMainInventory; }  	BOOL isMainInventoryPanelActive() const; @@ -99,7 +99,7 @@ protected:  	//  private:  	LLPanel*					mInventoryPanel; // Main inventory view -	LLInventoryPanel*			mInventoryPanelInbox; +	LLHandle<LLInventoryPanel>	mInventoryPanelInbox;  	LLSidepanelItemInfo*		mItemPanel; // Individual item view  	LLSidepanelTaskInfo*		mTaskPanel; // Individual in-world object view  	LLPanelMainInventory*		mPanelMainInventory; diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp index a179b61cff..991f6b40e6 100644 --- a/indra/newview/llviewerfoldertype.cpp +++ b/indra/newview/llviewerfoldertype.cpp @@ -30,6 +30,9 @@  #include "lldictionary.h"  #include "llmemory.h"  #include "llvisualparam.h" +#include "llcontrol.h" + +extern LLControlGroup gSavedSettings;  static const std::string empty_string; @@ -132,8 +135,9 @@ LLViewerFolderDictionary::LLViewerFolderDictionary()  	addEntry(LLFolderType::FT_MY_OUTFITS, 			new ViewerFolderEntry("My Outfits",				"Inv_SysOpen",			"Inv_SysClosed",		TRUE,      true));  	addEntry(LLFolderType::FT_MESH, 				new ViewerFolderEntry("Meshes",					"Inv_SysOpen",			"Inv_SysClosed",		FALSE,     true)); -	addEntry(LLFolderType::FT_INBOX, 				new ViewerFolderEntry("Inbox",					"Inv_SysOpen",			"Inv_SysClosed",		FALSE,     true)); -	addEntry(LLFolderType::FT_OUTBOX, 				new ViewerFolderEntry("Outbox",					"Inv_SysOpen",			"Inv_SysClosed",		FALSE,     true)); +	bool boxes_invisible = !gSavedSettings.getBOOL("InventoryOutboxMakeVisible"); +	addEntry(LLFolderType::FT_INBOX, 				new ViewerFolderEntry("Inbox",					"Inv_SysOpen",			"Inv_SysClosed",		FALSE,     boxes_invisible)); +	addEntry(LLFolderType::FT_OUTBOX, 				new ViewerFolderEntry("Merchant Outbox",		"Inv_SysOpen",			"Inv_SysClosed",		FALSE,     boxes_invisible));  	addEntry(LLFolderType::FT_BASIC_ROOT, 			new ViewerFolderEntry("Basic Root",				"Inv_SysOpen",			"Inv_SysClosed",		FALSE,     true)); diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index c97af4e9ef..370a2af5e0 100755 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -271,7 +271,7 @@ See the [[MARKETPLACE_IMPORTS_URL] error log] for more information.     icon="OutboxStatus_Error"     name="OutboxImportFailed"     type="outbox"> -Transfer failed +Transfer failed with error '[ERROR_CODE]'  No folders were sent to the Marketplace because of a system or network error.  Try again later. @@ -284,7 +284,7 @@ No folders were sent to the Marketplace because of a system or network error.  T     icon="OutboxStatus_Error"     name="OutboxInitFailed"     type="outbox"> -Marketplace initialization failed +Marketplace initialization failed with error '[ERROR_CODE]'  Initialization with the Marketplace failed because of a system or network error.  Try again later. diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 67f75fe1d2..3252ed2b62 100755 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2245,6 +2245,16 @@ If you'd like to become a merchant, you'll need to [[MARKETPLACE_CREATE_STORE_UR  	<string name="InventoryOutboxNoItems">  Drag folders to this area and click "Send to Marketplace" to list them for sale on the [[MARKETPLACE_DASHBOARD_URL] Marketplace].  	</string> +	<string name="InventoryOutboxInitializingTitle">Initializing Marketplace.</string> +	<string name="InventoryOutboxInitializingTooltip"></string> +	<string name="InventoryOutboxInitializing"> +We are accessing your account on the [[MARKETPLACE_CREATE_STORE_URL] Marketplace store]. +	</string> +	<string name="InventoryOutboxErrorTitle">Marketplace Errors.</string> +	<string name="InventoryOutboxErrorTooltip"></string> +	<string name="InventoryOutboxError"> +The [[MARKETPLACE_CREATE_STORE_URL] Marketplace store] is returning errors. +	</string>  	<string name="Marketplace Error None">No errors</string>  	<string name="Marketplace Error Not Merchant">Error: Before sending items to the Marketplace you will need to set yourself up as a merchant (free of charge).</string> | 
