Right click menus for text entry areas that include copy/paste options.

Signed-off-by: Beeks <HgDelirium@gmail.com>
This commit is contained in:
Beeks
2010-09-27 19:48:58 -04:00
parent 94d21fb256
commit b1bc45ac42
6 changed files with 334 additions and 92 deletions

View File

@@ -56,6 +56,7 @@
#include "lluictrlfactory.h" #include "lluictrlfactory.h"
#include "llclipboard.h" #include "llclipboard.h"
#include "../newview/llviewercontrol.h"
// //
// Imported globals // Imported globals
// //
@@ -103,6 +104,7 @@ LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect,
: :
LLUICtrl( name, rect, TRUE, commit_callback, userdata, FOLLOWS_TOP | FOLLOWS_LEFT ), LLUICtrl( name, rect, TRUE, commit_callback, userdata, FOLLOWS_TOP | FOLLOWS_LEFT ),
mMaxLengthBytes(max_length_bytes), mMaxLengthBytes(max_length_bytes),
mPopupMenuHandle(),
mCursorPos( 0 ), mCursorPos( 0 ),
mScrollHPos( 0 ), mScrollHPos( 0 ),
mTextPadLeft(0), mTextPadLeft(0),
@@ -174,6 +176,26 @@ LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect,
sImage = LLUI::getUIImage("sm_rounded_corners_simple.tga"); sImage = LLUI::getUIImage("sm_rounded_corners_simple.tga");
} }
mImage = sImage; mImage = sImage;
// make the popup menu available
//LLMenuGL* menu = LLUICtrlFactory::getInstance()->buildMenu("menu_texteditor.xml", parent_view);
LLMenuGL* menu = new LLMenuGL("wot");
/*if (!menu)
{
menu = new LLMenuGL(LLStringUtil::null);
}*/
menu->append(new LLMenuItemCallGL("Cut", context_cut, NULL, this));
menu->append(new LLMenuItemCallGL("Copy", context_copy, NULL, this));
menu->append(new LLMenuItemCallGL("Paste", context_paste, NULL, this));
menu->append(new LLMenuItemCallGL("Delete", context_delete, NULL, this));
menu->append(new LLMenuItemCallGL("Select All", context_selectall, NULL, this));
menu->appendSeparator("Transep");
LLMenuGL* translatemenu = new LLMenuGL("Translate To");
translatemenu->setCanTearOff(FALSE);
//menu->setBackgroundColor(gColors.getColor("MenuPopupBgColor"));
menu->setCanTearOff(FALSE);
menu->setVisible(FALSE);
mPopupMenuHandle = menu->getHandle();
} }
@@ -187,6 +209,7 @@ LLLineEditor::~LLLineEditor()
{ {
gEditMenuHandler = NULL; gEditMenuHandler = NULL;
} }
LLView::deleteViewByHandle(mPopupMenuHandle);
} }
@@ -342,7 +365,7 @@ void LLLineEditor::setText(const LLStringExplicit &new_text)
// Picks a new cursor position based on the actual screen size of text being drawn. // Picks a new cursor position based on the actual screen size of text being drawn.
void LLLineEditor::setCursorAtLocalPos( S32 local_mouse_x ) S32 LLLineEditor::calculateCursorFromMouse( S32 local_mouse_x )
{ {
const llwchar* wtext = mText.getWString().c_str(); const llwchar* wtext = mText.getWString().c_str();
LLWString asterix_text; LLWString asterix_text;
@@ -350,18 +373,22 @@ void LLLineEditor::setCursorAtLocalPos( S32 local_mouse_x )
{ {
for (S32 i = 0; i < mText.length(); i++) for (S32 i = 0; i < mText.length(); i++)
{ {
asterix_text += '*'; asterix_text += (llwchar) 0x2022L;
} }
wtext = asterix_text.c_str(); wtext = asterix_text.c_str();
} }
S32 cursor_pos = return mScrollHPos +
mScrollHPos +
mGLFont->charFromPixelOffset( mGLFont->charFromPixelOffset(
wtext, mScrollHPos, wtext, mScrollHPos,
(F32)(local_mouse_x - mMinHPixels), (F32)(local_mouse_x - mMinHPixels),
(F32)(mMaxHPixels - mMinHPixels + 1)); // min-max range is inclusive (F32)(mMaxHPixels - mMinHPixels + 1)); // min-max range is inclusive
setCursor(cursor_pos);
}
// Picks a new cursor position based on the actual screen size of text being drawn.
void LLLineEditor::setCursorAtLocalPos( S32 local_mouse_x )
{
setCursor(calculateCursorFromMouse(local_mouse_x));
} }
void LLLineEditor::setCursor( S32 pos ) void LLLineEditor::setCursor( S32 pos )
@@ -417,6 +444,35 @@ void LLLineEditor::deselect()
} }
void LLLineEditor::context_cut(void* data)
{
LLLineEditor* line = (LLLineEditor*)data;
if(line)line->cut();
}
void LLLineEditor::context_copy(void* data)
{
LLLineEditor* line = (LLLineEditor*)data;
if(line)line->copy();
}
void LLLineEditor::context_paste(void* data)
{
LLLineEditor* line = (LLLineEditor*)data;
if(line)line->paste();
}
void LLLineEditor::context_delete(void* data)
{
LLLineEditor* line = (LLLineEditor*)data;
if(line)line->doDelete();
}
void LLLineEditor::context_selectall(void* data)
{
LLLineEditor* line = (LLLineEditor*)data;
if(line)line->selectAll();
}
void LLLineEditor::startSelection() void LLLineEditor::startSelection()
{ {
mIsSelecting = TRUE; mIsSelecting = TRUE;
@@ -507,6 +563,27 @@ BOOL LLLineEditor::handleDoubleClick(S32 x, S32 y, MASK mask)
return TRUE; return TRUE;
} }
BOOL LLLineEditor::handleRightMouseDown( S32 x, S32 y, MASK mask )
{
setFocus(TRUE);
//setCursorAtLocalPos( x);
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
if (menu)
{
if(menu->isOpen())
{
menu->setVisible(FALSE);
}
menu->buildDrawLabels();
menu->updateParent(LLMenuGL::sMenuContainer);
LLMenuGL::showPopup(this, menu, x, y);
}
return TRUE;
}
BOOL LLLineEditor::handleMouseDown(S32 x, S32 y, MASK mask) BOOL LLLineEditor::handleMouseDown(S32 x, S32 y, MASK mask)
{ {
// Check first whether the "clear search" button wants to deal with this. // Check first whether the "clear search" button wants to deal with this.
@@ -970,6 +1047,23 @@ void LLLineEditor::copy()
} }
} }
void LLLineEditor::insert(std::string what, S32 wher)
{
LLLineEditorRollback rollback(this);
LLWString clean_string(utf8str_to_wstring(what));
LLWStringUtil::replaceTabsWithSpaces(clean_string, 4);
mText.insert(wher, clean_string);
//see if we should move over the cursor acordingly
// Validate new string and rollback the if needed.
BOOL need_to_rollback = ( mPrevalidateFunc && !mPrevalidateFunc( mText.getWString() ) );
if( need_to_rollback )
{
rollback.doRollback( this );
reportBadKeystroke();
}
else if( mKeystrokeCallback )
mKeystrokeCallback( this, mCallbackUserData );
}
BOOL LLLineEditor::canPaste() const BOOL LLLineEditor::canPaste() const
{ {
return !mReadOnly && gClipboard.canPasteString(); return !mReadOnly && gClipboard.canPasteString();
@@ -1329,6 +1423,14 @@ BOOL LLLineEditor::handleKeyHere(KEY key, MASK mask )
BOOL handled = FALSE; BOOL handled = FALSE;
BOOL selection_modified = FALSE; BOOL selection_modified = FALSE;
// SL-51858: Key presses are not being passed to the Popup menu.
// A proper fix is non-trivial so instead just close the menu.
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
if (menu && menu->isOpen())
{
LLMenuGL::sMenuContainer->hideMenus();
}
if ( gFocusMgr.getKeyboardFocus() == this ) if ( gFocusMgr.getKeyboardFocus() == this )
{ {
LLLineEditorRollback rollback( this ); LLLineEditorRollback rollback( this );
@@ -1403,6 +1505,13 @@ BOOL LLLineEditor::handleUnicodeCharHere(llwchar uni_char)
if ( (gFocusMgr.getKeyboardFocus() == this) && getVisible() && !mReadOnly) if ( (gFocusMgr.getKeyboardFocus() == this) && getVisible() && !mReadOnly)
{ {
// SL-51858: Key presses are not being passed to the Popup menu.
// A proper fix is non-trivial so instead just close the menu.
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
if (menu && menu->isOpen())
{
LLMenuGL::sMenuContainer->hideMenus();
}
handled = TRUE; handled = TRUE;
LLLineEditorRollback rollback( this ); LLLineEditorRollback rollback( this );
@@ -2173,6 +2282,7 @@ BOOL LLLineEditor::evaluateFloat()
{ {
bool success = false; bool success = false;
std::string expr = getText(); std::string expr = getText();
LLStringUtil::toUpper(expr);
// user deleted the contents, nothing to evaluate -- MC // user deleted the contents, nothing to evaluate -- MC
if (expr.empty()) if (expr.empty())

View File

@@ -91,10 +91,13 @@ public:
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleDoubleClick(S32 x,S32 y,MASK mask); /*virtual*/ BOOL handleDoubleClick(S32 x,S32 y,MASK mask);
/*virtual*/ BOOL handleMiddleMouseDown(S32 x,S32 y,MASK mask); /*virtual*/ BOOL handleMiddleMouseDown(S32 x,S32 y,MASK mask);
/*virtual*/ BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask ); /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask );
/*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char); /*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char);
/*virtual*/ void onMouseCaptureLost(); /*virtual*/ void onMouseCaptureLost();
virtual void insert(std::string what,S32 wher);
// LLEditMenuHandler overrides // LLEditMenuHandler overrides
virtual void cut(); virtual void cut();
virtual BOOL canCut() const; virtual BOOL canCut() const;
@@ -119,6 +122,11 @@ public:
virtual void deselect(); virtual void deselect();
virtual BOOL canDeselect() const; virtual BOOL canDeselect() const;
static void context_cut(void* data);
static void context_copy(void* data);
static void context_paste(void* data);
static void context_delete(void* data);
static void context_selectall(void* data);
// view overrides // view overrides
virtual void draw(); virtual void draw();
virtual void reshape(S32 width,S32 height,BOOL called_from_parent=TRUE); virtual void reshape(S32 width,S32 height,BOOL called_from_parent=TRUE);
@@ -232,6 +240,7 @@ private:
void removeChar(); void removeChar();
void addChar(const llwchar c); void addChar(const llwchar c);
void setCursorAtLocalPos(S32 local_mouse_x); void setCursorAtLocalPos(S32 local_mouse_x);
S32 calculateCursorFromMouse(S32 local_mouse_x);
S32 findPixelNearestPos(S32 cursor_offset = 0) const; S32 findPixelNearestPos(S32 cursor_offset = 0) const;
void reportBadKeystroke(); void reportBadKeystroke();
BOOL handleSpecialKey(KEY key, MASK mask); BOOL handleSpecialKey(KEY key, MASK mask);
@@ -255,6 +264,7 @@ private:
virtual S32 getPreeditFontSize() const; virtual S32 getPreeditFontSize() const;
protected: protected:
LLHandle<LLView> mPopupMenuHandle;
LLUIString mText; // The string being edited. LLUIString mText; // The string being edited.
std::string mPrevText; // Saved string for 'ESC' revert std::string mPrevText; // Saved string for 'ESC' revert
LLUIString mLabel; // text label that is visible when no user text provided LLUIString mLabel; // text label that is visible when no user text provided

View File

@@ -53,11 +53,14 @@
#include "llkeywords.h" #include "llkeywords.h"
#include "llundo.h" #include "llundo.h"
#include "llviewborder.h" #include "llviewborder.h"
#include "llcontrol.h" #include "llcontrol.h"
#include "llimagegl.h" #include "llimagegl.h"
#include "llwindow.h" #include "llwindow.h"
#include "lltextparser.h" #include "lltextparser.h"
#include <queue> #include <queue>
#include "llmenugl.h"
#include "../newview/llviewercontrol.h"
// //
// Globals // Globals
@@ -254,6 +257,7 @@ LLTextEditor::LLTextEditor(
LLUICtrl( name, rect, TRUE, NULL, NULL, FOLLOWS_TOP | FOLLOWS_LEFT ), LLUICtrl( name, rect, TRUE, NULL, NULL, FOLLOWS_TOP | FOLLOWS_LEFT ),
mTextIsUpToDate(TRUE), mTextIsUpToDate(TRUE),
mMaxTextByteLength( max_length ), mMaxTextByteLength( max_length ),
mPopupMenuHandle(),
mBaseDocIsPristine(TRUE), mBaseDocIsPristine(TRUE),
mPristineCmd( NULL ), mPristineCmd( NULL ),
mLastCmd( NULL ), mLastCmd( NULL ),
@@ -339,6 +343,21 @@ LLTextEditor::LLTextEditor(
mParseHTML=FALSE; mParseHTML=FALSE;
mHTML.clear(); mHTML.clear();
// make the popup menu available
//LLMenuGL* menu = LLUICtrlFactory::getInstance()->buildMenu("menu_texteditor.xml", parent_view);
LLMenuGL* menu = new LLMenuGL("rclickmenu");
/*if (!menu)
{
menu = new LLMenuGL(LLStringUtil::null);
}*/
menu->append(new LLMenuItemCallGL("Cut", context_cut, NULL, this));
menu->append(new LLMenuItemCallGL("Copy", context_copy, NULL, this));
menu->append(new LLMenuItemCallGL("Paste", context_paste, NULL, this));
menu->append(new LLMenuItemCallGL("Delete", context_delete, NULL, this));
menu->append(new LLMenuItemCallGL("Select All", context_selectall, NULL, this));
menu->setCanTearOff(FALSE);
menu->setVisible(FALSE);
mPopupMenuHandle = menu->getHandle();
} }
@@ -357,6 +376,32 @@ LLTextEditor::~LLTextEditor()
std::for_each(mSegments.begin(), mSegments.end(), DeletePointer()); std::for_each(mSegments.begin(), mSegments.end(), DeletePointer());
std::for_each(mUndoStack.begin(), mUndoStack.end(), DeletePointer()); std::for_each(mUndoStack.begin(), mUndoStack.end(), DeletePointer());
LLView::deleteViewByHandle(mPopupMenuHandle);
}
void LLTextEditor::context_cut(void* data)
{
LLTextEditor* line = (LLTextEditor*)data;
if(line)line->cut();
}
void LLTextEditor::context_copy(void* data)
{
LLTextEditor* line = (LLTextEditor*)data;
if(line)line->copy();
}
void LLTextEditor::context_paste(void* data)
{
LLTextEditor* line = (LLTextEditor*)data;
if(line)line->paste();
}
void LLTextEditor::context_delete(void* data)
{
LLTextEditor* line = (LLTextEditor*)data;
if(line)line->doDelete();
}
void LLTextEditor::context_selectall(void* data)
{
LLTextEditor* line = (LLTextEditor*)data;
if(line)line->selectAll();
} }
void LLTextEditor::setTrackColor( const LLColor4& color ) void LLTextEditor::setTrackColor( const LLColor4& color )
@@ -645,6 +690,7 @@ void LLTextEditor::selectNext(const std::string& search_text_in, BOOL case_insen
} }
setCursorPos(loc); setCursorPos(loc);
scrollToPos(mCursorPos);
mIsSelecting = TRUE; mIsSelecting = TRUE;
mSelectionEnd = mCursorPos; mSelectionEnd = mCursorPos;
@@ -747,7 +793,14 @@ S32 LLTextEditor::getLineStart( S32 line ) const
S32 segoffset = mLineStartList[line].mOffset; S32 segoffset = mLineStartList[line].mOffset;
LLTextSegment* seg = mSegments[segidx]; LLTextSegment* seg = mSegments[segidx];
S32 res = seg->getStart() + segoffset; S32 res = seg->getStart() + segoffset;
if (res > seg->getEnd()) llerrs << "wtf" << llendl; if (res > seg->getEnd())
{
//llerrs << "wtf" << llendl;
// This happens when creating a new notecard using the AO on certain opensims.
// Play it safe instead of bringing down the viewer - MC
llwarns << "BAD JOOJOO! Text length (" << res << ") greater than text end (" << seg->getEnd() << "). Setting line start to " << seg->getEnd() << llendl;
res = seg->getEnd();
}
return res; return res;
} }
@@ -875,6 +928,11 @@ S32 LLTextEditor::getCursorPosFromLocalCoord( S32 local_x, S32 local_y, BOOL rou
void LLTextEditor::setCursor(S32 row, S32 column) void LLTextEditor::setCursor(S32 row, S32 column)
{ {
// Make sure we're not trying to set the cursor anywhere
// it can't go by always setting the min to 0 -- MC
row = (row < 0) ? 0 : row;
column = (column < 0) ? 0 : column;
const llwchar* doc = mWText.c_str(); const llwchar* doc = mWText.c_str();
const char CR = 10; const char CR = 10;
while(row--) while(row--)
@@ -1126,6 +1184,14 @@ BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)
{ {
BOOL handled = FALSE; BOOL handled = FALSE;
// SL-51858: Key presses are not being passed to the Popup menu.
// A proper fix is non-trivial so instead just close the menu.
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
if (menu && menu->isOpen())
{
LLMenuGL::sMenuContainer->hideMenus();
}
// Let scrollbar have first dibs // Let scrollbar have first dibs
handled = LLView::childrenHandleMouseDown(x, y, mask) != NULL; handled = LLView::childrenHandleMouseDown(x, y, mask) != NULL;
@@ -1200,6 +1266,20 @@ BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)
return handled; return handled;
} }
BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask )
{
setFocus(TRUE);
llinfos << "Right mouse click - Opening menu." << llendl;
//setCursorAtLocalPos( x, y, TRUE );
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
if (menu)
{
menu->buildDrawLabels();
menu->updateParent(LLMenuGL::sMenuContainer);
LLMenuGL::showPopup(this, menu, x, y);
}
return TRUE;
}
BOOL LLTextEditor::handleMiddleMouseDown(S32 x, S32 y, MASK mask) BOOL LLTextEditor::handleMiddleMouseDown(S32 x, S32 y, MASK mask)
@@ -2251,6 +2331,13 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask )
BOOL selection_modified = FALSE; BOOL selection_modified = FALSE;
BOOL return_key_hit = FALSE; BOOL return_key_hit = FALSE;
BOOL text_may_have_changed = TRUE; BOOL text_may_have_changed = TRUE;
// SL-51858: Key presses are not being passed to the Popup menu.
// A proper fix is non-trivial so instead just close the menu.
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
if (menu && menu->isOpen())
{
LLMenuGL::sMenuContainer->hideMenus();
}
if ( gFocusMgr.getKeyboardFocus() == this ) if ( gFocusMgr.getKeyboardFocus() == this )
{ {
@@ -2295,6 +2382,14 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask )
} }
} }
// SL-51858: Key presses are not being passed to the Popup menu.
// A proper fix is non-trivial so instead just close the menu.
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
if (menu && menu->isOpen())
{
LLMenuGL::sMenuContainer->hideMenus();
}
// Handle most keys only if the text editor is writeable. // Handle most keys only if the text editor is writeable.
if( !mReadOnly ) if( !mReadOnly )
{ {
@@ -3239,6 +3334,8 @@ void LLTextEditor::onTabInto()
void LLTextEditor::clear() void LLTextEditor::clear()
{ {
setText(LLStringUtil::null); setText(LLStringUtil::null);
std::for_each(mSegments.begin(), mSegments.end(), DeletePointer());
mSegments.clear();
} }
// Start or stop the editor from accepting text-editing keystrokes // Start or stop the editor from accepting text-editing keystrokes
@@ -3415,6 +3512,43 @@ void LLTextEditor::setCursorAndScrollToEnd()
needsScroll(); needsScroll();
} }
void LLTextEditor::scrollToPos(S32 pos)
{
mScrollbar->setDocSize( getLineCount() );
S32 line, offset;
getLineAndOffset(pos, &line, &offset );
S32 page_size = mScrollbar->getPageSize();
if( line < mScrollbar->getDocPos() )
{
// scroll so that the cursor is at the top of the page
mScrollbar->setDocPos( line );
}
else if( line >= mScrollbar->getDocPos() + page_size - 1 )
{
S32 new_pos = 0;
if( line < mScrollbar->getDocSize() - 1 )
{
// scroll so that the cursor is one line above the bottom of the page,
new_pos = line - page_size + 1;
}
else
{
// if there is less than a page of text remaining, scroll so that the cursor is at the bottom
new_pos = mScrollbar->getDocPosMax();
}
mScrollbar->setDocPos( new_pos );
}
// Check if we've scrolled to bottom for callback if asked for callback
if (mOnScrollEndCallback && mOnScrollEndData && (mScrollbar->getDocPos() == mScrollbar->getDocPosMax()))
{
mOnScrollEndCallback(mOnScrollEndData);
}
}
void LLTextEditor::getLineAndColumnForPosition( S32 position, S32* line, S32* col, BOOL include_wordwrap ) void LLTextEditor::getLineAndColumnForPosition( S32 position, S32* line, S32* col, BOOL include_wordwrap )
{ {
if( include_wordwrap ) if( include_wordwrap )
@@ -3492,45 +3626,13 @@ void LLTextEditor::endOfDoc()
// Sets the scrollbar from the cursor position // Sets the scrollbar from the cursor position
void LLTextEditor::updateScrollFromCursor() void LLTextEditor::updateScrollFromCursor()
{ {
mScrollbar->setDocSize( getLineCount() );
if (mReadOnly) if (mReadOnly)
{ {
// no cursor in read only mode // no cursor in read only mode
return; return;
} }
S32 line, offset; scrollToPos(mCursorPos);
getLineAndOffset( mCursorPos, &line, &offset );
S32 page_size = mScrollbar->getPageSize();
if( line < mScrollbar->getDocPos() )
{
// scroll so that the cursor is at the top of the page
mScrollbar->setDocPos( line );
}
else if( line >= mScrollbar->getDocPos() + page_size - 1 )
{
S32 new_pos = 0;
if( line < mScrollbar->getDocSize() - 1 )
{
// scroll so that the cursor is one line above the bottom of the page,
new_pos = line - page_size + 1;
}
else
{
// if there is less than a page of text remaining, scroll so that the cursor is at the bottom
new_pos = mScrollbar->getDocPosMax();
}
mScrollbar->setDocPos( new_pos );
}
// Check if we've scrolled to bottom for callback if asked for callback
if (mOnScrollEndCallback && mOnScrollEndData && (mScrollbar->getDocPos() == mScrollbar->getDocPosMax()))
{
mOnScrollEndCallback(mOnScrollEndData);
}
} }
void LLTextEditor::reshape(S32 width, S32 height, BOOL called_from_parent) void LLTextEditor::reshape(S32 width, S32 height, BOOL called_from_parent)
@@ -3582,13 +3684,13 @@ void LLTextEditor::autoIndent()
} }
// Inserts new text at the cursor position // Inserts new text at the cursor position
void LLTextEditor::insertText(const std::string &new_text) void LLTextEditor::insertText(const std::string &new_text,BOOL deleteCurrentSelection)
{ {
BOOL enabled = getEnabled(); BOOL enabled = getEnabled();
setEnabled( TRUE ); setEnabled( TRUE );
// Delete any selected characters (the insertion replaces them) // Delete any selected characters (the insertion replaces them)
if( hasSelection() ) if( hasSelection() && (deleteCurrentSelection))
{ {
deleteSelection(TRUE); deleteSelection(TRUE);
} }

View File

@@ -45,6 +45,7 @@
#include "lldarray.h" #include "lldarray.h"
#include "llpreeditor.h" #include "llpreeditor.h"
#include "llmenugl.h"
class LLFontGL; class LLFontGL;
class LLScrollbar; class LLScrollbar;
@@ -84,6 +85,7 @@ public:
virtual BOOL handleHover(S32 x, S32 y, MASK mask); virtual BOOL handleHover(S32 x, S32 y, MASK mask);
virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask ); virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask );
virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
virtual BOOL handleMiddleMouseDown(S32 x,S32 y,MASK mask); virtual BOOL handleMiddleMouseDown(S32 x,S32 y,MASK mask);
virtual BOOL handleKeyHere(KEY key, MASK mask ); virtual BOOL handleKeyHere(KEY key, MASK mask );
@@ -132,6 +134,12 @@ public:
virtual BOOL canSelectAll() const; virtual BOOL canSelectAll() const;
virtual void deselect(); virtual void deselect();
virtual BOOL canDeselect() const; virtual BOOL canDeselect() const;
static void context_cut(void* data);
static void context_copy(void* data);
static void context_paste(void* data);
static void context_delete(void* data);
static void context_selectall(void* data);
void selectNext(const std::string& search_text_in, BOOL case_insensitive, BOOL wrap = TRUE); void selectNext(const std::string& search_text_in, BOOL case_insensitive, BOOL wrap = TRUE);
BOOL replaceText(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive, BOOL wrap = TRUE); BOOL replaceText(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive, BOOL wrap = TRUE);
@@ -146,7 +154,7 @@ public:
BOOL allowsEmbeddedItems() const { return mAllowEmbeddedItems; } BOOL allowsEmbeddedItems() const { return mAllowEmbeddedItems; }
// inserts text at cursor // inserts text at cursor
void insertText(const std::string &text); void insertText(const std::string &text, BOOL deleteSelection = TRUE);
// appends text at end // appends text at end
void appendText(const std::string &wtext, bool allow_undo, bool prepend_newline, void appendText(const std::string &wtext, bool allow_undo, bool prepend_newline,
const LLStyleSP stylep = NULL); const LLStyleSP stylep = NULL);
@@ -172,6 +180,7 @@ public:
void setCursor(S32 row, S32 column); void setCursor(S32 row, S32 column);
void setCursorPos(S32 offset); void setCursorPos(S32 offset);
void setCursorAndScrollToEnd(); void setCursorAndScrollToEnd();
void scrollToPos(S32 pos);
void getLineAndColumnForPosition( S32 position, S32* line, S32* col, BOOL include_wordwrap ); void getLineAndColumnForPosition( S32 position, S32* line, S32* col, BOOL include_wordwrap );
void getCurrentLineAndColumn( S32* line, S32* col, BOOL include_wordwrap ); void getCurrentLineAndColumn( S32* line, S32* col, BOOL include_wordwrap );
@@ -264,16 +273,20 @@ public:
static bool isPartOfWord(llwchar c) { return (c == '_') || LLStringOps::isAlnum((char)c); } static bool isPartOfWord(llwchar c) { return (c == '_') || LLStringOps::isAlnum((char)c); }
BOOL isReadOnly() { return mReadOnly; }
protected: protected:
// //
// Methods // Methods
// //
LLHandle<LLView> mPopupMenuHandle;
S32 getLength() const { return mWText.length(); } S32 getLength() const { return mWText.length(); }
void getSegmentAndOffset( S32 startpos, S32* segidxp, S32* offsetp ) const; void getSegmentAndOffset( S32 startpos, S32* segidxp, S32* offsetp ) const;
void drawPreeditMarker(); void drawPreeditMarker();
public:
void updateLineStartList(S32 startpos = 0); void updateLineStartList(S32 startpos = 0);
protected:
void updateScrollFromCursor(); void updateScrollFromCursor();
void updateTextRect(); void updateTextRect();
const LLRect& getTextRect() const { return mTextRect; } const LLRect& getTextRect() const { return mTextRect; }
@@ -405,8 +418,9 @@ protected:
// //
// I-beam is just after the mCursorPos-th character. // I-beam is just after the mCursorPos-th character.
public:
S32 mCursorPos; S32 mCursorPos;
protected:
// Use these to determine if a click on an embedded item is a drag or not. // Use these to determine if a click on an embedded item is a drag or not.
S32 mMouseDownX; S32 mMouseDownX;
S32 mMouseDownY; S32 mMouseDownY;

