diff options
Diffstat (limited to 'indra/llui')
32 files changed, 433 insertions, 393 deletions
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/llcontainerview.cpp b/indra/llui/llcontainerview.cpp index e08ccb0b78..e08ccb0b78 100755..100644 --- a/indra/llui/llcontainerview.cpp +++ b/indra/llui/llcontainerview.cpp diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index d14fe441fb..a29ad12d23 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -1119,11 +1119,11 @@ void LLFloater::handleReshape(const LLRect& new_rect, bool by_user) { setDocked( false, false); } - storeRectControl(); - mPositioning = LLFloaterEnums::POSITIONING_RELATIVE; - LLRect screen_rect = calcScreenRect(); - mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert(); - } + storeRectControl(); + mPositioning = LLFloaterEnums::POSITIONING_RELATIVE; + LLRect screen_rect = calcScreenRect(); + mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert(); + } // gather all snapped dependents for(handle_set_iter_t dependent_it = mDependents.begin(); @@ -1720,7 +1720,7 @@ void LLFloater::onClickHelp( LLFloater* self ) } } -// static +// static void LLFloater::closeFrontmostFloater() { LLFloater* floater_to_close = gFloaterView->getFrontmostClosableFloater(); @@ -3085,7 +3085,7 @@ bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::str parser.readXUI(node, output_params, LLUICtrlFactory::getInstance()->getCurFileName()); setupParamsForExport(output_params, parent); output_node->setName(node->getName()->mString); - parser.writeXUI(output_node, output_params, &default_params); + parser.writeXUI(output_node, output_params, LLInitParam::default_parse_rules(), &default_params); return TRUE; } @@ -3115,9 +3115,8 @@ bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::str { Params output_params(params); setupParamsForExport(output_params, parent); - Params default_params(LLUICtrlFactory::getDefaultParams<LLFloater>()); output_node->setName(node->getName()->mString); - parser.writeXUI(output_node, output_params, &default_params); + parser.writeXUI(output_node, output_params, LLInitParam::default_parse_rules(), &default_params); } // Default floater position to top-left corner of screen @@ -3214,24 +3213,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; } @@ -3256,7 +3245,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 0484ca622b..aef63bcf93 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/llfloaterreg.h b/indra/llui/llfloaterreg.h index a1e1f8a988..e3b17dcb4f 100644 --- a/indra/llui/llfloaterreg.h +++ b/indra/llui/llfloaterreg.h @@ -30,6 +30,7 @@ #include "llrect.h" #include "llsd.h" +#include <list> #include <boost/function.hpp> //******************************************************* diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 629eef2c3b..137c6efc53 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -464,7 +464,7 @@ LLNotification::LLNotification(const LLNotification::Params& p) : mTimestamp(p.time_stamp), mSubstitutions(p.substitutions), mPayload(p.payload), - mExpiresAt(0), + mExpiresAt(0.0), mTemporaryResponder(false), mRespondedTo(false), mPriority(p.priority), @@ -1424,17 +1424,11 @@ void addPathIfExists(const std::string& new_path, std::vector<std::string>& path bool LLNotifications::loadTemplates() { llinfos << "Reading notifications template" << llendl; - std::vector<std::string> 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(constraint=LLDir::ALL_SKINS) makes it + // output all relevant pathnames instead of just the ones from the most + // specific skin. + std::vector<std::string> search_paths = + gDirUtilp->findSkinnedFilenames(LLDir::XUI, "notifications.xml", LLDir::ALL_SKINS); std::string base_filename = search_paths.front(); LLXMLNodePtr root; @@ -1442,7 +1436,7 @@ bool LLNotifications::loadTemplates() 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 +1446,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 +1502,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..188a0fea74 100644 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -520,7 +520,7 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu Params output_params(params); setupParamsForExport(output_params, parent); output_node->setName(node->getName()->mString); - parser.writeXUI(output_node, output_params, &default_params); + parser.writeXUI(output_node, output_params, LLInitParam::default_parse_rules(), &default_params); return TRUE; } @@ -551,7 +551,7 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu Params output_params(params); setupParamsForExport(output_params, parent); output_node->setName(node->getName()->mString); - parser.writeXUI(output_node, output_params, &default_params); + parser.writeXUI(output_node, output_params, LLInitParam::default_parse_rules(), &default_params); } params.from_xui = true; @@ -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/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 b3499693dd..d332aa933e 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" @@ -158,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 ), @@ -180,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), @@ -356,7 +356,7 @@ void LLScrollListCtrl::clearRows() mScrollLines = 0; mLastSelected = NULL; updateLayout(); - mDirty = FALSE; + mDirty = false; } @@ -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(); @@ -591,13 +600,11 @@ 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; @@ -606,6 +613,35 @@ void LLScrollListCtrl::calcColumnWidths() 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) + { + LLScrollListColumn* column = *column_itor; + if (!column) continue; + // update column width S32 new_width = column->getWidth(); if (column->mRelWidth >= 0) @@ -617,23 +653,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; @@ -669,7 +695,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<LLScrollListColumn*>::iterator column_ordered_it; @@ -718,20 +749,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) @@ -772,7 +805,7 @@ BOOL LLScrollListCtrl::selectFirstItem() { deselectItem(itemp); } - first_item = FALSE; + first_item = false; } if (mCommitOnSelectionChange) { @@ -1406,17 +1439,23 @@ void LLScrollListCtrl::drawItems() S32 cur_y = y; - S32 line = 0; S32 max_columns = 0; LLColor4 highlight_color = LLColor4::white; static LLUICachedControl<F32> 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, @@ -1480,7 +1519,6 @@ void LLScrollListCtrl::drawItems() cur_y -= mLineHeight; } - line++; } } } @@ -1496,7 +1534,7 @@ void LLScrollListCtrl::draw() if (mNeedsScroll) { scrollToShowSelected(); - mNeedsScroll = FALSE; + mNeedsScroll = false; } LLRect background(0, getRect().getHeight(), getRect().getWidth(), 0); // Draw background @@ -1507,11 +1545,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()); @@ -1719,7 +1753,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); } @@ -1737,15 +1771,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(); } @@ -1805,7 +1839,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); } @@ -1859,7 +1895,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 @@ -1888,7 +1924,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; } @@ -1994,7 +2030,7 @@ BOOL LLScrollListCtrl::handleHover(S32 x,S32 y,MASK mask) if(mask == MASK_NONE) { selectItemAt(x, y, mask); - mNeedsScroll = TRUE; + mNeedsScroll = true; } } else @@ -2041,7 +2077,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) { // commit implicit in call selectPrevItem(FALSE); - mNeedsScroll = TRUE; + mNeedsScroll = true; handled = TRUE; } break; @@ -2050,7 +2086,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) { // commit implicit in call selectNextItem(FALSE); - mNeedsScroll = TRUE; + mNeedsScroll = true; handled = TRUE; } break; @@ -2058,7 +2094,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) if (mAllowKeyboardMovement || hasFocus()) { selectNthItem(getFirstSelectedIndex() - (mScrollbar->getPageSize() - 1)); - mNeedsScroll = TRUE; + mNeedsScroll = true; if (mCommitOnKeyboardMovement && !mCommitOnSelectionChange) { @@ -2071,7 +2107,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) if (mAllowKeyboardMovement || hasFocus()) { selectNthItem(getFirstSelectedIndex() + (mScrollbar->getPageSize() - 1)); - mNeedsScroll = TRUE; + mNeedsScroll = true; if (mCommitOnKeyboardMovement && !mCommitOnSelectionChange) { @@ -2084,7 +2120,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) if (mAllowKeyboardMovement || hasFocus()) { selectFirstItem(); - mNeedsScroll = TRUE; + mNeedsScroll = true; if (mCommitOnKeyboardMovement && !mCommitOnSelectionChange) { @@ -2097,7 +2133,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask ) if (mAllowKeyboardMovement || hasFocus()) { selectNthItem(getItemCount() - 1); - mNeedsScroll = TRUE; + mNeedsScroll = true; if (mCommitOnKeyboardMovement && !mCommitOnSelectionChange) { @@ -2136,7 +2172,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(); @@ -2177,7 +2213,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(); @@ -2223,7 +2259,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(); @@ -2294,7 +2330,7 @@ void LLScrollListCtrl::selectItem(LLScrollListItem* itemp, BOOL select_single_it } itemp->setSelected(TRUE); mLastSelected = itemp; - mSelectionChanged = TRUE; + mSelectionChanged = true; } } @@ -2315,7 +2351,7 @@ void LLScrollListCtrl::deselectItem(LLScrollListItem* itemp) { cellp->highlightText(0, 0); } - mSelectionChanged = TRUE; + mSelectionChanged = true; } } @@ -2323,7 +2359,7 @@ void LLScrollListCtrl::commitIfChanged() { if (mSelectionChanged) { - mDirty = TRUE; + mDirty = true; mSelectionChanged = FALSE; onCommit(); } @@ -2434,7 +2470,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 @@ -3003,7 +3040,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<std::string, LLScrollListColumn*> column_map_t; column_map_t mColumns; - BOOL mDirty; + bool mDirty; S32 mOriginalSelection; ContextMenuType mContextMenuType; diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp index c60e5431ae..1bc9a9fc67 100644 --- a/indra/llui/llstatbar.cpp +++ b/indra/llui/llstatbar.cpp @@ -34,7 +34,6 @@ #include "llgl.h" #include "llfontgl.h" -#include "llstat.h" #include "lluictrlfactory.h" #include "lltracerecording.h" @@ -46,18 +45,20 @@ LLStatBar::LLStatBar(const Params& p) mUnitLabel(p.unit_label), mMinBar(p.bar_min), mMaxBar(p.bar_max), - mStatp(LLStat::getInstance(p.stat)), - mNewStatp(LLTrace::Count<>::getInstance(p.stat)), + mCountFloatp(LLTrace::Count<>::getInstance(p.stat)), + mCountIntp(LLTrace::Count<S64>::getInstance(p.stat)), + mMeasurementFloatp(LLTrace::Measurement<>::getInstance(p.stat)), + mMeasurementIntp(LLTrace::Measurement<S64>::getInstance(p.stat)), mTickSpacing(p.tick_spacing), mLabelSpacing(p.label_spacing), mPrecision(p.precision), mUpdatesPerSec(p.update_rate), + mUnitScale(p.unit_scale), mPerSec(p.show_per_sec), mDisplayBar(p.show_bar), mDisplayHistory(p.show_history), mDisplayMean(p.show_mean) -{ -} +{} BOOL LLStatBar::handleMouseDown(S32 x, S32 y, MASK mask) { @@ -91,46 +92,67 @@ void LLStatBar::draw() max = 0.f, mean = 0.f; - if (mStatp) + LLTrace::PeriodicRecording& frame_recording = LLTrace::get_frame_recording(); + + if (mCountFloatp) { - // Get the values. + LLTrace::Recording& last_frame_recording = frame_recording.getLastRecordingPeriod(); + if (mPerSec) { - current = mStatp->getCurrentPerSec(); - min = mStatp->getMinPerSec(); - max = mStatp->getMaxPerSec(); - mean = mStatp->getMeanPerSec(); + current = last_frame_recording.getPerSec(*mCountFloatp); + min = frame_recording.getPeriodMinPerSec(*mCountFloatp); + max = frame_recording.getPeriodMaxPerSec(*mCountFloatp); + mean = frame_recording.getPeriodMeanPerSec(*mCountFloatp); } else { - current = mStatp->getCurrent(); - min = mStatp->getMin(); - max = mStatp->getMax(); - mean = mStatp->getMean(); + current = last_frame_recording.getSum(*mCountFloatp); + min = frame_recording.getPeriodMin(*mCountFloatp); + max = frame_recording.getPeriodMax(*mCountFloatp); + mean = frame_recording.getPeriodMean(*mCountFloatp); } } - else if (mNewStatp) + else if (mCountIntp) { - LLTrace::PeriodicRecording& frame_recording = LLTrace::get_frame_recording(); LLTrace::Recording& last_frame_recording = frame_recording.getLastRecordingPeriod(); - LLTrace::Recording& windowed_frame_recording = frame_recording.getTotalRecording(); if (mPerSec) { - current = last_frame_recording.getPerSec(*mNewStatp); - //min = frame_window_recording.getMin(*mNewStatp) / frame_window_recording.getDuration(); - //max = frame_window_recording.getMax(*mNewStatp) / frame_window_recording.getDuration(); - mean = windowed_frame_recording.getPerSec(*mNewStatp);//frame_window_recording.getMean(*mNewStatp) / frame_window_recording.getDuration(); + current = last_frame_recording.getPerSec(*mCountIntp); + min = frame_recording.getPeriodMinPerSec(*mCountIntp); + max = frame_recording.getPeriodMaxPerSec(*mCountIntp); + mean = frame_recording.getPeriodMeanPerSec(*mCountIntp); } else { - current = last_frame_recording.getSum(*mNewStatp); - //min = last_frame_recording.getMin(*mNewStatp); - //max = last_frame_recording.getMax(*mNewStatp); - mean = windowed_frame_recording.getSum(*mNewStatp); + current = last_frame_recording.getSum(*mCountIntp); + min = frame_recording.getPeriodMin(*mCountIntp); + max = frame_recording.getPeriodMax(*mCountIntp); + mean = frame_recording.getPeriodMean(*mCountIntp); } } - + else if (mMeasurementFloatp) + { + LLTrace::Recording& recording = frame_recording.getTotalRecording(); + current = recording.getLastValue(*mMeasurementFloatp); + min = recording.getMin(*mMeasurementFloatp); + max = recording.getMax(*mMeasurementFloatp); + mean = recording.getMean(*mMeasurementFloatp); + } + else if (mMeasurementIntp) + { + LLTrace::Recording& recording = frame_recording.getTotalRecording(); + current = recording.getLastValue(*mMeasurementIntp); + min = recording.getMin(*mMeasurementIntp); + max = recording.getMax(*mMeasurementIntp); + mean = recording.getMean(*mMeasurementIntp); + } + + current *= mUnitScale; + min *= mUnitScale; + max *= mUnitScale; + mean *= mUnitScale; if ((mUpdatesPerSec == 0.f) || (mUpdateTimer.getElapsedTimeF32() > 1.f/mUpdatesPerSec) || (mValue == 0.f)) { @@ -177,7 +199,7 @@ void LLStatBar::draw() LLFontGL::RIGHT, LLFontGL::TOP); value_format = llformat( "%%.%df", mPrecision); - if (mDisplayBar && mStatp) + if (mDisplayBar && (mCountFloatp || mCountIntp || mMeasurementFloatp || mMeasurementIntp)) { std::string tick_label; @@ -220,7 +242,7 @@ void LLStatBar::draw() right = width; gl_rect_2d(left, top, right, bottom, LLColor4(0.f, 0.f, 0.f, 0.25f)); - if (mStatp->getNumValues() == 0) + if (frame_recording.getNumPeriods() == 0) { // No data, don't draw anything... return; @@ -237,26 +259,58 @@ void LLStatBar::draw() right = (S32) ((max - mMinBar) * value_scale); gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 0.f, 0.f, 0.25f)); - if (mDisplayHistory) + if (mDisplayHistory && (mCountFloatp || mCountIntp || mMeasurementFloatp || mMeasurementIntp)) { - S32 num_values = mStatp->getNumValues() - 1; + S32 num_values = frame_recording.getNumPeriods() - 1; S32 i; - for (i = 0; i < num_values; i++) + for (i = 1; i <= num_values; i++) { - if (i == mStatp->getNextBin()) - { - continue; - } if (mPerSec) { - left = (S32)((mStatp->getPrevPerSec(i) - mMinBar) * value_scale); - right = (S32)((mStatp->getPrevPerSec(i) - mMinBar) * value_scale) + 1; + if (mCountFloatp) + { + left = (S32)((frame_recording.getPrevRecordingPeriod(i).getPerSec(*mCountFloatp) - mMinBar) * value_scale); + right = (S32)((frame_recording.getPrevRecordingPeriod(i).getPerSec(*mCountFloatp) - mMinBar) * value_scale) + 1; + } + else if (mCountIntp) + { + left = (S32)((frame_recording.getPrevRecordingPeriod(i).getPerSec(*mCountIntp) - mMinBar) * value_scale); + right = (S32)((frame_recording.getPrevRecordingPeriod(i).getPerSec(*mCountIntp) - mMinBar) * value_scale) + 1; + } + else if (mMeasurementFloatp) + { + left = (S32)((frame_recording.getPrevRecordingPeriod(i).getPerSec(*mMeasurementFloatp) - mMinBar) * value_scale); + right = (S32)((frame_recording.getPrevRecordingPeriod(i).getPerSec(*mMeasurementFloatp) - mMinBar) * value_scale) + 1; + } + else if (mMeasurementIntp) + { + left = (S32)((frame_recording.getPrevRecordingPeriod(i).getPerSec(*mMeasurementIntp) - mMinBar) * value_scale); + right = (S32)((frame_recording.getPrevRecordingPeriod(i).getPerSec(*mMeasurementIntp) - mMinBar) * value_scale) + 1; + } gl_rect_2d(left, bottom+i+1, right, bottom+i, LLColor4(1.f, 0.f, 0.f, 1.f)); } else { - left = (S32)((mStatp->getPrev(i) - mMinBar) * value_scale); - right = (S32)((mStatp->getPrev(i) - mMinBar) * value_scale) + 1; + if (mCountFloatp) + { + left = (S32)((frame_recording.getPrevRecordingPeriod(i).getSum(*mCountFloatp) - mMinBar) * value_scale); + right = (S32)((frame_recording.getPrevRecordingPeriod(i).getSum(*mCountFloatp) - mMinBar) * value_scale) + 1; + } + else if (mCountIntp) + { + left = (S32)((frame_recording.getPrevRecordingPeriod(i).getSum(*mCountIntp) - mMinBar) * value_scale); + right = (S32)((frame_recording.getPrevRecordingPeriod(i).getSum(*mCountIntp) - mMinBar) * value_scale) + 1; + } + else if (mMeasurementFloatp) + { + left = (S32)((frame_recording.getPrevRecordingPeriod(i).getSum(*mMeasurementFloatp) - mMinBar) * value_scale); + right = (S32)((frame_recording.getPrevRecordingPeriod(i).getSum(*mMeasurementFloatp) - mMinBar) * value_scale) + 1; + } + else if (mMeasurementIntp) + { + left = (S32)((frame_recording.getPrevRecordingPeriod(i).getSum(*mMeasurementIntp) - mMinBar) * value_scale); + right = (S32)((frame_recording.getPrevRecordingPeriod(i).getSum(*mMeasurementIntp) - mMinBar) * value_scale) + 1; + } gl_rect_2d(left, bottom+i+1, right, bottom+i, LLColor4(1.f, 0.f, 0.f, 1.f)); } } @@ -280,6 +334,15 @@ void LLStatBar::draw() LLView::draw(); } +void LLStatBar::setStat(const std::string& stat_name) +{ + mCountFloatp = LLTrace::Count<>::getInstance(stat_name); + mCountIntp = LLTrace::Count<S64>::getInstance(stat_name); + mMeasurementFloatp = LLTrace::Measurement<>::getInstance(stat_name); + mMeasurementIntp = LLTrace::Measurement<S64>::getInstance(stat_name); +} + + void LLStatBar::setRange(F32 bar_min, F32 bar_max, F32 tick_spacing, F32 label_spacing) { mMinBar = bar_min; @@ -294,9 +357,9 @@ LLRect LLStatBar::getRequiredRect() if (mDisplayBar) { - if (mDisplayHistory && mStatp) + if (mDisplayHistory) { - rect.mTop = 35 + mStatp->getNumBins(); + rect.mTop = 35 + LLTrace::get_frame_recording().getNumPeriods(); } else { diff --git a/indra/llui/llstatbar.h b/indra/llui/llstatbar.h index e4b0c61c42..c366fd65db 100644 --- a/indra/llui/llstatbar.h +++ b/indra/llui/llstatbar.h @@ -30,7 +30,6 @@ #include "llview.h" #include "llframetimer.h" #include "lltracerecording.h" -class LLStat; class LLStatBar : public LLView { @@ -45,7 +44,8 @@ public: bar_max, tick_spacing, label_spacing, - update_rate; + update_rate, + unit_scale; Optional<U32> precision; @@ -65,6 +65,7 @@ public: label_spacing("label_spacing", 10.0f), precision("precision", 0), update_rate("update_rate", 5.0f), + unit_scale("unit_scale", 1.f), show_per_sec("show_per_sec", true), show_bar("show_bar", TRUE), show_history("show_history", false), @@ -79,7 +80,8 @@ public: virtual void draw(); virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); - void setStat(LLStat* stat) { mStatp = stat; } + void setStat(const std::string& stat_name); + void setRange(F32 bar_min, F32 bar_max, F32 tick_spacing, F32 label_spacing); void getRange(F32& bar_min, F32& bar_max) { bar_min = mMinBar; bar_max = mMaxBar; } @@ -92,14 +94,16 @@ private: F32 mLabelSpacing; U32 mPrecision; F32 mUpdatesPerSec; + F32 mUnitScale; BOOL mPerSec; // Use the per sec stats. BOOL mDisplayBar; // Display the bar graph. BOOL mDisplayHistory; BOOL mDisplayMean; // If true, display mean, if false, display current value - LLTrace::PeriodicRecording* mFrameRecording; - LLStat* mStatp; - LLTrace::Count<>* mNewStatp; + LLTrace::TraceType<LLTrace::CountAccumulator<F64> >* mCountFloatp; + LLTrace::TraceType<LLTrace::CountAccumulator<S64> >* mCountIntp; + LLTrace::TraceType<LLTrace::MeasurementAccumulator<F64> >* mMeasurementFloatp; + LLTrace::TraceType<LLTrace::MeasurementAccumulator<S64> >* mMeasurementIntp; LLFrameTimer mUpdateTimer; LLUIString mLabel; diff --git a/indra/llui/llstatgraph.cpp b/indra/llui/llstatgraph.cpp index be3baeea76..22c276a018 100644 --- a/indra/llui/llstatgraph.cpp +++ b/indra/llui/llstatgraph.cpp @@ -32,7 +32,6 @@ #include "llmath.h" #include "llui.h" -#include "llstat.h" #include "llgl.h" #include "llglheaders.h" #include "lltracerecording.h" @@ -48,8 +47,8 @@ LLStatGraph::LLStatGraph(const Params& p) mPerSec(true), mPrecision(p.precision), mValue(p.value), - mStatp(p.stat.legacy_stat), - mNewStatp(p.stat.rate_stat) + mNewStatFloatp(p.stat.count_stat_float), + mNewStatIntp(p.stat.count_stat_int) { setToolTip(p.name()); @@ -73,30 +72,31 @@ void LLStatGraph::draw() { F32 range, frac; range = mMax - mMin; - if (mStatp) + if (mNewStatFloatp) { + LLTrace::Recording& recording = LLTrace::get_frame_recording().getLastRecordingPeriod(); + if (mPerSec) { - mValue = mStatp->getMeanPerSec(); + mValue = recording.getPerSec(*mNewStatFloatp); } else { - mValue = mStatp->getMean(); + mValue = recording.getSum(*mNewStatFloatp); } } - else if (mNewStatp) + else if (mNewStatIntp) { LLTrace::Recording& recording = LLTrace::get_frame_recording().getLastRecordingPeriod(); if (mPerSec) { - mValue = recording.getPerSec(*mNewStatp); + mValue = recording.getPerSec(*mNewStatIntp); } else { - mValue = recording.getSum(*mNewStatp); + mValue = recording.getSum(*mNewStatIntp); } - } frac = (mValue - mMin) / range; diff --git a/indra/llui/llstatgraph.h b/indra/llui/llstatgraph.h index 54a959f49e..57856ff6f2 100644 --- a/indra/llui/llstatgraph.h +++ b/indra/llui/llstatgraph.h @@ -32,8 +32,6 @@ #include "v4color.h" #include "lltrace.h" -class LLStat; - class LLStatGraph : public LLView { public: @@ -59,8 +57,10 @@ public: struct StatParams : public LLInitParam::ChoiceBlock<StatParams> { - Alternative<LLStat*> legacy_stat; - Alternative<LLTrace::Count<>* > rate_stat; + Alternative<LLTrace::TraceType<LLTrace::CountAccumulator<F64> >* > count_stat_float; + Alternative<LLTrace::TraceType<LLTrace::CountAccumulator<S64> >* > count_stat_int; + Alternative<LLTrace::TraceType<LLTrace::MeasurementAccumulator<F64> >* > measurement_stat_float; + Alternative<LLTrace::TraceType<LLTrace::MeasurementAccumulator<S64> >* > measurement_stat_int; }; struct Params : public LLInitParam::Block<Params, LLView::Params> @@ -105,8 +105,8 @@ public: /*virtual*/ void setValue(const LLSD& value); private: - LLStat* mStatp; - LLTrace::Count<>* mNewStatp; + LLTrace::TraceType<LLTrace::CountAccumulator<F64> >* mNewStatFloatp; + LLTrace::TraceType<LLTrace::CountAccumulator<S64> >* mNewStatIntp; BOOL mPerSec; diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 3815eec447..74e966560e 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -47,6 +47,8 @@ const F32 CURSOR_FLASH_DELAY = 1.0f; // in seconds const S32 CURSOR_THICKNESS = 2; +LLTrace::MemStat LLTextSegment::sMemStat("LLTextSegment"); + LLTextBase::line_info::line_info(S32 index_start, S32 index_end, LLRect rect, S32 line_num) : mDocIndexStart(index_start), mDocIndexEnd(index_end), @@ -561,7 +563,7 @@ void LLTextBase::drawText() if ( (mSpellCheckStart != start) || (mSpellCheckEnd != end) ) { const LLWString& wstrText = getWText(); - mMisspellRanges.clear(); + memDisclaim(mMisspellRanges).clear(); segment_set_t::const_iterator seg_it = getSegIterContaining(start); while (mSegments.end() != seg_it) @@ -632,6 +634,7 @@ void LLTextBase::drawText() mSpellCheckStart = start; mSpellCheckEnd = end; + memClaim(mMisspellRanges); } } @@ -890,10 +893,12 @@ void LLTextBase::createDefaultSegment() // ensures that there is always at least one segment if (mSegments.empty()) { + memDisclaim(mSegments); LLStyleConstSP sp(new LLStyle(getDefaultStyleParams())); LLTextSegmentPtr default_segment = new LLNormalTextSegment( sp, 0, getLength() + 1, *this); mSegments.insert(default_segment); default_segment->linkToDocument(this); + memClaim(mSegments); } } @@ -904,6 +909,8 @@ void LLTextBase::insertSegment(LLTextSegmentPtr segment_to_insert) return; } + memDisclaim(mSegments); + segment_set_t::iterator cur_seg_iter = getSegIterContaining(segment_to_insert->getStart()); S32 reflow_start_index = 0; @@ -976,6 +983,7 @@ void LLTextBase::insertSegment(LLTextSegmentPtr segment_to_insert) // layout potentially changed needsReflow(reflow_start_index); + memClaim(mSegments); } BOOL LLTextBase::handleMouseDown(S32 x, S32 y, MASK mask) @@ -1271,8 +1279,11 @@ void LLTextBase::replaceWithSuggestion(U32 index) removeStringNoUndo(it->first, it->second - it->first); // Insert the suggestion in its place + memDisclaim(mSuggestionList); LLWString suggestion = utf8str_to_wstring(mSuggestionList[index]); insertStringNoUndo(it->first, utf8str_to_wstring(mSuggestionList[index])); + memClaim(mSuggestionList); + setCursorPos(it->first + (S32)suggestion.length()); break; @@ -1334,7 +1345,7 @@ bool LLTextBase::isMisspelledWord(U32 pos) const void LLTextBase::onSpellCheckSettingsChange() { // Recheck the spelling on every change - mMisspellRanges.clear(); + memDisclaim(mMisspellRanges).clear(); mSpellCheckStart = mSpellCheckEnd = -1; } @@ -1593,7 +1604,7 @@ LLRect LLTextBase::getTextBoundingRect() void LLTextBase::clearSegments() { - mSegments.clear(); + memDisclaim(mSegments).clear(); createDefaultSegment(); } @@ -3057,7 +3068,9 @@ void LLNormalTextSegment::setToolTip(const std::string& tooltip) llwarns << "LLTextSegment::setToolTip: cannot replace keyword tooltip." << llendl; return; } + memDisclaim(mTooltip); mTooltip = tooltip; + memClaim(mTooltip); } bool LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 90b147cee1..7d791ec75a 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -50,7 +50,10 @@ class LLUrlMatch; /// includes a start/end offset from the start of the string, a /// style to render with, an optional tooltip, etc. /// -class LLTextSegment : public LLRefCount, public LLMouseHandler +class LLTextSegment +: public LLRefCount, + public LLMouseHandler, + public LLTrace::MemTrackable<LLTextSegment> { public: LLTextSegment(S32 start, S32 end) : mStart(start), mEnd(end){}; @@ -91,10 +94,12 @@ public: /*virtual*/ void localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const; /*virtual*/ BOOL hasMouseCapture(); - S32 getStart() const { return mStart; } - void setStart(S32 start) { mStart = start; } - S32 getEnd() const { return mEnd; } - void setEnd( S32 end ) { mEnd = end; } + S32 getStart() const { return mStart; } + void setStart(S32 start) { mStart = start; } + S32 getEnd() const { return mEnd; } + void setEnd( S32 end ) { mEnd = end; } + + static LLTrace::MemStat sMemStat; protected: S32 mStart; diff --git a/indra/llui/lltransutil.cpp b/indra/llui/lltransutil.cpp index 58fa8a0828..80d079cbc8 100644 --- a/indra/llui/lltransutil.cpp +++ b/indra/llui/lltransutil.cpp @@ -31,15 +31,20 @@ #include "lltrans.h" #include "lluictrlfactory.h" #include "llxmlnode.h" - +#include "lldir.h" bool LLTransUtil::parseStrings(const std::string& xml_filename, const std::set<std::string>& default_args) { LLXMLNodePtr root; - BOOL success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root); + // 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" << llendl; + llerrs << "Couldn't load string table " << xml_filename << llendl; return false; } @@ -54,7 +59,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; } diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index 1dac622f32..6a87977718 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -1854,88 +1854,37 @@ struct Paths : public LLInitParam::Block<Paths> {} }; -//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<Directory>::const_iterator it = paths.directories.begin(), - end_it = paths.directories.end(); - it != end_it; - ++it) - { - std::string path_val_ui; - for (LLInitParam::ParamIterator<SubDir>::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); + if (gDirUtilp->fileExists(found_file)) { - found_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, filename); + 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 LLVector2 LLUI::getWindowSize() diff --git a/indra/llui/llui.h b/indra/llui/llui.h index d3c88cfb5f..90a4617c4e 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -294,11 +294,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<std::string>& 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..ffeff15968 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 <boost/foreach.hpp> LLUIColorTable::ColorParams::ColorParams() : value("value"), @@ -206,19 +207,12 @@ 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 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", LLDir::ALL_SKINS)) { - 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/lluictrl.cpp b/indra/llui/lluictrl.cpp index b9c843e931..08358484ef 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -118,6 +118,7 @@ LLUICtrl::LLUICtrl(const LLUICtrl::Params& p, const LLViewModelPtr& viewmodel) mDoubleClickSignal(NULL), mTransparencyType(TT_DEFAULT) { + memClaim(viewmodel.get()); } void LLUICtrl::initFromParams(const Params& p) @@ -940,7 +941,7 @@ boost::signals2::connection LLUICtrl::setCommitCallback( boost::function<void (L } boost::signals2::connection LLUICtrl::setValidateBeforeCommit( boost::function<bool (const LLSD& data)> cb ) { - if (!mValidateSignal) mValidateSignal = new enable_signal_t(); + if (!mValidateSignal) mValidateSignal = memClaim(new enable_signal_t()); return mValidateSignal->connect(boost::bind(cb, _2)); } @@ -1003,55 +1004,55 @@ boost::signals2::connection LLUICtrl::setValidateCallback(const EnableCallbackPa boost::signals2::connection LLUICtrl::setCommitCallback( const commit_signal_t::slot_type& cb ) { - if (!mCommitSignal) mCommitSignal = new commit_signal_t(); + if (!mCommitSignal) mCommitSignal = memClaim(new commit_signal_t()); return mCommitSignal->connect(cb); } boost::signals2::connection LLUICtrl::setValidateCallback( const enable_signal_t::slot_type& cb ) { - if (!mValidateSignal) mValidateSignal = new enable_signal_t(); + if (!mValidateSignal) mValidateSignal = memClaim(new enable_signal_t()); return mValidateSignal->connect(cb); } boost::signals2::connection LLUICtrl::setMouseEnterCallback( const commit_signal_t::slot_type& cb ) { - if (!mMouseEnterSignal) mMouseEnterSignal = new commit_signal_t(); + if (!mMouseEnterSignal) mMouseEnterSignal = memClaim(new commit_signal_t()); return mMouseEnterSignal->connect(cb); } boost::signals2::connection LLUICtrl::setMouseLeaveCallback( const commit_signal_t::slot_type& cb ) { - if (!mMouseLeaveSignal) mMouseLeaveSignal = new commit_signal_t(); + if (!mMouseLeaveSignal) mMouseLeaveSignal = memClaim(new commit_signal_t()); return mMouseLeaveSignal->connect(cb); } boost::signals2::connection LLUICtrl::setMouseDownCallback( const mouse_signal_t::slot_type& cb ) { - if (!mMouseDownSignal) mMouseDownSignal = new mouse_signal_t(); + if (!mMouseDownSignal) mMouseDownSignal = memClaim(new mouse_signal_t()); return mMouseDownSignal->connect(cb); } boost::signals2::connection LLUICtrl::setMouseUpCallback( const mouse_signal_t::slot_type& cb ) { - if (!mMouseUpSignal) mMouseUpSignal = new mouse_signal_t(); + if (!mMouseUpSignal) mMouseUpSignal = memClaim(new mouse_signal_t()); return mMouseUpSignal->connect(cb); } boost::signals2::connection LLUICtrl::setRightMouseDownCallback( const mouse_signal_t::slot_type& cb ) { - if (!mRightMouseDownSignal) mRightMouseDownSignal = new mouse_signal_t(); + if (!mRightMouseDownSignal) mRightMouseDownSignal = memClaim(new mouse_signal_t()); return mRightMouseDownSignal->connect(cb); } boost::signals2::connection LLUICtrl::setRightMouseUpCallback( const mouse_signal_t::slot_type& cb ) { - if (!mRightMouseUpSignal) mRightMouseUpSignal = new mouse_signal_t(); + if (!mRightMouseUpSignal) mRightMouseUpSignal = memClaim(new mouse_signal_t()); return mRightMouseUpSignal->connect(cb); } boost::signals2::connection LLUICtrl::setDoubleClickCallback( const mouse_signal_t::slot_type& cb ) { - if (!mDoubleClickSignal) mDoubleClickSignal = new mouse_signal_t(); + if (!mDoubleClickSignal) mDoubleClickSignal = memClaim(new mouse_signal_t()); return mDoubleClickSignal->connect(cb); } diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index 25e7a31e90..bd06476936 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); @@ -149,22 +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<std::string> 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<std::string> paths = + gDirUtilp->findSkinnedFilenames(LLDir::XUI, xui_filename, constraint); if (paths.empty()) { @@ -177,23 +169,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() //----------------------------------------------------------------------------- S32 LLUICtrlFactory::saveToXML(LLView* viewp, const std::string& filename) @@ -239,8 +214,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() @@ -255,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->findSkinnedFilename(LLUI::getSkinPath(), filename); -} - //static void LLUICtrlFactory::copyName(LLXMLNodePtr src, LLXMLNodePtr dest) { diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index 4e54354731..e6e9c66aef 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -32,6 +32,7 @@ #include "llregistry.h" #include "llxuiparser.h" #include "llstl.h" +#include "lldir.h" class LLView; @@ -161,32 +162,21 @@ public: LLView* createFromXML(LLXMLNodePtr node, LLView* parent, const std::string& filename, const widget_registry_t&, LLXMLNodePtr output_node ); template<typename T> - 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; - std::string skinned_filename = findSkinnedFilename(filename); instance().pushFileName(filename); { 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)) + if (!LLUICtrlFactory::getLayeredXMLNode(filename, root_node)) { - llwarns << "Couldn't parse XUI file: " << filename << llendl; - goto fail; - } - } - else 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, output_node); + LLView* view = getInstance()->createFromXML(root_node, parent, filename, registry, NULL); if (view) { widget = dynamic_cast<T*>(view); @@ -214,8 +204,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 getLocalizedXMLNode(const std::string &xui_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 @@ -270,10 +260,8 @@ private: // We always want to output top-left coordinates typename T::Params output_params(params); T::setupParamsForExport(output_params, parent); - // Export only the differences between this any default params - typename T::Params default_params(getDefaultParams<T>()); copyName(node, output_node); - parser.writeXUI(output_node, output_params, &default_params); + parser.writeXUI(output_node, output_params, LLInitParam::default_parse_rules(), &getDefaultParams<T>()); } // Apply layout transformations, usually munging rect @@ -300,9 +288,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<std::string> mFileNames; }; diff --git a/indra/llui/lluistring.cpp b/indra/llui/lluistring.cpp index c4e073ccdb..23fc53ea88 100644 --- a/indra/llui/lluistring.cpp +++ b/indra/llui/lluistring.cpp @@ -26,6 +26,8 @@ #include "linden_common.h" #include "lluistring.h" + +#include "llfasttimer.h" #include "llsd.h" #include "lltrans.h" diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 54843227b7..47bf410af6 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -30,7 +30,6 @@ #define LLVIEW_CPP #include "llview.h" -#include <cassert> #include <sstream> #include <boost/tokenizer.hpp> #include <boost/foreach.hpp> @@ -68,6 +67,7 @@ LLView* LLView::sPreviewClickedElement = NULL; BOOL LLView::sDrawPreviewHighlights = FALSE; S32 LLView::sLastLeftXML = S32_MIN; S32 LLView::sLastBottomXML = S32_MIN; +LLTrace::MemStat LLView::sMemStat("LLView"); std::vector<LLViewDrawContext*> LLViewDrawContext::sDrawContextStack; LLView::DrilldownFunc LLView::sDrilldown = @@ -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 diff --git a/indra/llui/llview.h b/indra/llui/llview.h index 1c35349510..256f86c00d 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -101,7 +101,8 @@ class LLView : public LLMouseHandler, // handles mouse events public LLFocusableElement, // handles keyboard events public LLMortician, // lazy deletion - public LLHandleProvider<LLView> // passes out weak references to self + public LLHandleProvider<LLView>, // passes out weak references to self + public LLTrace::MemTrackable<LLView> // track memory usage { public: struct Follows : public LLInitParam::ChoiceBlock<Follows> @@ -672,6 +673,7 @@ public: static S32 sLastLeftXML; static S32 sLastBottomXML; static BOOL sForceReshape; + static LLTrace::MemStat sMemStat; }; class LLCompareByTabOrder diff --git a/indra/llui/llviewmodel.cpp b/indra/llui/llviewmodel.cpp index a9f8acc440..1bd09e8086 100644 --- a/indra/llui/llviewmodel.cpp +++ b/indra/llui/llviewmodel.cpp @@ -35,6 +35,8 @@ // external library headers // other Linden headers +LLTrace::MemStat LLViewModel::sMemStat("LLViewModel"); + /// LLViewModel::LLViewModel() : mDirty(false) @@ -80,7 +82,10 @@ LLTextViewModel::LLTextViewModel(const LLSD& value) void LLTextViewModel::setValue(const LLSD& value) { LLViewModel::setValue(value); + memDisclaim(mDisplay); mDisplay = utf8str_to_wstring(value.asString()); + memClaim(mDisplay); + // mDisplay and mValue agree mUpdateFromDisplay = false; } @@ -91,7 +96,9 @@ void LLTextViewModel::setDisplay(const LLWString& value) // and do the utf8str_to_wstring() to get the corresponding mDisplay // value. But a text editor might want to edit the display string // directly, then convert back to UTF8 on commit. + memDisclaim(mDisplay); mDisplay = value; + memClaim(mDisplay); mDirty = true; // Don't immediately convert to UTF8 -- do it lazily -- we expect many // more setDisplay() calls than getValue() calls. Just flag that it needs diff --git a/indra/llui/llviewmodel.h b/indra/llui/llviewmodel.h index ef2e314799..214780393b 100644 --- a/indra/llui/llviewmodel.h +++ b/indra/llui/llviewmodel.h @@ -39,6 +39,7 @@ #include "llrefcount.h" #include "stdenums.h" #include "llstring.h" +#include "lltrace.h" #include <string> class LLScrollListItem; @@ -60,7 +61,9 @@ typedef LLPointer<LLListViewModel> LLListViewModelPtr; * LLViewModel data. This way, the LLViewModel is quietly deleted when the * last referencing widget is destroyed. */ -class LLViewModel: public LLRefCount +class LLViewModel +: public LLRefCount, + public LLTrace::MemTrackable<LLViewModel> { public: LLViewModel(); @@ -80,6 +83,8 @@ public: // void setDirty() { mDirty = true; } + static LLTrace::MemStat sMemStat; + protected: LLSD mValue; bool mDirty; diff --git a/indra/llui/llxuiparser.cpp b/indra/llui/llxuiparser.cpp index afc76024d1..903f10ce10 100644 --- a/indra/llui/llxuiparser.cpp +++ b/indra/llui/llxuiparser.cpp @@ -29,7 +29,7 @@ #include "llxuiparser.h" #include "llxmlnode.h" - +#include "llfasttimer.h" #ifdef LL_STANDALONE #include <expat.h> #else @@ -861,11 +861,11 @@ bool LLXUIParser::readAttributes(LLXMLNodePtr nodep, LLInitParam::BaseBlock& blo return any_parsed; } -void LLXUIParser::writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock &block, const LLInitParam::BaseBlock* diff_block) +void LLXUIParser::writeXUIImpl(LLXMLNodePtr node, const LLInitParam::BaseBlock &block, const LLInitParam::predicate_rule_t rules, const LLInitParam::BaseBlock* diff_block) { mWriteRootNode = node; name_stack_t name_stack = Parser::name_stack_t(); - block.serializeBlock(*this, name_stack, diff_block); + block.serializeBlock(*this, name_stack, rules, diff_block); mOutNodes.clear(); } @@ -880,16 +880,24 @@ LLXMLNodePtr LLXUIParser::getNode(name_stack_t& stack) it = next_it) { ++next_it; + bool force_new_node = false; + if (it->first.empty()) { it->second = false; continue; } + if (next_it != stack.end() && next_it->first.empty() && next_it->second) + { + force_new_node = true; + } + + out_nodes_t::iterator found_it = mOutNodes.find(it->first); // node with this name not yet written - if (found_it == mOutNodes.end() || it->second) + if (found_it == mOutNodes.end() || it->second || force_new_node) { // make an attribute if we are the last element on the name stack bool is_attribute = next_it == stack.end(); diff --git a/indra/llui/llxuiparser.h b/indra/llui/llxuiparser.h index d7cd256967..8d0276a8ad 100644 --- a/indra/llui/llxuiparser.h +++ b/indra/llui/llxuiparser.h @@ -109,9 +109,25 @@ public: /*virtual*/ void parserError(const std::string& message); void readXUI(LLXMLNodePtr node, LLInitParam::BaseBlock& block, const std::string& filename = LLStringUtil::null, bool silent=false); - void writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const LLInitParam::BaseBlock* diff_block = NULL); + template<typename BLOCK> + void writeXUI(LLXMLNodePtr node, + const BLOCK& block, + const LLInitParam::predicate_rule_t rules = LLInitParam::default_parse_rules(), + const LLInitParam::BaseBlock* diff_block = NULL) + { + if (!diff_block + && !rules.isAmbivalent(LLInitParam::HAS_DEFAULT_VALUE)) + { + diff_block = &LLInitParam::defaultValue<BLOCK>(); + } + writeXUIImpl(node, block, rules, diff_block); + } private: + void writeXUIImpl(LLXMLNodePtr node, + const LLInitParam::BaseBlock& block, + const LLInitParam::predicate_rule_t rules, + const LLInitParam::BaseBlock* diff_block); bool readXUIImpl(LLXMLNodePtr node, LLInitParam::BaseBlock& block); bool readAttributes(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block); |