summaryrefslogtreecommitdiff
path: root/indra/llui
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llui')
-rw-r--r--indra/llui/llaccordionctrltab.cpp3
-rw-r--r--indra/llui/llbutton.cpp14
-rw-r--r--indra/llui/llbutton.h1
-rw-r--r--indra/llui/llflatlistview.cpp9
-rw-r--r--indra/llui/llfloater.cpp64
-rw-r--r--indra/llui/llfloater.h3
-rw-r--r--indra/llui/lllayoutstack.h2
-rw-r--r--indra/llui/llmenugl.cpp4
-rw-r--r--indra/llui/llpanel.cpp38
-rw-r--r--indra/llui/llpanel.h3
-rw-r--r--indra/llui/llresizehandle.cpp81
-rw-r--r--indra/llui/llscrollcontainer.cpp5
-rw-r--r--indra/llui/llscrolllistctrl.cpp5
-rw-r--r--indra/llui/llscrolllistctrl.h3
-rw-r--r--indra/llui/lltabcontainer.cpp31
-rw-r--r--indra/llui/lltabcontainer.h1
-rw-r--r--indra/llui/lltextbase.cpp14
-rw-r--r--indra/llui/lltexteditor.cpp3
-rw-r--r--indra/llui/lluictrl.cpp8
-rw-r--r--indra/llui/llurlentry.cpp59
-rw-r--r--indra/llui/llurlentry.h14
-rw-r--r--indra/llui/llurlregistry.cpp11
-rw-r--r--indra/llui/llurlregistry.h4
-rw-r--r--indra/llui/tests/llurlentry_stub.cpp7
-rw-r--r--indra/llui/tests/llurlentry_test.cpp55
25 files changed, 262 insertions, 180 deletions
diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp
index 9d6ba57c29..4bfe44135a 100644
--- a/indra/llui/llaccordionctrltab.cpp
+++ b/indra/llui/llaccordionctrltab.cpp
@@ -157,7 +157,8 @@ void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::draw()
// because the user's mental model of focus is that it goes away after
// the accordion is closed.
if (getParent()->hasFocus()
- && !(collapsible && !expanded))
+ /*&& !(collapsible && !expanded)*/ // WHY??
+ )
{
mImageHeaderFocused->draw(0,0,width,height);
}
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index e9f6288f44..9ce8ce8d55 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -1022,6 +1022,20 @@ void LLButton::setImageOverlay(const std::string& image_name, LLFontGL::HAlign a
}
}
+void LLButton::setImageOverlay(const LLUUID& image_id, LLFontGL::HAlign alignment, const LLColor4& color)
+{
+ if (image_id.isNull())
+ {
+ mImageOverlay = NULL;
+ }
+ else
+ {
+ mImageOverlay = LLUI::getUIImageByID(image_id);
+ mImageOverlayAlignment = alignment;
+ mImageOverlayColor = color;
+ }
+}
+
void LLButton::onMouseCaptureLost()
{
resetMouseDownTimer();
diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h
index 5e28b8cdff..cd149e3113 100644
--- a/indra/llui/llbutton.h
+++ b/indra/llui/llbutton.h
@@ -200,6 +200,7 @@ public:
void setDisabledSelectedLabelColor( const LLColor4& c ) { mDisabledSelectedLabelColor = c; }
void setImageOverlay(const std::string& image_name, LLFontGL::HAlign alignment = LLFontGL::HCENTER, const LLColor4& color = LLColor4::white);
+ void setImageOverlay(const LLUUID& image_id, LLFontGL::HAlign alignment = LLFontGL::HCENTER, const LLColor4& color = LLColor4::white);
LLPointer<LLUIImage> getImageOverlay() { return mImageOverlay; }
void autoResize(); // resize with label of current btn state
diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp
index 9cfc67af14..3694ecd4f4 100644
--- a/indra/llui/llflatlistview.cpp
+++ b/indra/llui/llflatlistview.cpp
@@ -711,19 +711,12 @@ void LLFlatListView::selectLastItem ()
void LLFlatListView::ensureSelectedVisible()
{
- LLRect visible_rc = getVisibleContentRect();
LLRect selected_rc = getLastSelectedItemRect();
- if ( !visible_rc.contains (selected_rc) )
+ if ( selected_rc.isValid() )
{
- // But scroll in Items panel coordinates
scrollToShowRect(selected_rc);
}
-
- // In case we are in accordion tab notify parent to show selected rectangle
- LLRect screen_rc;
- localRectToScreen(selected_rc, &screen_rc);
- notifyParent(LLSD().with("scrollToShowRect",screen_rc.getValue()));
}
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 845203b420..79d8f90fec 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -233,6 +233,7 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
mAutoFocus(TRUE), // automatically take focus when opened
mCanDock(false),
mDocked(false),
+ mTornOff(false),
mHasBeenDraggedWhileMinimized(FALSE),
mPreviousMinimizedBottom(0),
mPreviousMinimizedLeft(0)
@@ -878,9 +879,11 @@ void LLFloater::setSnappedTo(const LLView* snap_view)
else
{
//RN: assume it's a floater as it must be a sibling to our parent floater
- LLFloater* floaterp = (LLFloater*)snap_view;
-
- setSnapTarget(floaterp->getHandle());
+ const LLFloater* floaterp = dynamic_cast<const LLFloater*>(snap_view);
+ if (floaterp)
+ {
+ setSnapTarget(floaterp->getHandle());
+ }
}
}
@@ -1065,10 +1068,6 @@ void LLFloater::setMinimized(BOOL minimize)
reshape( mExpandedRect.getWidth(), mExpandedRect.getHeight(), TRUE );
}
- // don't show the help button while minimized - it's
- // not very useful when minimized and uses up space
- mButtonsEnabled[BUTTON_HELP] = !minimize;
-
applyTitle ();
make_ui_sound("UISndWindowClose");
@@ -1361,6 +1360,7 @@ void LLFloater::bringToFront( S32 x, S32 y )
// virtual
void LLFloater::setVisibleAndFrontmost(BOOL take_focus)
{
+ gFocusMgr.setTopCtrl(NULL);
setVisible(TRUE);
setFrontmost(take_focus);
}
@@ -1458,6 +1458,7 @@ void LLFloater::onClickTearOff(LLFloater* self)
}
self->setTornOff(false);
}
+ self->updateButtons();
}
// static
@@ -1741,14 +1742,32 @@ void LLFloater::updateButtons()
S32 button_count = 0;
for (S32 i = 0; i < BUTTON_COUNT; i++)
{
- if(!mButtons[i]) continue;
- mButtons[i]->setEnabled(mButtonsEnabled[i]);
+ if (!mButtons[i])
+ {
+ continue;
+ }
+
+ bool enabled = mButtonsEnabled[i];
+ if (i == BUTTON_HELP)
+ {
+ // don't show the help button if the floater is minimized
+ // or if it is a docked tear-off floater
+ if (isMinimized() || (mButtonsEnabled[BUTTON_TEAR_OFF] && ! mTornOff))
+ {
+ enabled = false;
+ }
+ }
+ if (i == BUTTON_CLOSE && mButtonScale != 1.f)
+ {
+ //*HACK: always render close button for hosted floaters so
+ //that users don't accidentally hit the button when
+ //closing multiple windows in the chatterbox
+ enabled = true;
+ }
- if (mButtonsEnabled[i]
- //*HACK: always render close button for hosted floaters
- // so that users don't accidentally hit the button when closing multiple windows
- // in the chatterbox
- || (i == BUTTON_CLOSE && mButtonScale != 1.f))
+ mButtons[i]->setEnabled(enabled);
+
+ if (enabled)
{
button_count++;
@@ -1775,7 +1794,7 @@ void LLFloater::updateButtons()
// the restore button should have a tab stop so that it takes action when you Ctrl-Tab to a minimized floater
mButtons[i]->setTabStop(i == BUTTON_RESTORE);
}
- else if (mButtons[i])
+ else
{
mButtons[i]->setVisible(FALSE);
}
@@ -2344,7 +2363,7 @@ void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_out
LLRect::tCoordType screen_width = getSnapRect().getWidth();
LLRect::tCoordType screen_height = getSnapRect().getHeight();
-
+
// only automatically resize non-minimized, resizable floaters
if( floater->isResizable() && !floater->isMinimized() )
{
@@ -2369,16 +2388,13 @@ void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_out
new_width = llmax(new_width, min_width);
new_height = llmax(new_height, min_height);
+ LLRect new_rect;
+ new_rect.setLeftTopAndSize(view_rect.mLeft,view_rect.mTop,new_width, new_height);
+
floater->reshape( new_width, new_height, TRUE );
- if (floater->followsRight())
- {
- floater->translate(old_width - new_width, 0);
- }
+ floater->setRect(new_rect);
- if (floater->followsTop())
- {
- floater->translate(0, old_height - new_height);
- }
+ floater->translateIntoRect( getLocalRect(), false );
}
}
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index daf558de24..f70495c0f0 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -256,7 +256,7 @@ public:
bool isDocked() const { return mDocked; }
virtual void setDocked(bool docked, bool pop_on_undock = true);
- virtual void setTornOff(bool torn_off) {}
+ virtual void setTornOff(bool torn_off) { mTornOff = torn_off; }
// Return a closeable floater, if any, given the current focus.
static LLFloater* getClosableFloaterFromFocus();
@@ -387,6 +387,7 @@ private:
bool mCanDock;
bool mDocked;
+ bool mTornOff;
static LLMultiFloater* sHostp;
static BOOL sQuitting;
diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h
index aba35773ee..c4f10038f8 100644
--- a/indra/llui/lllayoutstack.h
+++ b/indra/llui/lllayoutstack.h
@@ -93,6 +93,8 @@ public:
void updateLayout(BOOL force_resize = FALSE);
S32 getPanelSpacing() const { return mPanelSpacing; }
+ BOOL getAnimate () const { return mAnimate; }
+ void setAnimate (BOOL animate) { mAnimate = animate; }
static void updateClass();
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index bd67949c2a..c172a2b714 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -99,7 +99,7 @@ const S32 TEAROFF_SEPARATOR_HEIGHT_PIXELS = 10;
const S32 MENU_ITEM_PADDING = 4;
const std::string BOOLEAN_TRUE_PREFIX( "\xE2\x9C\x94" ); // U+2714 HEAVY CHECK MARK
-const std::string BRANCH_SUFFIX( ">" );
+const std::string BRANCH_SUFFIX( "\xE2\x96\xB6" ); // U+25B6 BLACK RIGHT-POINTING TRIANGLE
const std::string ARROW_UP ("^^^^^^^");
const std::string ARROW_DOWN("vvvvvvv");
@@ -2966,7 +2966,7 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
LLUI::getMousePositionLocal(menu->getParent(), &mouse_x, &mouse_y);
LLMenuHolderGL::sContextMenuSpawnPos.set(mouse_x,mouse_y);
- const LLRect menu_region_rect = LLMenuGL::sMenuContainer->getMenuRect();
+ const LLRect menu_region_rect = LLMenuGL::sMenuContainer->getRect();
const S32 HPAD = 2;
LLRect rect = menu->getRect();
diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp
index 143f19eea6..7f23fe2671 100644
--- a/indra/llui/llpanel.cpp
+++ b/indra/llui/llpanel.cpp
@@ -898,6 +898,44 @@ LLPanel *LLPanel::childGetVisibleTabWithHelp()
return ::childGetVisibleTabWithHelp(this);
}
+static LLPanel *childGetVisiblePanelWithHelp(LLView *parent)
+{
+ LLView *child;
+
+ // look through immediate children first for an active panel with help
+ for (child = parent->getFirstChild(); child; child = parent->findNextSibling(child))
+ {
+ // do we have a panel with a help topic?
+ LLPanel *panel = dynamic_cast<LLPanel *>(child);
+ if (panel && panel->getVisible() && !panel->getHelpTopic().empty())
+ {
+ return panel;
+ }
+ }
+
+ // then try a bit harder and recurse through all children
+ for (child = parent->getFirstChild(); child; child = parent->findNextSibling(child))
+ {
+ if (child->getVisible())
+ {
+ LLPanel* panel = ::childGetVisiblePanelWithHelp(child);
+ if (panel)
+ {
+ return panel;
+ }
+ }
+ }
+
+ // couldn't find any active panels with a help topic string
+ return NULL;
+}
+
+LLPanel *LLPanel::childGetVisiblePanelWithHelp()
+{
+ // find a visible tab with a help topic (to determine help context)
+ return ::childGetVisiblePanelWithHelp(this);
+}
+
void LLPanel::childSetPrevalidate(const std::string& id, BOOL (*func)(const LLWString &) )
{
LLLineEditor* child = findChild<LLLineEditor>(id);
diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h
index d0986a06d3..6de83fe3a7 100644
--- a/indra/llui/llpanel.h
+++ b/indra/llui/llpanel.h
@@ -214,7 +214,10 @@ public:
// LLTabContainer
void childShowTab(const std::string& id, const std::string& tabname, bool visible = true);
LLPanel *childGetVisibleTab(const std::string& id) const;
+
+ // Find a child with a nonempty Help topic
LLPanel *childGetVisibleTabWithHelp();
+ LLPanel *childGetVisiblePanelWithHelp();
// LLTextBox/LLTextEditor/LLLineEditor
void childSetText(const std::string& id, const LLStringExplicit& text) { childSetValue(id, LLSD(text)); }
diff --git a/indra/llui/llresizehandle.cpp b/indra/llui/llresizehandle.cpp
index 6239a8f721..3df09d124a 100644
--- a/indra/llui/llresizehandle.cpp
+++ b/indra/llui/llresizehandle.cpp
@@ -124,7 +124,7 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask)
{
// Make sure the mouse in still over the application. We don't want to make the parent
// so big that we can't see the resize handle any more.
-
+
S32 screen_x;
S32 screen_y;
localPointToScreen(x, y, &screen_x, &screen_y);
@@ -146,68 +146,61 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask)
LLRect scaled_rect = orig_rect;
S32 delta_x = screen_x - mDragLastScreenX;
S32 delta_y = screen_y - mDragLastScreenY;
+
+ if(delta_x == 0 && delta_y == 0)
+ return FALSE;
+
LLCoordGL mouse_dir;
// use hysteresis on mouse motion to preserve user intent when mouse stops moving
mouse_dir.mX = (screen_x == mLastMouseScreenX) ? mLastMouseDir.mX : screen_x - mLastMouseScreenX;
mouse_dir.mY = (screen_y == mLastMouseScreenY) ? mLastMouseDir.mY : screen_y - mLastMouseScreenY;
+
mLastMouseScreenX = screen_x;
mLastMouseScreenY = screen_y;
mLastMouseDir = mouse_dir;
- S32 x_multiple = 1;
- S32 y_multiple = 1;
- switch( mCorner )
- {
- case LEFT_TOP:
- x_multiple = -1;
- y_multiple = 1;
- break;
- case LEFT_BOTTOM:
- x_multiple = -1;
- y_multiple = -1;
- break;
- case RIGHT_TOP:
- x_multiple = 1;
- y_multiple = 1;
- break;
- case RIGHT_BOTTOM:
- x_multiple = 1;
- y_multiple = -1;
- break;
- }
+ S32 new_width = orig_rect.getWidth();
+ S32 new_height = orig_rect.getHeight();
- S32 new_width = orig_rect.getWidth() + x_multiple * delta_x;
- if( new_width < mMinWidth )
- {
- new_width = mMinWidth;
- delta_x = x_multiple * (mMinWidth - orig_rect.getWidth());
- }
-
- S32 new_height = orig_rect.getHeight() + y_multiple * delta_y;
- if( new_height < mMinHeight )
- {
- new_height = mMinHeight;
- delta_y = y_multiple * (mMinHeight - orig_rect.getHeight());
- }
+ S32 new_pos_x = orig_rect.mLeft;
+ S32 new_pos_y = orig_rect.mTop;
switch( mCorner )
{
- case LEFT_TOP:
- scaled_rect.translate(delta_x, 0);
+ case LEFT_TOP:
+ new_width-=delta_x;
+ new_height+=delta_y;
+ new_pos_x+=delta_x;
+ new_pos_y+=delta_y;
break;
case LEFT_BOTTOM:
- scaled_rect.translate(delta_x, delta_y);
+ new_width-=delta_x;
+ new_height-=delta_y;
+ new_pos_x+=delta_x;
break;
case RIGHT_TOP:
+ new_width+=delta_x;
+ new_height+=delta_y;
+ new_pos_y+=delta_y;
break;
case RIGHT_BOTTOM:
- scaled_rect.translate(0, delta_y);
+ new_width+=delta_x;
+ new_height-=delta_y;
break;
}
+ new_width = llmax(new_width,mMinWidth);
+ new_height = llmax(new_height,mMinHeight);
+
+ LLRect::tCoordType screen_width = resizing_view->getParent()->getSnapRect().getWidth();
+ LLRect::tCoordType screen_height = resizing_view->getParent()->getSnapRect().getHeight();
+
+ new_width = llmin(new_width, screen_width);
+ new_height = llmin(new_height, screen_height);
+
// temporarily set new parent rect
- scaled_rect.mRight = scaled_rect.mLeft + new_width;
- scaled_rect.mTop = scaled_rect.mBottom + new_height;
+ scaled_rect.setLeftTopAndSize(new_pos_x,new_pos_y,new_width,new_height);
+
resizing_view->setRect(scaled_rect);
LLView* snap_view = NULL;
@@ -258,7 +251,11 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask)
resizing_view->setRect(orig_rect);
// translate and scale to new shape
- resizing_view->setShape(scaled_rect, true);
+ resizing_view->reshape(scaled_rect.getWidth(),scaled_rect.getHeight());
+ resizing_view->setRect(scaled_rect);
+ //set shape to handle dependent floaters...
+ resizing_view->handleReshape(scaled_rect, false);
+
// update last valid mouse cursor position based on resized view's actual size
LLRect new_rect = resizing_view->getRect();
diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp
index a5e47e8547..94465a67ce 100644
--- a/indra/llui/llscrollcontainer.cpp
+++ b/indra/llui/llscrollcontainer.cpp
@@ -668,6 +668,11 @@ void LLScrollContainer::scrollToShowRect(const LLRect& rect, const LLRect& const
// propagate scroll to document
updateScroll();
+
+ // In case we are in accordion tab notify parent to show selected rectangle
+ LLRect screen_rc;
+ localRectToScreen(rect_to_constrain, &screen_rc);
+ notifyParent(LLSD().with("scrollToShowRect",screen_rc.getValue()));
}
void LLScrollContainer::pageUp(S32 overlap)
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index a53a30b501..4e84013db0 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -142,6 +142,7 @@ LLScrollListCtrl::Params::Params()
contents(""),
scroll_bar_bg_visible("scroll_bar_bg_visible"),
scroll_bar_bg_color("scroll_bar_bg_color")
+ , border("border")
{
name = "scroll_list";
mouse_opaque = true;
@@ -231,10 +232,8 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
if (p.has_border)
{
LLRect border_rect = getLocalRect();
- LLViewBorder::Params params;
- params.name("dig border");
+ LLViewBorder::Params params = p.border;
params.rect(border_rect);
- params.bevel_style(LLViewBorder::BEVEL_IN);
mBorder = LLUICtrlFactory::create<LLViewBorder> (params);
addChild(mBorder);
}
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 78bc60db6e..907dc90bea 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -51,6 +51,7 @@
#include "lldate.h"
#include "llscrolllistitem.h"
#include "llscrolllistcolumn.h"
+#include "llviewborder.h"
class LLScrollListCell;
class LLTextBox;
@@ -109,6 +110,8 @@ public:
scroll_bar_bg_color;
Optional<Contents> contents;
+
+ Optional<LLViewBorder::Params> border;
Params();
};
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index 327dd01612..43c44f2253 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -1507,6 +1507,37 @@ void LLTabContainer::setTabImage(LLPanel* child, std::string image_name, const L
}
}
+void LLTabContainer::setTabImage(LLPanel* child, const LLUUID& image_id, const LLColor4& color)
+{
+ static LLUICachedControl<S32> tab_padding ("UITabPadding", 0);
+ LLTabTuple* tuple = getTabByPanel(child);
+ if( tuple )
+ {
+ tuple->mButton->setImageOverlay(image_id, LLFontGL::RIGHT, color);
+
+ if (!mIsVertical)
+ {
+ // remove current width from total tab strip width
+ mTotalTabWidth -= tuple->mButton->getRect().getWidth();
+
+ S32 image_overlay_width = tuple->mButton->getImageOverlay().notNull() ?
+ tuple->mButton->getImageOverlay()->getImage()->getWidth(0) :
+ 0;
+
+ tuple->mPadding = image_overlay_width;
+
+ tuple->mButton->setRightHPad(6);
+ tuple->mButton->reshape(llclamp(mFont->getWidth(tuple->mButton->getLabelSelected()) + tab_padding + tuple->mPadding, mMinTabWidth, mMaxTabWidth),
+ tuple->mButton->getRect().getHeight());
+ // add back in button width to total tab strip width
+ mTotalTabWidth += tuple->mButton->getRect().getWidth();
+
+ // tabs have changed size, might need to scroll to see current tab
+ updateMaxScrollPos();
+ }
+ }
+}
+
void LLTabContainer::setTitle(const std::string& title)
{
if (mTitleBox)
diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h
index 5d0f194bf9..33c49e0d6f 100644
--- a/indra/llui/lltabcontainer.h
+++ b/indra/llui/lltabcontainer.h
@@ -172,6 +172,7 @@ public:
BOOL getTabPanelFlashing(LLPanel* child);
void setTabPanelFlashing(LLPanel* child, BOOL state);
void setTabImage(LLPanel* child, std::string img_name, const LLColor4& color = LLColor4::white);
+ void setTabImage(LLPanel* child, const LLUUID& img_id, const LLColor4& color = LLColor4::white);
void setTitle( const std::string& title );
const std::string getPanelTitle(S32 index);
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 5ebf49c488..17aecaf32f 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -346,7 +346,8 @@ void LLTextBase::drawSelectionBackground()
S32 segment_line_start = segmentp->getStart() + segment_offset;
S32 segment_line_end = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd);
- S32 segment_width, segment_height;
+ S32 segment_width = 0;
+ S32 segment_height = 0;
// if selection after beginning of segment
if(selection_left >= segment_line_start)
@@ -433,7 +434,8 @@ void LLTextBase::drawCursor()
if (LL_KIM_OVERWRITE == gKeyboard->getInsertMode() && !hasSelection())
{
- S32 segment_width, segment_height;
+ S32 segment_width = 0;
+ S32 segment_height = 0;
segmentp->getDimensions(mCursorPos - segmentp->getStart(), 1, segment_width, segment_height);
S32 width = llmax(CURSOR_THICKNESS, segment_width);
cursor_rect.mRight = cursor_rect.mLeft + width;
@@ -2443,10 +2445,12 @@ void LLNormalTextSegment::setToolTip(const std::string& tooltip)
bool LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const
{
- height = mFontHeight;
+ height = 0;
+ width = 0;
bool force_newline = false;
if (num_chars > 0)
{
+ height = mFontHeight;
LLWString text = mEditor.getWText();
// if last character is a newline, then return true, forcing line break
llwchar last_char = text[mStart + first_char + num_chars - 1];
@@ -2461,10 +2465,6 @@ bool LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& widt
width = mStyle->getFont()->getWidth(text.c_str(), mStart + first_char, num_chars);
}
}
- else
- {
- width = 0;
- }
LLUIImagePtr image = mStyle->getImage();
if( image.notNull())
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index e8fc9475a5..f2c3879a6c 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -308,7 +308,8 @@ LLTextEditor::~LLTextEditor()
// Scrollbar is deleted by LLView
std::for_each(mUndoStack.begin(), mUndoStack.end(), DeletePointer());
- delete mContextMenu;
+ // context menu is owned by menu holder, not us
+ //delete mContextMenu;
}
////////////////////////////////////////////////////////////
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
index 6044908ca7..3ade46d367 100644
--- a/indra/llui/lluictrl.cpp
+++ b/indra/llui/lluictrl.cpp
@@ -868,6 +868,14 @@ bool LLUICtrl::findHelpTopic(std::string& help_topic_out)
if (panel)
{
+ // does the panel have a sub-panel with a help topic?
+ LLPanel *subpanel = panel->childGetVisiblePanelWithHelp();
+ if (subpanel)
+ {
+ help_topic_out = subpanel->getHelpTopic();
+ return true; // success (subpanel)
+ }
+
// does the panel have an active tab with a help topic?
LLPanel *tab = panel->childGetVisibleTabWithHelp();
if (tab)
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index 1b6dd1b264..d04cb8c7ff 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -204,7 +204,7 @@ LLUrlEntryHTTPNoProtocol::LLUrlEntryHTTPNoProtocol()
mPattern = boost::regex("("
"\\bwww\\.\\S+\\.\\S+" // i.e. www.FOO.BAR
"|" // or
- "\\b[^ \\t\\n\\r\\f\\v:/]+\\.(?:com|net|edu|org)[^[:space:][:alnum:]]*\\>" // i.e. FOO.net
+ "(?<!@)\\b[^[:space:]:@/]+\\.(?:com|net|edu|org)([/:]\\S*)?\\b" // i.e. FOO.net
")",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_http.xml";
@@ -297,62 +297,7 @@ std::string LLUrlEntrySLURL::getLocation(const std::string &url) const
return url.substr(pos, url.size() - pos);
}
-//
-// LLUrlEntryAgent Describes a Second Life agent Url, e.g.,
-// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about
-//
-LLUrlEntryAgent::LLUrlEntryAgent()
-{
- mPattern = boost::regex("secondlife:///app/agent/[\\da-f-]+/\\w+",
- boost::regex::perl|boost::regex::icase);
- mMenuName = "menu_url_agent.xml";
- mIcon = "Generic_Person";
- mColor = LLUIColorTable::instance().getColor("AgentLinkColor");
-}
-
-void LLUrlEntryAgent::onAgentNameReceived(const LLUUID& id,
- const std::string& first,
- const std::string& last,
- BOOL is_group)
-{
- // received the agent name from the server - tell our observers
- callObservers(id.asString(), first + " " + last);
-}
-
-std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
-{
- if (!gCacheName)
- {
- // probably at the login screen, use short string for layout
- return LLTrans::getString("LoadingData");
- }
-
- std::string agent_id_string = getIDStringFromUrl(url);
- if (agent_id_string.empty())
- {
- // something went wrong, just give raw url
- return unescapeUrl(url);
- }
-
- LLUUID agent_id(agent_id_string);
- std::string full_name;
- if (agent_id.isNull())
- {
- return LLTrans::getString("AvatarNameNobody");
- }
- else if (gCacheName->getFullName(agent_id, full_name))
- {
- return full_name;
- }
- else
- {
- gCacheName->get(agent_id, FALSE,
- boost::bind(&LLUrlEntryAgent::onAgentNameReceived,
- this, _1, _2, _3, _4));
- addObserver(agent_id_string, url, cb);
- return LLTrans::getString("LoadingData");
- }
-}
+// LLUrlEntryAgent temporarily moved to newview IDEVO
//
// LLUrlEntryGroup Describes a Second Life group Url, e.g.,
diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h
index 4adffde99c..33ec9d82a9 100644
--- a/indra/llui/llurlentry.h
+++ b/indra/llui/llurlentry.h
@@ -156,19 +156,7 @@ public:
/*virtual*/ std::string getLocation(const std::string &url) const;
};
-///
-/// LLUrlEntryAgent Describes a Second Life agent Url, e.g.,
-/// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about
-///
-class LLUrlEntryAgent : public LLUrlEntryBase
-{
-public:
- LLUrlEntryAgent();
- /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
-private:
- void onAgentNameReceived(const LLUUID& id, const std::string& first,
- const std::string& last, BOOL is_group);
-};
+/// IDEVO LLUrlEntryAgent temporarily moved to newview
///
/// LLUrlEntryGroup Describes a Second Life group Url, e.g.,
diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp
index ad5c0911f8..4fbdae9d38 100644
--- a/indra/llui/llurlregistry.cpp
+++ b/indra/llui/llurlregistry.cpp
@@ -43,11 +43,13 @@ void LLUrlRegistryNullCallback(const std::string &url, const std::string &label)
LLUrlRegistry::LLUrlRegistry()
{
+ mUrlEntry.reserve(16);
+
// Urls are matched in the order that they were registered
registerUrl(new LLUrlEntrySLURL());
registerUrl(new LLUrlEntryHTTP());
registerUrl(new LLUrlEntryHTTPLabel());
- registerUrl(new LLUrlEntryAgent());
+ // IDEVO registerUrl(new LLUrlEntryAgent());
registerUrl(new LLUrlEntryGroup());
registerUrl(new LLUrlEntryParcel());
registerUrl(new LLUrlEntryTeleport());
@@ -73,11 +75,14 @@ LLUrlRegistry::~LLUrlRegistry()
}
}
-void LLUrlRegistry::registerUrl(LLUrlEntryBase *url)
+void LLUrlRegistry::registerUrl(LLUrlEntryBase *url, bool force_front)
{
if (url)
{
- mUrlEntry.push_back(url);
+ if (force_front) // IDEVO
+ mUrlEntry.insert(mUrlEntry.begin(), url);
+ else
+ mUrlEntry.push_back(url);
}
}
diff --git a/indra/llui/llurlregistry.h b/indra/llui/llurlregistry.h
index 399ee0a988..6d47c2c2a2 100644
--- a/indra/llui/llurlregistry.h
+++ b/indra/llui/llurlregistry.h
@@ -70,7 +70,9 @@ public:
~LLUrlRegistry();
/// add a new Url handler to the registry (will be freed on destruction)
- void registerUrl(LLUrlEntryBase *url);
+ /// optionally force it to the front of the list, making it take
+ /// priority over other regular expression matches for URLs
+ void registerUrl(LLUrlEntryBase *url, bool force_front = false);
/// get the next Url in an input string, starting at a given character offset
/// your callback is invoked if the matched Url's label changes in the future
diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp
index 26d1f2e067..3731800adf 100644
--- a/indra/llui/tests/llurlentry_stub.cpp
+++ b/indra/llui/tests/llurlentry_stub.cpp
@@ -36,6 +36,13 @@ BOOL LLCacheName::getFullName(const LLUUID& id, std::string& fullname)
return TRUE;
}
+BOOL LLCacheName::getName(const LLUUID& id, std::string& first, std::string& last)
+{
+ first = "Lynx";
+ last = "Linden";
+ return TRUE;
+}
+
BOOL LLCacheName::getGroupName(const LLUUID& id, std::string& group)
{
group = "My Group";
diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp
index 38cf7124ce..9200708784 100644
--- a/indra/llui/tests/llurlentry_test.cpp
+++ b/indra/llui/tests/llurlentry_test.cpp
@@ -266,28 +266,29 @@ namespace tut
//
// test LLUrlEntryAgent - secondlife://app/agent Urls
//
- LLUrlEntryAgent url;
- boost::regex r = url.getPattern();
+ // IDEVO - moved temporarily into newview, not available for test
+ //LLUrlEntryAgent url;
+ //boost::regex r = url.getPattern();
- testRegex("Invalid Agent Url", r,
- "secondlife:///app/agent/0e346d8b-4433-4d66-XXXX-fd37083abc4c/about",
- "");
+ //testRegex("Invalid Agent Url", r,
+ // "secondlife:///app/agent/0e346d8b-4433-4d66-XXXX-fd37083abc4c/about",
+ // "");
- testRegex("Agent Url ", r,
- "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about",
- "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");
+ //testRegex("Agent Url ", r,
+ // "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about",
+ // "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");
- testRegex("Agent Url in text", r,
- "XXX secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about XXX",
- "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");
+ //testRegex("Agent Url in text", r,
+ // "XXX secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about XXX",
+ // "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");
- testRegex("Agent Url multicase", r,
- "XXX secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/About XXX",
- "secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/About");
+ //testRegex("Agent Url multicase", r,
+ // "XXX secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/About XXX",
+ // "secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/About");
- testRegex("Agent Url alternate command", r,
- "XXX secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/foobar",
- "secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/foobar");
+ //testRegex("Agent Url alternate command", r,
+ // "XXX secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/foobar",
+ // "secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/foobar");
}
@@ -571,6 +572,26 @@ namespace tut
"MIT web site is at web.mit.edu and also www.mit.edu",
"web.mit.edu");
+ testRegex("don't match e-mail addresses", r,
+ "test@lindenlab.com",
+ "");
+
+ testRegex(".com URL with path", r,
+ "see secondlife.com/status for grid status",
+ "secondlife.com/status");
+
+ testRegex(".com URL with port", r,
+ "secondlife.com:80",
+ "secondlife.com:80");
+
+ testRegex(".com URL with port and path", r,
+ "see secondlife.com:80/status",
+ "secondlife.com:80/status");
+
+ testRegex("www.*.com URL with port and path", r,
+ "see www.secondlife.com:80/status",
+ "www.secondlife.com:80/status");
+
testRegex("invalid .com URL [1]", r,
"..com",
"");