diff options
author | Kelly Washington <kelly@lindenlab.com> | 2007-05-30 17:39:09 +0000 |
---|---|---|
committer | Kelly Washington <kelly@lindenlab.com> | 2007-05-30 17:39:09 +0000 |
commit | 3e9872a297c3cf3f929e688e0e89a78f6bc050f5 (patch) | |
tree | ab3877f764cc27dbdca0b683f07e6ea3a3ac8a23 /indra/llui | |
parent | 7b61f1d0ec30e97fd3b7c5caf4b0e675c6e9a1f5 (diff) |
merge -r61423:62602 svn/branches/maintenance --> release
Diffstat (limited to 'indra/llui')
-rw-r--r-- | indra/llui/lllineeditor.cpp | 81 | ||||
-rw-r--r-- | indra/llui/lllineeditor.h | 10 | ||||
-rw-r--r-- | indra/llui/lltexteditor.cpp | 25 | ||||
-rw-r--r-- | indra/llui/lltexteditor.h | 1 | ||||
-rw-r--r-- | indra/llui/llview.cpp | 3 |
5 files changed, 117 insertions, 3 deletions
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 43ea584aa1..7e7999c9f9 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -137,6 +137,14 @@ LLLineEditor::LLLineEditor(const LLString& name, const LLRect& rect, { llassert( max_length_bytes > 0 ); + // line history support: + // - initialize line history list + mLineHistory.insert( mLineHistory.end(), "" ); + // - disable line history by default + mHaveHistory = FALSE; + // - reset current history line pointer + mCurrentHistoryLine = 0; + if (font) { mGLFont = font; @@ -209,10 +217,33 @@ void LLLineEditor::onFocusLost() void LLLineEditor::onCommit() { + // put current line into the line history + updateHistory(); + LLUICtrl::onCommit(); selectAll(); } +// line history support +void LLLineEditor::updateHistory() +{ + // On history enabled line editors, remember committed line and + // reset current history line number. + // Be sure only to remember lines that are not empty and that are + // different from the last on the list. + if( mHaveHistory && mText.length() && ( mLineHistory.empty() || getText() != mLineHistory.back() ) ) + { + // discard possible empty line at the end of the history + // inserted by setText() + if( !mLineHistory.back().length() ) + { + mLineHistory.pop_back(); + } + mLineHistory.insert( mLineHistory.end(), getText() ); + mCurrentHistoryLine = mLineHistory.size() - 1; + } +} + void LLLineEditor::reshape(S32 width, S32 height, BOOL called_from_parent) { LLUICtrl::reshape(width, height, called_from_parent ); @@ -220,6 +251,10 @@ void LLLineEditor::reshape(S32 width, S32 height, BOOL called_from_parent) mMaxHPixels = mRect.getWidth() - 2 * (mBorderThickness + UI_LINEEDITOR_H_PAD) + 1 - mBorderRight; } +void LLLineEditor::setEnableLineHistory( BOOL enabled ) +{ + mHaveHistory = enabled; +} void LLLineEditor::setEnabled(BOOL enabled) { @@ -280,6 +315,13 @@ void LLLineEditor::setText(const LLString &new_text) deselect(); } setCursor(llmin((S32)mText.length(), getCursor())); + + // Newly set text goes always in the last line of history. + // Possible empty strings (as with chat line) will be deleted later. + mLineHistory.insert( mLineHistory.end(), new_text ); + // Set current history line to end of history. + mCurrentHistoryLine = mLineHistory.size() - 1; + mPrevText = mText; } @@ -1066,6 +1108,45 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask) } break; + // handle ctrl-uparrow if we have a history enabled line editor. + case KEY_UP: + if( mHaveHistory && ( MASK_CONTROL & mask ) ) + { + if( mCurrentHistoryLine > 0 ) + { + mText.assign( mLineHistory[ --mCurrentHistoryLine ] ); + setCursor(llmin((S32)mText.length(), getCursor())); + } + else + { + reportBadKeystroke(); + } + handled = TRUE; + } + break; + + // handle ctrl-downarrow if we have a history enabled line editor + case KEY_DOWN: + if( mHaveHistory && ( MASK_CONTROL & mask ) ) + { + if( !mLineHistory.empty() && mCurrentHistoryLine < mLineHistory.size() - 1 ) + { + mText.assign( mLineHistory[ ++mCurrentHistoryLine ] ); + setCursor(llmin((S32)mText.length(), getCursor())); + } + else + { + reportBadKeystroke(); + } + handled = TRUE; + } + break; + + case KEY_RETURN: + // store sent line in history + updateHistory(); + break; + case KEY_ESCAPE: if (mRevertOnEsc && mText.getString() != mPrevText) { diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index 27ae351d1f..b3eff3c8e2 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -16,6 +16,7 @@ // Clipboard (cut, copy, and paste) // Horizontal scrolling to allow strings longer than widget size allows // Pre-validation (limit which keys can be used) +// Optional line history so previous entries can be recalled by CTRL UP/DOWN #ifndef LL_LLLINEEDITOR_H @@ -186,6 +187,10 @@ public: static BOOL postvalidateFloat(const LLString &str); + // line history support: + void setEnableLineHistory( BOOL enabled ); // switches line history on or off + void updateHistory(); // stores current line in history + protected: void removeChar(); void addChar(const llwchar c); @@ -204,6 +209,11 @@ protected: LLString mPrevText; // Saved string for 'ESC' revert LLUIString mLabel; // text label that is visible when no user text provided + // line history support: + BOOL mHaveHistory; // flag for enabled line history + std::vector<LLString> mLineHistory; // line history storage + U32 mCurrentHistoryLine; // currently browsed history line + LLViewBorder* mBorder; const LLFontGL* mGLFont; S32 mMaxLengthChars; // Max number of characters diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 2b588cacce..9363415dc2 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -289,6 +289,9 @@ LLTextEditor::LLTextEditor( { mSourceID.generate(); + // reset desired x cursor position + mDesiredXPixel = -1; + if (font) { mGLFont = font; @@ -894,6 +897,8 @@ void LLTextEditor::setCursorPos(S32 offset) { mCursorPos = llclamp(offset, 0, (S32)getLength()); updateScrollFromCursor(); + // reset desired x cursor position + mDesiredXPixel = -1; } @@ -3078,6 +3083,9 @@ void LLTextEditor::changePage( S32 delta ) S32 line, offset; getLineAndOffset( mCursorPos, &line, &offset ); + // get desired x position to remember previous position + S32 desired_x_pixel = mDesiredXPixel; + // allow one line overlap S32 page_size = mScrollbar->getPageSize() - 1; if( delta == -1 ) @@ -3092,6 +3100,10 @@ void LLTextEditor::changePage( S32 delta ) setCursorPos(getPos( line + page_size, offset )); mScrollbar->setDocPos( mScrollbar->getDocPos() + page_size ); } + + // put desired position into remember-buffer after setCursorPos() + mDesiredXPixel = desired_x_pixel; + if (mOnScrollEndCallback && mOnScrollEndData && (mScrollbar->getDocPos() == mScrollbar->getDocPosMax())) { mOnScrollEndCallback(mOnScrollEndData); @@ -3107,9 +3119,13 @@ void LLTextEditor::changeLine( S32 delta ) S32 line_start = getLineStart(line); - S32 desired_x_pixel; - - desired_x_pixel = mGLFont->getWidth(mWText.c_str(), line_start, offset, mAllowEmbeddedItems ); + // set desired x position to remembered previous position + S32 desired_x_pixel = mDesiredXPixel; + // if remembered position was reset (thus -1), calculate new one here + if( desired_x_pixel == -1 ) + { + desired_x_pixel = mGLFont->getWidth(mWText.c_str(), line_start, offset, mAllowEmbeddedItems ); + } S32 new_line = 0; if( (delta < 0) && (line > 0 ) ) @@ -3145,6 +3161,9 @@ void LLTextEditor::changeLine( S32 delta ) mAllowEmbeddedItems); setCursorPos (getPos( new_line, new_offset )); + + // put desired position into remember-buffer after setCursorPos() + mDesiredXPixel = desired_x_pixel; unbindEmbeddedChars( mGLFont ); } diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index d95230f0dc..7454b192fd 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -339,6 +339,7 @@ protected: undo_stack_t mUndoStack; S32 mCursorPos; // I-beam is just after the mCursorPos-th character. + S32 mDesiredXPixel; // X pixel position where the user wants the cursor to be LLRect mTextRect; // The rect in which text is drawn. Excludes borders. // List of offsets and segment index of the start of each line. Always has at least one node (0). struct line_info diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index da5c77fc94..05c2247a35 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -176,6 +176,9 @@ LLView::~LLView() (*itor).second->clearDispatchers(); delete (*itor).second; } + + std::for_each(mFloaterControls.begin(), mFloaterControls.end(), + DeletePairedPointer()); } // virtual |