summaryrefslogtreecommitdiff
path: root/indra/llui
diff options
context:
space:
mode:
authorEuclid Linden <euclid@lindenlab.com>2022-04-18 21:56:26 +0000
committerEuclid Linden <euclid@lindenlab.com>2022-04-18 21:56:26 +0000
commite71201ac125cab5f3d3cf7d6a30500253fc29d90 (patch)
tree270e46eb85dd46fb6962a36a9357dbf31c3afb29 /indra/llui
parent2d63d2044e0a00d1969c3da254e016a6e520c0d5 (diff)
parent035b1996df3f357b5060e3eb778588da5b9e7b37 (diff)
Merged in DV528-merge-6.5.5 (pull request #945)
DRTVWR-528 merge up to 6.5.5
Diffstat (limited to 'indra/llui')
-rw-r--r--indra/llui/llfloaterreg.cpp52
-rw-r--r--indra/llui/llfloaterreg.h1
-rw-r--r--indra/llui/llfolderview.cpp2
-rw-r--r--indra/llui/llfolderviewitem.cpp14
-rw-r--r--indra/llui/llfolderviewitem.h15
-rw-r--r--indra/llui/lllineeditor.cpp17
-rw-r--r--indra/llui/lllineeditor.h2
-rw-r--r--indra/llui/llmenugl.cpp52
-rw-r--r--indra/llui/llmenugl.h5
-rw-r--r--indra/llui/llnotifications.cpp14
-rw-r--r--indra/llui/llnotifications.h6
-rw-r--r--indra/llui/llscrolllistcell.cpp23
-rw-r--r--indra/llui/llscrolllistcell.h7
-rw-r--r--indra/llui/llscrolllistctrl.cpp23
-rw-r--r--indra/llui/llscrolllistctrl.h4
-rw-r--r--indra/llui/llscrolllistitem.cpp3
-rw-r--r--indra/llui/llscrolllistitem.h4
-rw-r--r--indra/llui/lltextbase.cpp13
-rw-r--r--indra/llui/llui.cpp1
-rw-r--r--indra/llui/llurlentry.cpp18
-rw-r--r--indra/llui/llurlentry.h11
-rw-r--r--indra/llui/llurlregistry.cpp2
22 files changed, 259 insertions, 30 deletions
diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp
index 36a0cb0fd0..f888d7ff68 100644
--- a/indra/llui/llfloaterreg.cpp
+++ b/indra/llui/llfloaterreg.cpp
@@ -531,6 +531,58 @@ void LLFloaterReg::toggleInstanceOrBringToFront(const LLSD& sdname, const LLSD&
}
// static
+// Same as toggleInstanceOrBringToFront but does not close floater.
+// unlike showInstance() does not trigger onOpen() if already open
+void LLFloaterReg::showInstanceOrBringToFront(const LLSD& sdname, const LLSD& key)
+{
+ std::string name = sdname.asString();
+ LLFloater* instance = getInstance(name, key);
+
+
+ if (!instance)
+ {
+ LL_DEBUGS() << "Unable to get instance of floater '" << name << "'" << LL_ENDL;
+ return;
+ }
+
+ // If hosted, we need to take that into account
+ LLFloater* host = instance->getHost();
+
+ if (host)
+ {
+ if (host->isMinimized() || !host->isShown() || !host->isFrontmost())
+ {
+ host->setMinimized(FALSE);
+ instance->openFloater(key);
+ instance->setVisibleAndFrontmost(true, key);
+ }
+ else if (!instance->getVisible())
+ {
+ instance->openFloater(key);
+ instance->setVisibleAndFrontmost(true, key);
+ instance->setFocus(TRUE);
+ }
+ }
+ else
+ {
+ if (instance->isMinimized())
+ {
+ instance->setMinimized(FALSE);
+ instance->setVisibleAndFrontmost(true, key);
+ }
+ else if (!instance->isShown())
+ {
+ instance->openFloater(key);
+ instance->setVisibleAndFrontmost(true, key);
+ }
+ else if (!instance->isFrontmost())
+ {
+ instance->setVisibleAndFrontmost(true, key);
+ }
+ }
+}
+
+// static
U32 LLFloaterReg::getVisibleFloaterInstanceCount()
{
U32 count = 0;
diff --git a/indra/llui/llfloaterreg.h b/indra/llui/llfloaterreg.h
index a457a15673..eaa59b1d6f 100644
--- a/indra/llui/llfloaterreg.h
+++ b/indra/llui/llfloaterreg.h
@@ -129,6 +129,7 @@ public:
// Callback wrappers
static void toggleInstanceOrBringToFront(const LLSD& sdname, const LLSD& key = LLSD());
+ static void showInstanceOrBringToFront(const LLSD& sdname, const LLSD& key = LLSD());
// Typed find / get / show
template <class T>
diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 622c9edba7..54fdee6901 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -257,6 +257,8 @@ LLFolderView::LLFolderView(const Params& p)
mPopupMenuHandle = menu->getHandle();
mViewModelItem->openItem();
+
+ mAreChildrenInited = true; // root folder is a special case due to not being loaded normally, assume that it's inited.
}
// Destroys the object
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 285bf9f484..eba93beed9 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -132,7 +132,6 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
mCutGeneration(0),
mLabelStyle( LLFontGL::NORMAL ),
mHasVisibleChildren(FALSE),
- mIsFolderComplete(true),
mLocalIndentation(p.folder_indentation),
mIndentation(0),
mItemHeight(p.item_height),
@@ -1003,11 +1002,11 @@ LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ):
mCurHeight(0.f),
mTargetHeight(0.f),
mAutoOpenCountdown(0.f),
+ mIsFolderComplete(false), // folder might have children that are not loaded yet.
+ mAreChildrenInited(false), // folder might have children that are not built yet.
mLastArrangeGeneration( -1 ),
mLastCalculatedWidth(0)
{
- // folder might have children that are not loaded yet. Mark it as incomplete until chance to check it.
- mIsFolderComplete = false;
}
void LLFolderViewFolder::updateLabelRotation()
@@ -1063,13 +1062,16 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height )
{
// Sort before laying out contents
// Note that we sort from the root (CHUI-849)
- getRoot()->getFolderViewModel()->sort(this);
+ if (mAreChildrenInited)
+ {
+ getRoot()->getFolderViewModel()->sort(this);
+ }
LL_RECORD_BLOCK_TIME(FTM_ARRANGE);
// evaluate mHasVisibleChildren
mHasVisibleChildren = false;
- if (getViewModelItem()->descendantsPassedFilter())
+ if (mAreChildrenInited && getViewModelItem()->descendantsPassedFilter())
{
// We have to verify that there's at least one child that's not filtered out
bool found = false;
@@ -1095,7 +1097,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height )
mHasVisibleChildren = found;
}
- if (!mIsFolderComplete)
+ if (!mIsFolderComplete && mAreChildrenInited)
{
mIsFolderComplete = getFolderViewModel()->isFolderComplete(this);
}
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index 616d2e7d86..ee20d048fd 100644
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -116,7 +116,6 @@ protected:
F32 mControlLabelRotation;
LLFolderView* mRoot;
bool mHasVisibleChildren,
- mIsFolderComplete, // indicates that some children were not loaded/added yet
mIsCurSelection,
mDragAndDropTarget,
mIsMouseOverTitle,
@@ -219,7 +218,10 @@ public:
BOOL hasVisibleChildren() { return mHasVisibleChildren; }
// true if object can't have children
- BOOL isFolderComplete() { return mIsFolderComplete; }
+ virtual bool isFolderComplete() { return true; }
+ // true if object can't have children
+ virtual bool areChildrenInited() { return true; }
+ virtual void setChildrenInited(bool inited) { }
// Call through to the viewed object and return true if it can be
// removed. Returns true if it's removed.
@@ -334,6 +336,8 @@ protected:
S32 mLastArrangeGeneration;
S32 mLastCalculatedWidth;
bool mNeedsSort;
+ bool mIsFolderComplete; // indicates that some children were not loaded/added yet
+ bool mAreChildrenInited; // indicates that no children were initialized
public:
typedef enum e_recurse_type
@@ -385,6 +389,13 @@ public:
// destroys this folder, and all children
virtual void destroyView();
+ // whether known children are fully loaded (arrange sets to true)
+ virtual bool isFolderComplete() { return mIsFolderComplete; }
+
+ // whether known children are fully built
+ virtual bool areChildrenInited() { return mAreChildrenInited; }
+ virtual void setChildrenInited(bool inited) { mAreChildrenInited = inited; }
+
// extractItem() removes the specified item from the folder, but
// doesn't delete it.
virtual void extractItem( LLFolderViewItem* item, bool deparent_model = true);
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index 1badd54fca..33037b5001 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -175,6 +175,14 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
mTripleClickTimer.reset();
setText(p.default_text());
+ if (p.initial_value.isProvided()
+ && !p.control_name.isProvided())
+ {
+ // Initial value often is descriptive, like "Type some ID here"
+ // and can be longer than size limitation, ignore size
+ setText(p.initial_value.getValue().asString(), false);
+ }
+
// Initialize current history line iterator
mCurrentHistoryLine = mLineHistory.begin();
@@ -390,6 +398,11 @@ void LLLineEditor::updateTextPadding()
void LLLineEditor::setText(const LLStringExplicit &new_text)
{
+ setText(new_text, true);
+}
+
+void LLLineEditor::setText(const LLStringExplicit &new_text, bool use_size_limit)
+{
// If new text is identical, don't copy and don't move insertion point
if (mText.getString() == new_text)
{
@@ -407,13 +420,13 @@ void LLLineEditor::setText(const LLStringExplicit &new_text)
all_selected = all_selected || (len == 0 && hasFocus() && mSelectAllonFocusReceived);
std::string truncated_utf8 = new_text;
- if (truncated_utf8.size() > (U32)mMaxLengthBytes)
+ if (use_size_limit && truncated_utf8.size() > (U32)mMaxLengthBytes)
{
truncated_utf8 = utf8str_truncate(new_text, mMaxLengthBytes);
}
mText.assign(truncated_utf8);
- if (mMaxLengthChars)
+ if (use_size_limit && mMaxLengthChars)
{
mText.assign(utf8str_symbol_truncate(truncated_utf8, mMaxLengthChars));
}
diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h
index f84625bea7..ae4e05c065 100644
--- a/indra/llui/lllineeditor.h
+++ b/indra/llui/lllineeditor.h
@@ -320,6 +320,8 @@ private:
virtual S32 getPreeditFontSize() const;
virtual LLWString getPreeditString() const { return getWText(); }
+ void setText(const LLStringExplicit &new_text, bool use_size_limit);
+
void setContextMenu(LLContextMenu* new_context_menu);
protected:
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index cdaf03ebde..76fd789bec 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -2362,6 +2362,16 @@ void LLMenuGL::arrange( void )
(*item_iter)->setRect( rect );
}
}
+
+
+ if (getTornOff())
+ {
+ LLTearOffMenu * torn_off_menu = dynamic_cast<LLTearOffMenu*>(getParent());
+ if (torn_off_menu)
+ {
+ torn_off_menu->updateSize();
+ }
+ }
}
if (mKeepFixedSize)
{
@@ -3879,7 +3889,8 @@ void LLMenuHolderGL::setActivatedItem(LLMenuItemGL* item)
/// Class LLTearOffMenu
///============================================================================
LLTearOffMenu::LLTearOffMenu(LLMenuGL* menup) :
- LLFloater(LLSD())
+ LLFloater(LLSD()),
+ mQuitRequested(false)
{
S32 floater_header_size = getHeaderHeight();
@@ -3894,7 +3905,7 @@ LLTearOffMenu::LLTearOffMenu(LLMenuGL* menup) :
LLRect rect;
menup->localRectToOtherView(LLRect(-1, menup->getRect().getHeight(), menup->getRect().getWidth() + 3, 0), &rect, gFloaterView);
// make sure this floater is big enough for menu
- mTargetHeight = (F32)(rect.getHeight() + floater_header_size);
+ mTargetHeight = rect.getHeight() + floater_header_size;
reshape(rect.getWidth(), rect.getHeight());
setRect(rect);
@@ -3926,19 +3937,24 @@ LLTearOffMenu::~LLTearOffMenu()
void LLTearOffMenu::draw()
{
mMenu->setBackgroundVisible(isBackgroundOpaque());
- mMenu->needsArrange();
if (getRect().getHeight() != mTargetHeight)
{
// animate towards target height
- reshape(getRect().getWidth(), llceil(lerp((F32)getRect().getHeight(), mTargetHeight, LLSmoothInterpolation::getInterpolant(0.05f))));
+ reshape(getRect().getWidth(), llceil(lerp((F32)getRect().getHeight(), (F32)mTargetHeight, LLSmoothInterpolation::getInterpolant(0.05f))));
+ mMenu->needsArrange();
}
LLFloater::draw();
}
void LLTearOffMenu::onFocusReceived()
{
- // if nothing is highlighted, just highlight first item
+ if (mQuitRequested)
+ {
+ return;
+ }
+
+ // if nothing is highlighted, just highlight first item
if (!mMenu->getHighlightedItem())
{
mMenu->highlightNextItem(NULL);
@@ -4014,6 +4030,31 @@ LLTearOffMenu* LLTearOffMenu::create(LLMenuGL* menup)
return tearoffp;
}
+void LLTearOffMenu::updateSize()
+{
+ if (mMenu)
+ {
+ S32 floater_header_size = getHeaderHeight();
+ const LLRect &floater_rect = getRect();
+ LLRect new_rect;
+ mMenu->localRectToOtherView(LLRect(-1, mMenu->getRect().getHeight() + floater_header_size, mMenu->getRect().getWidth() + 3, 0), &new_rect, gFloaterView);
+
+ if (floater_rect.getWidth() != new_rect.getWidth()
+ || mTargetHeight != new_rect.getHeight())
+ {
+ // make sure this floater is big enough for menu
+ mTargetHeight = new_rect.getHeight();
+ reshape(new_rect.getWidth(), mTargetHeight);
+
+ // Restore menu position
+ LLRect menu_rect = mMenu->getRect();
+ menu_rect.setOriginAndSize(1, 1,
+ menu_rect.getWidth(), menu_rect.getHeight());
+ mMenu->setRect(menu_rect);
+ }
+ }
+}
+
void LLTearOffMenu::closeTearOff()
{
removeChild(mMenu);
@@ -4024,6 +4065,7 @@ void LLTearOffMenu::closeTearOff()
mMenu->setVisible(FALSE);
mMenu->setTornOff(FALSE);
mMenu->setDropShadowed(TRUE);
+ mQuitRequested = true;
}
LLContextMenuBranch::LLContextMenuBranch(const LLContextMenuBranch::Params& p)
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index 273bd789c4..abbfd9a24a 100644
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -873,6 +873,8 @@ public:
virtual BOOL handleKeyHere(KEY key, MASK mask);
virtual void translate(S32 x, S32 y);
+ void updateSize();
+
private:
LLTearOffMenu(LLMenuGL* menup);
@@ -880,7 +882,8 @@ private:
LLView* mOldParent;
LLMenuGL* mMenu;
- F32 mTargetHeight;
+ S32 mTargetHeight;
+ bool mQuitRequested;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index b791a19c2b..a1f0e78bf3 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -1700,6 +1700,20 @@ void LLNotifications::add(const LLNotificationPtr pNotif)
updateItem(LLSD().with("sigtype", "add").with("id", pNotif->id()), pNotif);
}
+void LLNotifications::load(const LLNotificationPtr pNotif)
+{
+ if (pNotif == NULL) return;
+
+ // first see if we already have it -- if so, that's a problem
+ LLNotificationSet::iterator it=mItems.find(pNotif);
+ if (it != mItems.end())
+ {
+ LL_ERRS() << "Notification loaded a second time to the master notification channel." << LL_ENDL;
+ }
+
+ updateItem(LLSD().with("sigtype", "load").with("id", pNotif->id()), pNotif);
+}
+
void LLNotifications::cancel(LLNotificationPtr pNotif)
{
if (pNotif == NULL || pNotif->isCancelled()) return;
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 1c4860aa99..921398a693 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -917,6 +917,7 @@ public:
LLNotificationPtr add(const LLNotification::Params& p);
void add(const LLNotificationPtr pNotif);
+ void load(const LLNotificationPtr pNotif);
void cancel(LLNotificationPtr pNotif);
void cancelByName(const std::string& name);
void cancelByOwner(const LLUUID ownerId);
@@ -1117,6 +1118,11 @@ private:
mHistory.push_back(p);
}
+ void onLoad(LLNotificationPtr p)
+ {
+ mHistory.push_back(p);
+ }
+
std::vector<LLNotificationPtr> mHistory;
};
diff --git a/indra/llui/llscrolllistcell.cpp b/indra/llui/llscrolllistcell.cpp
index 13839da400..8dd552d2ad 100644
--- a/indra/llui/llscrolllistcell.cpp
+++ b/indra/llui/llscrolllistcell.cpp
@@ -79,6 +79,14 @@ const LLSD LLScrollListCell::getValue() const
return LLStringUtil::null;
}
+
+// virtual
+const LLSD LLScrollListCell::getAltValue() const
+{
+ return LLStringUtil::null;
+}
+
+
//
// LLScrollListIcon
//
@@ -173,6 +181,7 @@ U32 LLScrollListText::sCount = 0;
LLScrollListText::LLScrollListText(const LLScrollListCell::Params& p)
: LLScrollListCell(p),
mText(p.label.isProvided() ? p.label() : p.value().asString()),
+ mAltText(p.alt_value().asString()),
mFont(p.font),
mColor(p.color),
mUseColor(p.color.isProvided()),
@@ -275,10 +284,22 @@ void LLScrollListText::setValue(const LLSD& text)
setText(text.asString());
}
+//virtual
+void LLScrollListText::setAltValue(const LLSD& text)
+{
+ mAltText = text.asString();
+}
+
//virtual
const LLSD LLScrollListText::getValue() const
{
- return LLSD(mText.getString());
+ return LLSD(mText.getString());
+}
+
+//virtual
+const LLSD LLScrollListText::getAltValue() const
+{
+ return LLSD(mAltText.getString());
}
diff --git a/indra/llui/llscrolllistcell.h b/indra/llui/llscrolllistcell.h
index 19576fb247..ede8d847d9 100644
--- a/indra/llui/llscrolllistcell.h
+++ b/indra/llui/llscrolllistcell.h
@@ -60,6 +60,7 @@ public:
Optional<void*> userdata;
Optional<LLSD> value; // state of checkbox, icon id/name, date
+ Optional<LLSD> alt_value;
Optional<std::string> label; // description or text
Optional<std::string> tool_tip;
@@ -76,6 +77,7 @@ public:
enabled("enabled", true),
visible("visible", true),
value("value"),
+ alt_value("alt_value", ""),
label("label"),
tool_tip("tool_tip", ""),
font("font", LLFontGL::getFontSansSerifSmall()),
@@ -98,7 +100,9 @@ public:
virtual S32 getContentWidth() const { return 0; }
virtual S32 getHeight() const { return 0; }
virtual const LLSD getValue() const;
+ virtual const LLSD getAltValue() const;
virtual void setValue(const LLSD& value) { }
+ virtual void setAltValue(const LLSD& value) { }
virtual const std::string &getToolTip() const { return mToolTip; }
virtual void setToolTip(const std::string &str) { mToolTip = str; }
virtual BOOL getVisible() const { return TRUE; }
@@ -138,7 +142,9 @@ public:
/*virtual*/ S32 getContentWidth() const;
/*virtual*/ S32 getHeight() const;
/*virtual*/ void setValue(const LLSD& value);
+ /*virtual*/ void setAltValue(const LLSD& value);
/*virtual*/ const LLSD getValue() const;
+ /*virtual*/ const LLSD getAltValue() const;
/*virtual*/ BOOL getVisible() const;
/*virtual*/ void highlightText(S32 offset, S32 num_chars);
@@ -156,6 +162,7 @@ public:
protected:
LLUIString mText;
+ LLUIString mAltText;
S32 mTextWidth;
const LLFontGL* mFont;
LLColor4 mColor;
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index de644185fd..cd87c44dc2 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -66,9 +66,10 @@ static LLDefaultChildRegistry::Register<LLScrollListCtrl> r("scroll_list");
// local structures & classes.
struct SortScrollListItem
{
- SortScrollListItem(const std::vector<std::pair<S32, BOOL> >& sort_orders,const LLScrollListCtrl::sort_signal_t* sort_signal)
+ SortScrollListItem(const std::vector<std::pair<S32, BOOL> >& sort_orders,const LLScrollListCtrl::sort_signal_t* sort_signal, bool alternate_sort)
: mSortOrders(sort_orders)
, mSortSignal(sort_signal)
+ , mAltSort(alternate_sort)
{}
bool operator()(const LLScrollListItem* i1, const LLScrollListItem* i2)
@@ -93,7 +94,14 @@ struct SortScrollListItem
}
else
{
- sort_result = order * LLStringUtil::compareDict(cell1->getValue().asString(), cell2->getValue().asString());
+ if (mAltSort && !cell1->getAltValue().asString().empty() && !cell2->getAltValue().asString().empty())
+ {
+ sort_result = order * LLStringUtil::compareDict(cell1->getAltValue().asString(), cell2->getAltValue().asString());
+ }
+ else
+ {
+ sort_result = order * LLStringUtil::compareDict(cell1->getValue().asString(), cell2->getValue().asString());
+ }
}
if (sort_result != 0)
{
@@ -109,6 +117,7 @@ struct SortScrollListItem
typedef std::vector<std::pair<S32, BOOL> > sort_order_t;
const LLScrollListCtrl::sort_signal_t* mSortSignal;
const sort_order_t& mSortOrders;
+ const bool mAltSort;
};
//---------------------------------------------------------------------------
@@ -213,6 +222,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
mSearchColumn(p.search_column),
mColumnPadding(p.column_padding),
mRowPadding(p.row_padding),
+ mAlternateSort(false),
mContextMenuType(MENU_NONE),
mIsFriendSignal(NULL)
{
@@ -336,8 +346,7 @@ LLScrollListCtrl::~LLScrollListCtrl()
std::for_each(mItemList.begin(), mItemList.end(), DeletePointer());
mItemList.clear();
- std::for_each(mColumns.begin(), mColumns.end(), DeletePairedPointer());
- mColumns.clear();
+ clearColumns(); //clears columns and deletes headers
delete mIsFriendSignal;
}
@@ -2680,7 +2689,7 @@ void LLScrollListCtrl::updateSort() const
std::stable_sort(
mItemList.begin(),
mItemList.end(),
- SortScrollListItem(mSortColumns,mSortCallback));
+ SortScrollListItem(mSortColumns,mSortCallback, mAlternateSort));
mSorted = true;
}
@@ -2696,7 +2705,7 @@ void LLScrollListCtrl::sortOnce(S32 column, BOOL ascending)
std::stable_sort(
mItemList.begin(),
mItemList.end(),
- SortScrollListItem(sort_column,mSortCallback));
+ SortScrollListItem(sort_column,mSortCallback,mAlternateSort));
}
void LLScrollListCtrl::dirtyColumns()
@@ -3011,6 +3020,8 @@ void LLScrollListCtrl::clearColumns()
mSortColumns.clear();
mTotalStaticColumnWidth = 0;
mTotalColumnPadding = 0;
+
+ dirtyColumns(); // Clears mColumnsIndexed
}
void LLScrollListCtrl::setColumnLabel(const std::string& column, const std::string& label)
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 0cc481b113..08134bbfc8 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -398,6 +398,8 @@ public:
BOOL hasSortOrder() const;
void clearSortOrder();
+ void setAlternateSort() { mAlternateSort = true; }
+
S32 selectMultiple( uuid_vec_t ids );
// conceptually const, but mutates mItemList
void updateSort() const;
@@ -482,6 +484,8 @@ private:
bool mColumnsDirty;
bool mColumnWidthsDirty;
+ bool mAlternateSort;
+
mutable item_list mItemList;
LLScrollListItem *mLastSelected;
diff --git a/indra/llui/llscrolllistitem.cpp b/indra/llui/llscrolllistitem.cpp
index 51c615dd00..e1360f80cd 100644
--- a/indra/llui/llscrolllistitem.cpp
+++ b/indra/llui/llscrolllistitem.cpp
@@ -44,7 +44,8 @@ LLScrollListItem::LLScrollListItem( const Params& p )
mSelectedIndex(-1),
mEnabled(p.enabled),
mUserdata(p.userdata),
- mItemValue(p.value)
+ mItemValue(p.value),
+ mItemAltValue(p.alt_value)
{
}
diff --git a/indra/llui/llscrolllistitem.h b/indra/llui/llscrolllistitem.h
index d2c3dd7721..a3398305b1 100644
--- a/indra/llui/llscrolllistitem.h
+++ b/indra/llui/llscrolllistitem.h
@@ -55,6 +55,7 @@ public:
Optional<bool> enabled;
Optional<void*> userdata;
Optional<LLSD> value;
+ Optional<LLSD> alt_value;
Ignored name; // use for localization tools
Ignored type;
@@ -65,6 +66,7 @@ public:
Params()
: enabled("enabled", true),
value("value"),
+ alt_value("alt_value"),
name("name"),
type("type"),
length("length"),
@@ -97,6 +99,7 @@ public:
virtual LLUUID getUUID() const { return mItemValue.asUUID(); }
LLSD getValue() const { return mItemValue; }
+ LLSD getAltValue() const { return mItemAltValue; }
void setRect(LLRect rect) { mRectangle = rect; }
LLRect getRect() const { return mRectangle; }
@@ -131,6 +134,7 @@ private:
BOOL mEnabled;
void* mUserdata;
LLSD mItemValue;
+ LLSD mItemAltValue;
std::vector<LLScrollListCell *> mColumns;
LLRect mRectangle;
};
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 05788f1b6c..0532750dce 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -1564,11 +1564,14 @@ void LLTextBase::reflow()
{
// find first element whose end comes after start_index
line_list_t::iterator iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), start_index, line_end_compare());
- line_start_index = iter->mDocIndexStart;
- line_count = iter->mLineNum;
- cur_top = iter->mRect.mTop;
- getSegmentAndOffset(iter->mDocIndexStart, &seg_iter, &seg_offset);
- mLineInfoList.erase(iter, mLineInfoList.end());
+ if (iter != mLineInfoList.end())
+ {
+ line_start_index = iter->mDocIndexStart;
+ line_count = iter->mLineNum;
+ cur_top = iter->mRect.mTop;
+ getSegmentAndOffset(iter->mDocIndexStart, &seg_iter, &seg_offset);
+ mLineInfoList.erase(iter, mLineInfoList.end());
+ }
}
S32 line_height = 0;
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index 6f16745bd3..3f3ec7ee8b 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -173,6 +173,7 @@ mHelpImpl(NULL)
reg.add("Floater.Toggle", boost::bind(&LLFloaterReg::toggleInstance, _2, LLSD()));
reg.add("Floater.ToggleOrBringToFront", boost::bind(&LLFloaterReg::toggleInstanceOrBringToFront, _2, LLSD()));
reg.add("Floater.Show", boost::bind(&LLFloaterReg::showInstance, _2, LLSD(), FALSE));
+ reg.add("Floater.ShowOrBringToFront", boost::bind(&LLFloaterReg::showInstanceOrBringToFront, _2, LLSD()));
reg.add("Floater.Hide", boost::bind(&LLFloaterReg::hideInstance, _2, LLSD()));
// Button initialization callback for toggle buttons
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index 38495e1e0b..1547a4ba5c 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -1017,6 +1017,24 @@ std::string LLUrlEntryObjectIM::getLocation(const std::string &url) const
return LLUrlEntryBase::getLocation(url);
}
+//
+// LLUrlEntryChat Describes a Second Life chat Url, e.g.,
+// secondlife:///app/chat/42/This%20Is%20a%20test
+//
+
+LLUrlEntryChat::LLUrlEntryChat()
+{
+ mPattern = boost::regex("secondlife:///app/chat/\\d+/\\S+",
+ boost::regex::perl|boost::regex::icase);
+ mMenuName = "menu_url_slapp.xml";
+ mTooltip = LLTrans::getString("TooltipSLAPP");
+}
+
+std::string LLUrlEntryChat::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
+{
+ return unescapeUrl(url);
+}
+
// LLUrlEntryParcel statics.
LLUUID LLUrlEntryParcel::sAgentID(LLUUID::null);
LLUUID LLUrlEntryParcel::sSessionID(LLUUID::null);
diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h
index 102e0a4fd9..63a1506731 100644
--- a/indra/llui/llurlentry.h
+++ b/indra/llui/llurlentry.h
@@ -370,6 +370,17 @@ public:
private:
};
+//
+// LLUrlEntryChat Describes a Second Life chat Url, e.g.,
+// secondlife:///app/chat/42/This%20Is%20a%20test
+//
+class LLUrlEntryChat : public LLUrlEntryBase
+{
+public:
+ LLUrlEntryChat();
+ /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
+};
+
///
/// LLUrlEntryParcel Describes a Second Life parcel Url, e.g.,
/// secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about
diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp
index bfcd970529..c9d7013a11 100644
--- a/indra/llui/llurlregistry.cpp
+++ b/indra/llui/llurlregistry.cpp
@@ -63,6 +63,7 @@ LLUrlRegistry::LLUrlRegistry()
// LLUrlEntryAgent*Name must appear before LLUrlEntryAgent since
// LLUrlEntryAgent is a less specific (catchall for agent urls)
registerUrl(new LLUrlEntryAgent());
+ registerUrl(new LLUrlEntryChat());
registerUrl(new LLUrlEntryGroup());
registerUrl(new LLUrlEntryParcel());
registerUrl(new LLUrlEntryTeleport());
@@ -71,7 +72,6 @@ LLUrlRegistry::LLUrlRegistry()
registerUrl(new LLUrlEntryObjectIM());
registerUrl(new LLUrlEntryPlace());
registerUrl(new LLUrlEntryInventory());
- registerUrl(new LLUrlEntryObjectIM());
registerUrl(new LLUrlEntryExperienceProfile());
//LLUrlEntrySL and LLUrlEntrySLLabel have more common pattern,
//so it should be registered in the end of list