summaryrefslogtreecommitdiff
path: root/indra/llui
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llui')
-rw-r--r--indra/llui/CMakeLists.txt2
-rw-r--r--indra/llui/llaccordionctrltab.cpp51
-rw-r--r--indra/llui/llaccordionctrltab.h6
-rw-r--r--indra/llui/llfiltereditor.cpp1
-rw-r--r--indra/llui/llflatlistview.cpp46
-rw-r--r--indra/llui/llflatlistview.h2
-rw-r--r--indra/llui/llfloater.cpp9
-rw-r--r--indra/llui/llfloater.h4
-rw-r--r--indra/llui/llmenugl.cpp18
-rw-r--r--indra/llui/llresizebar.cpp5
-rw-r--r--indra/llui/lltextbase.cpp11
-rw-r--r--indra/llui/lltextutil.cpp79
-rw-r--r--indra/llui/lltextutil.h72
-rw-r--r--indra/llui/llurlentry.cpp29
-rw-r--r--indra/llui/llview.cpp60
-rw-r--r--indra/llui/llview.h3
-rw-r--r--indra/llui/tests/llurlentry_test.cpp26
17 files changed, 335 insertions, 89 deletions
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 3ecab90756..12df9ccae4 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -91,6 +91,7 @@ set(llui_SOURCE_FILES
lltextbox.cpp
lltexteditor.cpp
lltextparser.cpp
+ lltextutil.cpp
lltextvalidate.cpp
lltransutil.cpp
lltoggleablemenu.cpp
@@ -185,6 +186,7 @@ set(llui_HEADER_FILES
lltextbox.h
lltexteditor.h
lltextparser.h
+ lltextutil.h
lltextvalidate.h
lltoggleablemenu.h
lltooltip.h
diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp
index 596da782ce..b09c108ec3 100644
--- a/indra/llui/llaccordionctrltab.cpp
+++ b/indra/llui/llaccordionctrltab.cpp
@@ -32,12 +32,13 @@
#include "linden_common.h"
-#include "lluictrl.h"
-#include "llscrollbar.h"
#include "llaccordionctrltab.h"
-#include "lllocalcliprect.h"
+#include "lllocalcliprect.h"
+#include "llscrollbar.h"
#include "lltextbox.h"
+#include "lltextutil.h"
+#include "lluictrl.h"
static const std::string DD_BUTTON_NAME = "dd_button";
static const std::string DD_TEXTBOX_NAME = "dd_textbox";
@@ -72,7 +73,8 @@ public:
virtual BOOL postBuild();
- void setTitle(const std::string& title);
+ std::string getTitle();
+ void setTitle(const std::string& title, const std::string& hl);
virtual void onMouseEnter(S32 x, S32 y, MASK mask);
virtual void onMouseLeave(S32 x, S32 y, MASK mask);
@@ -146,10 +148,28 @@ BOOL LLAccordionCtrlTab::LLAccordionCtrlTabHeader::postBuild()
return TRUE;
}
-void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::setTitle(const std::string& title)
+std::string LLAccordionCtrlTab::LLAccordionCtrlTabHeader::getTitle()
{
if(mHeaderTextbox)
- mHeaderTextbox->setText(title);
+ {
+ return mHeaderTextbox->getText();
+ }
+ else
+ {
+ return LLStringUtil::null;
+ }
+}
+
+void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::setTitle(const std::string& title, const std::string& hl)
+{
+ if(mHeaderTextbox)
+ {
+ LLTextUtil::textboxSetHighlightedVal(
+ mHeaderTextbox,
+ LLStyle::Params(),
+ title,
+ hl);
+ }
}
void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::draw()
@@ -436,12 +456,25 @@ void LLAccordionCtrlTab::setAccordionView(LLView* panel)
addChild(panel,0);
}
-void LLAccordionCtrlTab::setTitle(const std::string& title)
+std::string LLAccordionCtrlTab::getTitle()
+{
+ LLAccordionCtrlTabHeader* header = findChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME);
+ if (header)
+ {
+ return header->getTitle();
+ }
+ else
+ {
+ return LLStringUtil::null;
+ }
+}
+
+void LLAccordionCtrlTab::setTitle(const std::string& title, const std::string& hl)
{
LLAccordionCtrlTabHeader* header = findChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME);
if (header)
{
- header->setTitle(title);
+ header->setTitle(title, hl);
}
}
@@ -903,5 +936,3 @@ BOOL LLAccordionCtrlTab::handleToolTip(S32 x, S32 y, MASK mask)
}
return LLUICtrl::handleToolTip(x, y, mask);
}
-
-
diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h
index de254ed3eb..f5b7fd0af6 100644
--- a/indra/llui/llaccordionctrltab.h
+++ b/indra/llui/llaccordionctrltab.h
@@ -113,8 +113,10 @@ public:
void setAccordionView(LLView* panel);
LLView* getAccordionView() { return mContainerPanel; };
- // Set text in LLAccordionCtrlTabHeader
- void setTitle(const std::string& title);
+ std::string getTitle();
+
+ // Set text and highlight substring in LLAccordionCtrlTabHeader
+ void setTitle(const std::string& title, const std::string& hl = LLStringUtil::null);
boost::signals2::connection setFocusReceivedCallback(const focus_signal_t::slot_type& cb);
boost::signals2::connection setFocusLostCallback(const focus_signal_t::slot_type& cb);
diff --git a/indra/llui/llfiltereditor.cpp b/indra/llui/llfiltereditor.cpp
index 390504234d..6c80275713 100644
--- a/indra/llui/llfiltereditor.cpp
+++ b/indra/llui/llfiltereditor.cpp
@@ -39,6 +39,7 @@
LLFilterEditor::LLFilterEditor(const LLFilterEditor::Params& p)
: LLSearchEditor(p)
{
+ setCommitOnFocusLost(FALSE); // we'll commit on every keystroke, don't re-commit when we take focus away (i.e. we go to interact with the actual results!)
}
diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp
index bea2572ff8..2433c14315 100644
--- a/indra/llui/llflatlistview.cpp
+++ b/indra/llui/llflatlistview.cpp
@@ -379,6 +379,7 @@ LLFlatListView::LLFlatListView(const LLFlatListView::Params& p)
, mCommitOnSelectionChange(false)
, mPrevNotifyParentRect(LLRect())
, mNoItemsCommentTextbox(NULL)
+ , mIsConsecutiveSelection(false)
{
mBorderThickness = getBorderWidth();
@@ -536,6 +537,7 @@ void LLFlatListView::onItemMouseClick(item_pair_t* item_pair, MASK mask)
return;
bool grab_items = false;
+ bool reverse = false;
pairs_list_t pairs_to_select;
// Pick out items from list between last selected and current clicked item_pair.
@@ -547,6 +549,8 @@ void LLFlatListView::onItemMouseClick(item_pair_t* item_pair, MASK mask)
item_pair_t* cur = *iter;
if (cur == last_selected_pair || cur == item_pair)
{
+ // We've got reverse selection if last grabed item isn't a new selection.
+ reverse = grab_items && (cur != item_pair);
grab_items = !grab_items;
// Skip last selected and current clicked item pairs.
continue;
@@ -562,26 +566,35 @@ void LLFlatListView::onItemMouseClick(item_pair_t* item_pair, MASK mask)
}
}
- if (select_item)
+ if (reverse)
{
- pairs_to_select.push_back(item_pair);
+ pairs_to_select.reverse();
}
+ pairs_to_select.push_back(item_pair);
+
for (pairs_iterator_t
iter = pairs_to_select.begin(),
iter_end = pairs_to_select.end();
iter != iter_end; ++iter)
{
item_pair_t* pair_to_select = *iter;
- selectItemPair(pair_to_select, true);
+ if (isSelected(pair_to_select))
+ {
+ // Item was already selected but there is a need to keep order from last selected pair to new selection.
+ // Do it here to prevent extra mCommitOnSelectionChange in selectItemPair().
+ mSelectedItemPairs.remove(pair_to_select);
+ mSelectedItemPairs.push_back(pair_to_select);
+ }
+ else
+ {
+ selectItemPair(pair_to_select, true);
+ }
}
if (!select_item)
{
- // Item was already selected but there is a need to update last selected item and its border.
- // Do it here to prevent extra mCommitOnSelectionChange in selectItemPair().
- mSelectedItemPairs.remove(item_pair);
- mSelectedItemPairs.push_back(item_pair);
+ // Update last selected item border.
mSelectedItemsBorder->setRect(getLastSelectedItemRect().stretch(-1));
}
return;
@@ -749,6 +762,8 @@ bool LLFlatListView::selectItemPair(item_pair_t* item_pair, bool select)
// Stretch selected item rect to ensure it won't be clipped
mSelectedItemsBorder->setRect(getLastSelectedItemRect().stretch(-1));
+ // By default mark it as not consecutive selection
+ mIsConsecutiveSelection = false;
return true;
}
@@ -823,6 +838,17 @@ bool LLFlatListView::selectNextItemPair(bool is_up_direction, bool reset_selecti
if ( 0 == size() )
return false;
+ if (!mIsConsecutiveSelection)
+ {
+ // Leave only one item selected if list has not consecutive selection
+ if (mSelectedItemPairs.size() && !reset_selection)
+ {
+ item_pair_t* cur_sel_pair = mSelectedItemPairs.back();
+ resetSelection();
+ selectItemPair (cur_sel_pair, true);
+ }
+ }
+
if ( mSelectedItemPairs.size() )
{
item_pair_t* to_sel_pair = NULL;
@@ -877,6 +903,8 @@ bool LLFlatListView::selectNextItemPair(bool is_up_direction, bool reset_selecti
}
// Select/Deselect next item
selectItemPair(select ? to_sel_pair : cur_sel_pair, select);
+ // Mark it as consecutive selection
+ mIsConsecutiveSelection = true;
return true;
}
}
@@ -888,6 +916,8 @@ bool LLFlatListView::selectNextItemPair(bool is_up_direction, bool reset_selecti
selectLastItem();
else
selectFirstItem();
+ // Mark it as consecutive selection
+ mIsConsecutiveSelection = true;
return true;
}
@@ -1255,7 +1285,7 @@ void LLFlatListViewEx::filterItems()
}
}
- rearrangeItems();
+ sort();
notifyParentItemsRectChanged();
}
diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h
index 6395805aab..f4e0426f15 100644
--- a/indra/llui/llflatlistview.h
+++ b/indra/llui/llflatlistview.h
@@ -410,6 +410,8 @@ private:
bool mKeepOneItemSelected;
+ bool mIsConsecutiveSelection;
+
/** All pairs of the list */
pairs_list_t mItemPairs;
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 79c47a1136..6babaf936b 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -169,6 +169,7 @@ LLFloater::Params::Params()
save_rect("save_rect", false),
save_visibility("save_visibility", false),
can_dock("can_dock", false),
+ open_centered("open_centered", false),
header_height("header_height", 0),
legacy_header_height("legacy_header_height", 0),
close_image("close_image"),
@@ -763,6 +764,13 @@ void LLFloater::applySavedVariables()
void LLFloater::applyRectControl()
{
+ // first, center on screen if requested
+ if (mOpenCentered)
+ {
+ center();
+ }
+
+ // override center if we have saved rect control
if (mRectControl.size() > 1)
{
const LLRect& rect = LLUI::sSettingGroups["floater"]->getRect(mRectControl);
@@ -2711,6 +2719,7 @@ void LLFloater::initFromParams(const LLFloater::Params& p)
mLegacyHeaderHeight = p.legacy_header_height;
mSingleInstance = p.single_instance;
mAutoTile = p.auto_tile;
+ mOpenCentered = p.open_centered;
if (p.save_rect)
{
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 444711de81..654164ddc0 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -110,7 +110,8 @@ public:
save_rect,
save_visibility,
save_dock_state,
- can_dock;
+ can_dock,
+ open_centered;
Optional<S32> header_height,
legacy_header_height; // HACK see initFromXML()
@@ -373,6 +374,7 @@ private:
BOOL mCanClose;
BOOL mDragOnLeft;
BOOL mResizable;
+ bool mOpenCentered;
S32 mMinWidth;
S32 mMinHeight;
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index e0e86ae228..b77126996e 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -3420,6 +3420,12 @@ BOOL LLMenuHolderGL::handleKey(KEY key, MASK mask, BOOL called_from_parent)
if (pMenu)
{
+ //eat TAB key - EXT-7000
+ if (key == KEY_TAB && mask == MASK_NONE)
+ {
+ return TRUE;
+ }
+
//handle ESCAPE and RETURN key
handled = LLPanel::handleKey(key, mask, called_from_parent);
if (!handled)
@@ -3726,10 +3732,14 @@ void LLContextMenuBranch::buildDrawLabel( void )
void LLContextMenuBranch::showSubMenu()
{
- S32 center_x;
- S32 center_y;
- localPointToScreen(getRect().getWidth(), getRect().getHeight() , &center_x, &center_y);
- mBranch->show( center_x, center_y);
+ LLMenuItemGL* menu_item = mBranch->getParentMenuItem();
+ if (menu_item != NULL && menu_item->getVisible())
+ {
+ S32 center_x;
+ S32 center_y;
+ localPointToScreen(getRect().getWidth(), getRect().getHeight() , &center_x, &center_y);
+ mBranch->show(center_x, center_y);
+ }
}
// onCommit() - do the primary funcationality of the menu item.
diff --git a/indra/llui/llresizebar.cpp b/indra/llui/llresizebar.cpp
index 0c46edf300..5d26b904b5 100644
--- a/indra/llui/llresizebar.cpp
+++ b/indra/llui/llresizebar.cpp
@@ -182,6 +182,11 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask)
break;
}
+ notifyParent(LLSD().with("action", "resize")
+ .with("view_name", mResizingView->getName())
+ .with("new_height", new_height)
+ .with("new_width", new_width));
+
scaled_rect.mTop = scaled_rect.mBottom + new_height;
scaled_rect.mRight = scaled_rect.mLeft + new_width;
mResizingView->setRect(scaled_rect);
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 390ec234d3..78a6ab1eaa 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -1116,8 +1116,19 @@ void LLTextBase::reflow()
updateSegments();
+ S32 reflow_count = 0;
while(mReflowIndex < S32_MAX)
{
+ // we can get into an infinite loop if the document height does not monotonically increase
+ // with decreasing width (embedded ui elements with alternate layouts). In that case,
+ // we want to stop reflowing after 2 iterations. We use 2, since we need to handle the case
+ // of introducing a vertical scrollbar causing a reflow with less width. We should also always
+ // use an even number of iterations to avoid user visible oscillation of the layout
+ if(++reflow_count > 2)
+ {
+ lldebugs << "Breaking out of reflow due to possible infinite loop in " << getName() << llendl;
+ break;
+ }
S32 start_index = mReflowIndex;
mReflowIndex = S32_MAX;
diff --git a/indra/llui/lltextutil.cpp b/indra/llui/lltextutil.cpp
new file mode 100644
index 0000000000..c5f3929fb1
--- /dev/null
+++ b/indra/llui/lltextutil.cpp
@@ -0,0 +1,79 @@
+/**
+ * @file lltextutil.cpp
+ * @brief Misc text-related auxiliary methods
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "lltextutil.h"
+
+#include "lluicolor.h"
+#include "lltextbox.h"
+
+
+void LLTextUtil::textboxSetHighlightedVal(LLTextBox *txtbox, const LLStyle::Params& normal_style, const std::string& text, const std::string& hl)
+{
+ static LLUIColor sFilterTextColor = LLUIColorTable::instance().getColor("FilterTextColor", LLColor4::green);
+
+ std::string text_uc = text;
+ LLStringUtil::toUpper(text_uc);
+
+ size_t hl_begin = 0, hl_len = hl.size();
+
+ if (hl_len == 0 || (hl_begin = text_uc.find(hl)) == std::string::npos)
+ {
+ txtbox->setText(text, normal_style);
+ return;
+ }
+
+ LLStyle::Params hl_style = normal_style;
+ hl_style.color = sFilterTextColor;
+
+ txtbox->setText(LLStringUtil::null); // clear text
+ txtbox->appendText(text.substr(0, hl_begin), false, normal_style);
+ txtbox->appendText(text.substr(hl_begin, hl_len), false, hl_style);
+ txtbox->appendText(text.substr(hl_begin + hl_len), false, normal_style);
+}
+
+const std::string& LLTextUtil::formatPhoneNumber(const std::string& phone_str)
+{
+ static const std::string PHONE_SEPARATOR = LLUI::sSettingGroups["config"]->getString("AvalinePhoneSeparator");
+ static const S32 PHONE_PART_LEN = 2;
+
+ static std::string formatted_phone_str;
+ formatted_phone_str = phone_str;
+ S32 separator_pos = (S32)(formatted_phone_str.size()) - PHONE_PART_LEN;
+ for (; separator_pos >= PHONE_PART_LEN; separator_pos -= PHONE_PART_LEN)
+ {
+ formatted_phone_str.insert(separator_pos, PHONE_SEPARATOR);
+ }
+
+ return formatted_phone_str;
+}
+
+// EOF
diff --git a/indra/llui/lltextutil.h b/indra/llui/lltextutil.h
new file mode 100644
index 0000000000..325c3c5b7c
--- /dev/null
+++ b/indra/llui/lltextutil.h
@@ -0,0 +1,72 @@
+/**
+ * @file lltextutil.h
+ * @brief Misc text-related auxiliary methods
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLTEXTUTIL_H
+#define LL_LLTEXTUTIL_H
+
+#include "llstyle.h"
+
+class LLTextBox;
+
+namespace LLTextUtil
+{
+
+ /**
+ * Set value for text box, highlighting substring hl_uc.
+ *
+ * Used to highlight filter matches.
+ *
+ * @param txtbox Text box to set value for
+ * @param normal_style Style to use for non-highlighted text
+ * @param text Text to set
+ * @param hl Upper-cased string to highlight
+ */
+ void textboxSetHighlightedVal(
+ LLTextBox *txtbox,
+ const LLStyle::Params& normal_style,
+ const std::string& text,
+ const std::string& hl);
+
+ /**
+ * Formats passed phone number to be more human readable.
+ *
+ * It just divides the number on parts by two digits from right to left. The first left part
+ * can have 2 or 3 digits, i.e. +44-33-33-44-55-66 or 12-34-56-78-90. Separator is set in
+ * application settings (AvalinePhoneSeparator)
+ *
+ * @param[in] phone_str string with original phone number
+ * @return reference to string with formatted phone number
+ */
+ const std::string& formatPhoneNumber(const std::string& phone_str);
+}
+
+#endif // LL_LLTEXTUTIL_H
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index 3375c13c94..fd56a87345 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -41,6 +41,9 @@
#include "lltrans.h"
#include "lluicolortable.h"
+#define APP_HEADER_REGEX "((x-grid-location-info://[-\\w\\.]+/app)|(secondlife:///app))"
+
+
LLUrlEntryBase::LLUrlEntryBase() :
mColor(LLUIColorTable::instance().getColor("HTMLLinkColor")),
mDisabledLink(false)
@@ -303,10 +306,11 @@ std::string LLUrlEntrySLURL::getLocation(const std::string &url) const
//
// LLUrlEntryAgent Describes a Second Life agent Url, e.g.,
// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about
+// x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about
//
LLUrlEntryAgent::LLUrlEntryAgent()
{
- mPattern = boost::regex("secondlife:///app/agent/[\\da-f-]+/\\w+",
+ mPattern = boost::regex(APP_HEADER_REGEX "/agent/[\\da-f-]+/\\w+",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_agent.xml";
mIcon = "Generic_Person";
@@ -418,10 +422,11 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa
// LLUrlEntryGroup Describes a Second Life group Url, e.g.,
// secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about
// secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/inspect
+// x-grid-location-info://lincoln.lindenlab.com/app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/inspect
//
LLUrlEntryGroup::LLUrlEntryGroup()
{
- mPattern = boost::regex("secondlife:///app/group/[\\da-f-]+/\\w+",
+ mPattern = boost::regex(APP_HEADER_REGEX "/group/[\\da-f-]+/\\w+",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_group.xml";
mIcon = "Generic_Group";
@@ -482,7 +487,8 @@ LLUrlEntryInventory::LLUrlEntryInventory()
//*TODO: add supporting of inventory item names with whitespaces
//this pattern cann't parse for example
//secondlife:///app/inventory/0e346d8b-4433-4d66-a6b0-fd37083abc4c/select?name=name with spaces&param2=value
- mPattern = boost::regex("secondlife:///app/inventory/[\\da-f-]+/\\w+\\S*",
+ //x-grid-location-info://lincoln.lindenlab.com/app/inventory/0e346d8b-4433-4d66-a6b0-fd37083abc4c/select?name=name with spaces&param2=value
+ mPattern = boost::regex(APP_HEADER_REGEX "/inventory/[\\da-f-]+/\\w+\\S*",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_inventory.xml";
}
@@ -525,10 +531,11 @@ std::string LLUrlEntryObjectIM::getLocation(const std::string &url) const
///
/// LLUrlEntryParcel Describes a Second Life parcel Url, e.g.,
/// secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about
+/// x-grid-location-info://lincoln.lindenlab.com/app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about
///
LLUrlEntryParcel::LLUrlEntryParcel()
{
- mPattern = boost::regex("secondlife:///app/parcel/[\\da-f-]+/about",
+ mPattern = boost::regex(APP_HEADER_REGEX "/parcel/[\\da-f-]+/about",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_parcel.xml";
mTooltip = LLTrans::getString("TooltipParcelUrl");
@@ -544,7 +551,7 @@ std::string LLUrlEntryParcel::getLabel(const std::string &url, const LLUrlLabelC
//
LLUrlEntryPlace::LLUrlEntryPlace()
{
- mPattern = boost::regex("secondlife://\\S+/?(\\d+/\\d+/\\d+|\\d+/\\d+)/?",
+ mPattern = boost::regex("((x-grid-location-info://[-\\w\\.]+/region/)|(secondlife://))\\S+/?(\\d+/\\d+/\\d+|\\d+/\\d+)/?",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_slurl.xml";
mTooltip = LLTrans::getString("TooltipSLURL");
@@ -589,10 +596,11 @@ std::string LLUrlEntryPlace::getLocation(const std::string &url) const
//
// LLUrlEntryTeleport Describes a Second Life teleport Url, e.g.,
// secondlife:///app/teleport/Ahern/50/50/50/
+// x-grid-location-info://lincoln.lindenlab.com/app/teleport/Ahern/50/50/50/
//
LLUrlEntryTeleport::LLUrlEntryTeleport()
{
- mPattern = boost::regex("secondlife:///app/teleport/\\S+(/\\d+)?(/\\d+)?(/\\d+)?/?\\S*",
+ mPattern = boost::regex(APP_HEADER_REGEX "/teleport/\\S+(/\\d+)?(/\\d+)?(/\\d+)?/?\\S*",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_teleport.xml";
mTooltip = LLTrans::getString("TooltipTeleportUrl");
@@ -610,7 +618,12 @@ std::string LLUrlEntryTeleport::getLabel(const std::string &url, const LLUrlLabe
LLURI uri(url);
LLSD path_array = uri.pathArray();
S32 path_parts = path_array.size();
- const std::string label = LLTrans::getString("SLurlLabelTeleport");
+ std::string host = uri.hostName();
+ std::string label = LLTrans::getString("SLurlLabelTeleport");
+ if (!host.empty())
+ {
+ label += " " + host;
+ }
if (path_parts == 6)
{
// handle teleport url with (X,Y,Z) coordinates
@@ -709,7 +722,7 @@ std::string LLUrlEntrySLLabel::getTooltip(const std::string &string) const
//
LLUrlEntryWorldMap::LLUrlEntryWorldMap()
{
- mPattern = boost::regex("secondlife:///app/worldmap/\\S+/?(\\d+)?/?(\\d+)?/?(\\d+)?/?\\S*",
+ mPattern = boost::regex(APP_HEADER_REGEX "/worldmap/\\S+/?(\\d+)?/?(\\d+)?/?(\\d+)?/?\\S*",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_map.xml";
mTooltip = LLTrans::getString("TooltipMapUrl");
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index e67f0ec3fc..bd56da9121 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -107,8 +107,6 @@ LLView::Params::Params()
top_delta("top_delta", S32_MAX),
left_pad("left_pad"),
left_delta("left_delta", S32_MAX),
- center_horiz("center_horiz", false),
- center_vert("center_vert", false),
from_xui("from_xui", false),
user_resize("user_resize"),
auto_resize("auto_resize"),
@@ -1321,8 +1319,6 @@ void LLView::drawChildren()
if (viewp->getVisible() && viewp->getRect().isValid())
{
- // check for bad data
- llassert_always(viewp->getVisible() == TRUE);
// Only draw views that are within the root view
localRectToScreen(viewp->getRect(),&screenRect);
if ( rootRect.overlaps(screenRect) && LLUI::sDirtyRect.overlaps(screenRect))
@@ -2501,7 +2497,6 @@ void LLView::applyXUILayout(LLView::Params& p, LLView* parent)
p.layout = parent->getLayout();
}
-
if (parent)
{
LLRect parent_rect = parent->getLocalRect();
@@ -2509,60 +2504,21 @@ void LLView::applyXUILayout(LLView::Params& p, LLView* parent)
LLRect last_rect = parent->getLocalRect();
bool layout_topleft = (p.layout() == "topleft");
- if (layout_topleft)
- {
- //invert top to bottom
- if (p.rect.top.isProvided()) p.rect.top = parent_rect.getHeight() - p.rect.top;
- if (p.rect.bottom.isProvided()) p.rect.bottom = parent_rect.getHeight() - p.rect.bottom;
- }
// convert negative or centered coordinates to parent relative values
// Note: some of this logic matches the logic in TypedParam<LLRect>::setValueFromBlock()
+ if (p.rect.left.isProvided() && p.rect.left < 0) p.rect.left = p.rect.left + parent_rect.getWidth();
+ if (p.rect.right.isProvided() && p.rect.right < 0) p.rect.right = p.rect.right + parent_rect.getWidth();
+ if (p.rect.bottom.isProvided() && p.rect.bottom < 0) p.rect.bottom = p.rect.bottom + parent_rect.getHeight();
+ if (p.rect.top.isProvided() && p.rect.top < 0) p.rect.top = p.rect.top + parent_rect.getHeight();
- if (p.center_horiz)
- {
- if (p.rect.left.isProvided() && p.rect.right.isProvided())
- {
- S32 width = p.rect.right - p.rect.left;
- width = llmax(width, 0);
- S32 offset = parent_rect.getWidth()/2 - width/2;
- p.rect.left = p.rect.left + offset;
- p.rect.right = p.rect.right + offset;
- }
- else
- {
- p.rect.left = p.rect.left + parent_rect.getWidth()/2 - p.rect.width/2;
- p.rect.right.setProvided(false); // recalculate the right
- }
- }
- else
- {
- if (p.rect.left.isProvided() && p.rect.left < 0) p.rect.left = p.rect.left + parent_rect.getWidth();
- if (p.rect.right.isProvided() && p.rect.right < 0) p.rect.right = p.rect.right + parent_rect.getWidth();
- }
- if (p.center_vert)
- {
- if (p.rect.bottom.isProvided() && p.rect.top.isProvided())
- {
- S32 height = p.rect.top - p.rect.bottom;
- height = llmax(height, 0);
- S32 offset = parent_rect.getHeight()/2 - height/2;
- p.rect.bottom = p.rect.bottom + offset;
- p.rect.top = p.rect.top + offset;
- }
- else
- {
- p.rect.bottom = p.rect.bottom + parent_rect.getHeight()/2 - p.rect.height/2;
- p.rect.top.setProvided(false); // recalculate the top
- }
- }
- else
+ if (layout_topleft)
{
- if (p.rect.bottom.isProvided() && p.rect.bottom < 0) p.rect.bottom = p.rect.bottom + parent_rect.getHeight();
- if (p.rect.top.isProvided() && p.rect.top < 0) p.rect.top = p.rect.top + parent_rect.getHeight();
+ //invert top to bottom
+ if (p.rect.top.isProvided()) p.rect.top = parent_rect.getHeight() - p.rect.top;
+ if (p.rect.bottom.isProvided()) p.rect.bottom = parent_rect.getHeight() - p.rect.bottom;
}
-
// DEPRECATE: automatically fall back to height of MIN_WIDGET_HEIGHT pixels
if (!p.rect.height.isProvided() && !p.rect.top.isProvided() && p.rect.height == 0)
{
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index efae00f0e5..3779fedf34 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -143,9 +143,6 @@ public:
left_pad, // from last right to my left
left_delta; // from last left to my left
- Optional<bool> center_horiz,
- center_vert;
-
// these are nested attributes for LLLayoutPanel
//FIXME: get parent context involved in parsing traversal
Ignored user_resize,
diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp
index cbb303a059..4463b6cc6f 100644
--- a/indra/llui/tests/llurlentry_test.cpp
+++ b/indra/llui/tests/llurlentry_test.cpp
@@ -286,6 +286,13 @@ namespace tut
"XXX secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/foobar",
"secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/foobar");
+ testRegex("Standalone Agent Url ", url,
+ "x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about",
+ "x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");
+
+ testRegex("Standalone Agent Url Multicase with Text", url,
+ "M x-grid-location-info://lincoln.lindenlab.com/app/AGENT/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about M",
+ "x-grid-location-info://lincoln.lindenlab.com/app/AGENT/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");
}
template<> template<>
@@ -315,6 +322,15 @@ namespace tut
testRegex("Group Url multicase", url,
"XXX secondlife:///APP/Group/00005FF3-4044-c79f-9de8-fb28ae0df991/About XXX",
"secondlife:///APP/Group/00005FF3-4044-c79f-9de8-fb28ae0df991/About");
+
+ testRegex("Standalone Group Url ", url,
+ "x-grid-location-info://lincoln.lindenlab.com/app/group/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about",
+ "x-grid-location-info://lincoln.lindenlab.com/app/group/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");
+
+ testRegex("Standalone Group Url Multicase ith Text", url,
+ "M x-grid-location-info://lincoln.lindenlab.com/app/GROUP/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about M",
+ "x-grid-location-info://lincoln.lindenlab.com/app/GROUP/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");
+
}
template<> template<>
@@ -361,7 +377,11 @@ namespace tut
// DEV-35459: SLURLs and teleport Links not parsed properly
testRegex("SLURL with quote", url,
"XXX secondlife://A'ksha%20Oasis/41/166/701 XXX",
- "secondlife://A%27ksha%20Oasis/41/166/701");
+ "secondlife://A%27ksha%20Oasis/41/166/701");
+
+ testRegex("Standalone All Hands (50,50) [2] with text", url,
+ "XXX x-grid-location-info://lincoln.lindenlab.com/region/All%20Hands/50/50/50 XXX",
+ "x-grid-location-info://lincoln.lindenlab.com/region/All%20Hands/50/50/50");
}
template<> template<>
@@ -461,6 +481,10 @@ namespace tut
testRegex("Teleport url with quote", url,
"XXX secondlife:///app/teleport/A'ksha%20Oasis/41/166/701 XXX",
"secondlife:///app/teleport/A%27ksha%20Oasis/41/166/701");
+
+ testRegex("Standalone All Hands", url,
+ "XXX x-grid-location-info://lincoln.lindenlab.com/app/teleport/All%20Hands/50/50/50 XXX",
+ "x-grid-location-info://lincoln.lindenlab.com/app/teleport/All%20Hands/50/50/50");
}
template<> template<>