diff options
Diffstat (limited to 'indra/llui/lltextbase.cpp')
-rw-r--r-- | indra/llui/lltextbase.cpp | 198 |
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)) |