aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llui
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llui')
-rw-r--r--linden/indra/llui/llclipboard.cpp41
-rw-r--r--linden/indra/llui/llclipboard.h11
-rw-r--r--linden/indra/llui/llfloater.cpp6
-rw-r--r--linden/indra/llui/llfloater.h2
-rw-r--r--linden/indra/llui/lllineeditor.cpp83
-rw-r--r--linden/indra/llui/lllineeditor.h13
-rw-r--r--linden/indra/llui/llpanel.cpp4
-rw-r--r--linden/indra/llui/llpanel.h2
-rw-r--r--linden/indra/llui/llscrolllistctrl.cpp12
-rw-r--r--linden/indra/llui/llscrolllistctrl.h1
-rw-r--r--linden/indra/llui/lltextbox.cpp7
-rw-r--r--linden/indra/llui/lltextbox.h3
-rw-r--r--linden/indra/llui/lltexteditor.cpp107
-rw-r--r--linden/indra/llui/lltexteditor.h16
-rw-r--r--linden/indra/llui/llview.cpp98
-rw-r--r--linden/indra/llui/llview.h9
16 files changed, 373 insertions, 42 deletions
diff --git a/linden/indra/llui/llclipboard.cpp b/linden/indra/llui/llclipboard.cpp
index d5255e7..f33f3fa 100644
--- a/linden/indra/llui/llclipboard.cpp
+++ b/linden/indra/llui/llclipboard.cpp
@@ -92,3 +92,44 @@ BOOL LLClipboard::canPasteString() const
92{ 92{
93 return LLView::getWindow()->isClipboardTextAvailable(); 93 return LLView::getWindow()->isClipboardTextAvailable();
94} 94}
95
96
97void LLClipboard::copyFromPrimarySubstring(const LLWString &src, S32 pos, S32 len, const LLUUID& source_id )
98{
99 mSourceID = source_id;
100 mString = src.substr(pos, len);
101 LLView::getWindow()->copyTextToPrimary( mString );
102}
103
104
105const LLWString& LLClipboard::getPastePrimaryWString( LLUUID* source_id )
106{
107 if( mSourceID.notNull() )
108 {
109 LLWString temp_string;
110 LLView::getWindow()->pasteTextFromPrimary(temp_string);
111
112 if( temp_string != mString )
113 {
114 mSourceID.setNull();
115 mString = temp_string;
116 }
117 }
118 else
119 {
120 LLView::getWindow()->pasteTextFromPrimary(mString);
121 }
122
123 if( source_id )
124 {
125 *source_id = mSourceID;
126 }
127
128 return mString;
129}
130
131
132BOOL LLClipboard::canPastePrimaryString() const
133{
134 return LLView::getWindow()->isPrimaryTextAvailable();
135}
diff --git a/linden/indra/llui/llclipboard.h b/linden/indra/llui/llclipboard.h
index 706ed2a..7117f84 100644
--- a/linden/indra/llui/llclipboard.h
+++ b/linden/indra/llui/llclipboard.h
@@ -43,10 +43,19 @@ public:
43 LLClipboard(); 43 LLClipboard();
44 ~LLClipboard(); 44 ~LLClipboard();
45 45
46 /* We support two flavors of clipboard. The default is the explicitly
47 copy-and-pasted clipboard. The second is the so-called 'primary' clipboard
48 which is implicitly copied upon selection on platforms which expect this
49 (i.e. X11/Linux). */
50
46 void copyFromSubstring(const LLWString &copy_from, S32 pos, S32 len, const LLUUID& source_id = LLUUID::null ); 51 void copyFromSubstring(const LLWString &copy_from, S32 pos, S32 len, const LLUUID& source_id = LLUUID::null );
47 BOOL canPasteString() const; 52 BOOL canPasteString() const;
48 const LLWString& getPasteWString(LLUUID* source_id = NULL); 53 const LLWString& getPasteWString(LLUUID* source_id = NULL);
49 54
55 void copyFromPrimarySubstring(const LLWString &copy_from, S32 pos, S32 len, const LLUUID& source_id = LLUUID::null );
56 BOOL canPastePrimaryString() const;
57 const LLWString& getPastePrimaryWString(LLUUID* source_id = NULL);
58
50private: 59private:
51 LLUUID mSourceID; 60 LLUUID mSourceID;
52 LLWString mString; 61 LLWString mString;
diff --git a/linden/indra/llui/llfloater.cpp b/linden/indra/llui/llfloater.cpp
index 2924c29..efe49eb 100644
--- a/linden/indra/llui/llfloater.cpp
+++ b/linden/indra/llui/llfloater.cpp
@@ -1187,6 +1187,12 @@ BOOL LLFloater::handleRightMouseDown(S32 x, S32 y, MASK mask)
1187 return was_minimized || LLPanel::handleRightMouseDown( x, y, mask ); 1187 return was_minimized || LLPanel::handleRightMouseDown( x, y, mask );
1188} 1188}
1189 1189
1190BOOL LLFloater::handleMiddleMouseDown(S32 x, S32 y, MASK mask)
1191{
1192 bringToFront( x, y );
1193 return LLPanel::handleMiddleMouseDown( x, y, mask );
1194}
1195
1190 1196
1191// virtual 1197// virtual
1192BOOL LLFloater::handleDoubleClick(S32 x, S32 y, MASK mask) 1198BOOL LLFloater::handleDoubleClick(S32 x, S32 y, MASK mask)
diff --git a/linden/indra/llui/llfloater.h b/linden/indra/llui/llfloater.h
index a6fe3cc..37081c2 100644
--- a/linden/indra/llui/llfloater.h
+++ b/linden/indra/llui/llfloater.h
@@ -178,7 +178,7 @@ public:
178 virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); 178 virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
179 virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); 179 virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
180 virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask); 180 virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
181 181 virtual BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask);
182 virtual void draw(); 182 virtual void draw();
183 183
184 virtual void onOpen() {} 184 virtual void onOpen() {}
diff --git a/linden/indra/llui/lllineeditor.cpp b/linden/indra/llui/lllineeditor.cpp
index 498ef26..f905774 100644
--- a/linden/indra/llui/lllineeditor.cpp
+++ b/linden/indra/llui/lllineeditor.cpp
@@ -493,6 +493,9 @@ BOOL LLLineEditor::handleDoubleClick(S32 x, S32 y, MASK mask)
493 // delay cursor flashing 493 // delay cursor flashing
494 mKeystrokeTimer.reset(); 494 mKeystrokeTimer.reset();
495 495
496 // take selection to 'primary' clipboard
497 updatePrimary();
498
496 return TRUE; 499 return TRUE;
497} 500}
498 501
@@ -575,6 +578,17 @@ BOOL LLLineEditor::handleMouseDown(S32 x, S32 y, MASK mask)
575 return TRUE; 578 return TRUE;
576} 579}
577 580
581BOOL LLLineEditor::handleMiddleMouseDown(S32 x, S32 y, MASK mask)
582{
583 // llinfos << "MiddleMouseDown" << llendl;
584 setFocus( TRUE );
585 if( canPastePrimary() )
586 {
587 setCursorAtLocalPos(x);
588 pastePrimary();
589 }
590 return TRUE;
591}
578 592
579BOOL LLLineEditor::handleHover(S32 x, S32 y, MASK mask) 593BOOL LLLineEditor::handleHover(S32 x, S32 y, MASK mask)
580{ 594{
@@ -669,6 +683,9 @@ BOOL LLLineEditor::handleMouseUp(S32 x, S32 y, MASK mask)
669 { 683 {
670 // delay cursor flashing 684 // delay cursor flashing
671 mKeystrokeTimer.reset(); 685 mKeystrokeTimer.reset();
686
687 // take selection to 'primary' clipboard
688 updatePrimary();
672 } 689 }
673 690
674 return handled; 691 return handled;
@@ -872,7 +889,12 @@ BOOL LLLineEditor::handleSelectionKey(KEY key, MASK mask)
872 } 889 }
873 } 890 }
874 891
875 892 if(handled)
893 {
894 // take selection to 'primary' clipboard
895 updatePrimary();
896 }
897
876 return handled; 898 return handled;
877} 899}
878 900
@@ -945,20 +967,42 @@ BOOL LLLineEditor::canPaste() const
945 return !mReadOnly && gClipboard.canPasteString(); 967 return !mReadOnly && gClipboard.canPasteString();
946} 968}
947 969
948
949// paste from clipboard
950void LLLineEditor::paste() 970void LLLineEditor::paste()
951{ 971{
952 if (canPaste()) 972 bool is_primary = false;
973 pasteHelper(is_primary);
974}
975
976void LLLineEditor::pastePrimary()
977{
978 bool is_primary = true;
979 pasteHelper(is_primary);
980}
981
982// paste from primary (is_primary==true) or clipboard (is_primary==false)
983void LLLineEditor::pasteHelper(bool is_primary)
984{
985 bool can_paste_it;
986 if (is_primary)
987 can_paste_it = canPastePrimary();
988 else
989 can_paste_it = canPaste();
990
991 if (can_paste_it)
953 { 992 {
954 LLWString paste = gClipboard.getPasteWString(); 993 LLWString paste;
994 if (is_primary)
995 paste = gClipboard.getPastePrimaryWString();
996 else
997 paste = gClipboard.getPasteWString();
998
955 if (!paste.empty()) 999 if (!paste.empty())
956 { 1000 {
957 // Prepare for possible rollback 1001 // Prepare for possible rollback
958 LLLineEditorRollback rollback(this); 1002 LLLineEditorRollback rollback(this);
959 1003
960 // Delete any selected characters 1004 // Delete any selected characters
961 if (hasSelection()) 1005 if ((!is_primary) && hasSelection())
962 { 1006 {
963 deleteSelection(); 1007 deleteSelection();
964 } 1008 }
@@ -994,7 +1038,7 @@ void LLLineEditor::paste()
994 clean_string = clean_string.substr(0, wchars_that_fit); 1038 clean_string = clean_string.substr(0, wchars_that_fit);
995 reportBadKeystroke(); 1039 reportBadKeystroke();
996 } 1040 }
997 1041
998 mText.insert(getCursor(), clean_string); 1042 mText.insert(getCursor(), clean_string);
999 setCursor( getCursor() + (S32)clean_string.length() ); 1043 setCursor( getCursor() + (S32)clean_string.length() );
1000 deselect(); 1044 deselect();
@@ -1015,7 +1059,30 @@ void LLLineEditor::paste()
1015 } 1059 }
1016} 1060}
1017 1061
1018 1062// copy selection to primary
1063void LLLineEditor::copyPrimary()
1064{
1065 if( canCopy() )
1066 {
1067 S32 left_pos = llmin( mSelectionStart, mSelectionEnd );
1068 S32 length = abs( mSelectionStart - mSelectionEnd );
1069 gClipboard.copyFromPrimarySubstring( mText.getWString(), left_pos, length );
1070 }
1071}
1072
1073BOOL LLLineEditor::canPastePrimary() const
1074{
1075 return !mReadOnly && gClipboard.canPastePrimaryString();
1076}
1077
1078void LLLineEditor::updatePrimary()
1079{
1080 if(canCopy() )
1081 {
1082 copyPrimary();
1083 }
1084}
1085
1019BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask) 1086BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask)
1020{ 1087{
1021 BOOL handled = FALSE; 1088 BOOL handled = FALSE;
diff --git a/linden/indra/llui/lllineeditor.h b/linden/indra/llui/lllineeditor.h
index 11cbcd9..b11f8b9 100644
--- a/linden/indra/llui/lllineeditor.h
+++ b/linden/indra/llui/lllineeditor.h
@@ -89,6 +89,7 @@ public:
89 /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); 89 /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
90 /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); 90 /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
91 /*virtual*/ BOOL handleDoubleClick(S32 x,S32 y,MASK mask); 91 /*virtual*/ BOOL handleDoubleClick(S32 x,S32 y,MASK mask);
92 /*virtual*/ BOOL handleMiddleMouseDown(S32 x,S32 y,MASK mask);
92 /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask ); 93 /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask );
93 /*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char); 94 /*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char);
94 /*virtual*/ void onMouseCaptureLost(); 95 /*virtual*/ void onMouseCaptureLost();
@@ -96,13 +97,16 @@ public:
96 // LLEditMenuHandler overrides 97 // LLEditMenuHandler overrides
97 virtual void cut(); 98 virtual void cut();
98 virtual BOOL canCut() const; 99 virtual BOOL canCut() const;
99
100 virtual void copy(); 100 virtual void copy();
101 virtual BOOL canCopy() const; 101 virtual BOOL canCopy() const;
102
103 virtual void paste(); 102 virtual void paste();
104 virtual BOOL canPaste() const; 103 virtual BOOL canPaste() const;
105 104
105 virtual void updatePrimary();
106 virtual void copyPrimary();
107 virtual void pastePrimary();
108 virtual BOOL canPastePrimary() const;
109
106 virtual void doDelete(); 110 virtual void doDelete();
107 virtual BOOL canDoDelete() const; 111 virtual BOOL canDoDelete() const;
108 112
@@ -219,6 +223,9 @@ public:
219 223
220private: 224private:
221 // private helper methods 225 // private helper methods
226
227 void pasteHelper(bool is_primary);
228
222 void removeChar(); 229 void removeChar();
223 void addChar(const llwchar c); 230 void addChar(const llwchar c);
224 void setCursorAtLocalPos(S32 local_mouse_x); 231 void setCursorAtLocalPos(S32 local_mouse_x);
diff --git a/linden/indra/llui/llpanel.cpp b/linden/indra/llui/llpanel.cpp
index d37517f..05103dc 100644
--- a/linden/indra/llui/llpanel.cpp
+++ b/linden/indra/llui/llpanel.cpp
@@ -982,12 +982,12 @@ void LLPanel::childSetAction(const std::string& id, void(*function)(void*), void
982 } 982 }
983} 983}
984 984
985void LLPanel::childSetActionTextbox(const std::string& id, void(*function)(void*)) 985void LLPanel::childSetActionTextbox(const std::string& id, void(*function)(void*), void* value)
986{ 986{
987 LLTextBox* textbox = getChild<LLTextBox>(id); 987 LLTextBox* textbox = getChild<LLTextBox>(id);
988 if (textbox) 988 if (textbox)
989 { 989 {
990 textbox->setClickedCallback(function); 990 textbox->setClickedCallback(function, value);
991 } 991 }
992} 992}
993 993
diff --git a/linden/indra/llui/llpanel.h b/linden/indra/llui/llpanel.h
index 46022e5..8dea9b1 100644
--- a/linden/indra/llui/llpanel.h
+++ b/linden/indra/llui/llpanel.h
@@ -220,7 +220,7 @@ public:
220 220
221 // LLButton 221 // LLButton
222 void childSetAction(const std::string& id, void(*function)(void*), void* value); 222 void childSetAction(const std::string& id, void(*function)(void*), void* value);
223 void childSetActionTextbox(const std::string& id, void(*function)(void*)); 223 void childSetActionTextbox(const std::string& id, void(*function)(void*), void* value = NULL);
224 void childSetControlName(const std::string& id, const std::string& control_name); 224 void childSetControlName(const std::string& id, const std::string& control_name);
225 225
226 // Error reporting 226 // Error reporting
diff --git a/linden/indra/llui/llscrolllistctrl.cpp b/linden/indra/llui/llscrolllistctrl.cpp
index 7dba55f..c6da2d7 100644
--- a/linden/indra/llui/llscrolllistctrl.cpp
+++ b/linden/indra/llui/llscrolllistctrl.cpp
@@ -703,6 +703,18 @@ std::vector<LLScrollListItem*> LLScrollListCtrl::getAllSelected() const
703 return ret; 703 return ret;
704} 704}
705 705
706LLDynamicArray<LLUUID> LLScrollListCtrl::getSelectedIDs()
707{
708 LLUUID selected_id;
709 LLDynamicArray<LLUUID> ids;
710 std::vector<LLScrollListItem*> selected = this->getAllSelected();
711 for(std::vector<LLScrollListItem*>::iterator itr = selected.begin(); itr != selected.end(); ++itr)
712 {
713 ids.push_back((*itr)->getUUID());
714 }
715 return ids;
716}
717
706S32 LLScrollListCtrl::getFirstSelectedIndex() const 718S32 LLScrollListCtrl::getFirstSelectedIndex() const
707{ 719{
708 S32 CurSelectedIndex = 0; 720 S32 CurSelectedIndex = 0;
diff --git a/linden/indra/llui/llscrolllistctrl.h b/linden/indra/llui/llscrolllistctrl.h
index f276562..73f9a5b 100644
--- a/linden/indra/llui/llscrolllistctrl.h
+++ b/linden/indra/llui/llscrolllistctrl.h
@@ -517,6 +517,7 @@ public:
517 LLScrollListItem* getFirstSelected() const; 517 LLScrollListItem* getFirstSelected() const;
518 virtual S32 getFirstSelectedIndex() const; 518 virtual S32 getFirstSelectedIndex() const;
519 std::vector<LLScrollListItem*> getAllSelected() const; 519 std::vector<LLScrollListItem*> getAllSelected() const;
520 LLDynamicArray<LLUUID> getSelectedIDs();
520 LLScrollListItem* getLastSelectedItem() const { return mLastSelected; } 521 LLScrollListItem* getLastSelectedItem() const { return mLastSelected; }
521 522
522 // iterate over all items 523 // iterate over all items
diff --git a/linden/indra/llui/lltextbox.cpp b/linden/indra/llui/lltextbox.cpp
index f43b7d2..e45f97b 100644
--- a/linden/indra/llui/lltextbox.cpp
+++ b/linden/indra/llui/lltextbox.cpp
@@ -33,6 +33,7 @@
33#include "lltextbox.h" 33#include "lltextbox.h"
34#include "lluictrlfactory.h" 34#include "lluictrlfactory.h"
35#include "llfocusmgr.h" 35#include "llfocusmgr.h"
36#include "llwindow.h"
36 37
37static LLRegisterWidget<LLTextBox> r("text"); 38static LLRegisterWidget<LLTextBox> r("text");
38 39
@@ -193,12 +194,14 @@ BOOL LLTextBox::handleMouseUp(S32 x, S32 y, MASK mask)
193 194
194BOOL LLTextBox::handleHover(S32 x, S32 y, MASK mask) 195BOOL LLTextBox::handleHover(S32 x, S32 y, MASK mask)
195{ 196{
197 BOOL handled = LLView::handleHover(x,y,mask);
196 if(mHoverActive) 198 if(mHoverActive)
197 { 199 {
198 mHasHover = TRUE; // This should be set every frame during a hover. 200 mHasHover = TRUE; // This should be set every frame during a hover.
199 return TRUE; 201 getWindow()->setCursor(UI_CURSOR_ARROW);
200 } 202 }
201 return LLView::handleHover(x,y,mask); 203
204 return (handled || mHasHover);
202} 205}
203 206
204void LLTextBox::setText(const LLStringExplicit& text) 207void LLTextBox::setText(const LLStringExplicit& text)
diff --git a/linden/indra/llui/lltextbox.h b/linden/indra/llui/lltextbox.h
index 83e4a9b..aac5344 100644
--- a/linden/indra/llui/lltextbox.h
+++ b/linden/indra/llui/lltextbox.h
@@ -88,8 +88,7 @@ public:
88 void setVPad(S32 pixels) { mVPad = pixels; } 88 void setVPad(S32 pixels) { mVPad = pixels; }
89 void setRightAlign() { mHAlign = LLFontGL::RIGHT; } 89 void setRightAlign() { mHAlign = LLFontGL::RIGHT; }
90 void setHAlign( LLFontGL::HAlign align ) { mHAlign = align; } 90 void setHAlign( LLFontGL::HAlign align ) { mHAlign = align; }
91 void setClickedCallback( void (*cb)(void *data) ){ mClickedCallback = cb; } // mouse down and up within button 91 void setClickedCallback( void (*cb)(void *data), void* data = NULL ){ mClickedCallback = cb; mCallbackUserData = data; } // mouse down and up within button
92 void setCallbackUserData( void* data ) { mCallbackUserData = data; }
93 92
94 const LLFontGL* getFont() const { return mFontGL; } 93 const LLFontGL* getFont() const { return mFontGL; }
95 94
diff --git a/linden/indra/llui/lltexteditor.cpp b/linden/indra/llui/lltexteditor.cpp
index 3813e76..8fa253a 100644
--- a/linden/indra/llui/lltexteditor.cpp
+++ b/linden/indra/llui/lltexteditor.cpp
@@ -1203,6 +1203,18 @@ BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)
1203} 1203}
1204 1204
1205 1205
1206BOOL LLTextEditor::handleMiddleMouseDown(S32 x, S32 y, MASK mask)
1207{
1208 setFocus( TRUE );
1209 if( canPastePrimary() )
1210 {
1211 setCursorAtLocalPos( x, y, TRUE );
1212 pastePrimary();
1213 }
1214 return TRUE;
1215}
1216
1217
1206BOOL LLTextEditor::handleHover(S32 x, S32 y, MASK mask) 1218BOOL LLTextEditor::handleHover(S32 x, S32 y, MASK mask)
1207{ 1219{
1208 BOOL handled = FALSE; 1220 BOOL handled = FALSE;
@@ -1323,6 +1335,9 @@ BOOL LLTextEditor::handleMouseUp(S32 x, S32 y, MASK mask)
1323 1335
1324 setCursorAtLocalPos( x, y, TRUE ); 1336 setCursorAtLocalPos( x, y, TRUE );
1325 endSelection(); 1337 endSelection();
1338
1339 // take selection to primary clipboard
1340 updatePrimary();
1326 } 1341 }
1327 1342
1328 if( !hasSelection() ) 1343 if( !hasSelection() )
@@ -1330,6 +1345,9 @@ BOOL LLTextEditor::handleMouseUp(S32 x, S32 y, MASK mask)
1330 handleMouseUpOverSegment( x, y, mask ); 1345 handleMouseUpOverSegment( x, y, mask );
1331 } 1346 }
1332 1347
1348 // take selection to 'primary' clipboard
1349 updatePrimary();
1350
1333 handled = TRUE; 1351 handled = TRUE;
1334 } 1352 }
1335 1353
@@ -1392,8 +1410,12 @@ BOOL LLTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask)
1392 // delay cursor flashing 1410 // delay cursor flashing
1393 resetKeystrokeTimer(); 1411 resetKeystrokeTimer();
1394 1412
1413 // take selection to 'primary' clipboard
1414 updatePrimary();
1415
1395 handled = TRUE; 1416 handled = TRUE;
1396 } 1417 }
1418
1397 return handled; 1419 return handled;
1398} 1420}
1399 1421
@@ -1689,6 +1711,12 @@ BOOL LLTextEditor::handleSelectionKey(const KEY key, const MASK mask)
1689 } 1711 }
1690 } 1712 }
1691 1713
1714 if( handled )
1715 {
1716 // take selection to 'primary' clipboard
1717 updatePrimary();
1718 }
1719
1692 return handled; 1720 return handled;
1693} 1721}
1694 1722
@@ -1868,22 +1896,46 @@ BOOL LLTextEditor::canPaste() const
1868 return !mReadOnly && gClipboard.canPasteString(); 1896 return !mReadOnly && gClipboard.canPasteString();
1869} 1897}
1870 1898
1871
1872// paste from clipboard 1899// paste from clipboard
1873void LLTextEditor::paste() 1900void LLTextEditor::paste()
1874{ 1901{
1875 if (!canPaste()) 1902 bool is_primary = false;
1903 pasteHelper(is_primary);
1904}
1905
1906// paste from primary
1907void LLTextEditor::pastePrimary()
1908{
1909 bool is_primary = true;
1910 pasteHelper(is_primary);
1911}
1912
1913// paste from primary (itsprimary==true) or clipboard (itsprimary==false)
1914void LLTextEditor::pasteHelper(bool is_primary)
1915{
1916 bool can_paste_it;
1917 if (is_primary)
1918 can_paste_it = canPastePrimary();
1919 else
1920 can_paste_it = canPaste();
1921
1922 if (!can_paste_it)
1876 { 1923 {
1877 return; 1924 return;
1878 } 1925 }
1879 LLUUID source_id; 1926 LLUUID source_id;
1880 LLWString paste = gClipboard.getPasteWString(&source_id); 1927 LLWString paste;
1928 if (is_primary)
1929 paste = gClipboard.getPastePrimaryWString(&source_id);
1930 else
1931 paste = gClipboard.getPasteWString(&source_id);
1932
1881 if (paste.empty()) 1933 if (paste.empty())
1882 { 1934 {
1883 return; 1935 return;
1884 } 1936 }
1885 // Delete any selected characters (the paste replaces them) 1937 // Delete any selected characters (the paste replaces them)
1886 if( hasSelection() ) 1938 if( (!is_primary) && hasSelection() )
1887 { 1939 {
1888 deleteSelection(TRUE); 1940 deleteSelection(TRUE);
1889 } 1941 }
@@ -1917,6 +1969,32 @@ void LLTextEditor::paste()
1917} 1969}
1918 1970
1919 1971
1972
1973// copy selection to primary
1974void LLTextEditor::copyPrimary()
1975{
1976 if( !canCopy() )
1977 {
1978 return;
1979 }
1980 S32 left_pos = llmin( mSelectionStart, mSelectionEnd );
1981 S32 length = abs( mSelectionStart - mSelectionEnd );
1982 gClipboard.copyFromPrimarySubstring(mWText, left_pos, length, mSourceID);
1983}
1984
1985BOOL LLTextEditor::canPastePrimary() const
1986{
1987 return !mReadOnly && gClipboard.canPastePrimaryString();
1988}
1989
1990void LLTextEditor::updatePrimary()
1991{
1992 if (canCopy())
1993 {
1994 copyPrimary();
1995 }
1996}
1997
1920BOOL LLTextEditor::handleControlKey(const KEY key, const MASK mask) 1998BOOL LLTextEditor::handleControlKey(const KEY key, const MASK mask)
1921{ 1999{
1922 BOOL handled = FALSE; 2000 BOOL handled = FALSE;
@@ -1992,6 +2070,11 @@ BOOL LLTextEditor::handleControlKey(const KEY key, const MASK mask)
1992 } 2070 }
1993 } 2071 }
1994 2072
2073 if (handled)
2074 {
2075 updatePrimary();
2076 }
2077
1995 return handled; 2078 return handled;
1996} 2079}
1997 2080
@@ -3522,13 +3605,13 @@ void LLTextEditor::appendColoredText(const std::string &new_text,
3522 style->setVisible(true); 3605 style->setVisible(true);
3523 style->setColor(color); 3606 style->setColor(color);
3524 style->setFontName(font_name); 3607 style->setFontName(font_name);
3525 appendStyledText(new_text, allow_undo, prepend_newline, &style); 3608 appendStyledText(new_text, allow_undo, prepend_newline, style);
3526} 3609}
3527 3610
3528void LLTextEditor::appendStyledText(const std::string &new_text, 3611void LLTextEditor::appendStyledText(const std::string &new_text,
3529 bool allow_undo, 3612 bool allow_undo,
3530 bool prepend_newline, 3613 bool prepend_newline,
3531 const LLStyleSP *stylep) 3614 const LLStyleSP stylep)
3532{ 3615{
3533 if(mParseHTML) 3616 if(mParseHTML)
3534 { 3617 {
@@ -3543,14 +3626,14 @@ void LLTextEditor::appendStyledText(const std::string &new_text,
3543 html->setColor(mLinkColor); 3626 html->setColor(mLinkColor);
3544 if (stylep) 3627 if (stylep)
3545 { 3628 {
3546 html->setFontName((*stylep)->getFontString()); 3629 html->setFontName(stylep->getFontString());
3547 } 3630 }
3548 html->mUnderline = TRUE; 3631 html->mUnderline = TRUE;
3549 3632
3550 if (start > 0) appendText(text.substr(0,start),allow_undo, prepend_newline, stylep); 3633 if (start > 0) appendText(text.substr(0,start),allow_undo, prepend_newline, stylep);
3551 html->setLinkHREF(text.substr(start,end-start)); 3634 html->setLinkHREF(text.substr(start,end-start));
3552 appendText(text.substr(start, end-start),allow_undo, prepend_newline, &html); 3635 appendText(text.substr(start, end-start),allow_undo, prepend_newline, html);
3553 if (end < (S32)text.length()) 3636 if (end < (S32)text.length())
3554 { 3637 {
3555 text = text.substr(end,text.length() - end); 3638 text = text.substr(end,text.length() - end);
3556 end=0; 3639 end=0;
@@ -3570,7 +3653,7 @@ void LLTextEditor::appendStyledText(const std::string &new_text,
3570 3653
3571// Appends new text to end of document 3654// Appends new text to end of document
3572void LLTextEditor::appendText(const std::string &new_text, bool allow_undo, bool prepend_newline, 3655void LLTextEditor::appendText(const std::string &new_text, bool allow_undo, bool prepend_newline,
3573 const LLStyleSP *stylep) 3656 const LLStyleSP stylep)
3574{ 3657{
3575 // Save old state 3658 // Save old state
3576 BOOL was_scrolled_to_bottom = (mScrollbar->getDocPos() == mScrollbar->getDocPosMax()); 3659 BOOL was_scrolled_to_bottom = (mScrollbar->getDocPos() == mScrollbar->getDocPosMax());
@@ -3602,7 +3685,7 @@ void LLTextEditor::appendText(const std::string &new_text, bool allow_undo, bool
3602 { 3685 {
3603 S32 segment_start = old_length; 3686 S32 segment_start = old_length;
3604 S32 segment_end = getLength(); 3687 S32 segment_end = getLength();
3605 LLTextSegment* segment = new LLTextSegment(*stylep, segment_start, segment_end ); 3688 LLTextSegment* segment = new LLTextSegment(stylep, segment_start, segment_end );
3606 mSegments.push_back(segment); 3689 mSegments.push_back(segment);
3607 } 3690 }
3608 3691
diff --git a/linden/indra/llui/lltexteditor.h b/linden/indra/llui/lltexteditor.h
index 643b7c3..7e93de1 100644
--- a/linden/indra/llui/lltexteditor.h
+++ b/linden/indra/llui/lltexteditor.h
@@ -82,6 +82,8 @@ public:
82 virtual BOOL handleHover(S32 x, S32 y, MASK mask); 82 virtual BOOL handleHover(S32 x, S32 y, MASK mask);
83 virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); 83 virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
84 virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask ); 84 virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask );
85 virtual BOOL handleMiddleMouseDown(S32 x,S32 y,MASK mask);
86
85 virtual BOOL handleKeyHere(KEY key, MASK mask ); 87 virtual BOOL handleKeyHere(KEY key, MASK mask );
86 virtual BOOL handleUnicodeCharHere(llwchar uni_char); 88 virtual BOOL handleUnicodeCharHere(llwchar uni_char);
87 89
@@ -117,6 +119,10 @@ public:
117 virtual BOOL canCopy() const; 119 virtual BOOL canCopy() const;
118 virtual void paste(); 120 virtual void paste();
119 virtual BOOL canPaste() const; 121 virtual BOOL canPaste() const;
122 virtual void updatePrimary();
123 virtual void copyPrimary();
124 virtual void pastePrimary();
125 virtual BOOL canPastePrimary() const;
120 virtual void doDelete(); 126 virtual void doDelete();
121 virtual BOOL canDoDelete() const; 127 virtual BOOL canDoDelete() const;
122 virtual void selectAll(); 128 virtual void selectAll();
@@ -140,16 +146,16 @@ public:
140 void insertText(const std::string &text); 146 void insertText(const std::string &text);
141 // appends text at end 147 // appends text at end
142 void appendText(const std::string &wtext, bool allow_undo, bool prepend_newline, 148 void appendText(const std::string &wtext, bool allow_undo, bool prepend_newline,
143 const LLStyleSP *stylep = NULL); 149 const LLStyleSP stylep = NULL);
144 150
145 void appendColoredText(const std::string &wtext, bool allow_undo, 151 void appendColoredText(const std::string &wtext, bool allow_undo,
146 bool prepend_newline, 152 bool prepend_newline,
147 const LLColor4 &color, 153 const LLColor4 &color,
148 const std::string& font_name = LLStringUtil::null); 154 const std::string& font_name = LLStringUtil::null);
149 // if styled text starts a line, you need to prepend a newline. 155 // if styled text starts a line, you need to prepend a newline.
150 void appendStyledText(const std::string &new_text, bool allow_undo, 156 void appendStyledText(const std::string &new_text, bool allow_undo,
151 bool prepend_newline, 157 bool prepend_newline,
152 const LLStyleSP *stylep = NULL); 158 const LLStyleSP stylep = NULL);
153 159
154 // Removes text from the end of document 160 // Removes text from the end of document
155 // Does not change highlight or cursor position. 161 // Does not change highlight or cursor position.
@@ -425,6 +431,8 @@ private:
425 // 431 //
426 // Methods 432 // Methods
427 // 433 //
434 void pasteHelper(bool is_primary);
435
428 void updateSegments(); 436 void updateSegments();
429 void pruneSegments(); 437 void pruneSegments();
430 438
diff --git a/linden/indra/llui/llview.cpp b/linden/indra/llui/llview.cpp
index 9cdf481..e3652b7 100644
--- a/linden/indra/llui/llview.cpp
+++ b/linden/indra/llui/llview.cpp
@@ -85,7 +85,8 @@ LLView::LLView() :
85 mLastVisible(TRUE), 85 mLastVisible(TRUE),
86 mUseBoundingRect(FALSE), 86 mUseBoundingRect(FALSE),
87 mVisible(TRUE), 87 mVisible(TRUE),
88 mNextInsertionOrdinal(0) 88 mNextInsertionOrdinal(0),
89 mHoverCursor(UI_CURSOR_ARROW)
89{ 90{
90} 91}
91 92
@@ -102,7 +103,8 @@ LLView::LLView(const std::string& name, BOOL mouse_opaque) :
102 mLastVisible(TRUE), 103 mLastVisible(TRUE),
103 mUseBoundingRect(FALSE), 104 mUseBoundingRect(FALSE),
104 mVisible(TRUE), 105 mVisible(TRUE),
105 mNextInsertionOrdinal(0) 106 mNextInsertionOrdinal(0),
107 mHoverCursor(UI_CURSOR_ARROW)
106{ 108{
107} 109}
108 110
@@ -123,7 +125,8 @@ LLView::LLView(
123 mLastVisible(TRUE), 125 mLastVisible(TRUE),
124 mUseBoundingRect(FALSE), 126 mUseBoundingRect(FALSE),
125 mVisible(TRUE), 127 mVisible(TRUE),
126 mNextInsertionOrdinal(0) 128 mNextInsertionOrdinal(0),
129 mHoverCursor(UI_CURSOR_ARROW)
127{ 130{
128} 131}
129 132
@@ -657,7 +660,7 @@ BOOL LLView::handleHover(S32 x, S32 y, MASK mask)
657 if( !handled 660 if( !handled
658 && blockMouseEvent(x, y) ) 661 && blockMouseEvent(x, y) )
659 { 662 {
660 LLUI::sWindow->setCursor(UI_CURSOR_ARROW); 663 LLUI::sWindow->setCursor(mHoverCursor);
661 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl; 664 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl;
662 handled = TRUE; 665 handled = TRUE;
663 } 666 }
@@ -981,6 +984,30 @@ BOOL LLView::handleRightMouseUp(S32 x, S32 y, MASK mask)
981 } 984 }
982 return handled; 985 return handled;
983} 986}
987
988BOOL LLView::handleMiddleMouseDown(S32 x, S32 y, MASK mask)
989{
990 LLView* handled_view = childrenHandleMiddleMouseDown( x, y, mask );
991 BOOL handled = (handled_view != NULL);
992 if( !handled && blockMouseEvent(x, y) )
993 {
994 handled = TRUE;
995 handled_view = this;
996 }
997
998 return handled;
999}
1000
1001BOOL LLView::handleMiddleMouseUp(S32 x, S32 y, MASK mask)
1002{
1003 BOOL handled = childrenHandleMiddleMouseUp( x, y, mask ) != NULL;
1004 if( !handled && blockMouseEvent(x, y) )
1005 {
1006 handled = TRUE;
1007 }
1008 return handled;
1009}
1010
984 1011
985LLView* LLView::childrenHandleScrollWheel(S32 x, S32 y, S32 clicks) 1012LLView* LLView::childrenHandleScrollWheel(S32 x, S32 y, S32 clicks)
986{ 1013{
@@ -1142,6 +1169,34 @@ LLView* LLView::childrenHandleRightMouseDown(S32 x, S32 y, MASK mask)
1142 return handled_view; 1169 return handled_view;
1143} 1170}
1144 1171
1172LLView* LLView::childrenHandleMiddleMouseDown(S32 x, S32 y, MASK mask)
1173{
1174 LLView* handled_view = NULL;
1175
1176 if (getVisible() && getEnabled() )
1177 {
1178 for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it)
1179 {
1180 LLView* viewp = *child_it;
1181 S32 local_x = x - viewp->getRect().mLeft;
1182 S32 local_y = y - viewp->getRect().mBottom;
1183 if (viewp->pointInView(local_x, local_y) &&
1184 viewp->getVisible() &&
1185 viewp->getEnabled() &&
1186 viewp->handleMiddleMouseDown( local_x, local_y, mask ))
1187 {
1188 if (sDebugMouseHandling)
1189 {
1190 sMouseHandlerMessage = std::string("->") + viewp->mName + sMouseHandlerMessage;
1191 }
1192 handled_view = viewp;
1193 break;
1194 }
1195 }
1196 }
1197 return handled_view;
1198}
1199
1145LLView* LLView::childrenHandleDoubleClick(S32 x, S32 y, MASK mask) 1200LLView* LLView::childrenHandleDoubleClick(S32 x, S32 y, MASK mask)
1146{ 1201{
1147 LLView* handled_view = NULL; 1202 LLView* handled_view = NULL;
@@ -1227,6 +1282,32 @@ LLView* LLView::childrenHandleRightMouseUp(S32 x, S32 y, MASK mask)
1227 return handled_view; 1282 return handled_view;
1228} 1283}
1229 1284
1285LLView* LLView::childrenHandleMiddleMouseUp(S32 x, S32 y, MASK mask)
1286{
1287 LLView* handled_view = NULL;
1288 if( getVisible() && getEnabled() )
1289 {
1290 for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it)
1291 {
1292 LLView* viewp = *child_it;
1293 S32 local_x = x - viewp->getRect().mLeft;
1294 S32 local_y = y - viewp->getRect().mBottom;
1295 if (viewp->pointInView(local_x, local_y) &&
1296 viewp->getVisible() &&
1297 viewp->getEnabled() &&
1298 viewp->handleMiddleMouseUp( local_x, local_y, mask ))
1299 {
1300 if (sDebugMouseHandling)
1301 {
1302 sMouseHandlerMessage = std::string("->") + viewp->mName + sMouseHandlerMessage;
1303 }
1304 handled_view = viewp;
1305 break;
1306 }
1307 }
1308 }
1309 return handled_view;
1310}
1230 1311
1231void LLView::draw() 1312void LLView::draw()
1232{ 1313{
@@ -2544,7 +2625,14 @@ void LLView::initFromXML(LLXMLNodePtr node, LLView* parent)
2544 node->getAttributeBOOL("visible", visible); 2625 node->getAttributeBOOL("visible", visible);
2545 setVisible(visible); 2626 setVisible(visible);
2546 } 2627 }
2547 2628
2629 if (node->hasAttribute("hover_cursor"))
2630 {
2631 std::string cursor_string;
2632 node->getAttributeString("hover_cursor", cursor_string);
2633 mHoverCursor = getCursorFromString(cursor_string);
2634 }
2635
2548 node->getAttributeBOOL("use_bounding_rect", mUseBoundingRect); 2636 node->getAttributeBOOL("use_bounding_rect", mUseBoundingRect);
2549 node->getAttributeBOOL("mouse_opaque", mMouseOpaque); 2637 node->getAttributeBOOL("mouse_opaque", mMouseOpaque);
2550 2638
diff --git a/linden/indra/llui/llview.h b/linden/indra/llui/llview.h
index 80dd348..df34a3e 100644
--- a/linden/indra/llui/llview.h
+++ b/linden/indra/llui/llview.h
@@ -51,6 +51,7 @@
51#include "llxmlnode.h" 51#include "llxmlnode.h"
52#include "stdenums.h" 52#include "stdenums.h"
53#include "lluistring.h" 53#include "lluistring.h"
54#include "llcursortypes.h"
54 55
55const U32 FOLLOWS_NONE = 0x00; 56const U32 FOLLOWS_NONE = 0x00;
56const U32 FOLLOWS_LEFT = 0x01; 57const U32 FOLLOWS_LEFT = 0x01;
@@ -463,6 +464,8 @@ public:
463 /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); 464 /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
464 /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); 465 /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
465 /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); 466 /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
467 /*virtual*/ BOOL handleMiddleMouseUp(S32 x, S32 y, MASK mask);
468 /*virtual*/ BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask);
466 /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); 469 /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
467 /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); 470 /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
468 /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); 471 /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
@@ -596,6 +599,8 @@ protected:
596 LLView* childrenHandleHover(S32 x, S32 y, MASK mask); 599 LLView* childrenHandleHover(S32 x, S32 y, MASK mask);
597 LLView* childrenHandleMouseUp(S32 x, S32 y, MASK mask); 600 LLView* childrenHandleMouseUp(S32 x, S32 y, MASK mask);
598 LLView* childrenHandleMouseDown(S32 x, S32 y, MASK mask); 601 LLView* childrenHandleMouseDown(S32 x, S32 y, MASK mask);
602 LLView* childrenHandleMiddleMouseUp(S32 x, S32 y, MASK mask);
603 LLView* childrenHandleMiddleMouseDown(S32 x, S32 y, MASK mask);
599 LLView* childrenHandleDoubleClick(S32 x, S32 y, MASK mask); 604 LLView* childrenHandleDoubleClick(S32 x, S32 y, MASK mask);
600 LLView* childrenHandleScrollWheel(S32 x, S32 y, S32 clicks); 605 LLView* childrenHandleScrollWheel(S32 x, S32 y, S32 clicks);
601 LLView* childrenHandleRightMouseDown(S32 x, S32 y, MASK mask); 606 LLView* childrenHandleRightMouseDown(S32 x, S32 y, MASK mask);
@@ -649,7 +654,9 @@ private:
649 mutable dummy_widget_map_t mDummyWidgets; 654 mutable dummy_widget_map_t mDummyWidgets;
650 655
651 boost::signals::connection mControlConnection; 656 boost::signals::connection mControlConnection;
652 657
658 ECursorType mHoverCursor;
659
653public: 660public:
654 static BOOL sDebugRects; // Draw debug rects behind everything. 661 static BOOL sDebugRects; // Draw debug rects behind everything.
655 static BOOL sDebugKeys; 662 static BOOL sDebugKeys;