diff options
Diffstat (limited to 'indra/llui')
-rwxr-xr-x | indra/llui/llfolderview.cpp | 12 | ||||
-rwxr-xr-x | indra/llui/llfolderview.h | 8 | ||||
-rwxr-xr-x[-rw-r--r--] | indra/llui/llfolderviewitem.h | 7 | ||||
-rwxr-xr-x | indra/llui/llnotifications.cpp | 32 | ||||
-rwxr-xr-x | indra/llui/llnotifications.h | 4 | ||||
-rwxr-xr-x | indra/llui/llnotificationtemplate.h | 1 | ||||
-rwxr-xr-x | indra/llui/lltabcontainer.cpp | 5 | ||||
-rwxr-xr-x | indra/llui/lltabcontainer.h | 5 | ||||
-rwxr-xr-x | indra/llui/llurlentry.cpp | 55 | ||||
-rwxr-xr-x | indra/llui/llurlentry.h | 14 | ||||
-rwxr-xr-x | indra/llui/llurlregistry.cpp | 1 | ||||
-rwxr-xr-x | indra/llui/tests/llurlentry_test.cpp | 14 |
12 files changed, 152 insertions, 6 deletions
diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp index f60129e601..4c05d001a0 100755 --- a/indra/llui/llfolderview.cpp +++ b/indra/llui/llfolderview.cpp @@ -170,7 +170,8 @@ LLFolderView::LLFolderView(const Params& p) mDraggingOverItem(NULL), mStatusTextBox(NULL), mShowItemLinkOverlays(p.show_item_link_overlays), - mViewModel(p.view_model) + mViewModel(p.view_model), + mGroupedItemModel(p.grouped_item_model) { claimMem(mViewModel); LLPanel* panel = p.parent_panel; @@ -1810,7 +1811,6 @@ void LLFolderView::updateMenuOptions(LLMenuGL* menu) } // Successively filter out invalid options - U32 multi_select_flag = (mSelectedItems.size() > 1 ? ITEM_IN_MULTI_SELECTION : 0x0); U32 flags = multi_select_flag | FIRST_SELECTED_ITEM; for (selected_items_t::iterator item_itor = mSelectedItems.begin(); @@ -1822,6 +1822,14 @@ void LLFolderView::updateMenuOptions(LLMenuGL* menu) flags = multi_select_flag; } + // This adds a check for restrictions based on the entire + // selection set - for example, any one wearable may not push you + // over the limit, but all wearables together still might. + if (getFolderViewGroupedItemModel()) + { + getFolderViewGroupedItemModel()->groupFilterContextMenu(mSelectedItems,*menu); + } + addNoOptions(menu); } diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h index 08e0a6220a..114dd7bd2f 100755 --- a/indra/llui/llfolderview.h +++ b/indra/llui/llfolderview.h @@ -45,6 +45,7 @@ #include "llscrollcontainer.h" class LLFolderViewModelInterface; +class LLFolderViewGroupedItemModel; class LLFolderViewFolder; class LLFolderViewItem; class LLFolderViewFilter; @@ -93,6 +94,7 @@ public: use_ellipses, show_item_link_overlays; Mandatory<LLFolderViewModelInterface*> view_model; + Optional<LLFolderViewGroupedItemModel*> grouped_item_model; Mandatory<std::string> options_menu; @@ -100,7 +102,7 @@ public: }; friend class LLFolderViewScrollContainer; - typedef std::deque<LLFolderViewItem*> selected_items_t; + typedef folder_view_item_deque selected_items_t; LLFolderView(const Params&); virtual ~LLFolderView( void ); @@ -113,6 +115,9 @@ public: LLFolderViewModelInterface* getFolderViewModel() { return mViewModel; } const LLFolderViewModelInterface* getFolderViewModel() const { return mViewModel; } + LLFolderViewGroupedItemModel* getFolderViewGroupedItemModel() { return mGroupedItemModel; } + const LLFolderViewGroupedItemModel* getFolderViewGroupedItemModel() const { return mGroupedItemModel; } + 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); } void setReshapeCallback(const signal_t::slot_type& cb) { mReshapeSignal.connect(cb); } @@ -300,6 +305,7 @@ protected: LLHandle<LLPanel> mParentPanel; LLFolderViewModelInterface* mViewModel; + LLFolderViewGroupedItemModel* mGroupedItemModel; /** * Is used to determine if we need to cut text In LLFolderViewItem to avoid horizontal scroll. diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h index 0cd20a0f2d..5ad5731cad 100644..100755 --- a/indra/llui/llfolderviewitem.h +++ b/indra/llui/llfolderviewitem.h @@ -454,5 +454,12 @@ public: template<typename SORT_FUNC> void sortItems(const SORT_FUNC& func) { mItems.sort(func); } }; +typedef std::deque<LLFolderViewItem*> folder_view_item_deque; + +class LLFolderViewGroupedItemModel: public LLRefCount +{ +public: + virtual void groupFilterContextMenu(folder_view_item_deque& selected_items, LLMenuGL& menu) = 0; +}; #endif // LLFOLDERVIEWITEM_H diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index de14391d1f..7e235997d8 100755 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -678,7 +678,7 @@ void LLNotification::respond(const LLSD& response) // and then call it functor(asLLSD(), response); } - else + else if (mCombinedNotifications.empty()) { // no registered responder return; @@ -700,6 +700,14 @@ void LLNotification::respond(const LLSD& response) } } + for (std::vector<LLNotificationPtr>::const_iterator it = mCombinedNotifications.begin(); it != mCombinedNotifications.end(); ++it) + { + if ((*it)) + { + (*it)->respond(response); + } + } + update(); } @@ -1322,6 +1330,28 @@ bool LLNotifications::failedUniquenessTest(const LLSD& payload) } } break; + case LLNotification::COMBINE_WITH_NEW: + // Add to the existing unique notification with the data from this particular instance... + // This guarantees that duplicate notifications will be collapsed to the one + // most recently triggered + for (LLNotificationMap::iterator existing_it = mUniqueNotifications.find(pNotif->getName()); + existing_it != mUniqueNotifications.end(); + ++existing_it) + { + LLNotificationPtr existing_notification = existing_it->second; + if (pNotif != existing_notification + && pNotif->isEquivalentTo(existing_notification)) + { + // copy the notifications from the newest instance into the oldest + existing_notification->mCombinedNotifications.push_back(pNotif); + existing_notification->mCombinedNotifications.insert(existing_notification->mCombinedNotifications.end(), + pNotif->mCombinedNotifications.begin(), pNotif->mCombinedNotifications.end()); + + // pop up again + existing_notification->update(); + } + } + break; case LLNotification::KEEP_OLD: break; case LLNotification::CANCEL_OLD: diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 3cf432f330..0d673d178b 100755 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -414,6 +414,9 @@ private: using the same mechanism. */ bool mTemporaryResponder; + + // keep track of other notifications combined with COMBINE_WITH_NEW + std::vector<LLNotificationPtr> mCombinedNotifications; void init(const std::string& template_name, const LLSD& form_elements); @@ -560,6 +563,7 @@ public: typedef enum e_combine_behavior { REPLACE_WITH_NEW, + COMBINE_WITH_NEW, KEEP_OLD, CANCEL_OLD diff --git a/indra/llui/llnotificationtemplate.h b/indra/llui/llnotificationtemplate.h index 0315ddbea8..c23fc53763 100755 --- a/indra/llui/llnotificationtemplate.h +++ b/indra/llui/llnotificationtemplate.h @@ -43,6 +43,7 @@ struct LLNotificationTemplate static void declareValues() { declare("replace_with_new", LLNotification::REPLACE_WITH_NEW); + declare("combine_with_new", LLNotification::COMBINE_WITH_NEW); declare("keep_old", LLNotification::KEEP_OLD); declare("cancel_old", LLNotification::CANCEL_OLD); } diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index 6f858cdeb3..4b08798892 100755 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -2094,3 +2094,8 @@ void LLTabContainer::commitHoveredButton(S32 x, S32 y) } } } + +S32 LLTabContainer::getTotalTabWidth() const +{ + return mTotalTabWidth; +} diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h index 57862fc626..057809dc42 100755 --- a/indra/llui/lltabcontainer.h +++ b/indra/llui/lltabcontainer.h @@ -182,7 +182,8 @@ public: LLPanel* getPanelByIndex(S32 index); S32 getIndexForPanel(LLPanel* panel); S32 getPanelIndexByTitle(const std::string& title); - LLPanel* getPanelByName(const std::string& name); + LLPanel* getPanelByName(const std::string& name); + S32 getTotalTabWidth() const; void setCurrentTabName(const std::string& name); void selectFirstTab(); @@ -287,7 +288,7 @@ private: S32 mMaxTabWidth; S32 mTotalTabWidth; - S32 mTabHeight; + S32 mTabHeight; // Padding under the text labels of tab buttons S32 mLabelPadBottom; diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 5f60d80858..6db0d88998 100755 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -38,6 +38,7 @@ #include "lltrans.h" #include "lluicolortable.h" #include "message.h" +#include "llexperiencecache.h" #define APP_HEADER_REGEX "((x-grid-location-info://[-\\w\\.]+/app)|(secondlife:///app))" @@ -1399,3 +1400,57 @@ std::string LLUrlEntryIcon::getIcon(const std::string &url) LLStringUtil::trim(mIcon); return mIcon; } + +LLUrlEntryExperienceProfile::LLUrlEntryExperienceProfile() +{ + mPattern = boost::regex(APP_HEADER_REGEX "/experience/[\\da-f-]+/\\w+\\S*", + boost::regex::perl|boost::regex::icase); + mIcon = "Generic_Experience"; + mMenuName = "menu_url_experience.xml"; +} + +std::string LLUrlEntryExperienceProfile::getLabel( const std::string &url, const LLUrlLabelCallback &cb ) +{ + if (!gCacheName) + { + // probably at the login screen, use short string for layout + return LLTrans::getString("LoadingData"); + } + + std::string experience_id_string = getIDStringFromUrl(url); + if (experience_id_string.empty()) + { + // something went wrong, just give raw url + return unescapeUrl(url); + } + + LLUUID experience_id(experience_id_string); + if (experience_id.isNull()) + { + return LLTrans::getString("ExperienceNameNull"); + } + + const LLSD& experience_details = LLExperienceCache::get(experience_id); + if(!experience_details.isUndefined()) + { + std::string experience_name_string = experience_details[LLExperienceCache::NAME].asString(); + return experience_name_string.empty() ? LLTrans::getString("ExperienceNameUntitled") : experience_name_string; + } + + addObserver(experience_id_string, url, cb); + LLExperienceCache::get(experience_id, boost::bind(&LLUrlEntryExperienceProfile::onExperienceDetails, this, _1)); + return LLTrans::getString("LoadingData"); + +} + +void LLUrlEntryExperienceProfile::onExperienceDetails( const LLSD& experience_details ) +{ + std::string name = experience_details[LLExperienceCache::NAME].asString(); + if(name.empty()) + { + name = LLTrans::getString("ExperienceNameUntitled"); + } + callObservers(experience_details[LLExperienceCache::EXPERIENCE_ID].asString(), name, LLStringUtil::null); +} + + diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index 60a494974f..dd1f257a3d 100755 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -309,6 +309,20 @@ private: }; /// +/// LLUrlEntryExperienceProfile Describes a Second Life experience profile Url, e.g., +/// secondlife:///app/experience/0e346d8b-4433-4d66-a6b0-fd37083abc4c/profile +/// that displays the experience name +class LLUrlEntryExperienceProfile : public LLUrlEntryBase +{ +public: + LLUrlEntryExperienceProfile(); + /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); +private: + void onExperienceDetails(const LLSD& experience_details); +}; + + +/// /// LLUrlEntryGroup Describes a Second Life group Url, e.g., /// secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about /// diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index 1143574968..2085505947 100755 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -70,6 +70,7 @@ LLUrlRegistry::LLUrlRegistry() registerUrl(new LLUrlEntryPlace()); registerUrl(new LLUrlEntryInventory()); registerUrl(new LLUrlEntryObjectIM()); + registerUrl(new LLUrlEntryExperienceProfile()); //LLUrlEntrySL and LLUrlEntrySLLabel have more common pattern, //so it should be registered in the end of list registerUrl(new LLUrlEntrySL()); diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp index c3f0e92cb0..15f2354552 100755 --- a/indra/llui/tests/llurlentry_test.cpp +++ b/indra/llui/tests/llurlentry_test.cpp @@ -32,9 +32,23 @@ #include "lltut.h" #include "../lluicolortable.h" #include "../llrender/lluiimage.h" +#include "../llmessage/llexperiencecache.h" #include <boost/regex.hpp> + +namespace LLExperienceCache +{ + const LLSD& get( const LLUUID& key) + { + static LLSD boo; + return boo; + } + + void get( const LLUUID& key, callback_slot_t slot ){} + +} + typedef std::map<std::string, LLControlGroup*> settings_map_t; settings_map_t LLUI::sSettingGroups; |