diff options
Diffstat (limited to 'indra/llui')
49 files changed, 455 insertions, 274 deletions
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index 7fb1db15fb..8054eb3619 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -3,6 +3,7 @@ project(llui) include(00-Common) +include(Hunspell) include(LLCommon) include(LLImage) include(LLInventory) @@ -294,7 +295,11 @@ if(LL_TESTS) ) LL_ADD_PROJECT_UNIT_TESTS(llui "${llui_TEST_SOURCE_FILES}") # INTEGRATION TESTS - set(test_libs llui llmessage llcorehttp llcommon ${LLCOMMON_LIBRARIES} ${BOOST_COROUTINE_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ${BOOST_SYSTEM_LIBRARY} ${WINDOWS_LIBRARIES}) + set(test_libs llui llmessage llcorehttp llcommon + ${HUNSPELL_LIBRARY} + ${LLCOMMON_LIBRARIES} + ${BOOST_COROUTINE_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ${BOOST_SYSTEM_LIBRARY} + ${WINDOWS_LIBRARIES}) if(NOT LINUX) LL_ADD_INTEGRATION_TEST(llurlentry llurlentry.cpp "${test_libs}") endif(NOT LINUX) diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp index 53720a6044..f8ef5289db 100644 --- a/indra/llui/llaccordionctrltab.cpp +++ b/indra/llui/llaccordionctrltab.cpp @@ -361,6 +361,7 @@ LLAccordionCtrlTab::LLAccordionCtrlTab(const LLAccordionCtrlTab::Params&p) { mStoredOpenCloseState = false; mWasStateStored = false; + mSkipChangesOnNotifyParent = false; mDropdownBGColor = LLColor4::white; LLAccordionCtrlTabHeader::Params headerParams; @@ -691,7 +692,7 @@ S32 LLAccordionCtrlTab::notifyParent(const LLSD& info) mExpandedHeight = height; - if(isExpanded()) + if(isExpanded() && !mSkipChangesOnNotifyParent) { LLRect panel_rect = getRect(); panel_rect.setLeftTopAndSize( panel_rect.mLeft, panel_rect.mTop, panel_rect.getWidth(), height); diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h index 7a78700e0f..0263bce4be 100644 --- a/indra/llui/llaccordionctrltab.h +++ b/indra/llui/llaccordionctrltab.h @@ -195,6 +195,8 @@ public: void setFitPanel( bool fit ) { mFitPanel = true; } bool getFitParent() const { return mFitPanel; } + void setIgnoreResizeNotification(bool ignore) { mSkipChangesOnNotifyParent = ignore;} + protected: void adjustContainerPanel (const LLRect& child_rect); void adjustContainerPanel (); @@ -235,6 +237,7 @@ private: bool mStoredOpenCloseState; bool mWasStateStored; + bool mSkipChangesOnNotifyParent; bool mSelectionEnabled; diff --git a/indra/llui/llclipboard.cpp b/indra/llui/llclipboard.cpp index 1d18cb2bb0..06fac190ed 100644 --- a/indra/llui/llclipboard.cpp +++ b/indra/llui/llclipboard.cpp @@ -123,7 +123,15 @@ bool LLClipboard::copyToClipboard(const LLWString &src, S32 pos, S32 len, bool u // Concatenate the input string to the LL and the system clipboard bool LLClipboard::addToClipboard(const LLWString &src, S32 pos, S32 len, bool use_primary) { - mString = src.substr(pos, len); + try + { + mString = src.substr(pos, len); + } + catch (const std::exception& e) + { + LL_WARNS() << "Can't add the substring to clipboard: " << e.what() << LL_ENDL; + return false; + } return (use_primary ? LLView::getWindow()->copyTextToPrimary(mString) : LLView::getWindow()->copyTextToClipboard(mString)); } diff --git a/indra/llui/llclipboard.h b/indra/llui/llclipboard.h index 58d80e2687..a668ac1ac6 100644 --- a/indra/llui/llclipboard.h +++ b/indra/llui/llclipboard.h @@ -48,10 +48,10 @@ class LLClipboard : public LLSingleton<LLClipboard> { -public: - LLClipboard(); + LLSINGLETON(LLClipboard); ~LLClipboard(); +public: // Clears the clipboard void reset(); // Returns the state of the clipboard so client can know if it has been modified (comparing with tracked state) diff --git a/indra/llui/llcommandmanager.h b/indra/llui/llcommandmanager.h index f2f2145953..8cec5e2b24 100644 --- a/indra/llui/llcommandmanager.h +++ b/indra/llui/llcommandmanager.h @@ -173,6 +173,9 @@ private: class LLCommandManager : public LLSingleton<LLCommandManager> { + LLSINGLETON(LLCommandManager); + ~LLCommandManager(); + public: struct Params : public LLInitParam::Block<Params> { @@ -184,9 +187,6 @@ public: } }; - LLCommandManager(); - ~LLCommandManager(); - U32 commandCount() const; LLCommand * getCommand(U32 commandIndex); LLCommand * getCommand(const LLCommandId& commandId); diff --git a/indra/llui/llcontainerview.h b/indra/llui/llcontainerview.h index ac92b19977..99267d978a 100644 --- a/indra/llui/llcontainerview.h +++ b/indra/llui/llcontainerview.h @@ -35,7 +35,9 @@ class LLScrollContainer; struct ContainerViewRegistry : public LLChildRegistry<ContainerViewRegistry> -{}; +{ + LLSINGLETON_EMPTY_CTOR(ContainerViewRegistry); +}; class LLContainerView : public LLView { diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp index 299f5e42d4..5e00bf7f45 100644 --- a/indra/llui/llflatlistview.cpp +++ b/indra/llui/llflatlistview.cpp @@ -105,6 +105,81 @@ bool LLFlatListView::addItem(LLPanel * item, const LLSD& value /*= LLUUID::null* return true; } +bool LLFlatListView::addItemPairs(pairs_list_t panel_list, bool rearrange /*= true*/) +{ + if (!mItemComparator) + { + LL_WARNS_ONCE() << "No comparator specified for inserting FlatListView items." << LL_ENDL; + return false; + } + if (panel_list.size() == 0) + { + return false; + } + + // presort list so that it will be easier to sort elements into mItemPairs + panel_list.sort(ComparatorAdaptor(*mItemComparator)); + + pairs_const_iterator_t new_pair_it = panel_list.begin(); + item_pair_t* new_pair = *new_pair_it; + pairs_iterator_t pair_it = mItemPairs.begin(); + item_pair_t* item_pair = *pair_it; + + // sort panel_list into mItemPars + while (new_pair_it != panel_list.end() && pair_it != mItemPairs.end()) + { + if (!new_pair->first || new_pair->first->getParent() == mItemsPanel) + { + // iterator already used or we are reusing existing panel + new_pair_it++; + new_pair = *new_pair_it; + } + else if (mItemComparator->compare(new_pair->first, item_pair->first)) + { + LLPanel* panel = new_pair->first; + + mItemPairs.insert(pair_it, new_pair); + mItemsPanel->addChild(panel); + + //_4 is for MASK + panel->setMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, new_pair, _4)); + panel->setRightMouseDownCallback(boost::bind(&LLFlatListView::onItemRightMouseClick, this, new_pair, _4)); + // Children don't accept the focus + panel->setTabStop(false); + } + else + { + pair_it++; + item_pair = *pair_it; + } + } + + // Add what is left of panel_list into the end of mItemPairs. + for (; new_pair_it != panel_list.end(); ++new_pair_it) + { + item_pair_t* item_pair = *new_pair_it; + LLPanel *panel = item_pair->first; + if (panel && panel->getParent() != mItemsPanel) + { + mItemPairs.push_back(item_pair); + mItemsPanel->addChild(panel); + + //_4 is for MASK + panel->setMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, item_pair, _4)); + panel->setRightMouseDownCallback(boost::bind(&LLFlatListView::onItemRightMouseClick, this, item_pair, _4)); + // Children don't accept the focus + panel->setTabStop(false); + } + } + + if (rearrange) + { + rearrangeItems(); + notifyParentItemsRectChanged(); + } + return true; +} + bool LLFlatListView::insertItemAfter(LLPanel* after_item, LLPanel* item_to_add, const LLSD& value /*= LLUUID::null*/) { @@ -1289,6 +1364,28 @@ void LLFlatListViewEx::setFilterSubString(const std::string& filter_str) } } +void LLFlatListViewEx::updateItemVisibility(LLPanel* item, const LLSD &action) +{ + if (!item) return; + + // 0 signifies that filter is matched, + // i.e. we don't hide items that don't support 'match_filter' action, separators etc. + if (0 == item->notify(action)) + { + mHasMatchedItems = true; + item->setVisible(true); + } + else + { + // TODO: implement (re)storing of current selection. + if (!mForceShowingUnmatchedItems) + { + selectItem(item, false); + } + item->setVisible(mForceShowingUnmatchedItems); + } +} + void LLFlatListViewEx::filterItems() { typedef std::vector <LLPanel*> item_panel_list_t; @@ -1309,22 +1406,7 @@ void LLFlatListViewEx::filterItems() iter != iter_end; ++iter) { LLPanel* pItem = (*iter); - // 0 signifies that filter is matched, - // i.e. we don't hide items that don't support 'match_filter' action, separators etc. - if (0 == pItem->notify(action)) - { - mHasMatchedItems = true; - pItem->setVisible(true); - } - else - { - // TODO: implement (re)storing of current selection. - if(!mForceShowingUnmatchedItems) - { - selectItem(pItem, false); - } - pItem->setVisible(mForceShowingUnmatchedItems); - } + updateItemVisibility(pItem, action); } sort(); diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h index 92bf429031..230ea200d8 100644 --- a/indra/llui/llflatlistview.h +++ b/indra/llui/llflatlistview.h @@ -351,6 +351,8 @@ protected: virtual bool removeItemPair(item_pair_t* item_pair, bool rearrange); + bool addItemPairs(pairs_list_t panel_list, bool rearrange = true); + /** * Notify parent about changed size of internal controls with "size_changes" action * @@ -480,6 +482,7 @@ public: * Sets up new filter string and filters the list. */ void setFilterSubString(const std::string& filter_str); + std::string getFilterSubString() { return mFilterSubString; } /** * Filters the list, rearranges and notifies parent about shape changes. @@ -503,6 +506,14 @@ protected: */ void updateNoItemsMessage(const std::string& filter_string); + /** + * Applies visibility acording to action and LLFlatListView settings. + * + * @param item - item we are changing + * @param item - action - parameters to determin visibility from + */ + void updateItemVisibility(LLPanel* item, const LLSD &action); + private: std::string mNoFilteredItemsMsg; std::string mNoItemsMsg; diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 5ea9f5b6cc..3ece1c12bf 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -64,8 +64,6 @@ // use this to control "jumping" behavior when Ctrl-Tabbing const S32 TABBED_FLOATER_OFFSET = 0; -extern LLControlGroup gSavedSettings; - namespace LLInitParam { void TypeValues<LLFloaterEnums::EOpenPositioning>::declareValues() @@ -653,13 +651,7 @@ void LLFloater::openFloater(const LLSD& key) && !getFloaterHost() && (!getVisible() || isMinimized())) { - //Don't play a sound for incoming voice call based upon chat preference setting - bool playSound = !(getName() == "incoming call" && gSavedSettings.getBOOL("PlaySoundIncomingVoiceCall") == FALSE); - - if(playSound) - { - make_ui_sound("UISndWindowOpen"); - } + make_ui_sound("UISndWindowOpen"); } //RN: for now, we don't allow rehosting from one multifloater to another @@ -2263,7 +2255,7 @@ void LLFloaterView::reshape(S32 width, S32 height, BOOL called_from_parent) for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) { LLView* viewp = *child_it; - LLFloater* floaterp = (LLFloater*)viewp; + LLFloater* floaterp = dynamic_cast<LLFloater*>(viewp); if (floaterp->isDependent()) { // dependents are moved with their "dependee" @@ -2318,10 +2310,14 @@ void LLFloaterView::reshape(S32 width, S32 height, BOOL called_from_parent) void LLFloaterView::restoreAll() { // make sure all subwindows aren't minimized - for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) + child_list_t child_list = *(getChildList()); + for (child_list_const_iter_t child_it = child_list.begin(); child_it != child_list.end(); ++child_it) { - LLFloater* floaterp = (LLFloater*)*child_it; - floaterp->setMinimized(FALSE); + LLFloater* floaterp = dynamic_cast<LLFloater*>(*child_it); + if (floaterp) + { + floaterp->setMinimized(FALSE); + } } // *FIX: make sure dependents are restored @@ -2597,7 +2593,7 @@ void LLFloaterView::getMinimizePosition(S32 *left, S32 *bottom) ++child_it) //loop floaters { // Examine minimized children. - LLFloater* floater = (LLFloater*)((LLView*)*child_it); + LLFloater* floater = dynamic_cast<LLFloater*>(*child_it); if(floater->isMinimized()) { LLRect r = floater->getRect(); @@ -2650,7 +2646,7 @@ void LLFloaterView::closeAllChildren(bool app_quitting) continue; } - LLFloater* floaterp = (LLFloater*)viewp; + LLFloater* floaterp = dynamic_cast<LLFloater*>(viewp); // Attempt to close floater. This will cause the "do you want to save" // dialogs to appear. @@ -2716,8 +2712,7 @@ BOOL LLFloaterView::allChildrenClosed() // by setting themselves invisible) for (child_list_const_iter_t it = getChildList()->begin(); it != getChildList()->end(); ++it) { - LLView* viewp = *it; - LLFloater* floaterp = (LLFloater*)viewp; + LLFloater* floaterp = dynamic_cast<LLFloater*>(*it); if (floaterp->getVisible() && !floaterp->isDead() && floaterp->isCloseable()) { @@ -2953,7 +2948,7 @@ void LLFloaterView::syncFloaterTabOrder() // otherwise, make sure the focused floater is in the front of the child list for ( child_list_const_reverse_iter_t child_it = getChildList()->rbegin(); child_it != getChildList()->rend(); ++child_it) { - LLFloater* floaterp = (LLFloater*)*child_it; + LLFloater* floaterp = dynamic_cast<LLFloater*>(*child_it); if (gFocusMgr.childHasKeyboardFocus(floaterp)) { bringToFront(floaterp, FALSE); @@ -2975,7 +2970,7 @@ LLFloater* LLFloaterView::getParentFloater(LLView* viewp) const if (parentp == this) { - return (LLFloater*)viewp; + return dynamic_cast<LLFloater*>(viewp); } return NULL; diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp index 1a51b96fdf..1b213c3418 100644 --- a/indra/llui/llfocusmgr.cpp +++ b/indra/llui/llfocusmgr.cpp @@ -186,7 +186,6 @@ void LLFocusMgr::releaseFocusIfNeeded( LLView* view ) LLUI::removePopup(view); } - void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL keystrokes_only) { // notes if keyboard focus is changed again (by onFocusLost/onFocusReceived) diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp index 8166ef6a07..f9664e0658 100644 --- a/indra/llui/llfolderview.cpp +++ b/indra/llui/llfolderview.cpp @@ -684,6 +684,13 @@ void LLFolderView::draw() } } + if (mRenameItem && mRenamer && mRenamer->getVisible() && !getVisibleRect().overlaps(mRenamer->getRect())) + { + // renamer is not connected to the item we are renaming in any form so manage it manually + // TODO: consider stopping on any scroll action instead of when out of visible area + finishRenamingItem(); + } + // skip over LLFolderViewFolder::draw since we don't want the folder icon, label, // and arrow for the root folder LLView::draw(); diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp index 5eb5ca4f82..3d618548c4 100644 --- a/indra/llui/llfolderviewitem.cpp +++ b/indra/llui/llfolderviewitem.cpp @@ -127,6 +127,8 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p) mIsSelected( FALSE ), mIsCurSelection( FALSE ), mSelectPending(FALSE), + mIsItemCut(false), + mCutGeneration(0), mLabelStyle( LLFontGL::NORMAL ), mHasVisibleChildren(FALSE), mIsFolderComplete(true), @@ -694,6 +696,19 @@ void LLFolderViewItem::drawOpenFolderArrow(const Params& default_params, const L return mIsCurSelection; } +/*virtual*/ bool LLFolderViewItem::isFadeItem() +{ + LLClipboard& clipboard = LLClipboard::instance(); + if (mCutGeneration != clipboard.getGeneration()) + { + mCutGeneration = clipboard.getGeneration(); + mIsItemCut = clipboard.isCutMode() + && ((getParentFolder() && getParentFolder()->isFadeItem()) + || getViewModelItem()->isCutToClipboard()); + } + return mIsItemCut; +} + void LLFolderViewItem::drawHighlight(const BOOL showContent, const BOOL hasKeyboardFocus, const LLUIColor &selectColor, const LLUIColor &flashColor, const LLUIColor &focusOutlineColor, const LLUIColor &mouseOverColor) { @@ -875,6 +890,12 @@ void LLFolderViewItem::draw() } LLColor4 color = (mIsSelected && filled) ? mFontHighlightColor : mFontColor; + + if (isFadeItem()) + { + // Fade out item color to indicate it's being cut + color.mV[VALPHA] *= 0.5f; + } drawLabel(font, text_left, y, color, right_x); //--------------------------------------------------------------------------------// @@ -882,7 +903,7 @@ void LLFolderViewItem::draw() // if (!mLabelSuffix.empty()) { - font->renderUTF8( mLabelSuffix, 0, right_x, y, sSuffixColor, + font->renderUTF8( mLabelSuffix, 0, right_x, y, isFadeItem() ? color : (LLColor4)sSuffixColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, &right_x, FALSE ); } diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h index 0322c8836d..61c39e0175 100644 --- a/indra/llui/llfolderviewitem.h +++ b/indra/llui/llfolderviewitem.h @@ -121,8 +121,11 @@ protected: mIsMouseOverTitle, mAllowWear, mAllowDrop, - mSelectPending; - + mSelectPending, + mIsItemCut; + + S32 mCutGeneration; + LLUIColor mFontColor; LLUIColor mFontHighlightColor; @@ -145,6 +148,7 @@ protected: virtual void addFolder(LLFolderViewFolder*) { } virtual bool isHighlightAllowed(); virtual bool isHighlightActive(); + virtual bool isFadeItem(); virtual bool isFlashing() { return false; } virtual void setFlashState(bool) { } diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h index a395af537a..641241a88c 100644 --- a/indra/llui/llfolderviewmodel.h +++ b/indra/llui/llfolderviewmodel.h @@ -173,6 +173,7 @@ public: virtual BOOL isItemCopyable() const = 0; virtual BOOL copyToClipboard() const = 0; virtual BOOL cutToClipboard() = 0; + virtual bool isCutToClipboard() { return false; }; virtual BOOL isClipboardPasteable() const = 0; virtual void pasteFromClipboard() = 0; diff --git a/indra/llui/llfunctorregistry.h b/indra/llui/llfunctorregistry.h index f5364f4863..e43974bc52 100644 --- a/indra/llui/llfunctorregistry.h +++ b/indra/llui/llfunctorregistry.h @@ -53,14 +53,8 @@ template <typename FUNCTOR_TYPE> class LLFunctorRegistry : public LLSingleton<LLFunctorRegistry<FUNCTOR_TYPE> > { - friend class LLSingleton<LLFunctorRegistry>; + LLSINGLETON(LLFunctorRegistry); LOG_CLASS(LLFunctorRegistry); -private: - LLFunctorRegistry() : LOGFUNCTOR("LogFunctor"), DONOTHING("DoNothing") - { - mMap[LOGFUNCTOR] = log_functor; - mMap[DONOTHING] = do_nothing; - } public: typedef FUNCTOR_TYPE ResponseFunctor; @@ -125,6 +119,14 @@ private: }; template <typename FUNCTOR_TYPE> +LLFunctorRegistry<FUNCTOR_TYPE>::LLFunctorRegistry() : + LOGFUNCTOR("LogFunctor"), DONOTHING("DoNothing") +{ + mMap[LOGFUNCTOR] = log_functor; + mMap[DONOTHING] = do_nothing; +} + +template <typename FUNCTOR_TYPE> class LLFunctorRegistration { public: diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h index a245ebe1b9..f772dbc6b4 100644 --- a/indra/llui/lllayoutstack.h +++ b/indra/llui/lllayoutstack.h @@ -40,7 +40,9 @@ class LLLayoutStack : public LLView, public LLInstanceTracker<LLLayoutStack> public: struct LayoutStackRegistry : public LLChildRegistry<LayoutStackRegistry> - {}; + { + LLSINGLETON_EMPTY_CTOR(LayoutStackRegistry); + }; struct Params : public LLInitParam::Block<Params, LLView::Params> { diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index a08cf91a69..becb45fa79 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -163,6 +163,9 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) { llassert( mMaxLengthBytes > 0 ); + LLUICtrl::setEnabled(TRUE); + setEnabled(p.enabled); + mScrollTimer.reset(); mTripleClickTimer.reset(); setText(p.default_text()); @@ -218,6 +221,13 @@ LLLineEditor::~LLLineEditor() gFocusMgr.releaseFocusIfNeeded( this ); } +void LLLineEditor::initFromParams(const LLLineEditor::Params& params) +{ + LLUICtrl::initFromParams(params); + LLUICtrl::setEnabled(TRUE); + setEnabled(params.enabled); +} + void LLLineEditor::onFocusReceived() { gEditMenuHandler = this; @@ -400,12 +410,7 @@ void LLLineEditor::setText(const LLStringExplicit &new_text) if (mMaxLengthChars) { - LLWString truncated_wstring = utf8str_to_wstring(truncated_utf8); - if (truncated_wstring.size() > (U32)mMaxLengthChars) - { - truncated_wstring = truncated_wstring.substr(0, mMaxLengthChars); - } - mText.assign(wstring_to_utf8str(truncated_wstring)); + mText.assign(utf8str_symbol_truncate(truncated_utf8, mMaxLengthChars)); } if (all_selected) @@ -2641,10 +2646,17 @@ void LLLineEditor::showContextMenu(S32 x, S32 y) void LLLineEditor::setContextMenu(LLContextMenu* new_context_menu) { - if (new_context_menu) - mContextMenuHandle = new_context_menu->getHandle(); - else - mContextMenuHandle.markDead(); + LLContextMenu* menu = static_cast<LLContextMenu*>(mContextMenuHandle.get()); + if (menu) + { + menu->die(); + mContextMenuHandle.markDead(); + } + + if (new_context_menu) + { + mContextMenuHandle = new_context_menu->getHandle(); + } } void LLLineEditor::setFont(const LLFontGL* font) diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index c6d472f59b..88468503df 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -108,6 +108,9 @@ public: Params(); }; + + void initFromParams(const LLLineEditor::Params& params); + protected: LLLineEditor(const Params&); friend class LLUICtrlFactory; @@ -272,7 +275,7 @@ public: void setReplaceNewlinesWithSpaces(BOOL replace); - void setContextMenu(LLContextMenu* new_context_menu); + void resetContextMenu() { setContextMenu(NULL); }; private: // private helper methods @@ -308,6 +311,8 @@ private: virtual S32 getPreeditFontSize() const; virtual LLWString getPreeditString() const { return getWText(); } + void setContextMenu(LLContextMenu* new_context_menu); + protected: LLUIString mText; // The string being edited. std::string mPrevText; // Saved string for 'ESC' revert diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 628dedb906..c7f7f6848c 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -347,7 +347,9 @@ private: // child widget registry struct MenuRegistry : public LLChildRegistry<MenuRegistry> -{}; +{ + LLSINGLETON_EMPTY_CTOR(MenuRegistry); +}; class LLMenuGL diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 354add0b82..024332ee65 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -884,9 +884,9 @@ class LLNotifications : public LLSingleton<LLNotifications>, public LLNotificationChannelBase { + LLSINGLETON(LLNotifications); LOG_CLASS(LLNotifications); - friend class LLSingleton<LLNotifications>; public: // Needed to clear up RefCounted things prior to actual destruction @@ -966,8 +966,6 @@ public: bool isVisibleByRules(LLNotificationPtr pNotification); private: - // we're a singleton, so we don't have a public constructor - LLNotifications(); /*virtual*/ void initSingleton(); void loadPersistentNotifications(); diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index c2185f24de..b8f47ef6ba 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -268,8 +268,9 @@ typedef boost::function<LLPanel* (void)> LLPanelClassCreatorFunc; class LLRegisterPanelClass : public LLSingleton< LLRegisterPanelClass > { + LLSINGLETON_EMPTY_CTOR(LLRegisterPanelClass); public: - // reigister with either the provided builder, or the generic templated builder + // register with either the provided builder, or the generic templated builder void addPanelClass(const std::string& tag,LLPanelClassCreatorFunc func) { mPanelClassesNames[tag] = func; diff --git a/indra/llui/llresmgr.h b/indra/llui/llresmgr.h index a652dcd2c0..b19d8d40b8 100644 --- a/indra/llui/llresmgr.h +++ b/indra/llui/llresmgr.h @@ -42,9 +42,9 @@ enum LLLOCALE_ID class LLResMgr : public LLSingleton<LLResMgr> { -public: - LLResMgr(); + LLSINGLETON(LLResMgr); +public: void setLocale( LLLOCALE_ID locale_id ); LLLOCALE_ID getLocale() const { return mLocale; } diff --git a/indra/llui/llscrollcontainer.h b/indra/llui/llscrollcontainer.h index f64cf43a8e..c4c4d0a136 100644 --- a/indra/llui/llscrollcontainer.h +++ b/indra/llui/llscrollcontainer.h @@ -48,7 +48,9 @@ class LLUICtrlFactory; *****************************************************************************/ struct ScrollContainerRegistry : public LLChildRegistry<ScrollContainerRegistry> -{}; +{ + LLSINGLETON_EMPTY_CTOR(ScrollContainerRegistry); +}; class LLScrollContainer : public LLUICtrl { diff --git a/indra/llui/llspellcheck.h b/indra/llui/llspellcheck.h index 4ab80195ea..acac589e43 100644 --- a/indra/llui/llspellcheck.h +++ b/indra/llui/llspellcheck.h @@ -29,16 +29,15 @@ #include "llsingleton.h" #include "llui.h" +#include "llinitdestroyclass.h" #include <boost/signals2.hpp> class Hunspell; class LLSpellChecker : public LLSingleton<LLSpellChecker>, public LLInitClass<LLSpellChecker> { - friend class LLSingleton<LLSpellChecker>; + LLSINGLETON(LLSpellChecker); friend class LLInitClass<LLSpellChecker>; -protected: - LLSpellChecker(); ~LLSpellChecker(); public: diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp index 8b1ba406c8..d49e216898 100644 --- a/indra/llui/llspinctrl.cpp +++ b/indra/llui/llspinctrl.cpp @@ -153,7 +153,7 @@ F32 clamp_precision(F32 value, S32 decimal_precision) for (S32 i = 0; i < decimal_precision; i++) clamped_value *= 10.0; - clamped_value = ll_round((F32)clamped_value); + clamped_value = ll_round(clamped_value); for (S32 i = 0; i < decimal_precision; i++) clamped_value /= 10.0; diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp index 35f5330a3f..6c8e63442b 100644 --- a/indra/llui/llstatbar.cpp +++ b/indra/llui/llstatbar.cpp @@ -40,6 +40,7 @@ #include "lltooltip.h" #include "lllocalcliprect.h" #include <iostream> +#include "lltrans.h" // rate at which to update display of value that is rapidly changing const F32 MEAN_VALUE_UPDATE_TIME = 1.f / 4.f; @@ -619,19 +620,19 @@ void LLStatBar::drawLabelAndValue( F32 value, std::string &label, LLRect &bar_re std::string value_str = !llisnan(value) ? llformat("%10.*f %s", decimal_digits, value, label.c_str()) - : "n/a"; + : LLTrans::getString("na"); // Draw the current value. if (mOrientation == HORIZONTAL) { LLFontGL::getFontMonospace()->renderUTF8(value_str, 0, bar_rect.mRight, getRect().getHeight(), - LLColor4(1.f, 1.f, 1.f, 0.5f), + LLColor4(1.f, 1.f, 1.f, 1.f), LLFontGL::RIGHT, LLFontGL::TOP); } else { LLFontGL::getFontMonospace()->renderUTF8(value_str, 0, bar_rect.mRight, getRect().getHeight(), - LLColor4(1.f, 1.f, 1.f, 0.5f), + LLColor4(1.f, 1.f, 1.f, 1.f), LLFontGL::RIGHT, LLFontGL::TOP); } } diff --git a/indra/llui/llstatgraph.h b/indra/llui/llstatgraph.h index f381e92a4d..ba7cfc5d10 100644 --- a/indra/llui/llstatgraph.h +++ b/indra/llui/llstatgraph.h @@ -126,7 +126,7 @@ private: F32 mValue; LLUIColor mColor; - bool operator <(const Threshold& other) + bool operator <(const Threshold& other) const { return mValue < other.mValue; } diff --git a/indra/llui/llstatview.h b/indra/llui/llstatview.h index bc78d3b5fd..af4db7d7ea 100644 --- a/indra/llui/llstatview.h +++ b/indra/llui/llstatview.h @@ -35,7 +35,9 @@ class LLStatBar; // widget registrars struct StatViewRegistry : public LLChildRegistry<StatViewRegistry> -{}; +{ + LLSINGLETON_EMPTY_CTOR(StatViewRegistry); +}; class LLStatView : public LLContainerView { diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index c7d7535f87..20be739286 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -181,7 +181,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p) mMaxTextByteLength( p.max_text_length ), mFont(p.font), mFontShadow(p.font_shadow), - mPopupMenu(NULL), + mPopupMenuHandle(), mReadOnly(p.read_only), mSpellCheck(p.spellcheck), mSpellCheckStart(-1), @@ -1263,9 +1263,10 @@ void LLTextBase::setReadOnlyColor(const LLColor4 &c) //virtual void LLTextBase::onVisibilityChange( BOOL new_visibility ) { - if(!new_visibility && mPopupMenu) + LLContextMenu* menu = static_cast<LLContextMenu*>(mPopupMenuHandle.get()); + if(!new_visibility && menu) { - mPopupMenu->hide(); + menu->hide(); } LLUICtrl::onVisibilityChange(new_visibility); } @@ -1956,41 +1957,48 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url) registrar.add("Url.CopyUrl", boost::bind(&LLUrlAction::copyURLToClipboard, url)); // create and return the context menu from the XUI file - delete mPopupMenu; + + LLContextMenu* menu = static_cast<LLContextMenu*>(mPopupMenuHandle.get()); + if (menu) + { + menu->die(); + mPopupMenuHandle.markDead(); + } llassert(LLMenuGL::sMenuContainer != NULL); - mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(xui_file, LLMenuGL::sMenuContainer, - LLMenuHolderGL::child_registry_t::instance()); - if (mIsFriendSignal) - { - bool isFriend = *(*mIsFriendSignal)(LLUUID(LLUrlAction::getUserID(url))); - LLView* addFriendButton = mPopupMenu->getChild<LLView>("add_friend"); - LLView* removeFriendButton = mPopupMenu->getChild<LLView>("remove_friend"); + menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(xui_file, LLMenuGL::sMenuContainer, + LLMenuHolderGL::child_registry_t::instance()); + if (menu) + { + mPopupMenuHandle = menu->getHandle(); - if (addFriendButton && removeFriendButton) - { - addFriendButton->setEnabled(!isFriend); - removeFriendButton->setEnabled(isFriend); - } - } + if (mIsFriendSignal) + { + bool isFriend = *(*mIsFriendSignal)(LLUUID(LLUrlAction::getUserID(url))); + LLView* addFriendButton = menu->getChild<LLView>("add_friend"); + LLView* removeFriendButton = menu->getChild<LLView>("remove_friend"); - if (mIsObjectBlockedSignal) - { - bool is_blocked = *(*mIsObjectBlockedSignal)(LLUUID(LLUrlAction::getObjectId(url)), LLUrlAction::getObjectName(url)); - LLView* blockButton = mPopupMenu->getChild<LLView>("block_object"); - LLView* unblockButton = mPopupMenu->getChild<LLView>("unblock_object"); + if (addFriendButton && removeFriendButton) + { + addFriendButton->setEnabled(!isFriend); + removeFriendButton->setEnabled(isFriend); + } + } - if (blockButton && unblockButton) - { - blockButton->setVisible(!is_blocked); - unblockButton->setVisible(is_blocked); - } - } - - if (mPopupMenu) - { - mPopupMenu->show(x, y); - LLMenuGL::showPopup(this, mPopupMenu, x, y); - } + if (mIsObjectBlockedSignal) + { + bool is_blocked = *(*mIsObjectBlockedSignal)(LLUUID(LLUrlAction::getObjectId(url)), LLUrlAction::getObjectName(url)); + LLView* blockButton = menu->getChild<LLView>("block_object"); + LLView* unblockButton = menu->getChild<LLView>("unblock_object"); + + if (blockButton && unblockButton) + { + blockButton->setVisible(!is_blocked); + unblockButton->setVisible(is_blocked); + } + } + menu->show(x, y); + LLMenuGL::showPopup(this, menu, x, y); + } } void LLTextBase::setText(const LLStringExplicit &utf8str, const LLStyle::Params& input_params) diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 85641fd899..3d3a6ca869 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -673,7 +673,7 @@ protected: S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes // support widgets - LLContextMenu* mPopupMenu; + LLHandle<LLContextMenu> mPopupMenuHandle; LLView* mDocumentView; LLScrollContainer* mScroller; diff --git a/indra/llui/lltextparser.h b/indra/llui/lltextparser.h index 400aeeb8be..3d71e40452 100644 --- a/indra/llui/lltextparser.h +++ b/indra/llui/lltextparser.h @@ -37,14 +37,14 @@ class LLColor4; class LLTextParser : public LLSingleton<LLTextParser> { + LLSINGLETON(LLTextParser); + public: typedef enum e_condition_type { CONTAINS, MATCHES, STARTS_WITH, ENDS_WITH } EConditionType; typedef enum e_highlight_type { PART, ALL } EHighlightType; typedef enum e_highlight_position { WHOLE, START, MIDDLE, END } EHighlightPosition; typedef enum e_dialog_action { ACTION_NONE, ACTION_CLOSE, ACTION_ADD, ACTION_COPY, ACTION_UPDATE } EDialogAction; - LLTextParser(); - LLSD parsePartialLineHighlights(const std::string &text,const LLColor4 &color, EHighlightPosition part=WHOLE, S32 index=0); bool parseFullLineHighlights(const std::string &text, LLColor4 *color); diff --git a/indra/llui/lltextvalidate.cpp b/indra/llui/lltextvalidate.cpp index 324ceb7fba..bfe0a5bb5d 100644 --- a/indra/llui/lltextvalidate.cpp +++ b/indra/llui/lltextvalidate.cpp @@ -328,6 +328,15 @@ namespace LLTextValidate return rv; } + bool validateASCIINoLeadingSpace(const LLWString &str) + { + if (LLStringOps::isSpace(str[0])) + { + return FALSE; + } + return validateASCII(str); + } + // Used for multiline text stored on the server. // Example is landmark description in Places SP. bool validateASCIIWithNewLine(const LLWString &str) diff --git a/indra/llui/lltextvalidate.h b/indra/llui/lltextvalidate.h index 5c830d7db3..e2b6c313d6 100644 --- a/indra/llui/lltextvalidate.h +++ b/indra/llui/lltextvalidate.h @@ -52,6 +52,7 @@ namespace LLTextValidate bool validateASCIIPrintableNoPipe(const LLWString &str); bool validateASCIIPrintableNoSpace(const LLWString &str); bool validateASCII(const LLWString &str); + bool validateASCIINoLeadingSpace(const LLWString &str); bool validateASCIIWithNewLine(const LLWString &str); } diff --git a/indra/llui/lltooltip.h b/indra/llui/lltooltip.h index fad127fc4c..0b1fbe5367 100644 --- a/indra/llui/lltooltip.h +++ b/indra/llui/lltooltip.h @@ -129,9 +129,10 @@ public: class LLToolTipMgr : public LLSingleton<LLToolTipMgr> { + LLSINGLETON(LLToolTipMgr); LOG_CLASS(LLToolTipMgr); + public: - LLToolTipMgr(); void show(const LLToolTip::Params& params); void show(const std::string& message); diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index aabc7ed2e4..770f13c1c3 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -60,6 +60,7 @@ #include "llflyoutbutton.h" #include "llsearcheditor.h" #include "lltoolbar.h" +#include "llcleanup.h" // for XUIParse #include "llquaternion.h" @@ -208,7 +209,7 @@ void LLUI::initClass(const settings_map_t& settings, void LLUI::cleanupClass() { - LLRender2D::cleanupClass(); + SUBSYSTEM_CLEANUP(LLRender2D); } void LLUI::setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t& remove_popup, const clear_popups_t& clear_popups) @@ -522,7 +523,7 @@ const LLView* LLUI::resolvePath(const LLView* context, const std::string& path) else { std::string part(ti->begin(), ti->end()); - context = context->findChildView(part, recurse); + context = context->findChildView(LLURI::unescape(part), recurse); recurse = false; } } diff --git a/indra/llui/llui.h b/indra/llui/llui.h index c727f75c4f..d7151dbee9 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -344,95 +344,6 @@ private: // Moved LLLocalClipRect to lllocalcliprect.h -class LLCallbackRegistry -{ -public: - typedef boost::signals2::signal<void()> callback_signal_t; - - void registerCallback(const callback_signal_t::slot_type& slot) - { - mCallbacks.connect(slot); - } - - void fireCallbacks() - { - mCallbacks(); - } - -private: - callback_signal_t mCallbacks; -}; - -class LLInitClassList : - public LLCallbackRegistry, - public LLSingleton<LLInitClassList> -{ - friend class LLSingleton<LLInitClassList>; -private: - LLInitClassList() {} -}; - -class LLDestroyClassList : - public LLCallbackRegistry, - public LLSingleton<LLDestroyClassList> -{ - friend class LLSingleton<LLDestroyClassList>; -private: - LLDestroyClassList() {} -}; - -template<typename T> -class LLRegisterWith -{ -public: - LLRegisterWith(boost::function<void ()> func) - { - T::instance().registerCallback(func); - } - - // this avoids a MSVC bug where non-referenced static members are "optimized" away - // even if their constructors have side effects - S32 reference() - { - S32 dummy; - dummy = 0; - return dummy; - } -}; - -template<typename T> -class LLInitClass -{ -public: - LLInitClass() { sRegister.reference(); } - - static LLRegisterWith<LLInitClassList> sRegister; -private: - - static void initClass() - { - LL_ERRS() << "No static initClass() method defined for " << typeid(T).name() << LL_ENDL; - } -}; - -template<typename T> -class LLDestroyClass -{ -public: - LLDestroyClass() { sRegister.reference(); } - - static LLRegisterWith<LLDestroyClassList> sRegister; -private: - - static void destroyClass() - { - LL_ERRS() << "No static destroyClass() method defined for " << typeid(T).name() << LL_ENDL; - } -}; - -template <typename T> LLRegisterWith<LLInitClassList> LLInitClass<T>::sRegister(&T::initClass); -template <typename T> LLRegisterWith<LLDestroyClassList> LLDestroyClass<T>::sRegister(&T::destroyClass); - // useful parameter blocks struct TimeIntervalParam : public LLInitParam::ChoiceBlock<TimeIntervalParam> { diff --git a/indra/llui/lluicolortable.h b/indra/llui/lluicolortable.h index 6a7a681d57..44472070cc 100644 --- a/indra/llui/lluicolortable.h +++ b/indra/llui/lluicolortable.h @@ -38,7 +38,8 @@ class LLUIColor; class LLUIColorTable : public LLSingleton<LLUIColorTable> { -LOG_CLASS(LLUIColorTable); + LLSINGLETON_EMPTY_CTOR(LLUIColorTable); + LOG_CLASS(LLUIColorTable); // consider using sorted vector, can be much faster typedef std::map<std::string, LLUIColor> string_color_map_t; diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index 99553ee0d2..550bee5c70 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -258,18 +258,25 @@ public: class LLTextInputFilter : public LLQueryFilter, public LLSingleton<LLTextInputFilter> { + LLSINGLETON_EMPTY_CTOR(LLTextInputFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const { return filterResult_t(view->isCtrl() && static_cast<const LLUICtrl *>(view)->acceptsTextInput(), TRUE); } }; - + template <typename F, typename DERIVED> class CallbackRegistry : public LLRegistrySingleton<std::string, F, DERIVED > {}; - class CommitCallbackRegistry : public CallbackRegistry<commit_callback_t, CommitCallbackRegistry>{}; + class CommitCallbackRegistry : public CallbackRegistry<commit_callback_t, CommitCallbackRegistry> + { + LLSINGLETON_EMPTY_CTOR(CommitCallbackRegistry); + }; // the enable callback registry is also used for visiblity callbacks - class EnableCallbackRegistry : public CallbackRegistry<enable_callback_t, EnableCallbackRegistry>{}; + class EnableCallbackRegistry : public CallbackRegistry<enable_callback_t, EnableCallbackRegistry> + { + LLSINGLETON_EMPTY_CTOR(EnableCallbackRegistry); + }; protected: diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index 4cc7da1267..fdefae01b1 100644 --- a/indra/llui/lluictrlfactory.cpp +++ b/indra/llui/lluictrlfactory.cpp @@ -92,15 +92,27 @@ void LLUICtrlFactory::loadWidgetTemplate(const std::string& widget_tag, LLInitPa { std::string filename = gDirUtilp->add("widgets", widget_tag + ".xml"); LLXMLNodePtr root_node; + std::vector<std::string> search_paths = + gDirUtilp->findSkinnedFilenames(LLDir::XUI, 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()) + if (search_paths.empty()) { - LLUICtrlFactory::instance().pushFileName(full_filename); - LLSimpleXUIParser parser; - parser.readXUI(full_filename, block); + return; + } + + // "en" version, the default-language version of the file. + std::string base_filename = search_paths.front(); + if (!base_filename.empty()) + { + LLUICtrlFactory::instance().pushFileName(base_filename); + + if (!LLXMLNode::getLayeredXMLNode(root_node, search_paths)) + { + LL_WARNS() << "Couldn't parse widget from: " << base_filename << LL_ENDL; + return; + } + LLXUIParser parser; + parser.readXUI(root_node, block, base_filename); LLUICtrlFactory::instance().popFileName(); } } diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index 3ce39c947f..03d946f1b7 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -33,6 +33,8 @@ #include "llxuiparser.h" #include "llstl.h" #include "lldir.h" +#include "llsingleton.h" +#include "llheteromap.h" class LLView; @@ -57,22 +59,24 @@ protected: class LLDefaultChildRegistry : public LLChildRegistry<LLDefaultChildRegistry> { -protected: - LLDefaultChildRegistry(){} - friend class LLSingleton<LLDefaultChildRegistry>; + LLSINGLETON_EMPTY_CTOR(LLDefaultChildRegistry); }; // lookup widget name by type class LLWidgetNameRegistry : public LLRegistrySingleton<const std::type_info*, std::string, LLWidgetNameRegistry> -{}; +{ + LLSINGLETON_EMPTY_CTOR(LLWidgetNameRegistry); +}; // 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<const std::type_info*, empty_param_block_func_t, LLDefaultParamBlockRegistry> -//{}; +//{ +// LLSINGLETON(LLDefaultParamBlockRegistry); +//}; extern LLTrace::BlockTimerStatHandle FTM_WIDGET_SETUP; extern LLTrace::BlockTimerStatHandle FTM_WIDGET_CONSTRUCTION; @@ -85,31 +89,15 @@ extern template class LLUICtrlFactory* LLSingleton<class LLUICtrlFactory>::getIn class LLUICtrlFactory : public LLSingleton<LLUICtrlFactory> { -private: - friend class LLSingleton<LLUICtrlFactory>; - LLUICtrlFactory(); + LLSINGLETON(LLUICtrlFactory); ~LLUICtrlFactory(); // only partial specialization allowed in inner classes, so use extra dummy parameter template <typename PARAM_BLOCK, int DUMMY> - class ParamDefaults : public LLSingleton<ParamDefaults<PARAM_BLOCK, DUMMY> > + class ParamDefaults { public: - ParamDefaults() - { - // look up template file for this param block... - const std::string* param_block_tag = LLWidgetNameRegistry::instance().getValue(&typeid(PARAM_BLOCK)); - if (param_block_tag) - { // ...and if it exists, back fill values using the most specific template first - PARAM_BLOCK params; - LLUICtrlFactory::loadWidgetTemplate(*param_block_tag, params); - mPrototype.fillFrom(params); - } - // recursively fill from base class param block - ((typename PARAM_BLOCK::base_block_t&)mPrototype).fillFrom(ParamDefaults<typename PARAM_BLOCK::base_block_t, DUMMY>::instance().get()); - - } - + ParamDefaults(); const PARAM_BLOCK& get() { return mPrototype; } private: @@ -118,9 +106,10 @@ private: // base case for recursion, there are NO base classes of LLInitParam::BaseBlock template<int DUMMY> - class ParamDefaults<LLInitParam::BaseBlock, DUMMY> : public LLSingleton<ParamDefaults<LLInitParam::BaseBlock, DUMMY> > + class ParamDefaults<LLInitParam::BaseBlock, DUMMY> { public: + ParamDefaults(); const LLInitParam::BaseBlock& get() { return mBaseBlock; } private: LLInitParam::BaseBlock mBaseBlock; @@ -132,7 +121,7 @@ public: template<typename T> static const typename T::Params& getDefaultParams() { - return ParamDefaults<typename T::Params, 0>::instance().get(); + return instance().mParamDefaultsMap.obtain< ParamDefaults<typename T::Params, 0> >().get(); } // Does what you want for LLFloaters and LLPanels @@ -147,7 +136,8 @@ public: template<typename T> static T* create(typename T::Params& params, LLView* parent = NULL) { - params.fillFrom(ParamDefaults<typename T::Params, 0>::instance().get()); + params.fillFrom(instance().mParamDefaultsMap.obtain< + ParamDefaults<typename T::Params, 0> >().get()); T* widget = createWidgetImpl<T>(params, parent); if (widget) @@ -295,8 +285,40 @@ private: class LLPanel* mDummyPanel; std::vector<std::string> mFileNames; + + // store ParamDefaults specializations + // Each ParamDefaults specialization used to be an LLSingleton in its own + // right. But the 2016 changes to the LLSingleton mechanism, making + // LLSingleton instances polymorphic, are incompatible with current + // LLInitParam::BaseBlock functionality. (Thanks NickyD for spotting + // that!) Moreover, instances of the private nested ParamDefaults template + // aren't global resources -- which is what LLSingleton is designed for. + // This is simply a cache looked up by type. Its lifespan is tied to + // LLUICtrlFactory. Use LLHeteroMap for this cache. + LLHeteroMap mParamDefaultsMap; }; +template <typename PARAM_BLOCK, int DUMMY> +LLUICtrlFactory::ParamDefaults<PARAM_BLOCK, DUMMY>::ParamDefaults() +{ + // look up template file for this param block... + const std::string* param_block_tag = LLWidgetNameRegistry::instance().getValue(&typeid(PARAM_BLOCK)); + if (param_block_tag) + { // ...and if it exists, back fill values using the most specific template first + PARAM_BLOCK params; + LLUICtrlFactory::loadWidgetTemplate(*param_block_tag, params); + mPrototype.fillFrom(params); + } + // recursively fill from base class param block + ((typename PARAM_BLOCK::base_block_t&)mPrototype).fillFrom( + LLUICtrlFactory::instance().mParamDefaultsMap.obtain< + ParamDefaults<typename PARAM_BLOCK::base_block_t, DUMMY> >().get()); + +} + +template <int DUMMY> +LLUICtrlFactory::ParamDefaults<LLInitParam::BaseBlock, DUMMY>::ParamDefaults() {} + // this is here to make gcc happy with reference to LLUICtrlFactory template<typename DERIVED> template<typename T> diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index e4848362a7..b5a31f5118 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -183,8 +183,9 @@ bool LLUrlEntryBase::isLinkDisabled() const bool LLUrlEntryBase::isWikiLinkCorrect(std::string url) { - std::string label = getLabelFromWikiLink(url); - return (LLUrlRegistry::instance().hasUrl(label)) ? false : true; + LLWString label = utf8str_to_wstring(getLabelFromWikiLink(url)); + label.erase(std::remove(label.begin(), label.end(), L'\u200B'), label.end()); + return (LLUrlRegistry::instance().hasUrl(wstring_to_utf8str(label))) ? false : true; } std::string LLUrlEntryBase::urlToLabelWithGreyQuery(const std::string &url) const @@ -205,9 +206,15 @@ std::string LLUrlEntryBase::urlToGreyQuery(const std::string &url) const std::string label; up.extractParts(); - up.glueFirst(label); - std::string query = url.substr(label.size()); - return query; + up.glueFirst(label, false); + + size_t pos = url.find(label); + if (pos == std::string::npos) + { + return ""; + } + pos += label.size(); + return url.substr(pos); } @@ -1370,7 +1377,7 @@ std::string LLUrlEntryIcon::getIcon(const std::string &url) LLUrlEntryEmail::LLUrlEntryEmail() : LLUrlEntryBase() { - mPattern = boost::regex("(mailto:)?[\\w\\.\\-]+@[\\w\\.\\-]+\\.[a-z]{2,6}", + mPattern = boost::regex("(mailto:)?[\\w\\.\\-]+@[\\w\\.\\-]+\\.[a-z]{2,63}", boost::regex::perl | boost::regex::icase); mMenuName = "menu_url_email.xml"; mTooltip = LLTrans::getString("TooltipEmail"); diff --git a/indra/llui/llurlregistry.h b/indra/llui/llurlregistry.h index 24c3a2b513..efafe543ab 100644 --- a/indra/llui/llurlregistry.h +++ b/indra/llui/llurlregistry.h @@ -62,9 +62,9 @@ void LLUrlRegistryNullCallback(const std::string &url, /// class LLUrlRegistry : public LLSingleton<LLUrlRegistry> { -public: + LLSINGLETON(LLUrlRegistry); ~LLUrlRegistry(); - +public: /// add a new Url handler to the registry (will be freed on destruction) /// optionally force it to the front of the list, making it take /// priority over other regular expression matches for URLs @@ -89,9 +89,6 @@ public: bool isUrl(const LLWString &text); private: - LLUrlRegistry(); - friend class LLSingleton<LLUrlRegistry>; - std::vector<LLUrlEntryBase *> mUrlEntry; LLUrlEntryBase* mUrlEntryTrusted; LLUrlEntryBase* mUrlEntryIcon; diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 8f7cac1f61..89ad8138d8 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -391,7 +391,27 @@ static void buildPathname(std::ostream& out, const LLView* view) buildPathname(out, view->getParent()); // Build pathname into ostream on the way back from recursion. - out << '/' << view->getName(); + out << '/'; + + // substitute all '/' in name with appropriate code + std::string name = view->getName(); + std::size_t found = name.find('/'); + std::size_t start = 0; + while (found != std::string::npos) + { + std::size_t sub_len = found - start; + if (sub_len > 0) + { + out << name.substr(start, sub_len); + } + out << "%2F"; + start = found + 1; + found = name.find('/', start); + } + if (start < name.size()) + { + out << name.substr(start, name.size() - start); + } } std::string LLView::getPathname() const @@ -588,6 +608,11 @@ void LLView::onVisibilityChange ( BOOL new_visibility ) BOOL log_visibility_change = LLViewerEventRecorder::instance().getLoggingStatus(); BOOST_FOREACH(LLView* viewp, mChildList) { + if (!viewp) + { + continue; + } + // only views that are themselves visible will have their overall visibility affected by their ancestors old_visibility=viewp->getVisible(); @@ -807,7 +832,7 @@ LLView* LLView::childrenHandleHover(S32 x, S32 y, MASK mask) LLView* LLView::childFromPoint(S32 x, S32 y, bool recur) { if (!getVisible()) - return false; + return NULL; BOOST_FOREACH(LLView* viewp, mChildList) { @@ -1887,6 +1912,7 @@ private: class SortByTabOrder : public LLQuerySorter, public LLSingleton<SortByTabOrder> { + LLSINGLETON_EMPTY_CTOR(SortByTabOrder); /*virtual*/ void sort(LLView * parent, LLView::child_list_t &children) const { children.sort(CompareByTabOrder(parent->getTabOrder(), parent->getDefaultTabGroup())); @@ -1910,6 +1936,7 @@ const LLViewQuery & LLView::getTabOrderQuery() // This class is only used internally by getFocusRootsQuery below. class LLFocusRootsFilter : public LLQueryFilter, public LLSingleton<LLFocusRootsFilter> { + LLSINGLETON_EMPTY_CTOR(LLFocusRootsFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const { return filterResult_t(view->isCtrl() && view->isFocusRoot(), !view->isFocusRoot()); diff --git a/indra/llui/llviewereventrecorder.h b/indra/llui/llviewereventrecorder.h index 375efcc3de..d1059d55de 100644 --- a/indra/llui/llviewereventrecorder.h +++ b/indra/llui/llviewereventrecorder.h @@ -44,13 +44,10 @@ class LLViewerEventRecorder : public LLSingleton<LLViewerEventRecorder> { - - public: - - LLViewerEventRecorder(); // TODO Protect constructor better if we can (not happy in private section) - could add a factory... - we are singleton + LLSINGLETON(LLViewerEventRecorder); ~LLViewerEventRecorder(); - + public: void updateMouseEventInfo(S32 local_x,S32 local_y, S32 global_x, S32 global_y, std::string mName); void setMouseLocalCoords(S32 x,S32 y); void setMouseGlobalCoords(S32 x,S32 y); diff --git a/indra/llui/llviewquery.h b/indra/llui/llviewquery.h index 9044c4ff29..21bb1be26f 100644 --- a/indra/llui/llviewquery.h +++ b/indra/llui/llviewquery.h @@ -54,31 +54,37 @@ public: class LLLeavesFilter : public LLQueryFilter, public LLSingleton<LLLeavesFilter> { + LLSINGLETON_EMPTY_CTOR(LLLeavesFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; }; class LLRootsFilter : public LLQueryFilter, public LLSingleton<LLRootsFilter> { + LLSINGLETON_EMPTY_CTOR(LLRootsFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; }; class LLVisibleFilter : public LLQueryFilter, public LLSingleton<LLVisibleFilter> { + LLSINGLETON_EMPTY_CTOR(LLVisibleFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; }; class LLEnabledFilter : public LLQueryFilter, public LLSingleton<LLEnabledFilter> { + LLSINGLETON_EMPTY_CTOR(LLEnabledFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; }; class LLTabStopFilter : public LLQueryFilter, public LLSingleton<LLTabStopFilter> { + LLSINGLETON_EMPTY_CTOR(LLTabStopFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; }; class LLCtrlFilter : public LLQueryFilter, public LLSingleton<LLCtrlFilter> { + LLSINGLETON_EMPTY_CTOR(LLCtrlFilter); /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; }; diff --git a/indra/llui/llxuiparser.h b/indra/llui/llxuiparser.h index ad2a39cab7..eb0eac8194 100644 --- a/indra/llui/llxuiparser.h +++ b/indra/llui/llxuiparser.h @@ -41,7 +41,9 @@ class LLView; // lookup widget type by name class LLWidgetTypeRegistry : public LLRegistrySingleton<std::string, const std::type_info*, LLWidgetTypeRegistry> -{}; +{ + LLSINGLETON_EMPTY_CTOR(LLWidgetTypeRegistry); +}; // global static instance for registering all widget types @@ -51,7 +53,9 @@ typedef LLRegistry<std::string, LLWidgetCreatorFunc> widget_registry_t; class LLChildRegistryRegistry : public LLRegistrySingleton<const std::type_info*, widget_registry_t, LLChildRegistryRegistry> -{}; +{ + LLSINGLETON_EMPTY_CTOR(LLChildRegistryRegistry); +}; class LLXSDWriter : public LLInitParam::Parser { @@ -60,7 +64,7 @@ public: void writeXSD(const std::string& name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace); /*virtual*/ std::string getCurrentElementName() { return LLStringUtil::null; } - + /*virtual*/ std::string getCurrentFileName() { return LLStringUtil::null; } LLXSDWriter(); ~LLXSDWriter(); @@ -98,6 +102,7 @@ public: typedef LLInitParam::Parser::name_stack_t name_stack_t; /*virtual*/ std::string getCurrentElementName(); + /*virtual*/ std::string getCurrentFileName() { return mCurFileName; } /*virtual*/ void parserWarning(const std::string& message); /*virtual*/ void parserError(const std::string& message); @@ -200,6 +205,7 @@ public: virtual ~LLSimpleXUIParser(); /*virtual*/ std::string getCurrentElementName(); + /*virtual*/ std::string getCurrentFileName() { return mCurFileName; } /*virtual*/ void parserWarning(const std::string& message); /*virtual*/ void parserError(const std::string& message); diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp index f01178c374..338be1808d 100644..100755 --- a/indra/llui/tests/llurlentry_stub.cpp +++ b/indra/llui/tests/llurlentry_stub.cpp @@ -31,6 +31,7 @@ #include "llcachename.h" #include "lluuid.h" #include "message.h" +#include "llpounceable.h" #include <string> @@ -165,7 +166,7 @@ LLFontGL* LLFontGL::getFontDefault() char const* const _PREHASH_AgentData = (char *)"AgentData"; char const* const _PREHASH_AgentID = (char *)"AgentID"; -LLMessageSystem* gMessageSystem = NULL; +LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem; // // Stub implementation for LLMessageSystem diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp index 233fb6da23..119cbebc81 100644 --- a/indra/llui/tests/llurlentry_test.cpp +++ b/indra/llui/tests/llurlentry_test.cpp @@ -28,7 +28,7 @@ #include "linden_common.h" #include "../llurlentry.h" #include "../lluictrl.h" -#include "llurlentry_stub.cpp" +//#include "llurlentry_stub.cpp" #include "lltut.h" #include "../lluicolortable.h" #include "../llrender/lluiimage.h" @@ -49,6 +49,7 @@ // // } +/*==========================================================================*| typedef std::map<std::string, LLControlGroup*> settings_map_t; settings_map_t LLUI::sSettingGroups; @@ -83,6 +84,7 @@ S32 LLUIImage::getHeight() const { return 0; } +|*==========================================================================*/ namespace tut { |