summaryrefslogtreecommitdiff
path: root/indra/llui/lltextbase.cpp
diff options
context:
space:
mode:
authorDessie Linden <dessie@lindenlab.com>2010-06-11 11:51:14 -0700
committerDessie Linden <dessie@lindenlab.com>2010-06-11 11:51:14 -0700
commit6b7470480692fc614d625212f9c17afd688e42de (patch)
treef510e51c81fb930ed42ef22de47cd7071a7c3b43 /indra/llui/lltextbase.cpp
parent61d6669ffd766208abfa6240edc52723d8d141de (diff)
parentb228915d1f45dc6d2c88a9381957b904410428f8 (diff)
Merge
Diffstat (limited to 'indra/llui/lltextbase.cpp')
-rw-r--r--indra/llui/lltextbase.cpp198
1 files changed, 92 insertions, 106 deletions
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index b95596fa70..72f3a14822 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -3,25 +3,31 @@
* @author Martin Reddy
* @brief The base class of text box/editor, providing Url handling support
*
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
+ * 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
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
+ * 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
*
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * 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.
*
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * 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$
*/
@@ -34,7 +40,6 @@
#include "llscrollcontainer.h"
#include "llstl.h"
#include "lltextparser.h"
-#include "lltextutil.h"
#include "lltooltip.h"
#include "lluictrl.h"
#include "llurlaction.h"
@@ -60,10 +65,7 @@ bool LLTextBase::compare_segment_end::operator()(const LLTextSegmentPtr& a, cons
{
return a->getStart() < b->getStart();
}
- else
- {
- return a->getEnd() < b->getEnd();
- }
+ return a->getEnd() < b->getEnd();
}
@@ -150,7 +152,6 @@ LLTextBase::Params::Params()
bg_writeable_color("bg_writeable_color"),
bg_focus_color("bg_focus_color"),
allow_scroll("allow_scroll", true),
- plain_text("plain_text",false),
track_end("track_end", false),
read_only("read_only", false),
v_pad("v_pad", 0),
@@ -171,7 +172,7 @@ LLTextBase::Params::Params()
LLTextBase::LLTextBase(const LLTextBase::Params &p)
: LLUICtrl(p, LLTextViewModelPtr(new LLTextViewModel)),
- mURLClickSignal(NULL),
+ mURLClickSignal(),
mMaxTextByteLength( p.max_text_length ),
mDefaultFont(p.font),
mFontShadow(p.font_shadow),
@@ -191,7 +192,6 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
mHPad(p.h_pad),
mVPad(p.v_pad),
mHAlign(p.font_halign),
- mVAlign(p.font_valign),
mLineSpacingMult(p.line_spacing.multiple),
mLineSpacingPixels(p.line_spacing.pixels),
mClipPartial(p.clip_partial && !p.allow_scroll),
@@ -200,14 +200,12 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
mSelectionStart( 0 ),
mSelectionEnd( 0 ),
mIsSelecting( FALSE ),
- mPlainText ( p.plain_text ),
mWordWrap(p.wrap),
mUseEllipses( p.use_ellipses ),
mParseHTML(p.allow_html),
mParseHighlights(p.parse_highlights),
mBGVisible(p.bg_visible),
- mScroller(NULL),
- mStyleDirty(true)
+ mScroller(NULL)
{
if(p.allow_scroll)
{
@@ -246,8 +244,9 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
LLTextBase::~LLTextBase()
{
+ // Menu, like any other LLUICtrl, is deleted by its parent - gMenuHolder
+
mSegments.clear();
- delete mURLClickSignal;
}
void LLTextBase::initFromParams(const LLTextBase::Params& p)
@@ -293,18 +292,13 @@ bool LLTextBase::truncate()
return did_truncate;
}
-const LLStyle::Params& LLTextBase::getDefaultStyleParams()
+LLStyle::Params LLTextBase::getDefaultStyleParams()
{
- if (mStyleDirty)
- {
- mDefaultStyle
- .color(LLUIColor(&mFgColor))
- .readonly_color(LLUIColor(&mReadOnlyFgColor))
- .font(mDefaultFont)
- .drop_shadow(mFontShadow);
- mStyleDirty = false;
- }
- return mDefaultStyle;
+ return LLStyle::Params()
+ .color(LLUIColor(&mFgColor))
+ .readonly_color(LLUIColor(&mReadOnlyFgColor))
+ .font(mDefaultFont)
+ .drop_shadow(mFontShadow);
}
void LLTextBase::onValueChange(S32 start, S32 end)
@@ -486,9 +480,9 @@ void LLTextBase::drawCursor()
text_color = mFgColor.get();
fontp = mDefaultFont;
}
- fontp->render(text, mCursorPos, cursor_rect,
+ fontp->render(text, mCursorPos, cursor_rect.mLeft, cursor_rect.mTop,
LLColor4(1.f - text_color.mV[VRED], 1.f - text_color.mV[VGREEN], 1.f - text_color.mV[VBLUE], alpha),
- LLFontGL::LEFT, mVAlign,
+ LLFontGL::LEFT, LLFontGL::TOP,
LLFontGL::NORMAL,
LLFontGL::NO_SHADOW,
1);
@@ -863,12 +857,11 @@ BOOL LLTextBase::handleMouseUp(S32 x, S32 y, MASK mask)
if (cur_segment && cur_segment->handleMouseUp(x, y, mask))
{
// Did we just click on a link?
- if (mURLClickSignal
- && cur_segment->getStyle()
+ if (cur_segment->getStyle()
&& cur_segment->getStyle()->isLink())
{
// *TODO: send URL here?
- (*mURLClickSignal)(this, LLSD() );
+ mURLClickSignal(this, LLSD() );
}
return TRUE;
}
@@ -1042,14 +1035,12 @@ void LLTextBase::draw()
void LLTextBase::setColor( const LLColor4& c )
{
mFgColor = c;
- mStyleDirty = true;
}
//virtual
void LLTextBase::setReadOnlyColor(const LLColor4 &c)
{
mReadOnlyFgColor = c;
- mStyleDirty = true;
}
//virtual
@@ -1493,22 +1484,12 @@ void LLTextBase::getSegmentAndOffset( S32 startpos, segment_set_t::iterator* seg
LLTextBase::segment_set_t::iterator LLTextBase::getSegIterContaining(S32 index)
{
- if (index > getLength()) { return mSegments.end(); }
-
- // when there are no segments, we return the end iterator, which must be checked by caller
- if (mSegments.size() <= 1) { return mSegments.begin(); }
-
segment_set_t::iterator it = mSegments.upper_bound(new LLIndexSegment(index));
return it;
}
LLTextBase::segment_set_t::const_iterator LLTextBase::getSegIterContaining(S32 index) const
{
- if (index > getLength()) { return mSegments.end(); }
-
- // when there are no segments, we return the end iterator, which must be checked by caller
- if (mSegments.size() <= 1) { return mSegments.begin(); }
-
LLTextBase::segment_set_t::const_iterator it = mSegments.upper_bound(new LLIndexSegment(index));
return it;
}
@@ -1633,20 +1614,32 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
part = (S32)LLTextParser::MIDDLE;
}
std::string subtext=text.substr(0,start);
- appendAndHighlightText(subtext, part, style_params);
+ appendAndHighlightTextImpl(subtext, part, style_params);
}
- // inserts an avatar icon preceding the Url if appropriate
- LLTextUtil::processUrlMatch(&match,this);
+ // output an optional icon before the Url
+ if (! match.getIcon().empty())
+ {
+ LLUIImagePtr image = LLUI::getUIImage(match.getIcon());
+ if (image)
+ {
+ LLStyle::Params icon;
+ icon.image = image;
+ // Text will be replaced during rendering with the icon,
+ // but string cannot be empty or the segment won't be
+ // added (or drawn).
+ appendImageSegment(part, icon);
+ }
+ }
// output the styled Url (unless we've been asked to suppress hyperlinking)
if (match.isLinkDisabled())
{
- appendAndHighlightText(match.getLabel(), part, style_params);
+ appendAndHighlightTextImpl(match.getLabel(), part, style_params);
}
else
{
- appendAndHighlightText(match.getLabel(), part, link_params);
+ appendAndHighlightTextImpl(match.getLabel(), part, link_params);
// set the tooltip for the Url label
if (! match.getTooltip().empty())
@@ -1674,11 +1667,11 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
if (part != (S32)LLTextParser::WHOLE)
part=(S32)LLTextParser::END;
if (end < (S32)text.length())
- appendAndHighlightText(text, part, style_params);
+ appendAndHighlightTextImpl(text, part, style_params);
}
else
{
- appendAndHighlightText(new_text, part, style_params);
+ appendAndHighlightTextImpl(new_text, part, style_params);
}
}
@@ -1689,7 +1682,23 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c
if(prepend_newline)
appendLineBreakSegment(input_params);
- appendTextImpl(new_text,input_params);
+ std::string::size_type start = 0;
+ std::string::size_type pos = new_text.find("\n",start);
+
+ while(pos!=-1)
+ {
+ if(pos!=start)
+ {
+ std::string str = std::string(new_text,start,pos-start);
+ appendTextImpl(str,input_params);
+ }
+ appendLineBreakSegment(input_params);
+ start = pos+1;
+ pos = new_text.find("\n",start);
+ }
+
+ std::string str = std::string(new_text,start,new_text.length()-start);
+ appendTextImpl(str,input_params);
}
void LLTextBase::needsReflow(S32 index)
@@ -1707,12 +1716,8 @@ void LLTextBase::appendLineBreakSegment(const LLStyle::Params& style_params)
insertStringNoUndo(getLength(), utf8str_to_wstring("\n"), &segments);
}
-void LLTextBase::appendImageSegment(const LLStyle::Params& style_params)
+void LLTextBase::appendImageSegment(S32 highlight_part, const LLStyle::Params& style_params)
{
- if(getPlainText())
- {
- return;
- }
segment_vec_t segments;
LLStyleConstSP sp(new LLStyle(style_params));
segments.push_back(new LLImageTextSegment(sp, getLength(),*this));
@@ -1720,14 +1725,7 @@ void LLTextBase::appendImageSegment(const LLStyle::Params& style_params)
insertStringNoUndo(getLength(), utf8str_to_wstring(" "), &segments);
}
-void LLTextBase::appendWidget(const LLInlineViewSegment::Params& params, const std::string& text, bool allow_undo)
-{
- segment_vec_t segments;
- LLWString widget_wide_text = utf8str_to_wstring(text);
- segments.push_back(new LLInlineViewSegment(params, getLength(), getLength() + widget_wide_text.size()));
- insertStringNoUndo(getLength(), widget_wide_text, &segments);
-}
void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params)
{
@@ -1799,10 +1797,13 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig
}
}
-void LLTextBase::appendAndHighlightText(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params)
+void LLTextBase::appendAndHighlightText(const std::string &new_text, bool prepend_newline, S32 highlight_part, const LLStyle::Params& style_params)
{
if (new_text.empty()) return;
+ if(prepend_newline)
+ appendLineBreakSegment(style_params);
+
std::string::size_type start = 0;
std::string::size_type pos = new_text.find("\n",start);
@@ -2277,12 +2278,6 @@ void LLTextBase::updateRects()
? llmax(mVisibleTextRect.getWidth(), mTextBoundingRect.mRight)
: mVisibleTextRect.getWidth();
- if (!mScroller)
- {
- // push doc rect to top of text widget
- doc_rect.translate(0, mVisibleTextRect.getHeight() - doc_rect.mTop);
- }
-
mDocumentView->setShape(doc_rect);
//update mVisibleTextRect *after* mDocumentView has been resized
@@ -2346,15 +2341,6 @@ LLRect LLTextBase::getVisibleDocumentRect() const
}
}
-boost::signals2::connection LLTextBase::setURLClickedCallback(const commit_signal_t::slot_type& cb)
-{
- if (!mURLClickSignal)
- {
- mURLClickSignal = new commit_signal_t();
- }
- return mURLClickSignal->connect(cb);
-}
-
//
// LLTextSegment
//
@@ -2462,12 +2448,12 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele
S32 end = llmin( selection_start, seg_end );
S32 length = end - start;
font->render(text, start,
- rect,
+ rect.mLeft, rect.mTop,
color,
- LLFontGL::LEFT, mEditor.mVAlign,
+ LLFontGL::LEFT, LLFontGL::TOP,
LLFontGL::NORMAL,
mStyle->getShadowType(),
- length,
+ length, rect.getWidth(),
&right_x,
mEditor.getUseEllipses());
}
@@ -2481,12 +2467,12 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele
S32 length = end - start;
font->render(text, start,
- rect,
+ rect.mLeft, rect.mTop,
LLColor4( 1.f - color.mV[0], 1.f - color.mV[1], 1.f - color.mV[2], 1.f ),
- LLFontGL::LEFT, mEditor.mVAlign,
+ LLFontGL::LEFT, LLFontGL::TOP,
LLFontGL::NORMAL,
LLFontGL::NO_SHADOW,
- length,
+ length, rect.getWidth(),
&right_x,
mEditor.getUseEllipses());
}
@@ -2498,12 +2484,12 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele
S32 end = seg_end;
S32 length = end - start;
font->render(text, start,
- rect,
+ rect.mLeft, rect.mTop,
color,
- LLFontGL::LEFT, mEditor.mVAlign,
+ LLFontGL::LEFT, LLFontGL::TOP,
LLFontGL::NORMAL,
mStyle->getShadowType(),
- length,
+ length, rect.getWidth(),
&right_x,
mEditor.getUseEllipses());
}
@@ -2787,9 +2773,9 @@ F32 LLLineBreakTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 se
}
LLImageTextSegment::LLImageTextSegment(LLStyleConstSP style,S32 pos,class LLTextBase& editor)
-: LLTextSegment(pos,pos+1),
- mStyle( style ),
- mEditor(editor)
+ :LLTextSegment(pos,pos+1)
+ ,mStyle( style )
+ ,mEditor(editor)
{
}
@@ -2805,7 +2791,7 @@ bool LLImageTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width
height = llceil(mStyle->getFont()->getLineHeight());;
LLUIImagePtr image = mStyle->getImage();
- if( num_chars>0 && image.notNull())
+ if( image.notNull())
{
width += image->getWidth() + IMAGE_HPAD;
height = llmax(height, image->getHeight() + IMAGE_HPAD );
@@ -2817,13 +2803,13 @@ S32 LLImageTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin
{
LLUIImagePtr image = mStyle->getImage();
S32 image_width = image->getWidth();
- if(line_offset == 0 || num_pixels>image_width + IMAGE_HPAD)
+ if(num_pixels>image_width + IMAGE_HPAD)
{
return 1;
}
+
return 0;
}
-
F32 LLImageTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect)
{
if ( (start >= 0) && (end <= mEnd - mStart))