View File

@@ -149,6 +149,11 @@ LLView::~LLView()
{ {
//llinfos << "Deleting view " << mName << ":" << (void*) this << llendl; //llinfos << "Deleting view " << mName << ":" << (void*) this << llendl;
// llassert(LLView::sIsDrawing == FALSE); // llassert(LLView::sIsDrawing == FALSE);
if( gFocusMgr.getKeyboardFocus() == this )
{
llwarns << "View holding keyboard focus deleted: " << getName() << ". Keyboard focus removed." << llendl;
gFocusMgr.removeKeyboardFocusWithoutCallback( this );
}
if( hasMouseCapture() ) if( hasMouseCapture() )
{ {

View File

@@ -935,6 +935,7 @@ BOOL LLViewerTextEditor::handleMouseUp(S32 x, S32 y, MASK mask)
BOOL LLViewerTextEditor::handleRightMouseDown(S32 x, S32 y, MASK mask) BOOL LLViewerTextEditor::handleRightMouseDown(S32 x, S32 y, MASK mask)
{ {
BOOL handled = childrenHandleRightMouseDown(x, y, mask) != NULL; BOOL handled = childrenHandleRightMouseDown(x, y, mask) != NULL;
if(!handled)handled = LLTextEditor::handleRightMouseDown(x, y, mask);
// *TODO: Add right click menus for SLURLs // *TODO: Add right click menus for SLURLs
// if(! handled) // if(! handled)
@@ -1079,28 +1080,28 @@ BOOL LLViewerTextEditor::handleDragAndDrop(S32 x, S32 y, MASK mask,
{ {
switch( cargo_type ) switch( cargo_type )
{ {
// <edit> // <edit>
// This does not even appear to be used maybe // This does not even appear to be used maybe
// Throwing it out so I can embed calling cards // Throwing it out so I can embed calling cards
/* /*
case DAD_CALLINGCARD: case DAD_CALLINGCARD:
if(acceptsCallingCardNames()) if(acceptsCallingCardNames())
{ {
if (drop) if (drop)
{ {
LLInventoryItem *item = (LLInventoryItem *)cargo_data; LLInventoryItem *item = (LLInventoryItem *)cargo_data;
std::string name = item->getName(); std::string name = item->getName();
appendText(name, true, true); appendText(name, true, true);
} }
*accept = ACCEPT_YES_COPY_SINGLE; *accept = ACCEPT_YES_COPY_SINGLE;
} }
else else
{ {
*accept = ACCEPT_NO; *accept = ACCEPT_NO;
} }
break; break;
*/ */
case DAD_CALLINGCARD: case DAD_CALLINGCARD:
// </edit> // </edit>
case DAD_TEXTURE: case DAD_TEXTURE:
case DAD_SOUND: case DAD_SOUND:
@@ -1114,29 +1115,29 @@ BOOL LLViewerTextEditor::handleDragAndDrop(S32 x, S32 y, MASK mask,
case DAD_GESTURE: case DAD_GESTURE:
{ {
LLInventoryItem *item = (LLInventoryItem *)cargo_data; LLInventoryItem *item = (LLInventoryItem *)cargo_data;
// <edit> // <edit>
if((item->getPermissions().getMaskOwner() & PERM_ITEM_UNRESTRICTED) != PERM_ITEM_UNRESTRICTED) if((item->getPermissions().getMaskOwner() & PERM_ITEM_UNRESTRICTED) != PERM_ITEM_UNRESTRICTED)
{ {
if(gSavedSettings.getBOOL("ForceNotecardDragCargoPermissive")) if(gSavedSettings.getBOOL("ForceNotecardDragCargoPermissive"))
{ {
item = new LLInventoryItem((LLInventoryItem *)cargo_data); item = new LLInventoryItem((LLInventoryItem *)cargo_data);
LLPermissions old = item->getPermissions(); LLPermissions old = item->getPermissions();
LLPermissions perm; LLPermissions perm;
perm.init(old.getCreator(), old.getOwner(), old.getLastOwner(), old.getGroup()); perm.init(old.getCreator(), old.getOwner(), old.getLastOwner(), old.getGroup());
perm.setMaskBase(PERM_ITEM_UNRESTRICTED); perm.setMaskBase(PERM_ITEM_UNRESTRICTED);
perm.setMaskEveryone(PERM_ITEM_UNRESTRICTED); perm.setMaskEveryone(PERM_ITEM_UNRESTRICTED);
perm.setMaskGroup(PERM_ITEM_UNRESTRICTED); perm.setMaskGroup(PERM_ITEM_UNRESTRICTED);
perm.setMaskNext(PERM_ITEM_UNRESTRICTED); perm.setMaskNext(PERM_ITEM_UNRESTRICTED);
perm.setMaskOwner(PERM_ITEM_UNRESTRICTED); perm.setMaskOwner(PERM_ITEM_UNRESTRICTED);
item->setPermissions(perm); item->setPermissions(perm);
} }
} }
// </edit> // </edit>
if( item && allowsEmbeddedItems() ) if( item && allowsEmbeddedItems() )
{ {
U32 mask_next = item->getPermissions().getMaskNextOwner(); U32 mask_next = item->getPermissions().getMaskNextOwner();
// <edit> // <edit>
//if((mask_next & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) //if((mask_next & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED)
if(((mask_next & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) || gSavedSettings.getBOOL("ForceNotecardDragCargoAcceptance")) if(((mask_next & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) || gSavedSettings.getBOOL("ForceNotecardDragCargoAcceptance"))
{ {
if( drop ) if( drop )
@@ -1551,13 +1552,13 @@ bool LLViewerTextEditor::hasEmbeddedInventory()
return ! mEmbeddedItemList->empty(); return ! mEmbeddedItemList->empty();
} }
// <edit> // <edit>
std::vector<LLPointer<LLInventoryItem> > LLViewerTextEditor::getEmbeddedItems() std::vector<LLPointer<LLInventoryItem> > LLViewerTextEditor::getEmbeddedItems()
{ {
std::vector<LLPointer<LLInventoryItem> > items; std::vector<LLPointer<LLInventoryItem> > items;
mEmbeddedItemList->getEmbeddedItemList(items); mEmbeddedItemList->getEmbeddedItemList(items);
return items; return items;
} }
// </edit> // </edit>
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////