From e35f3b7db4803c287e95fb5aaa563e8432e71349 Mon Sep 17 00:00:00 2001 From: MartinRJ Fayray Date: Mon, 25 Jun 2012 05:09:22 +0200 Subject: STORM-1879: Inventory gear menu remains on screen after floater is closed --- indra/llui/llfloater.cpp | 4 ++++ indra/llui/lltoggleablemenu.cpp | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 8ca1e685a9..90251ac7c6 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -748,6 +748,10 @@ void LLFloater::closeFloater(bool app_quitting) dependee->setFocus(TRUE); } } + + // STORM-1879: since this floater has focus, treat the closeFloater- call + // like a click on the close-button, and close gear- and contextmenus + LLMenuGL::sMenuContainer->hideMenus(); } dirtyRect(); diff --git a/indra/llui/lltoggleablemenu.cpp b/indra/llui/lltoggleablemenu.cpp index d29260750f..e4d1a37569 100644 --- a/indra/llui/lltoggleablemenu.cpp +++ b/indra/llui/lltoggleablemenu.cpp @@ -57,7 +57,9 @@ void LLToggleableMenu::handleVisibilityChange (BOOL curVisibilityIn) S32 x,y; LLUI::getMousePositionLocal(LLUI::getRootView(), &x, &y); - if (!curVisibilityIn && mButtonRect.pointInRect(x, y)) + // STORM-1879: also check MouseCapture to see if the button was really + // clicked (otherwise the VisibilityChange was triggered via keyboard shortcut) + if (!curVisibilityIn && mButtonRect.pointInRect(x, y) && gFocusMgr.getMouseCapture()) { mClosedByButtonClick = true; } -- cgit v1.2.3 From 0ee53b21d2a7bf2cd37c7bcdc2a86e0f079fbefc Mon Sep 17 00:00:00 2001 From: Kelly Washington Date: Mon, 25 Jun 2012 13:41:53 -0700 Subject: MAINT-30 Estate access lists for groups and residents are blank when "Allow public access" is checked. MAINT-1200 Resident names not sorted in About Land (or Estate management) floater's allowed/banned boxes reviewed with Simon --- indra/llui/llscrolllistctrl.cpp | 5 +++++ indra/llui/llscrolllistctrl.h | 1 + 2 files changed, 6 insertions(+) (limited to 'indra/llui') diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index b3e1b63db5..82a914a30a 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -2704,6 +2704,11 @@ BOOL LLScrollListCtrl::hasSortOrder() const return !mSortColumns.empty(); } +void LLScrollListCtrl::clearSortOrder() +{ + mSortColumns.clear(); +} + void LLScrollListCtrl::clearColumns() { column_map_t::iterator itor; diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index ae8aea9245..6660c07b8e 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -373,6 +373,7 @@ public: std::string getSortColumnName(); BOOL getSortAscending() { return mSortColumns.empty() ? TRUE : mSortColumns.back().second; } BOOL hasSortOrder() const; + void clearSortOrder(); S32 selectMultiple( uuid_vec_t ids ); // conceptually const, but mutates mItemList -- cgit v1.2.3 From 18bd525d00ee3ce16164900293ee6ea8c2204589 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 11 Jul 2012 08:14:34 -0400 Subject: MAINT-1175: Forbid LLRegistry[Singleton]. Back out code that selects LLTypeInfoLookup for the underlying map implementation when KEY = [const] std::type_info*, because LLTypeInfoLookup's API is changing to become incompatible with std::map. Instead, fail with STATIC_ASSERT when LLRegistry's KEY is [const] std::type_info*. Fix all existing uses to use std::type_info::name() string instead. --- indra/llui/llfloater.cpp | 2 +- indra/llui/llradiogroup.cpp | 2 +- indra/llui/llrngwriter.cpp | 2 +- indra/llui/llscrolllistcolumn.cpp | 2 +- indra/llui/lltextbase.cpp | 2 +- indra/llui/lltooltip.cpp | 2 +- indra/llui/lluictrlfactory.cpp | 6 +++--- indra/llui/lluictrlfactory.h | 4 ++-- indra/llui/llxuiparser.cpp | 2 +- indra/llui/llxuiparser.h | 3 ++- 10 files changed, 14 insertions(+), 13 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 8ca1e685a9..f20cc2452f 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -232,7 +232,7 @@ void LLFloater::initClass() } // defaults for floater param block pulled from widgets/floater.xml -static LLWidgetNameRegistry::StaticRegistrar sRegisterFloaterParams(&typeid(LLFloater::Params), "floater"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterFloaterParams(typeid(LLFloater::Params).name(), "floater"); LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p) : LLPanel(), // intentionally do not pass params here, see initFromParams diff --git a/indra/llui/llradiogroup.cpp b/indra/llui/llradiogroup.cpp index 95a7d09382..71bbcd8ade 100644 --- a/indra/llui/llradiogroup.cpp +++ b/indra/llui/llradiogroup.cpp @@ -66,7 +66,7 @@ protected: LLSD mPayload; // stores data that this item represents in the radio group }; -static LLWidgetNameRegistry::StaticRegistrar register_radio_item(&typeid(LLRadioGroup::ItemParams), "radio_item"); +static LLWidgetNameRegistry::StaticRegistrar register_radio_item(typeid(LLRadioGroup::ItemParams).name(), "radio_item"); LLRadioGroup::Params::Params() : allow_deselect("allow_deselect"), diff --git a/indra/llui/llrngwriter.cpp b/indra/llui/llrngwriter.cpp index 5e6840d7df..90a1e77b1a 100644 --- a/indra/llui/llrngwriter.cpp +++ b/indra/llui/llrngwriter.cpp @@ -92,7 +92,7 @@ void LLRNGWriter::addDefinition(const std::string& type_name, const LLInitParam: // add includes for all possible children const std::type_info* type = *LLWidgetTypeRegistry::instance().getValue(type_name); - const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type); + const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type->name()); // add include declarations for all valid children for (widget_registry_t::Registrar::registry_map_t::const_iterator it = widget_registryp->currentRegistrar().beginItems(); diff --git a/indra/llui/llscrolllistcolumn.cpp b/indra/llui/llscrolllistcolumn.cpp index 07a6dfaa10..d132d0cc7e 100644 --- a/indra/llui/llscrolllistcolumn.cpp +++ b/indra/llui/llscrolllistcolumn.cpp @@ -39,7 +39,7 @@ const S32 MIN_COLUMN_WIDTH = 20; // defaults for LLScrollColumnHeader param block pulled from widgets/scroll_column_header.xml -static LLWidgetNameRegistry::StaticRegistrar sRegisterColumnHeaderParams(&typeid(LLScrollColumnHeader::Params), "scroll_column_header"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterColumnHeaderParams(typeid(LLScrollColumnHeader::Params).name(), "scroll_column_header"); //--------------------------------------------------------------------------- // LLScrollColumnHeader diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 7aeeae298f..8314386632 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -131,7 +131,7 @@ struct LLTextBase::line_end_compare // // register LLTextBase::Params under name "textbase" -static LLWidgetNameRegistry::StaticRegistrar sRegisterTextBaseParams(&typeid(LLTextBase::Params), "textbase"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterTextBaseParams(typeid(LLTextBase::Params).name(), "textbase"); LLTextBase::LineSpacingParams::LineSpacingParams() : multiple("multiple", 1.f), diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp index f737d48abf..0723dbec70 100644 --- a/indra/llui/lltooltip.cpp +++ b/indra/llui/lltooltip.cpp @@ -129,7 +129,7 @@ void LLToolTipView::drawStickyRect() } // defaults for floater param block pulled from widgets/floater.xml -static LLWidgetNameRegistry::StaticRegistrar sRegisterInspectorParams(&typeid(LLInspector::Params), "inspector"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterInspectorParams(typeid(LLInspector::Params).name(), "inspector"); // // LLToolTip diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index 25e7a31e90..fe3b470722 100644 --- a/indra/llui/lluictrlfactory.cpp +++ b/indra/llui/lluictrlfactory.cpp @@ -281,7 +281,7 @@ const LLInitParam::BaseBlock& get_empty_param_block() void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const std::type_info* param_block_type, const std::string& tag) { // associate parameter block type with template .xml file - std::string* existing_tag = LLWidgetNameRegistry::instance().getValue(param_block_type); + std::string* existing_tag = LLWidgetNameRegistry::instance().getValue(param_block_type->name()); if (existing_tag != NULL) { if(*existing_tag != tag) @@ -297,7 +297,7 @@ void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const st return; } } - LLWidgetNameRegistry::instance().defaultRegistrar().add(param_block_type, tag); + LLWidgetNameRegistry::instance().defaultRegistrar().add(param_block_type->name(), tag); //FIXME: comment this in when working on schema generation //LLWidgetTypeRegistry::instance().defaultRegistrar().add(tag, widget_type); //LLDefaultParamBlockRegistry::instance().defaultRegistrar().add(widget_type, &get_empty_param_block); @@ -306,6 +306,6 @@ void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const st //static const std::string* LLUICtrlFactory::getWidgetTag(const std::type_info* widget_type) { - return LLWidgetNameRegistry::instance().getValue(widget_type); + return LLWidgetNameRegistry::instance().getValue(widget_type->name()); } diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index d612ad5005..1f7a8e08ce 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -69,9 +69,9 @@ protected: friend class LLSingleton; }; -// lookup widget name by type +// lookup widget name by type (actually by std::type_info::name()) class LLWidgetNameRegistry -: public LLRegistrySingleton +: public LLRegistrySingleton {}; // lookup function for generating empty param block by widget type diff --git a/indra/llui/llxuiparser.cpp b/indra/llui/llxuiparser.cpp index afc76024d1..c3a246b9a5 100644 --- a/indra/llui/llxuiparser.cpp +++ b/indra/llui/llxuiparser.cpp @@ -606,7 +606,7 @@ void LLXUIXSDWriter::writeXSD(const std::string& type_name, const std::string& p // add includes for all possible children const std::type_info* type = *LLWidgetTypeRegistry::instance().getValue(type_name); - const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type); + const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type->name()); // add choices for valid children if (widget_registryp) diff --git a/indra/llui/llxuiparser.h b/indra/llui/llxuiparser.h index d7cd256967..3c092afdd6 100644 --- a/indra/llui/llxuiparser.h +++ b/indra/llui/llxuiparser.h @@ -55,8 +55,9 @@ typedef boost::function widget_registry_t; +// const char* key used for std::type_info::name() string class LLChildRegistryRegistry -: public LLRegistrySingleton +: public LLRegistrySingleton {}; -- cgit v1.2.3 From 709c1eeae90dae106800e3742f3655bd7b590b7b Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 11 Jul 2012 14:13:45 -0400 Subject: MAINT-1175: Properly pass LLRegistry's COMPARATOR to underlying map. Although LLRegistry and LLRegistrySingleton have always defined a COMPARATOR template parameter, it wasn't used for the underlying map. Therefore every type, including any pointer type, was being compared using std::less. This happens to work most of the time -- but is tripping us up now. Pass COMPARATOR to underlying std::map. Fix a couple minor bugs in LLRegistryDefaultComparator (never before used!). Specialize for const char*. Remove CompareTypeID and LLCompareTypeID because we now actively forbid using LLRegistry; remove only known reference (LLWidgetNameRegistry definition). --- indra/llui/lluictrlfactory.h | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index 1f7a8e08ce..a5fd83e555 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -34,15 +34,6 @@ class LLView; -// sort functor for typeid maps -struct LLCompareTypeID -{ - bool operator()(const std::type_info* lhs, const std::type_info* rhs) const - { - return lhs->before(*rhs); - } -}; - // lookup widget constructor funcs by widget name template class LLChildRegistry : public LLRegistrySingleton @@ -71,7 +62,7 @@ protected: // lookup widget name by type (actually by std::type_info::name()) class LLWidgetNameRegistry -: public LLRegistrySingleton +: public LLRegistrySingleton {}; // lookup function for generating empty param block by widget type -- cgit v1.2.3 From 7f609b6a6958f519bb1becb604132b583ada3fad Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 18 Jul 2012 15:51:34 -0400 Subject: Backed out changeset a25bfa87418d (using std::type_info::name()) The changeset above touched every consumer of the two LLRegistrySingletons originally defined with std::type_info* as keys. Those two LLRegistrySingletons were changed to use const char* as keys, then all consumers were changed to pass std::type_info::name() instead of the plain std::type_info* pointer -- to deal with the observed fact that on Linux, a given type might produce different std::type_info* pointers in different load modules. Since then, Richard turned up the fascinating fact that at least some implementations of gcc's std::type_info::before() method already accommodate this peculiarity. It seems worth backing out the (dismayingly pervasive) change to see if properly using std::type_info::before() as the map comparator will work just as well, with conceptually simpler source code. This backout is transitional: we don't expect things to build/run properly until we've cherry-picked certain other pertinent changes. --- indra/llui/llfloater.cpp | 2 +- indra/llui/llradiogroup.cpp | 2 +- indra/llui/llrngwriter.cpp | 2 +- indra/llui/llscrolllistcolumn.cpp | 2 +- indra/llui/lltextbase.cpp | 2 +- indra/llui/lltooltip.cpp | 2 +- indra/llui/lluictrlfactory.cpp | 6 +++--- indra/llui/lluictrlfactory.h | 4 ++-- indra/llui/llxuiparser.cpp | 2 +- indra/llui/llxuiparser.h | 3 +-- 10 files changed, 13 insertions(+), 14 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index f20cc2452f..8ca1e685a9 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -232,7 +232,7 @@ void LLFloater::initClass() } // defaults for floater param block pulled from widgets/floater.xml -static LLWidgetNameRegistry::StaticRegistrar sRegisterFloaterParams(typeid(LLFloater::Params).name(), "floater"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterFloaterParams(&typeid(LLFloater::Params), "floater"); LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p) : LLPanel(), // intentionally do not pass params here, see initFromParams diff --git a/indra/llui/llradiogroup.cpp b/indra/llui/llradiogroup.cpp index 71bbcd8ade..95a7d09382 100644 --- a/indra/llui/llradiogroup.cpp +++ b/indra/llui/llradiogroup.cpp @@ -66,7 +66,7 @@ protected: LLSD mPayload; // stores data that this item represents in the radio group }; -static LLWidgetNameRegistry::StaticRegistrar register_radio_item(typeid(LLRadioGroup::ItemParams).name(), "radio_item"); +static LLWidgetNameRegistry::StaticRegistrar register_radio_item(&typeid(LLRadioGroup::ItemParams), "radio_item"); LLRadioGroup::Params::Params() : allow_deselect("allow_deselect"), diff --git a/indra/llui/llrngwriter.cpp b/indra/llui/llrngwriter.cpp index 90a1e77b1a..5e6840d7df 100644 --- a/indra/llui/llrngwriter.cpp +++ b/indra/llui/llrngwriter.cpp @@ -92,7 +92,7 @@ void LLRNGWriter::addDefinition(const std::string& type_name, const LLInitParam: // add includes for all possible children const std::type_info* type = *LLWidgetTypeRegistry::instance().getValue(type_name); - const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type->name()); + const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type); // add include declarations for all valid children for (widget_registry_t::Registrar::registry_map_t::const_iterator it = widget_registryp->currentRegistrar().beginItems(); diff --git a/indra/llui/llscrolllistcolumn.cpp b/indra/llui/llscrolllistcolumn.cpp index d132d0cc7e..07a6dfaa10 100644 --- a/indra/llui/llscrolllistcolumn.cpp +++ b/indra/llui/llscrolllistcolumn.cpp @@ -39,7 +39,7 @@ const S32 MIN_COLUMN_WIDTH = 20; // defaults for LLScrollColumnHeader param block pulled from widgets/scroll_column_header.xml -static LLWidgetNameRegistry::StaticRegistrar sRegisterColumnHeaderParams(typeid(LLScrollColumnHeader::Params).name(), "scroll_column_header"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterColumnHeaderParams(&typeid(LLScrollColumnHeader::Params), "scroll_column_header"); //--------------------------------------------------------------------------- // LLScrollColumnHeader diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 8314386632..7aeeae298f 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -131,7 +131,7 @@ struct LLTextBase::line_end_compare // // register LLTextBase::Params under name "textbase" -static LLWidgetNameRegistry::StaticRegistrar sRegisterTextBaseParams(typeid(LLTextBase::Params).name(), "textbase"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterTextBaseParams(&typeid(LLTextBase::Params), "textbase"); LLTextBase::LineSpacingParams::LineSpacingParams() : multiple("multiple", 1.f), diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp index 0723dbec70..f737d48abf 100644 --- a/indra/llui/lltooltip.cpp +++ b/indra/llui/lltooltip.cpp @@ -129,7 +129,7 @@ void LLToolTipView::drawStickyRect() } // defaults for floater param block pulled from widgets/floater.xml -static LLWidgetNameRegistry::StaticRegistrar sRegisterInspectorParams(typeid(LLInspector::Params).name(), "inspector"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterInspectorParams(&typeid(LLInspector::Params), "inspector"); // // LLToolTip diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index fe3b470722..25e7a31e90 100644 --- a/indra/llui/lluictrlfactory.cpp +++ b/indra/llui/lluictrlfactory.cpp @@ -281,7 +281,7 @@ const LLInitParam::BaseBlock& get_empty_param_block() void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const std::type_info* param_block_type, const std::string& tag) { // associate parameter block type with template .xml file - std::string* existing_tag = LLWidgetNameRegistry::instance().getValue(param_block_type->name()); + std::string* existing_tag = LLWidgetNameRegistry::instance().getValue(param_block_type); if (existing_tag != NULL) { if(*existing_tag != tag) @@ -297,7 +297,7 @@ void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const st return; } } - LLWidgetNameRegistry::instance().defaultRegistrar().add(param_block_type->name(), tag); + LLWidgetNameRegistry::instance().defaultRegistrar().add(param_block_type, tag); //FIXME: comment this in when working on schema generation //LLWidgetTypeRegistry::instance().defaultRegistrar().add(tag, widget_type); //LLDefaultParamBlockRegistry::instance().defaultRegistrar().add(widget_type, &get_empty_param_block); @@ -306,6 +306,6 @@ void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const st //static const std::string* LLUICtrlFactory::getWidgetTag(const std::type_info* widget_type) { - return LLWidgetNameRegistry::instance().getValue(widget_type->name()); + return LLWidgetNameRegistry::instance().getValue(widget_type); } diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index 1f7a8e08ce..d612ad5005 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -69,9 +69,9 @@ protected: friend class LLSingleton; }; -// lookup widget name by type (actually by std::type_info::name()) +// lookup widget name by type class LLWidgetNameRegistry -: public LLRegistrySingleton +: public LLRegistrySingleton {}; // lookup function for generating empty param block by widget type diff --git a/indra/llui/llxuiparser.cpp b/indra/llui/llxuiparser.cpp index c3a246b9a5..afc76024d1 100644 --- a/indra/llui/llxuiparser.cpp +++ b/indra/llui/llxuiparser.cpp @@ -606,7 +606,7 @@ void LLXUIXSDWriter::writeXSD(const std::string& type_name, const std::string& p // add includes for all possible children const std::type_info* type = *LLWidgetTypeRegistry::instance().getValue(type_name); - const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type->name()); + const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type); // add choices for valid children if (widget_registryp) diff --git a/indra/llui/llxuiparser.h b/indra/llui/llxuiparser.h index 3c092afdd6..d7cd256967 100644 --- a/indra/llui/llxuiparser.h +++ b/indra/llui/llxuiparser.h @@ -55,9 +55,8 @@ typedef boost::function widget_registry_t; -// const char* key used for std::type_info::name() string class LLChildRegistryRegistry -: public LLRegistrySingleton +: public LLRegistrySingleton {}; -- cgit v1.2.3 From 2e83dfa217feb90e7b94e499346ad9b98fa711b2 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 18 Jul 2012 20:33:54 -0400 Subject: MAINT-1175: Ditch LLTypeInfoLookup, make map work. Instead of forbidding std::map outright (which includes LLRegistry and LLRegistrySingleton), try to make it work by specializing std::less to use std::type_info::before(). Make LLRegistryDefaultComparator use std::less so it can capitalize on that specialization. --- indra/llui/lluictrlfactory.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index ab16805cb1..4e54354731 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -31,6 +31,7 @@ #include "llinitparam.h" #include "llregistry.h" #include "llxuiparser.h" +#include "llstl.h" class LLView; @@ -62,14 +63,14 @@ protected: // lookup widget name by type class LLWidgetNameRegistry -: public LLRegistrySingleton +: public LLRegistrySingleton {}; // lookup function for generating empty param block by widget type // this is used for schema generation //typedef const LLInitParam::BaseBlock& (*empty_param_block_func_t)(); //class LLDefaultParamBlockRegistry -//: public LLRegistrySingleton +//: public LLRegistrySingleton //{}; extern LLFastTimer::DeclareTimer FTM_WIDGET_SETUP; -- cgit v1.2.3 From 50f3e227a2ba511a1110b3e5a214db73ba3cc4e8 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 8 Aug 2012 13:23:02 -0400 Subject: Move llhandle.h into llcommon; same generality as llpointer.h. Leaving llhandle.h in llui restricts the set of viewer project directories which could potentially use it, and there's nothing whatsoever UI-specific about it. --- indra/llui/CMakeLists.txt | 1 - indra/llui/llhandle.h | 181 ---------------------------------------------- 2 files changed, 182 deletions(-) delete mode 100644 indra/llui/llhandle.h (limited to 'indra/llui') diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index cca4ca3981..d92b6aa1c0 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -155,7 +155,6 @@ set(llui_HEADER_FILES llflyoutbutton.h llfocusmgr.h llfunctorregistry.h - llhandle.h llhelp.h lliconctrl.h llkeywords.h diff --git a/indra/llui/llhandle.h b/indra/llui/llhandle.h deleted file mode 100644 index 37c657dd92..0000000000 --- a/indra/llui/llhandle.h +++ /dev/null @@ -1,181 +0,0 @@ -/** -* @file llhandle.h -* @brief "Handle" to an object (usually a floater) whose lifetime you don't -* control. -* -* $LicenseInfo:firstyear=2001&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 LLHANDLE_H -#define LLHANDLE_H - -#include "llpointer.h" -#include -#include - -class LLTombStone : public LLRefCount -{ -public: - LLTombStone(void* target = NULL) : mTarget(target) {} - - void setTarget(void* target) { mTarget = target; } - void* getTarget() const { return mTarget; } -private: - mutable void* mTarget; -}; - -// LLHandles are used to refer to objects whose lifetime you do not control or influence. -// Calling get() on a handle will return a pointer to the referenced object or NULL, -// if the object no longer exists. Note that during the lifetime of the returned pointer, -// you are assuming that the object will not be deleted by any action you perform, -// or any other thread, as normal when using pointers, so avoid using that pointer outside of -// the local code block. -// -// https://wiki.lindenlab.com/mediawiki/index.php?title=LLHandle&oldid=79669 - -template -class LLHandle -{ - template friend class LLHandle; - template friend class LLHandleProvider; -public: - LLHandle() : mTombStone(getDefaultTombStone()) {} - - template - LLHandle(const LLHandle& other, typename boost::enable_if< typename boost::is_convertible >::type* dummy = 0) - : mTombStone(other.mTombStone) - {} - - bool isDead() const - { - return mTombStone->getTarget() == NULL; - } - - void markDead() - { - mTombStone = getDefaultTombStone(); - } - - T* get() const - { - return reinterpret_cast(mTombStone->getTarget()); - } - - friend bool operator== (const LLHandle& lhs, const LLHandle& rhs) - { - return lhs.mTombStone == rhs.mTombStone; - } - friend bool operator!= (const LLHandle& lhs, const LLHandle& rhs) - { - return !(lhs == rhs); - } - friend bool operator< (const LLHandle& lhs, const LLHandle& rhs) - { - return lhs.mTombStone < rhs.mTombStone; - } - friend bool operator> (const LLHandle& lhs, const LLHandle& rhs) - { - return lhs.mTombStone > rhs.mTombStone; - } - -protected: - LLPointer mTombStone; - -private: - typedef T* pointer_t; - static LLPointer& getDefaultTombStone() - { - static LLPointer sDefaultTombStone = new LLTombStone; - return sDefaultTombStone; - } -}; - -template -class LLRootHandle : public LLHandle -{ -public: - typedef LLRootHandle self_t; - typedef LLHandle base_t; - - LLRootHandle(T* object) { bind(object); } - LLRootHandle() {}; - ~LLRootHandle() { unbind(); } - - // this is redundant, since an LLRootHandle *is* an LLHandle - //LLHandle getHandle() { return LLHandle(*this); } - - void bind(T* object) - { - // unbind existing tombstone - if (LLHandle::mTombStone.notNull()) - { - if (LLHandle::mTombStone->getTarget() == (void*)object) return; - LLHandle::mTombStone->setTarget(NULL); - } - // tombstone reference counted, so no paired delete - LLHandle::mTombStone = new LLTombStone((void*)object); - } - - void unbind() - { - LLHandle::mTombStone->setTarget(NULL); - } - - //don't allow copying of root handles, since there should only be one -private: - LLRootHandle(const LLRootHandle& other) {}; -}; - -// Use this as a mixin for simple classes that need handles and when you don't -// want handles at multiple points of the inheritance hierarchy -template -class LLHandleProvider -{ -public: - LLHandle getHandle() const - { - // perform lazy binding to avoid small tombstone allocations for handle - // providers whose handles are never referenced - mHandle.bind(static_cast(const_cast* >(this))); - return mHandle; - } - -protected: - typedef LLHandle handle_type_t; - LLHandleProvider() - { - // provided here to enforce T deriving from LLHandleProvider - } - - template - LLHandle getDerivedHandle(typename boost::enable_if< typename boost::is_convertible >::type* dummy = 0) const - { - LLHandle downcast_handle; - downcast_handle.mTombStone = getHandle().mTombStone; - return downcast_handle; - } - - -private: - mutable LLRootHandle mHandle; -}; - -#endif -- cgit v1.2.3 From 3653727e7f84f10caefb6ea7dc33859455ebfa0b Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 10 Oct 2012 14:57:43 -0400 Subject: Introduce new LLDir::findSkinnedFilenames() method. Use as needed. In a number of different places, for different reasons, the viewer wants to load a UI-related file that might be overridden by a non-default skin; and within that skin, might further be overridden by a non-default language. Apparently, for each of those use cases, every individual developer approached it as an entirely new problem, solving it idiosyncratically for that one case. Not only is this a maintenance problem, but it rubs one's nose in the fact that most such solutions consider only a subset of the relevant skin directories. Richard and I evolved an API intended to address all such cases: a central LLDir method returning a list of relevant pathnames, from most general to most localized, filtered to present only existing files; plus a couple of convenience methods to specifically obtain the most general and most localized available file. There were several load-skinned-file methods (LLFloater::buildFromFile(), LLPanel::buildFromFile() and LLUICtrlFactory::createFromFile() -- apparently cloned-and-modified from each other) that contained funky bolted-on logic to output the loaded data to an optional passed LLXMLNodePtr param. The trouble is that passing that param forced each of these methods to subvert its normal search: specifically for that case, it needed to find the baseline XML file instead of the localized one. Richard agreed that for the intended usage (reformatting XML files) we should use XML schema instead, and that the hacky functionality should be removed. Remove it. Also remove LLUICtrlFactory::getLocalizedXMLNode(), only used for those three special cases. Some callers explicitly passed the optional LLXMLNodePtr param as NULL. Remove that. Remove LLFloaterUIPreview::displayFloater(save) param, which relied on the optional output LLXMLNodePtr param. Make onClickSaveFloater() and onClickSaveAll() emit popupAndPrintWarning() about discontinued functionality. Recast LLFloater::buildFromFile(), LLPanel::buildFromFile(), LLUICtrlFactory::createFromFile(), LLNotifications::loadTemplates(), LLUI::locateSkin(), LLFontRegistry::parseFontInfo(), LLUIColorTable::loadFromSettings(), LLUICtrlFactory::loadWidgetTemplate(), LLUICtrlFactory::getLayeredXMLNode(), LLUIImageList::initFromFile(), LLAppViewer::launchUpdater() and LLMediaCtrl::navigateToLocalPage() to use findSkinnedFilenames(). (Is LLAppViewer::launchUpdater() ever called any more? Apparently so -- though the linux-updater.bin logic to process the relevant command-line switch has been disabled. Shrug.) (Is LLMediaCtrl::navigateToLocalPage() ever used?? If so, why?) Remove LLUI::setupPaths(), getXUIPaths(), getSkinPath() and getLocalizedSkinPath(). Remove the skins/paths.xml file read by setupPaths(). The only configuration it contained was the pair of partial paths "xui/en" and "xui/[LANGUAGE]" -- hardly likely to change. getSkinPath() specifically returned the first of these, while getLocalizedSkinPath() specifically returned the second. This knowledge is now embedded in findSkinnedFilenames(). Also remove paths.xml from viewer_manifest.py. Remove injected xui_paths from LLFontGL::initClass() and LLFontRegistry::LLFontRegistry(). These are no longer needed since LLFontRegistry can now directly consult LLDir for its path search. Stop passing LLUI::getXUIPaths() to LLFontGL::initClass() in LLViewerWindow's constructor and initFonts() method. Add LLDir::append() and add() methods for the simple task of combining two path components separated by getDirDelimiter() -- but only if they're both non-empty. Amazing how often that logic is replicated. Replace some existing concatenations with add() or append(). New LLDir::findSkinnedFilenames() method must know current language. Allow injecting current language by adding an LLDir::setSkinFolder(language) param, and pass it where LLAppViewer::init() and initConfiguration() currently call setSkinFolder(). Also add LLDir::getSkinFolder() and getLanguage() methods. Change LLFLoaterUIPreview's LLLocalizationResetForcer helper to "forcibly reset language" using LLDir::setSkinFolder() instead of LLUI::setupPaths(). Update LLDir stubs in lldir_stub.cpp and llupdaterservice_test.cpp. Add LLDir::getUserDefaultSkinDir() to obtain often-overlooked possible skin directory -- like getUserSkinDir() but with "default" in place of the current skin name as the last path component. (However, we hope findSkinnedFilenames() obviates most explicit use of such individual skin directory pathnames.) Add LLDir unit tests for new findSkinnedFilenames() and add() methods -- the latter exercises append() as well. Tweak indra/integration_tests/llui_libtest/llui_libtest.cpp for all the above. Notably, comment out its export_test_floaters() function, since the essential LLFloater::buildFromFile(optional LLXMLNodePtr) functionality has been removed. This may mean that llui_libtest.cpp has little remaining value, not sure. --- indra/llui/llfloater.cpp | 18 ++------- indra/llui/llfloater.h | 2 +- indra/llui/llfloaterreg.cpp | 2 +- indra/llui/llnotifications.cpp | 25 +++++------- indra/llui/llpanel.cpp | 18 ++------- indra/llui/llpanel.h | 2 +- indra/llui/llui.cpp | 87 +++++++++--------------------------------- indra/llui/llui.h | 5 --- indra/llui/lluicolortable.cpp | 17 +++------ indra/llui/lluictrlfactory.cpp | 46 ++++++---------------- indra/llui/lluictrlfactory.h | 17 ++------- 11 files changed, 59 insertions(+), 180 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 8ca1e685a9..33295f882d 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -3229,24 +3229,14 @@ bool LLFloater::isVisible(const LLFloater* floater) static LLFastTimer::DeclareTimer FTM_BUILD_FLOATERS("Build Floaters"); -bool LLFloater::buildFromFile(const std::string& filename, LLXMLNodePtr output_node) +bool LLFloater::buildFromFile(const std::string& filename) { LLFastTimer timer(FTM_BUILD_FLOATERS); LLXMLNodePtr root; - //if exporting, only load the language being exported, - //instead of layering localized version on top of english - if (output_node) - { - if (!LLUICtrlFactory::getLocalizedXMLNode(filename, root)) - { - llwarns << "Couldn't parse floater from: " << LLUI::getLocalizedSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl; - return false; - } - } - else if (!LLUICtrlFactory::getLayeredXMLNode(filename, root)) + if (!LLUICtrlFactory::getLayeredXMLNode(filename, root)) { - llwarns << "Couldn't parse floater from: " << LLUI::getSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl; + llwarns << "Couldn't find (or parse) floater from: " << filename << llendl; return false; } @@ -3271,7 +3261,7 @@ bool LLFloater::buildFromFile(const std::string& filename, LLXMLNodePtr output_n getCommitCallbackRegistrar().pushScope(); getEnableCallbackRegistrar().pushScope(); - res = initFloaterXML(root, getParent(), filename, output_node); + res = initFloaterXML(root, getParent(), filename, NULL); setXMLFilename(filename); diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 64d6dcea04..e64b6d04d3 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -202,7 +202,7 @@ public: // Don't export top/left for rect, only height/width static void setupParamsForExport(Params& p, LLView* parent); - bool buildFromFile(const std::string &filename, LLXMLNodePtr output_node = NULL); + bool buildFromFile(const std::string &filename); boost::signals2::connection setMinimizeCallback( const commit_signal_t::slot_type& cb ); boost::signals2::connection setOpenCallback( const commit_signal_t::slot_type& cb ); diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp index 9115eb7174..306caf2b91 100644 --- a/indra/llui/llfloaterreg.cpp +++ b/indra/llui/llfloaterreg.cpp @@ -154,7 +154,7 @@ LLFloater* LLFloaterReg::getInstance(const std::string& name, const LLSD& key) llwarns << "Failed to build floater type: '" << name << "'." << llendl; return NULL; } - bool success = res->buildFromFile(xui_file, NULL); + bool success = res->buildFromFile(xui_file); if (!success) { llwarns << "Failed to build floater type: '" << name << "'." << llendl; diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 629eef2c3b..4fbee8cd80 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -1424,25 +1424,18 @@ void addPathIfExists(const std::string& new_path, std::vector& path bool LLNotifications::loadTemplates() { llinfos << "Reading notifications template" << llendl; - std::vector search_paths; - - std::string skin_relative_path = gDirUtilp->getDirDelimiter() + LLUI::getSkinPath() + gDirUtilp->getDirDelimiter() + "notifications.xml"; - std::string localized_skin_relative_path = gDirUtilp->getDirDelimiter() + LLUI::getLocalizedSkinPath() + gDirUtilp->getDirDelimiter() + "notifications.xml"; - - addPathIfExists(gDirUtilp->getDefaultSkinDir() + skin_relative_path, search_paths); - addPathIfExists(gDirUtilp->getDefaultSkinDir() + localized_skin_relative_path, search_paths); - addPathIfExists(gDirUtilp->getSkinDir() + skin_relative_path, search_paths); - addPathIfExists(gDirUtilp->getSkinDir() + localized_skin_relative_path, search_paths); - addPathIfExists(gDirUtilp->getUserSkinDir() + skin_relative_path, search_paths); - addPathIfExists(gDirUtilp->getUserSkinDir() + localized_skin_relative_path, search_paths); + // Passing findSkinnedFilenames(merge=true) makes it output all relevant + // pathnames instead of just the ones from the most specific skin. + std::vector search_paths = + gDirUtilp->findSkinnedFilenames(LLDir::XUI, "notifications.xml", true); std::string base_filename = search_paths.front(); LLXMLNodePtr root; BOOL success = LLXMLNode::getLayeredXMLNode(root, search_paths); - + if (!success || root.isNull() || !root->hasName( "notifications" )) { - llerrs << "Problem reading UI Notifications file: " << base_filename << llendl; + llerrs << "Problem reading XML from UI Notifications file: " << base_filename << llendl; return false; } @@ -1452,7 +1445,7 @@ bool LLNotifications::loadTemplates() if(!params.validateBlock()) { - llerrs << "Problem reading UI Notifications file: " << base_filename << llendl; + llerrs << "Problem reading XUI from UI Notifications file: " << base_filename << llendl; return false; } @@ -1508,7 +1501,9 @@ bool LLNotifications::loadTemplates() bool LLNotifications::loadVisibilityRules() { const std::string xml_filename = "notification_visibility.xml"; - std::string full_filename = gDirUtilp->findSkinnedFilename(LLUI::getXUIPaths().front(), xml_filename); + // Note that here we're looking for the "en" version, the default + // language, rather than the most localized version of this file. + std::string full_filename = gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, xml_filename); LLNotificationVisibilityRule::Rules params; LLSimpleXUIParser parser; diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index 00318cec6b..67472ad166 100644 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -968,25 +968,15 @@ static LLFastTimer::DeclareTimer FTM_BUILD_PANELS("Build Panels"); //----------------------------------------------------------------------------- // buildPanel() //----------------------------------------------------------------------------- -BOOL LLPanel::buildFromFile(const std::string& filename, LLXMLNodePtr output_node, const LLPanel::Params& default_params) +BOOL LLPanel::buildFromFile(const std::string& filename, const LLPanel::Params& default_params) { LLFastTimer timer(FTM_BUILD_PANELS); BOOL didPost = FALSE; LLXMLNodePtr root; - //if exporting, only load the language being exported, - //instead of layering localized version on top of english - if (output_node) - { - if (!LLUICtrlFactory::getLocalizedXMLNode(filename, root)) - { - llwarns << "Couldn't parse panel from: " << LLUI::getLocalizedSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl; - return didPost; - } - } - else if (!LLUICtrlFactory::getLayeredXMLNode(filename, root)) + if (!LLUICtrlFactory::getLayeredXMLNode(filename, root)) { - llwarns << "Couldn't parse panel from: " << LLUI::getSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl; + llwarns << "Couldn't parse panel from: " << filename << llendl; return didPost; } @@ -1010,7 +1000,7 @@ BOOL LLPanel::buildFromFile(const std::string& filename, LLXMLNodePtr output_nod getCommitCallbackRegistrar().pushScope(); getEnableCallbackRegistrar().pushScope(); - didPost = initPanelXML(root, NULL, output_node, default_params); + didPost = initPanelXML(root, NULL, NULL, default_params); getCommitCallbackRegistrar().popScope(); getEnableCallbackRegistrar().popScope(); diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index f620201020..e63b41f97c 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -105,7 +105,7 @@ protected: LLPanel(const LLPanel::Params& params = getDefaultParams()); public: - BOOL buildFromFile(const std::string &filename, LLXMLNodePtr output_node = NULL, const LLPanel::Params&default_params = getDefaultParams()); + BOOL buildFromFile(const std::string &filename, const LLPanel::Params& default_params = getDefaultParams()); static LLPanel* createFactoryPanel(const std::string& name); diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index 87bf518aa1..507ced9172 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -1836,88 +1836,39 @@ struct Paths : public LLInitParam::Block {} }; -//static -void LLUI::setupPaths() -{ - std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_SKINS, "paths.xml"); - - LLXMLNodePtr root; - BOOL success = LLXMLNode::parseFile(filename, root, NULL); - Paths paths; - - if(success) - { - LLXUIParser parser; - parser.readXUI(root, paths, filename); - } - sXUIPaths.clear(); - - if (success && paths.validateBlock()) - { - LLStringUtil::format_map_t path_args; - path_args["[LANGUAGE]"] = LLUI::getLanguage(); - - for (LLInitParam::ParamIterator::const_iterator it = paths.directories.begin(), - end_it = paths.directories.end(); - it != end_it; - ++it) - { - std::string path_val_ui; - for (LLInitParam::ParamIterator::const_iterator subdir_it = it->subdirs.begin(), - subdir_end_it = it->subdirs.end(); - subdir_it != subdir_end_it;) - { - path_val_ui += subdir_it->value(); - if (++subdir_it != subdir_end_it) - path_val_ui += gDirUtilp->getDirDelimiter(); - } - LLStringUtil::format(path_val_ui, path_args); - if (std::find(sXUIPaths.begin(), sXUIPaths.end(), path_val_ui) == sXUIPaths.end()) - { - sXUIPaths.push_back(path_val_ui); - } - - } - } - else // parsing failed - { - std::string slash = gDirUtilp->getDirDelimiter(); - std::string dir = "xui" + slash + "en"; - llwarns << "XUI::config file unable to open: " << filename << llendl; - sXUIPaths.push_back(dir); - } -} - //static std::string LLUI::locateSkin(const std::string& filename) { - std::string slash = gDirUtilp->getDirDelimiter(); std::string found_file = filename; - if (!gDirUtilp->fileExists(found_file)) + if (gDirUtilp->fileExists(found_file)) { - found_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename); // Should be CUSTOM_SKINS? + return found_file; } - if (sSettingGroups["config"] && sSettingGroups["config"]->controlExists("Language")) + + found_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename); // Should be CUSTOM_SKINS? + if (gDirUtilp->fileExists(found_file)) { - if (!gDirUtilp->fileExists(found_file)) - { - std::string localization = getLanguage(); - std::string local_skin = "xui" + slash + localization + slash + filename; - found_file = gDirUtilp->findSkinnedFilename(local_skin); - } + return found_file; } - if (!gDirUtilp->fileExists(found_file)) + + found_file = gDirUtilp->findSkinnedFilename(LLDir::XUI, filename); + if (! found_file.empty()) { - std::string local_skin = "xui" + slash + "en" + slash + filename; - found_file = gDirUtilp->findSkinnedFilename(local_skin); + return found_file; } - if (!gDirUtilp->fileExists(found_file)) + + found_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, filename); +/*==========================================================================*| + // Hmm, if we got this far, previous implementation of this method would + // return this last found_file value whether or not it actually exists. + if (gDirUtilp->fileExists(found_file)) { - found_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, filename); + return found_file; } +|*==========================================================================*/ return found_file; -} +} //static LLVector2 LLUI::getWindowSize() diff --git a/indra/llui/llui.h b/indra/llui/llui.h index 28e84fa444..c5a12d2b31 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -292,11 +292,6 @@ public: // Return the ISO639 language name ("en", "ko", etc.) for the viewer UI. // http://www.loc.gov/standards/iso639-2/php/code_list.php static std::string getLanguage(); - - static void setupPaths(); - static const std::vector& getXUIPaths() { return sXUIPaths; } - static std::string getSkinPath() { return sXUIPaths.front(); } - static std::string getLocalizedSkinPath() { return sXUIPaths.back(); } //all files may not exist at the localized path //helper functions (should probably move free standing rendering helper functions here) static LLView* getRootView() { return sRootView; } diff --git a/indra/llui/lluicolortable.cpp b/indra/llui/lluicolortable.cpp index 9455d09cc0..2717445396 100644 --- a/indra/llui/lluicolortable.cpp +++ b/indra/llui/lluicolortable.cpp @@ -32,6 +32,7 @@ #include "llui.h" #include "lluicolortable.h" #include "lluictrlfactory.h" +#include LLUIColorTable::ColorParams::ColorParams() : value("value"), @@ -206,19 +207,11 @@ bool LLUIColorTable::loadFromSettings() { bool result = false; - std::string default_filename = gDirUtilp->getExpandedFilename(LL_PATH_DEFAULT_SKIN, "colors.xml"); - result |= loadFromFilename(default_filename, mLoadedColors); - - std::string current_filename = gDirUtilp->getExpandedFilename(LL_PATH_TOP_SKIN, "colors.xml"); - if(current_filename != default_filename) - { - result |= loadFromFilename(current_filename, mLoadedColors); - } - - current_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SKIN, "colors.xml"); - if(current_filename != default_filename) + // pass merge=true because we want colors.xml from every skin dir + BOOST_FOREACH(std::string colors_path, + gDirUtilp->findSkinnedFilenames(LLDir::SKINBASE, "colors.xml", true)) { - result |= loadFromFilename(current_filename, mLoadedColors); + result |= loadFromFilename(colors_path, mLoadedColors); } std::string user_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "colors.xml"); diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index 25e7a31e90..2b317b46e3 100644 --- a/indra/llui/lluictrlfactory.cpp +++ b/indra/llui/lluictrlfactory.cpp @@ -90,10 +90,12 @@ LLUICtrlFactory::~LLUICtrlFactory() void LLUICtrlFactory::loadWidgetTemplate(const std::string& widget_tag, LLInitParam::BaseBlock& block) { - std::string filename = std::string("widgets") + gDirUtilp->getDirDelimiter() + widget_tag + ".xml"; + std::string filename = gDirUtilp->add("widgets", widget_tag + ".xml"); LLXMLNodePtr root_node; - std::string full_filename = gDirUtilp->findSkinnedFilename(LLUI::getXUIPaths().front(), filename); + // Here we're looking for the "en" version, the default-language version + // of the file, rather than the localized version. + std::string full_filename = gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, filename); if (!full_filename.empty()) { LLUICtrlFactory::instance().pushFileName(full_filename); @@ -152,19 +154,8 @@ static LLFastTimer::DeclareTimer FTM_XML_PARSE("XML Reading/Parsing"); bool LLUICtrlFactory::getLayeredXMLNode(const std::string &xui_filename, LLXMLNodePtr& root) { LLFastTimer timer(FTM_XML_PARSE); - - std::vector paths; - std::string path = gDirUtilp->findSkinnedFilename(LLUI::getSkinPath(), xui_filename); - if (!path.empty()) - { - paths.push_back(path); - } - - std::string localize_path = gDirUtilp->findSkinnedFilename(LLUI::getLocalizedSkinPath(), xui_filename); - if (!localize_path.empty() && localize_path != path) - { - paths.push_back(localize_path); - } + std::vector paths = + gDirUtilp->findSkinnedFilenames(LLDir::XUI, xui_filename); if (paths.empty()) { @@ -176,23 +167,6 @@ bool LLUICtrlFactory::getLayeredXMLNode(const std::string &xui_filename, LLXMLNo } -//----------------------------------------------------------------------------- -// getLocalizedXMLNode() -//----------------------------------------------------------------------------- -bool LLUICtrlFactory::getLocalizedXMLNode(const std::string &xui_filename, LLXMLNodePtr& root) -{ - LLFastTimer timer(FTM_XML_PARSE); - std::string full_filename = gDirUtilp->findSkinnedFilename(LLUI::getLocalizedSkinPath(), xui_filename); - if (!LLXMLNode::parseFile(full_filename, root, NULL)) - { - return false; - } - else - { - return true; - } -} - //----------------------------------------------------------------------------- // saveToXML() //----------------------------------------------------------------------------- @@ -239,8 +213,10 @@ std::string LLUICtrlFactory::getCurFileName() void LLUICtrlFactory::pushFileName(const std::string& name) -{ - mFileNames.push_back(gDirUtilp->findSkinnedFilename(LLUI::getSkinPath(), name)); +{ + // Here we seem to be looking for the default language file ("en") rather + // than the localized one, if any. + mFileNames.push_back(gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, name)); } void LLUICtrlFactory::popFileName() @@ -260,7 +236,7 @@ void LLUICtrlFactory::setCtrlParent(LLView* view, LLView* parent, S32 tab_group) //static std::string LLUICtrlFactory::findSkinnedFilename(const std::string& filename) { - return gDirUtilp->findSkinnedFilename(LLUI::getSkinPath(), filename); + return gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, filename); } //static diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index d612ad5005..56e5f3eb7b 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -169,7 +169,7 @@ public: LLView* createFromXML(LLXMLNodePtr node, LLView* parent, const std::string& filename, const widget_registry_t&, LLXMLNodePtr output_node ); template - static T* createFromFile(const std::string &filename, LLView *parent, const widget_registry_t& registry, LLXMLNodePtr output_node = NULL) + static T* createFromFile(const std::string &filename, LLView *parent, const widget_registry_t& registry) { T* widget = NULL; @@ -178,23 +178,13 @@ public: { LLXMLNodePtr root_node; - //if exporting, only load the language being exported, - //instead of layering localized version on top of english - if (output_node) - { - if (!LLUICtrlFactory::getLocalizedXMLNode(filename, root_node)) - { - llwarns << "Couldn't parse XUI file: " << filename << llendl; - goto fail; - } - } - else if (!LLUICtrlFactory::getLayeredXMLNode(filename, root_node)) + if (!LLUICtrlFactory::getLayeredXMLNode(filename, root_node)) { llwarns << "Couldn't parse XUI file: " << skinned_filename << llendl; goto fail; } - LLView* view = getInstance()->createFromXML(root_node, parent, filename, registry, output_node); + LLView* view = getInstance()->createFromXML(root_node, parent, filename, registry, NULL); if (view) { widget = dynamic_cast(view); @@ -223,7 +213,6 @@ fail: static void createChildren(LLView* viewp, LLXMLNodePtr node, const widget_registry_t&, LLXMLNodePtr output_node = NULL); static bool getLayeredXMLNode(const std::string &filename, LLXMLNodePtr& root); - static bool getLocalizedXMLNode(const std::string &xui_filename, LLXMLNodePtr& root); private: //NOTE: both friend declarations are necessary to keep both gcc and msvc happy -- cgit v1.2.3 From 9e4927ece5448c94bc3f46f7be019c0ffe14a686 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 11 Oct 2012 17:29:04 -0400 Subject: Make LLTransUtil::parseStrings() merge all relevant strings.xml files. Until now, adding a xui/en/strings.xml file in any non-default skin meant you had to clone the entire file, editing only the particular entries you wanted to override. With this change, we load strings.xml file(s) from the default skin before loading the specified skin -- so a non-default skin can now provide a strings.xml file containing only the specific entries it wants to override. --- indra/llui/lltransutil.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/lltransutil.cpp b/indra/llui/lltransutil.cpp index 58fa8a0828..97a72b55e1 100644 --- a/indra/llui/lltransutil.cpp +++ b/indra/llui/lltransutil.cpp @@ -31,15 +31,27 @@ #include "lltrans.h" #include "lluictrlfactory.h" #include "llxmlnode.h" - +#include "lldir.h" bool LLTransUtil::parseStrings(const std::string& xml_filename, const std::set& default_args) { + // LLUICtrlFactory::getLayeredXMLNode() just calls + // gDirUtilp->findSkinnedFilenames(merge=false) and then passes the + // resulting paths to LLXMLNode::getLayeredXMLNode(). Bypass that and call + // LLXMLNode::getLayeredXMLNode() directly: we want merge=true. + std::vector paths = + gDirUtilp->findSkinnedFilenames(LLDir::XUI, xml_filename, true); + if (paths.empty()) + { + // xml_filename not found at all in any skin -- check whether entire + // path was passed (but I hope we no longer have callers who do that) + paths.push_back(xml_filename); + } LLXMLNodePtr root; - BOOL success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root); + bool success = LLXMLNode::getLayeredXMLNode(root, paths); if (!success) { - llerrs << "Couldn't load string table" << llendl; + llerrs << "Couldn't load string table " << xml_filename << llendl; return false; } @@ -54,7 +66,7 @@ bool LLTransUtil::parseLanguageStrings(const std::string& xml_filename) if (!success) { - llerrs << "Couldn't load string table " << xml_filename << llendl; + llerrs << "Couldn't load localization table " << xml_filename << llendl; return false; } -- cgit v1.2.3 From 730d13a76a4b06e6dbdd4bd5829a90bcb98b52b3 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 11 Oct 2012 19:51:07 -0400 Subject: Change LLDir::findSkinnedFilenames() to use enum instead of bool. At Richard's suggestion, changed the bool merge parameter to new enum ESkinConstraint with values CURRENT_SKIN and ALL_SKINS. This clarifies what we're requesting at the point of the call. --- indra/llui/llnotifications.cpp | 7 ++++--- indra/llui/lltransutil.cpp | 9 +++++---- indra/llui/lluicolortable.cpp | 5 +++-- 3 files changed, 12 insertions(+), 9 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 4fbee8cd80..210a320f41 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -1424,10 +1424,11 @@ void addPathIfExists(const std::string& new_path, std::vector& path bool LLNotifications::loadTemplates() { llinfos << "Reading notifications template" << llendl; - // Passing findSkinnedFilenames(merge=true) makes it output all relevant - // pathnames instead of just the ones from the most specific skin. + // Passing findSkinnedFilenames(constraint=LLDir::ALL_SKINS) makes it + // output all relevant pathnames instead of just the ones from the most + // specific skin. std::vector search_paths = - gDirUtilp->findSkinnedFilenames(LLDir::XUI, "notifications.xml", true); + gDirUtilp->findSkinnedFilenames(LLDir::XUI, "notifications.xml", LLDir::ALL_SKINS); std::string base_filename = search_paths.front(); LLXMLNodePtr root; diff --git a/indra/llui/lltransutil.cpp b/indra/llui/lltransutil.cpp index 97a72b55e1..3b7e737dea 100644 --- a/indra/llui/lltransutil.cpp +++ b/indra/llui/lltransutil.cpp @@ -36,11 +36,12 @@ bool LLTransUtil::parseStrings(const std::string& xml_filename, const std::set& default_args) { // LLUICtrlFactory::getLayeredXMLNode() just calls - // gDirUtilp->findSkinnedFilenames(merge=false) and then passes the - // resulting paths to LLXMLNode::getLayeredXMLNode(). Bypass that and call - // LLXMLNode::getLayeredXMLNode() directly: we want merge=true. + // gDirUtilp->findSkinnedFilenames(constraint=LLDir::CURRENT_SKIN) and + // then passes the resulting paths to LLXMLNode::getLayeredXMLNode(). + // Bypass that and call LLXMLNode::getLayeredXMLNode() directly: we want + // constraint=LLDir::ALL_SKINS. std::vector paths = - gDirUtilp->findSkinnedFilenames(LLDir::XUI, xml_filename, true); + gDirUtilp->findSkinnedFilenames(LLDir::XUI, xml_filename, LLDir::ALL_SKINS); if (paths.empty()) { // xml_filename not found at all in any skin -- check whether entire diff --git a/indra/llui/lluicolortable.cpp b/indra/llui/lluicolortable.cpp index 2717445396..ffeff15968 100644 --- a/indra/llui/lluicolortable.cpp +++ b/indra/llui/lluicolortable.cpp @@ -207,9 +207,10 @@ bool LLUIColorTable::loadFromSettings() { bool result = false; - // pass merge=true because we want colors.xml from every skin dir + // pass constraint=LLDir::ALL_SKINS because we want colors.xml from every + // skin dir BOOST_FOREACH(std::string colors_path, - gDirUtilp->findSkinnedFilenames(LLDir::SKINBASE, "colors.xml", true)) + gDirUtilp->findSkinnedFilenames(LLDir::SKINBASE, "colors.xml", LLDir::ALL_SKINS)) { result |= loadFromFilename(colors_path, mLoadedColors); } -- cgit v1.2.3 From 6ca37068080e3b26e5cb163dfd874bc0e2f4c837 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 12 Oct 2012 08:42:18 -0400 Subject: LLUICtrlFactory::getLayeredXMLNode() gets LLDir::ESkinConstraint. At this point, LLUICtrlFactory::getLayeredXMLNode() is a pretty thin wrapper around LLDir::findSkinnedFilenames() and LLXMLNode::getLayeredXMLNode(). Until now, LLUICtrlFactory::getLayeredXMLNode() passed (by default) LLDir::CURRENT_SKIN to LLDir::findSkinnedFilenames(). But that meant that a caller such as LLTransUtil::parseStrings() that wants almost the same functionality, but with LLDir::ALL_SKINS instead, had to clone the logic from LLUICtrlFactory::getLayeredXMLNode(). Allowing its caller to pass the desired LLDir::ESkinConstraint enum value eliminates the need to clone its logic. Remove cloned logic from LLTransUtil::parseStrings(). --- indra/llui/lltransutil.cpp | 20 ++++++-------------- indra/llui/lluictrlfactory.cpp | 5 +++-- indra/llui/lluictrlfactory.h | 4 +++- 3 files changed, 12 insertions(+), 17 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/lltransutil.cpp b/indra/llui/lltransutil.cpp index 3b7e737dea..80d079cbc8 100644 --- a/indra/llui/lltransutil.cpp +++ b/indra/llui/lltransutil.cpp @@ -35,21 +35,13 @@ bool LLTransUtil::parseStrings(const std::string& xml_filename, const std::set& default_args) { - // LLUICtrlFactory::getLayeredXMLNode() just calls - // gDirUtilp->findSkinnedFilenames(constraint=LLDir::CURRENT_SKIN) and - // then passes the resulting paths to LLXMLNode::getLayeredXMLNode(). - // Bypass that and call LLXMLNode::getLayeredXMLNode() directly: we want - // constraint=LLDir::ALL_SKINS. - std::vector paths = - gDirUtilp->findSkinnedFilenames(LLDir::XUI, xml_filename, LLDir::ALL_SKINS); - if (paths.empty()) - { - // xml_filename not found at all in any skin -- check whether entire - // path was passed (but I hope we no longer have callers who do that) - paths.push_back(xml_filename); - } LLXMLNodePtr root; - bool success = LLXMLNode::getLayeredXMLNode(root, paths); + // Pass LLDir::ALL_SKINS to load a composite of all the individual string + // definitions in the default skin and the current skin. This means an + // individual skin can provide an xml_filename that overrides only a + // subset of the available string definitions; any string definition not + // overridden by that skin will be sought in the default skin. + bool success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root, LLDir::ALL_SKINS); if (!success) { llerrs << "Couldn't load string table " << xml_filename << llendl; diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index 2b317b46e3..f7307cd076 100644 --- a/indra/llui/lluictrlfactory.cpp +++ b/indra/llui/lluictrlfactory.cpp @@ -151,11 +151,12 @@ static LLFastTimer::DeclareTimer FTM_XML_PARSE("XML Reading/Parsing"); //----------------------------------------------------------------------------- // getLayeredXMLNode() //----------------------------------------------------------------------------- -bool LLUICtrlFactory::getLayeredXMLNode(const std::string &xui_filename, LLXMLNodePtr& root) +bool LLUICtrlFactory::getLayeredXMLNode(const std::string &xui_filename, LLXMLNodePtr& root, + LLDir::ESkinConstraint constraint) { LLFastTimer timer(FTM_XML_PARSE); std::vector paths = - gDirUtilp->findSkinnedFilenames(LLDir::XUI, xui_filename); + gDirUtilp->findSkinnedFilenames(LLDir::XUI, xui_filename, constraint); if (paths.empty()) { diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index 56e5f3eb7b..1acfd24112 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -31,6 +31,7 @@ #include "llinitparam.h" #include "llregistry.h" #include "llxuiparser.h" +#include "lldir.h" class LLView; @@ -212,7 +213,8 @@ fail: static void createChildren(LLView* viewp, LLXMLNodePtr node, const widget_registry_t&, LLXMLNodePtr output_node = NULL); - static bool getLayeredXMLNode(const std::string &filename, LLXMLNodePtr& root); + static bool getLayeredXMLNode(const std::string &filename, LLXMLNodePtr& root, + LLDir::ESkinConstraint constraint=LLDir::CURRENT_SKIN); private: //NOTE: both friend declarations are necessary to keep both gcc and msvc happy -- cgit v1.2.3 From 543b7ee9f7eb104497e971961fc0c39ed32ef54d Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 12 Oct 2012 11:09:25 -0400 Subject: Fix LLUI::locateSkin() failure case; clarify lldir.cpp static init. Per code review: Previous refactoring of LLUI::locateSkin() preserved odd failure behavior: it would return last-considered pathname, whether or not it exists. Changed to emit LL_WARNS log message and return empty string. Use Boost.Assign to simplify initialization of a couple static containers in lldir.cpp. --- indra/llui/llui.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index 507ced9172..6d2bc1837c 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -1859,15 +1859,13 @@ std::string LLUI::locateSkin(const std::string& filename) } found_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, filename); -/*==========================================================================*| - // Hmm, if we got this far, previous implementation of this method would - // return this last found_file value whether or not it actually exists. if (gDirUtilp->fileExists(found_file)) { return found_file; } -|*==========================================================================*/ - return found_file; + LL_WARNS("LLUI") << "Can't find '" << filename + << "' in user settings, any skin directory or app_settings" << LL_ENDL; + return ""; } //static -- cgit v1.2.3 From bf99126a37062d80e7887e2634b34f1da0ed309e Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 15 Oct 2012 09:38:28 -0400 Subject: Remove LLUICtrlFactory::findSkinnedFilename(): cf. LLDir method. Richard points out that LLUICtrlFactory::findSkinnedFilename() adds little value. It was called from exactly one place, and that one place could easily obtain the information another way. The concern is that it could confuse a reader of the code with regard to the other findSkinnedFilename[s]() methods in LLDir. Clarifying the code base is a Good Thing. Removing. --- indra/llui/lluictrlfactory.cpp | 8 -------- indra/llui/lluictrlfactory.h | 10 +++------- 2 files changed, 3 insertions(+), 15 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index f7307cd076..bd06476936 100644 --- a/indra/llui/lluictrlfactory.cpp +++ b/indra/llui/lluictrlfactory.cpp @@ -232,14 +232,6 @@ void LLUICtrlFactory::setCtrlParent(LLView* view, LLView* parent, S32 tab_group) parent->addChild(view, tab_group); } - -// Avoid directly using LLUI and LLDir in the template code -//static -std::string LLUICtrlFactory::findSkinnedFilename(const std::string& filename) -{ - return gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, filename); -} - //static void LLUICtrlFactory::copyName(LLXMLNodePtr src, LLXMLNodePtr dest) { diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index 1acfd24112..ca6ad254b1 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -173,18 +173,17 @@ public: static T* createFromFile(const std::string &filename, LLView *parent, const widget_registry_t& registry) { T* widget = NULL; - - std::string skinned_filename = findSkinnedFilename(filename); + instance().pushFileName(filename); { LLXMLNodePtr root_node; if (!LLUICtrlFactory::getLayeredXMLNode(filename, root_node)) { - llwarns << "Couldn't parse XUI file: " << skinned_filename << llendl; + llwarns << "Couldn't parse XUI file: " << instance().getCurFileName() << llendl; goto fail; } - + LLView* view = getInstance()->createFromXML(root_node, parent, filename, registry, NULL); if (view) { @@ -299,9 +298,6 @@ private: // this exists to get around dependency on llview static void setCtrlParent(LLView* view, LLView* parent, S32 tab_group); - // Avoid directly using LLUI and LLDir in the template code - static std::string findSkinnedFilename(const std::string& filename); - class LLPanel* mDummyPanel; std::vector mFileNames; }; -- cgit v1.2.3 From fc93c80e87ab6067b2be10ed2ae69dcd988cc7a3 Mon Sep 17 00:00:00 2001 From: Kelly Washington Date: Mon, 12 Nov 2012 14:16:45 -0800 Subject: MAINT-1897 Poor performance viewing large group member lists * LLScrollListControl to use LLAvatarNameCache instead of gCacheName --- indra/llui/llscrolllistctrl.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index b3499693dd..da371622be 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -35,6 +35,7 @@ #include "llboost.h" //#include "indra_constants.h" +#include "llavatarnamecache.h" #include "llcheckboxctrl.h" #include "llclipboard.h" #include "llfocusmgr.h" @@ -1805,7 +1806,9 @@ void LLScrollListCtrl::copyNameToClipboard(std::string id, bool is_group) } else { - gCacheName->getFullName(LLUUID(id), name); + LLAvatarName av_name; + LLAvatarNameCache::get(LLUUID(id), &av_name); + name = av_name.getLegacyName(); } LLUrlAction::copyURLToClipboard(name); } -- cgit v1.2.3 From c5f6ff43da6a7cf5a20c61c16ba0c7aaaeb5687f Mon Sep 17 00:00:00 2001 From: Kelly Washington Date: Mon, 12 Nov 2012 15:38:58 -0800 Subject: MAINT-1897 Poor performance viewing large group member lists * Improve draw performance of scroll lists by only drawing what is visible * Reduce frequency of expensive column width calculations Fixes by Richard --- indra/llui/llcombobox.cpp | 3 +- indra/llui/llscrolllistcolumn.cpp | 3 + indra/llui/llscrolllistctrl.cpp | 161 ++++++++++++++++++++++---------------- indra/llui/llscrolllistctrl.h | 28 +++---- indra/llui/llview.cpp | 12 +-- 5 files changed, 118 insertions(+), 89 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index 806d2ef3f6..41e5d74042 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -563,8 +563,7 @@ void LLComboBox::showList() S32 min_width = getRect().getWidth(); S32 max_width = llmax(min_width, MAX_COMBO_WIDTH); // make sure we have up to date content width metrics - mList->calcColumnWidths(); - S32 list_width = llclamp(mList->getMaxContentWidth(), min_width, max_width); + S32 list_width = llclamp(mList->calcMaxContentWidth(), min_width, max_width); if (mListPosition == BELOW) { diff --git a/indra/llui/llscrolllistcolumn.cpp b/indra/llui/llscrolllistcolumn.cpp index 07a6dfaa10..af124d9826 100644 --- a/indra/llui/llscrolllistcolumn.cpp +++ b/indra/llui/llscrolllistcolumn.cpp @@ -98,6 +98,7 @@ BOOL LLScrollColumnHeader::handleDoubleClick(S32 x, S32 y, MASK mask) if (canResize() && mResizeBar->getRect().pointInRect(x, y)) { // reshape column to max content width + mColumn->mParentCtrl->calcMaxContentWidth(); LLRect column_rect = getRect(); column_rect.mRight = column_rect.mLeft + mColumn->mMaxContentWidth; setShape(column_rect, true); @@ -127,6 +128,8 @@ LLView* LLScrollColumnHeader::findSnapEdge(S32& new_edge_val, const LLCoordGL& m LLRect snap_rect = getSnapRect(); + mColumn->mParentCtrl->calcMaxContentWidth(); + S32 snap_delta = mColumn->mMaxContentWidth - snap_rect.getWidth(); // x coord growing means column growing, so same signs mean we're going in right direction diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index da371622be..3e0653e9a4 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -159,15 +159,14 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p) mMouseWheelOpaque(p.mouse_wheel_opaque), mPageLines(p.page_lines), mMaxSelectable(0), - mAllowKeyboardMovement(TRUE), + mAllowKeyboardMovement(true), mCommitOnKeyboardMovement(p.commit_on_keyboard_movement), - mCommitOnSelectionChange(FALSE), - mSelectionChanged(FALSE), - mNeedsScroll(FALSE), - mCanSelect(TRUE), - mColumnsDirty(FALSE), + mCommitOnSelectionChange(false), + mSelectionChanged(false), + mNeedsScroll(false), + mCanSelect(true), + mColumnsDirty(false), mMaxItemCount(INT_MAX), - mMaxContentWidth(0), mBorderThickness( 2 ), mOnDoubleClickCallback( NULL ), mOnMaximumSelectCallback( NULL ), @@ -181,7 +180,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p) mTotalStaticColumnWidth(0), mTotalColumnPadding(0), mSorted(false), - mDirty(FALSE), + mDirty(false), mOriginalSelection(-1), mLastSelected(NULL), mHeadingHeight(p.heading_height), @@ -357,7 +356,7 @@ void LLScrollListCtrl::clearRows() mScrollLines = 0; mLastSelected = NULL; updateLayout(); - mDirty = FALSE; + mDirty = false; } @@ -592,15 +591,42 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r // NOTE: This is *very* expensive for large lists, especially when we are dirtying the list every frame // while receiving a long list of names. // *TODO: Use bookkeeping to make this an incramental cost with item additions -void LLScrollListCtrl::calcColumnWidths() +S32 LLScrollListCtrl::calcMaxContentWidth() { const S32 HEADING_TEXT_PADDING = 25; const S32 COLUMN_TEXT_PADDING = 10; - mMaxContentWidth = 0; - S32 max_item_width = 0; + ordered_columns_t::iterator column_itor; + for (column_itor = mColumnsIndexed.begin(); column_itor != mColumnsIndexed.end(); ++column_itor) + { + LLScrollListColumn* column = *column_itor; + if (!column) continue; + + if (mColumnWidthsDirty) + { + mColumnWidthsDirty = false; + // update max content width for this column, by looking at all items + column->mMaxContentWidth = column->mHeader ? LLFontGL::getFontSansSerifSmall()->getWidth(column->mLabel) + mColumnPadding + HEADING_TEXT_PADDING : 0; + item_list::iterator iter; + for (iter = mItemList.begin(); iter != mItemList.end(); iter++) + { + LLScrollListCell* cellp = (*iter)->getColumn(column->mIndex); + if (!cellp) continue; + + column->mMaxContentWidth = llmax(LLFontGL::getFontSansSerifSmall()->getWidth(cellp->getValue().asString()) + mColumnPadding + COLUMN_TEXT_PADDING, column->mMaxContentWidth); + } + } + max_item_width += column->mMaxContentWidth; + } + + return max_item_width; +} + +bool LLScrollListCtrl::updateColumnWidths() +{ + bool width_changed = false; ordered_columns_t::iterator column_itor; for (column_itor = mColumnsIndexed.begin(); column_itor != mColumnsIndexed.end(); ++column_itor) { @@ -618,23 +644,13 @@ void LLScrollListCtrl::calcColumnWidths() new_width = (mItemListRect.getWidth() - mTotalStaticColumnWidth - mTotalColumnPadding) / mNumDynamicWidthColumns; } - column->setWidth(new_width); - - // update max content width for this column, by looking at all items - column->mMaxContentWidth = column->mHeader ? LLFontGL::getFontSansSerifSmall()->getWidth(column->mLabel) + mColumnPadding + HEADING_TEXT_PADDING : 0; - item_list::iterator iter; - for (iter = mItemList.begin(); iter != mItemList.end(); iter++) + if (column->getWidth() != new_width) { - LLScrollListCell* cellp = (*iter)->getColumn(column->mIndex); - if (!cellp) continue; - - column->mMaxContentWidth = llmax(LLFontGL::getFontSansSerifSmall()->getWidth(cellp->getValue().asString()) + mColumnPadding + COLUMN_TEXT_PADDING, column->mMaxContentWidth); + column->setWidth(new_width); + width_changed = true; } - - max_item_width += column->mMaxContentWidth; } - - mMaxContentWidth = max_item_width; + return width_changed; } const S32 SCROLL_LIST_ROW_PAD = 2; @@ -670,7 +686,12 @@ void LLScrollListCtrl::updateLineHeightInsert(LLScrollListItem* itemp) void LLScrollListCtrl::updateColumns() { - calcColumnWidths(); + if (!mColumnsDirty) + return; + + mColumnsDirty = false; + + bool columns_changed_width = updateColumnWidths(); // update column headers std::vector::iterator column_ordered_it; @@ -719,20 +740,22 @@ void LLScrollListCtrl::updateColumns() } // propagate column widths to individual cells - item_list::iterator iter; - for (iter = mItemList.begin(); iter != mItemList.end(); iter++) + if (columns_changed_width) { - LLScrollListItem *itemp = *iter; - S32 num_cols = itemp->getNumColumns(); - S32 i = 0; - for (LLScrollListCell* cell = itemp->getColumn(i); i < num_cols; cell = itemp->getColumn(++i)) + item_list::iterator iter; + for (iter = mItemList.begin(); iter != mItemList.end(); iter++) { - if (i >= (S32)mColumnsIndexed.size()) break; + LLScrollListItem *itemp = *iter; + S32 num_cols = itemp->getNumColumns(); + S32 i = 0; + for (LLScrollListCell* cell = itemp->getColumn(i); i < num_cols; cell = itemp->getColumn(++i)) + { + if (i >= (S32)mColumnsIndexed.size()) break; - cell->setWidth(mColumnsIndexed[i]->getWidth()); + cell->setWidth(mColumnsIndexed[i]->getWidth()); + } } } - } void LLScrollListCtrl::setHeadingHeight(S32 heading_height) @@ -773,7 +796,7 @@ BOOL LLScrollListCtrl::selectFirstItem() { deselectItem(itemp); } - first_item = FALSE; + first_item = false; } if (mCommitOnSelectionChange) { @@ -1407,17 +1430,23 @@ void LLScrollListCtrl::drawItems() S32 cur_y = y; - S32 line = 0; S32 max_columns = 0; LLColor4 highlight_color = LLColor4::white; static LLUICachedControl type_ahead_timeout ("TypeAheadTimeout", 0); highlight_color.mV[VALPHA] = clamp_rescale(mSearchTimer.getElapsedTimeF32(), type_ahead_timeout * 0.7f, type_ahead_timeout, 0.4f, 0.f); + S32 first_line = mScrollLines; + S32 last_line = llmin((S32)mItemList.size() - 1, mScrollLines + getLinesPerPage()); + + if (first_line >= mItemList.size()) + { + return; + } item_list::iterator iter; - for (iter = mItemList.begin(); iter != mItemList.end(); iter++) + for (S32 line = first_line; line <= last_line; line++) { - LLScrollListItem* item = *iter; + LLScrollListItem* item = mItemList[line]; item_rect.setOriginAndSize( x, @@ -1481,7 +1510,6 @@ void LLScrollListCtrl::drawItems() cur_y -= mLineHeight; } - line++; } } } @@ -1497,7 +1525,7 @@ void LLScrollListCtrl::draw() if (mNeedsScroll) { scrollToShowSelected(); - mNeedsScroll = FALSE; + mNeedsScroll = false; } LLRect background(0, getRect().getHeight(), getRect().getWidth(), 0); // Draw background @@ -1508,11 +1536,7 @@ void LLScrollListCtrl::draw() gl_rect_2d(background, getEnabled() ? mBgWriteableColor.get() % alpha : mBgReadOnlyColor.get() % alpha ); } - if (mColumnsDirty) - { - updateColumns(); - mColumnsDirty = FALSE; - } + updateColumns(); getChildView("comment_text")->setVisible(mItemList.empty()); @@ -1720,7 +1744,7 @@ BOOL LLScrollListCtrl::handleMouseDown(S32 x, S32 y, MASK mask) setFocus(TRUE); // clear selection changed flag because user is starting a selection operation - mSelectionChanged = FALSE; + mSelectionChanged = false; handleClick(x, y, mask); } @@ -1738,15 +1762,15 @@ BOOL LLScrollListCtrl::handleMouseUp(S32 x, S32 y, MASK mask) if(mask == MASK_NONE) { selectItemAt(x, y, mask); - mNeedsScroll = TRUE; + mNeedsScroll = true; } } // always commit when mouse operation is completed inside list if (mItemListRect.pointInRect(x,y)) { - mDirty |= mSelectionChanged; - mSelectionChanged = FALSE; + mDirty = mDirty || mSelectionChanged; + mSelectionChanged = false; onCommit(); } @@ -1862,7 +1886,7 @@ BOOL LLScrollListCtrl::handleClick(S32 x, S32 y, MASK mask) { selectItemAt(x, y, mask); gFocusMgr.setMouseCapture(this); - mNeedsScroll = TRUE; + mNeedsScroll = true; } // propagate state of cell to rest of selected column @@ -1891,7 +1915,7 @@ BOOL LLScrollListCtrl::handleClick(S32 x, S32 y, MASK mask) // treat this as a normal single item selection selectItemAt(x, y, mask); gFocusMgr.setMouseCapture(this); - mNeedsScroll = TRUE; + mNeedsScroll = true; // do not eat click (allow double click callback) return FALSE; } @@ -1997,7 +2021,7 @@ BOOL LLScrollListCtrl::handleHover(S32 x,S32 y,MASK mask) if(mask == MASK_NONE) { selectItemAt(x, y, mask); - mNeedsScroll = TRUE; + mNeedsScroll = true; } } else @@ -2044,7 +2068,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) { // commit implicit in call selectPrevItem(FALSE); - mNeedsScroll = TRUE; + mNeedsScroll = true; handled = TRUE; } break; @@ -2053,7 +2077,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) { // commit implicit in call selectNextItem(FALSE); - mNeedsScroll = TRUE; + mNeedsScroll = true; handled = TRUE; } break; @@ -2061,7 +2085,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) if (mAllowKeyboardMovement || hasFocus()) { selectNthItem(getFirstSelectedIndex() - (mScrollbar->getPageSize() - 1)); - mNeedsScroll = TRUE; + mNeedsScroll = true; if (mCommitOnKeyboardMovement && !mCommitOnSelectionChange) { @@ -2074,7 +2098,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) if (mAllowKeyboardMovement || hasFocus()) { selectNthItem(getFirstSelectedIndex() + (mScrollbar->getPageSize() - 1)); - mNeedsScroll = TRUE; + mNeedsScroll = true; if (mCommitOnKeyboardMovement && !mCommitOnSelectionChange) { @@ -2087,7 +2111,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) if (mAllowKeyboardMovement || hasFocus()) { selectFirstItem(); - mNeedsScroll = TRUE; + mNeedsScroll = true; if (mCommitOnKeyboardMovement && !mCommitOnSelectionChange) { @@ -2100,7 +2124,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) if (mAllowKeyboardMovement || hasFocus()) { selectNthItem(getItemCount() - 1); - mNeedsScroll = TRUE; + mNeedsScroll = true; if (mCommitOnKeyboardMovement && !mCommitOnSelectionChange) { @@ -2139,7 +2163,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) } else if (selectItemByPrefix(wstring_to_utf8str(mSearchString), FALSE)) { - mNeedsScroll = TRUE; + mNeedsScroll = true; // update search string only on successful match mSearchTimer.reset(); @@ -2180,7 +2204,7 @@ BOOL LLScrollListCtrl::handleUnicodeCharHere(llwchar uni_char) if (selectItemByPrefix(wstring_to_utf8str(mSearchString + (llwchar)uni_char), FALSE)) { // update search string only on successful match - mNeedsScroll = TRUE; + mNeedsScroll = true; mSearchString += uni_char; mSearchTimer.reset(); @@ -2226,7 +2250,7 @@ BOOL LLScrollListCtrl::handleUnicodeCharHere(llwchar uni_char) if (item->getEnabled() && LLStringOps::toLower(item_label[0]) == uni_char) { selectItem(item); - mNeedsScroll = TRUE; + mNeedsScroll = true; cellp->highlightText(0, 1); mSearchTimer.reset(); @@ -2297,7 +2321,7 @@ void LLScrollListCtrl::selectItem(LLScrollListItem* itemp, BOOL select_single_it } itemp->setSelected(TRUE); mLastSelected = itemp; - mSelectionChanged = TRUE; + mSelectionChanged = true; } } @@ -2318,7 +2342,7 @@ void LLScrollListCtrl::deselectItem(LLScrollListItem* itemp) { cellp->highlightText(0, 0); } - mSelectionChanged = TRUE; + mSelectionChanged = true; } } @@ -2326,7 +2350,7 @@ void LLScrollListCtrl::commitIfChanged() { if (mSelectionChanged) { - mDirty = TRUE; + mDirty = true; mSelectionChanged = FALSE; onCommit(); } @@ -2437,7 +2461,8 @@ void LLScrollListCtrl::sortOnce(S32 column, BOOL ascending) void LLScrollListCtrl::dirtyColumns() { - mColumnsDirty = TRUE; + mColumnsDirty = true; + mColumnWidthsDirty = true; // need to keep mColumnsIndexed up to date // just in case someone indexes into it immediately @@ -3006,7 +3031,7 @@ void LLScrollListCtrl::resetDirty() void LLScrollListCtrl::onFocusReceived() { // forget latent selection changes when getting focus - mSelectionChanged = FALSE; + mSelectionChanged = false; LLUICtrl::onFocusReceived(); } diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index e83794e173..38450b6313 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -343,8 +343,8 @@ public: static void onClickColumn(void *userdata); virtual void updateColumns(); - void calcColumnWidths(); - S32 getMaxContentWidth() { return mMaxContentWidth; } + S32 calcMaxContentWidth(); + bool updateColumnWidths(); void setHeadingHeight(S32 heading_height); /** @@ -440,16 +440,17 @@ private: S32 mHeadingHeight; // the height of the column header buttons, if visible U32 mMaxSelectable; LLScrollbar* mScrollbar; - BOOL mAllowMultipleSelection; - BOOL mAllowKeyboardMovement; - BOOL mCommitOnKeyboardMovement; - BOOL mCommitOnSelectionChange; - BOOL mSelectionChanged; - BOOL mNeedsScroll; - BOOL mMouseWheelOpaque; - BOOL mCanSelect; - const BOOL mDisplayColumnHeaders; - BOOL mColumnsDirty; + bool mAllowMultipleSelection; + bool mAllowKeyboardMovement; + bool mCommitOnKeyboardMovement; + bool mCommitOnSelectionChange; + bool mSelectionChanged; + bool mNeedsScroll; + bool mMouseWheelOpaque; + bool mCanSelect; + bool mDisplayColumnHeaders; + bool mColumnsDirty; + bool mColumnWidthsDirty; mutable item_list mItemList; @@ -458,7 +459,6 @@ private: S32 mMaxItemCount; LLRect mItemListRect; - S32 mMaxContentWidth; S32 mColumnPadding; BOOL mBackgroundVisible; @@ -498,7 +498,7 @@ private: typedef std::map column_map_t; column_map_t mColumns; - BOOL mDirty; + bool mDirty; S32 mOriginalSelection; ContextMenuType mContextMenuType; diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 54843227b7..ad9bec9f61 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -1549,16 +1549,18 @@ void LLView::screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* l void LLView::localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const { - *screen_x = local_x + getRect().mLeft; - *screen_y = local_y + getRect().mBottom; + *screen_x = local_x; + *screen_y = local_y; const LLView* cur = this; - while( cur->mParentView ) + do { + LLRect cur_rect = cur->getRect(); + *screen_x += cur_rect.mLeft; + *screen_y += cur_rect.mBottom; cur = cur->mParentView; - *screen_x += cur->getRect().mLeft; - *screen_y += cur->getRect().mBottom; } + while( cur ); } void LLView::screenRectToLocal(const LLRect& screen, LLRect* local) const -- cgit v1.2.3 From 70c6b0859578dfb04d8e53656a60f242240b9cbe Mon Sep 17 00:00:00 2001 From: Kelly Washington Date: Thu, 13 Dec 2012 08:44:22 -0800 Subject: MAINT-1995 Names of banned and allowed residents are not shown in Access tab of the About Land dialog Code by Richard, reviewed by merov and kelly --- indra/llui/llscrolllistctrl.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'indra/llui') diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 3e0653e9a4..5b0894b064 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -580,6 +580,15 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r addColumn(col_params); } + S32 num_cols = item->getNumColumns(); + S32 i = 0; + for (LLScrollListCell* cell = item->getColumn(i); i < num_cols; cell = item->getColumn(++i)) + { + if (i >= (S32)mColumnsIndexed.size()) break; + + cell->setWidth(mColumnsIndexed[i]->getWidth()); + } + updateLineHeightInsert(item); updateLayout(); -- cgit v1.2.3 From 00ebeaba581c5ed1686458502091ac8a30c75237 Mon Sep 17 00:00:00 2001 From: Kelly Washington Date: Thu, 13 Dec 2012 11:14:16 -0800 Subject: Fix line endings. --- indra/llui/llscrolllistctrl.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 5b0894b064..d332aa933e 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -580,13 +580,13 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r addColumn(col_params); } - S32 num_cols = item->getNumColumns(); - S32 i = 0; - for (LLScrollListCell* cell = item->getColumn(i); i < num_cols; cell = item->getColumn(++i)) - { - if (i >= (S32)mColumnsIndexed.size()) break; - - cell->setWidth(mColumnsIndexed[i]->getWidth()); + S32 num_cols = item->getNumColumns(); + S32 i = 0; + for (LLScrollListCell* cell = item->getColumn(i); i < num_cols; cell = item->getColumn(++i)) + { + if (i >= (S32)mColumnsIndexed.size()) break; + + cell->setWidth(mColumnsIndexed[i]->getWidth()); } updateLineHeightInsert(item); -- cgit v1.2.3