00001
00032
00033
00034 #ifndef LL_LLTEXTEDITOR_H
00035 #define LL_LLTEXTEDITOR_H
00036
00037 #include "llrect.h"
00038 #include "llkeywords.h"
00039 #include "lluictrl.h"
00040 #include "llframetimer.h"
00041 #include "lldarray.h"
00042 #include "llstyle.h"
00043 #include "lleditmenuhandler.h"
00044 #include "lldarray.h"
00045
00046 class LLFontGL;
00047 class LLScrollbar;
00048 class LLViewBorder;
00049 class LLKeywordToken;
00050 class LLTextCmd;
00051 class LLUICtrlFactory;
00052
00053
00054
00055
00056
00057 const llwchar FIRST_EMBEDDED_CHAR = 0x100000;
00058 const llwchar LAST_EMBEDDED_CHAR = 0x10ffff;
00059 const S32 MAX_EMBEDDED_ITEMS = LAST_EMBEDDED_CHAR - FIRST_EMBEDDED_CHAR + 1;
00060
00061
00062
00063
00064 class LLTextSegment;
00065 class LLTextCmd;
00066
00067 class LLTextEditor : public LLUICtrl, LLEditMenuHandler
00068 {
00069 friend class LLTextCmd;
00070 public:
00071 LLTextEditor(const LLString& name,
00072 const LLRect& rect,
00073 S32 max_length,
00074 const LLString &default_text,
00075 const LLFontGL* glfont = NULL,
00076 BOOL allow_embedded_items = FALSE);
00077
00078 virtual ~LLTextEditor();
00079
00080 virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_TEXT_EDITOR; }
00081 virtual LLString getWidgetTag() const;
00082
00083 virtual LLXMLNodePtr getXML(bool save_children = true) const;
00084 static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
00085 void setTextEditorParameters(LLXMLNodePtr node);
00086 void setParseHTML(BOOL parsing) {mParseHTML=parsing;}
00087
00088
00089 virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
00090 virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
00091 virtual BOOL handleHover(S32 x, S32 y, MASK mask);
00092 virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
00093 virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask );
00094 virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent );
00095 virtual BOOL handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent);
00096
00097 virtual BOOL handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect);
00098 virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
00099 EDragAndDropType cargo_type, void *cargo_data,
00100 EAcceptance *accept, LLString& tooltip_msg);
00101 virtual void onMouseCaptureLost();
00102
00103
00104
00105 virtual void reshape(S32 width, S32 height, BOOL called_from_parent);
00106 virtual void draw();
00107 virtual void onFocusLost();
00108 virtual void setEnabled(BOOL enabled);
00109
00110
00111 virtual void onTabInto();
00112 virtual void clear();
00113 virtual void setFocus( BOOL b );
00114 virtual BOOL acceptsTextInput() const;
00115 virtual BOOL isDirty() const;
00116
00117
00118 virtual void undo();
00119 virtual BOOL canUndo();
00120
00121 virtual void redo();
00122 virtual BOOL canRedo();
00123
00124 virtual void cut();
00125 virtual BOOL canCut();
00126
00127 virtual void copy();
00128 virtual BOOL canCopy();
00129
00130 virtual void paste();
00131 virtual BOOL canPaste();
00132
00133 virtual void doDelete();
00134 virtual BOOL canDoDelete();
00135
00136 virtual void selectAll();
00137 virtual BOOL canSelectAll();
00138
00139 virtual void deselect();
00140 virtual BOOL canDeselect();
00141
00142 void selectNext(const LLString& search_text_in, BOOL case_insensitive, BOOL wrap = TRUE);
00143 BOOL replaceText(const LLString& search_text, const LLString& replace_text, BOOL case_insensitive, BOOL wrap = TRUE);
00144 void replaceTextAll(const LLString& search_text, const LLString& replace_text, BOOL case_insensitive);
00145
00146
00147 void blockUndo();
00148
00149
00150 virtual void makePristine();
00151 BOOL isPristine() const;
00152
00153
00154 void insertText(const LLString &text);
00155
00156 void appendText(const LLString &wtext, bool allow_undo, bool prepend_newline,
00157 const LLStyle* segment_style = NULL);
00158
00159 void appendColoredText(const LLString &wtext, bool allow_undo,
00160 bool prepend_newline,
00161 const LLColor4 &color,
00162 const LLString& font_name = LLString::null);
00163
00164 void appendStyledText(const LLString &new_text, bool allow_undo,
00165 bool prepend_newline,
00166 const LLStyle* style);
00167
00168
00169
00170 void removeTextFromEnd(S32 num_chars);
00171
00172 BOOL tryToRevertToPristineState();
00173
00174 void setCursor(S32 row, S32 column);
00175 void setCursorPos(S32 offset);
00176 void setCursorAndScrollToEnd();
00177
00178 void getCurrentLineAndColumn( S32* line, S32* col, BOOL include_wordwrap );
00179
00180 void loadKeywords(const LLString& filename,
00181 const LLDynamicArray<const char*>& funcs,
00182 const LLDynamicArray<const char*>& tooltips,
00183 const LLColor3& func_color);
00184
00185 void setCursorColor(const LLColor4& c) { mCursorColor = c; }
00186 void setFgColor( const LLColor4& c ) { mFgColor = c; }
00187 void setReadOnlyFgColor( const LLColor4& c ) { mReadOnlyFgColor = c; }
00188 void setWriteableBgColor( const LLColor4& c ) { mWriteableBgColor = c; }
00189 void setReadOnlyBgColor( const LLColor4& c ) { mReadOnlyBgColor = c; }
00190
00191 void setTrackColor( const LLColor4& color );
00192 void setThumbColor( const LLColor4& color );
00193 void setHighlightColor( const LLColor4& color );
00194 void setShadowColor( const LLColor4& color );
00195
00196
00197
00198 void setBorderVisible(BOOL b);
00199 void setTakesNonScrollClicks(BOOL b);
00200 void setHideScrollbarForShortDocs(BOOL b);
00201
00202 void setWordWrap( BOOL b );
00203 void setTabToNextField(BOOL b) { mTabToNextField = b; }
00204 void setCommitOnFocusLost(BOOL b) { mCommitOnFocusLost = b; }
00205
00206
00207 void setTakesFocus(BOOL b) { mTakesFocus = b; }
00208
00209
00210 virtual BOOL importBuffer(const LLString& buffer );
00211 virtual BOOL exportBuffer(LLString& buffer );
00212
00213 void setSourceID(const LLUUID& id) { mSourceID = id; }
00214 void setAcceptCallingCardNames(BOOL enable) { mAcceptCallingCardNames = enable; }
00215
00216 void setHandleEditKeysDirectly( BOOL b ) { mHandleEditKeysDirectly = b; }
00217
00218
00219 static void setLinkColor(LLColor4 color) { mLinkColor = color; }
00220 static void setURLCallbacks(void (*callback1) (const char* url),
00221 bool (*callback2) (const std::string& url),
00222 bool (*callback3) (const std::string& url) )
00223 { mURLcallback = callback1; mSecondlifeURLcallback = callback2; mSecondlifeURLcallbackRightClick = callback3;}
00224
00225 void setOnScrollEndCallback(void (*callback)(void*), void* userdata);
00226
00227
00228 void setValue(const LLSD& value);
00229 LLSD getValue() const;
00230
00231 const LLString& getText() const;
00232
00233
00234 void setText(const LLStringExplicit &utf8str);
00235 void setWText(const LLWString &wtext);
00236
00237 S32 getMaxLength() const { return mMaxTextLength; }
00238
00239
00240 void startOfLine();
00241 void endOfLine();
00242 void endOfDoc();
00243
00244
00245 const LLWString& getWText() const;
00246 llwchar getWChar(S32 pos);
00247 LLWString getWSubString(S32 pos, S32 len);
00248
00249 LLTextSegment* getCurrentSegment();
00250 LLTextSegment* getPreviousSegment();
00251 void getSelectedSegments(std::vector<LLTextSegment*>& segments);
00252
00253 protected:
00254 S32 getLength() const;
00255 void getSegmentAndOffset( S32 startpos, S32* segidxp, S32* offsetp );
00256
00257 void drawBackground();
00258 void drawSelectionBackground();
00259 void drawCursor();
00260 void drawText();
00261 void drawClippedSegment(const LLWString &wtext, S32 seg_start, S32 seg_end, F32 x, F32 y, S32 selection_left, S32 selection_right, const LLStyle& color, F32* right_x);
00262
00263 void updateLineStartList(S32 startpos = 0);
00264 void updateScrollFromCursor();
00265 void updateTextRect();
00266 void updateSegments();
00267 void pruneSegments();
00268
00269 void assignEmbedded(const LLString &s);
00270 void truncate();
00271
00272 static BOOL isPartOfWord(llwchar c);
00273
00274 void removeCharOrTab();
00275 void setCursorAtLocalPos(S32 x, S32 y, BOOL round);
00276 S32 getCursorPosFromLocalCoord( S32 local_x, S32 local_y, BOOL round );
00277
00278 void indentSelectedLines( S32 spaces );
00279 S32 indentLine( S32 pos, S32 spaces );
00280 void unindentLineBeforeCloseBrace();
00281
00282 S32 getSegmentIdxAtOffset(S32 offset);
00283 LLTextSegment* getSegmentAtLocalPos(S32 x, S32 y);
00284 LLTextSegment* getSegmentAtOffset(S32 offset);
00285
00286 void reportBadKeystroke();
00287
00288 BOOL handleNavigationKey(const KEY key, const MASK mask);
00289 BOOL handleSpecialKey(const KEY key, const MASK mask, BOOL* return_key_hit);
00290 BOOL handleSelectionKey(const KEY key, const MASK mask);
00291 BOOL handleControlKey(const KEY key, const MASK mask);
00292 BOOL handleEditKey(const KEY key, const MASK mask);
00293
00294 BOOL hasSelection() { return (mSelectionStart !=mSelectionEnd); }
00295 BOOL selectionContainsLineBreaks();
00296 void startSelection();
00297 void endSelection();
00298 void deleteSelection(BOOL transient_operation);
00299
00300 S32 prevWordPos(S32 cursorPos) const;
00301 S32 nextWordPos(S32 cursorPos) const;
00302
00303 S32 getLineCount();
00304 S32 getLineStart( S32 line );
00305 void getLineAndOffset(S32 pos, S32* linep, S32* offsetp);
00306 S32 getPos(S32 line, S32 offset);
00307
00308 void changePage(S32 delta);
00309 void changeLine(S32 delta);
00310
00311 void autoIndent();
00312
00313 S32 execute(LLTextCmd* cmd);
00314
00315 void findEmbeddedItemSegments();
00316
00317 virtual BOOL handleMouseUpOverSegment(S32 x, S32 y, MASK mask);
00318 virtual llwchar pasteEmbeddedItem(llwchar ext_char);
00319 virtual void bindEmbeddedChars(const LLFontGL* font);
00320 virtual void unbindEmbeddedChars(const LLFontGL* font);
00321
00322 S32 findHTMLToken(const LLString &line, S32 pos, BOOL reverse);
00323 BOOL findHTML(const LLString &line, S32 *begin, S32 *end);
00324
00325 protected:
00326
00327 void addChar(llwchar c);
00328 S32 addChar(S32 pos, llwchar wc);
00329 S32 overwriteChar(S32 pos, llwchar wc);
00330 void removeChar();
00331 S32 removeChar(S32 pos);
00332 S32 insert(const S32 pos, const LLWString &wstr, const BOOL group_with_next_op);
00333 S32 remove(const S32 pos, const S32 length, const BOOL group_with_next_op);
00334 S32 append(const LLWString &wstr, const BOOL group_with_next_op);
00335
00336
00337 S32 insertStringNoUndo(S32 pos, const LLWString &wstr);
00338 S32 removeStringNoUndo(S32 pos, S32 length);
00339 S32 overwriteCharNoUndo(S32 pos, llwchar wc);
00340
00341 public:
00342 LLKeywords mKeywords;
00343 static LLColor4 mLinkColor;
00344 static void (*mURLcallback) (const char* url);
00345 static bool (*mSecondlifeURLcallback) (const std::string& url);
00346 static bool (*mSecondlifeURLcallbackRightClick) (const std::string& url);
00347 protected:
00348 LLWString mWText;
00349 mutable LLString mUTF8Text;
00350 mutable BOOL mTextIsUpToDate;
00351
00352 S32 mMaxTextLength;
00353
00354 const LLFontGL* mGLFont;
00355
00356 LLScrollbar* mScrollbar;
00357 LLViewBorder* mBorder;
00358
00359 BOOL mBaseDocIsPristine;
00360 LLTextCmd* mPristineCmd;
00361
00362 LLTextCmd* mLastCmd;
00363
00364 typedef std::deque<LLTextCmd*> undo_stack_t;
00365 undo_stack_t mUndoStack;
00366
00367 S32 mCursorPos;
00368 S32 mDesiredXPixel;
00369 LLRect mTextRect;
00370
00371 struct line_info
00372 {
00373 line_info(S32 segment, S32 offset) : mSegment(segment), mOffset(offset) {}
00374 S32 mSegment;
00375 S32 mOffset;
00376 };
00377 struct line_info_compare
00378 {
00379 bool operator()(const line_info& a, const line_info& b) const
00380 {
00381 if (a.mSegment < b.mSegment)
00382 return true;
00383 else if (a.mSegment > b.mSegment)
00384 return false;
00385 else
00386 return a.mOffset < b.mOffset;
00387 }
00388 };
00389 typedef std::vector<line_info> line_list_t;
00390 line_list_t mLineStartList;
00391
00392
00393
00394 BOOL mIsSelecting;
00395
00396 S32 mSelectionStart;
00397 S32 mSelectionEnd;
00398
00399 void (*mOnScrollEndCallback)(void*);
00400 void *mOnScrollEndData;
00401
00402 typedef std::vector<LLTextSegment *> segment_list_t;
00403 segment_list_t mSegments;
00404 LLTextSegment* mHoverSegment;
00405 LLFrameTimer mKeystrokeTimer;
00406
00407 LLColor4 mCursorColor;
00408
00409 LLColor4 mFgColor;
00410 LLColor4 mReadOnlyFgColor;
00411 LLColor4 mWriteableBgColor;
00412 LLColor4 mReadOnlyBgColor;
00413 LLColor4 mFocusBgColor;
00414
00415 BOOL mReadOnly;
00416 BOOL mWordWrap;
00417
00418 BOOL mTabToNextField;
00419 BOOL mCommitOnFocusLost;
00420 BOOL mTakesFocus;
00421 BOOL mHideScrollbarForShortDocs;
00422 BOOL mTakesNonScrollClicks;
00423
00424 BOOL mAllowEmbeddedItems;
00425
00426 BOOL mAcceptCallingCardNames;
00427
00428 LLUUID mSourceID;
00429
00430 BOOL mHandleEditKeysDirectly;
00431
00432
00433
00434 S32 mMouseDownX;
00435 S32 mMouseDownY;
00436
00437 S32 mLastSelectionX;
00438 S32 mLastSelectionY;
00439
00440 BOOL mParseHTML;
00441 LLString mHTML;
00442
00443 LLCoordGL mLastIMEPosition;
00444 };
00445
00446 class LLTextSegment
00447 {
00448 public:
00449
00450 LLTextSegment(S32 start);
00451 LLTextSegment( const LLStyle& style, S32 start, S32 end );
00452 LLTextSegment( const LLColor4& color, S32 start, S32 end, BOOL is_visible);
00453 LLTextSegment( const LLColor4& color, S32 start, S32 end );
00454 LLTextSegment( const LLColor3& color, S32 start, S32 end );
00455
00456 S32 getStart() { return mStart; }
00457 S32 getEnd() { return mEnd; }
00458 void setEnd( S32 end ) { mEnd = end; }
00459 const LLColor4& getColor() { return mStyle.getColor(); }
00460 void setColor(const LLColor4 &color) { mStyle.setColor(color); }
00461 const LLStyle& getStyle() { return mStyle; }
00462 void setStyle(const LLStyle &style) { mStyle = style; }
00463 void setIsDefault(BOOL b) { mIsDefault = b; }
00464 BOOL getIsDefault() { return mIsDefault; }
00465
00466 void setToken( LLKeywordToken* token ) { mToken = token; }
00467 LLKeywordToken* getToken() { return mToken; }
00468 BOOL getToolTip( LLString& msg );
00469
00470 void dump();
00471
00472 struct compare
00473 {
00474 bool operator()(const LLTextSegment* a, const LLTextSegment* b) const
00475 {
00476 return a->mStart < b->mStart;
00477 }
00478 };
00479
00480 private:
00481 LLStyle mStyle;
00482 S32 mStart;
00483 S32 mEnd;
00484 LLKeywordToken* mToken;
00485 BOOL mIsDefault;
00486 };
00487
00488 class LLTextCmd
00489 {
00490 public:
00491 LLTextCmd( S32 pos, BOOL group_with_next )
00492 : mPos(pos),
00493 mGroupWithNext(group_with_next)
00494 {
00495 }
00496 virtual ~LLTextCmd() {}
00497 virtual BOOL execute(LLTextEditor* editor, S32* delta) = 0;
00498 virtual S32 undo(LLTextEditor* editor) = 0;
00499 virtual S32 redo(LLTextEditor* editor) = 0;
00500 virtual BOOL canExtend(S32 pos);
00501 virtual void blockExtensions();
00502 virtual BOOL extendAndExecute( LLTextEditor* editor, S32 pos, llwchar c, S32* delta );
00503 virtual BOOL hasExtCharValue( llwchar value );
00504
00505
00506 S32 insert(LLTextEditor* editor, S32 pos, const LLWString &wstr);
00507 S32 remove(LLTextEditor* editor, S32 pos, S32 length);
00508 S32 overwrite(LLTextEditor* editor, S32 pos, llwchar wc);
00509
00510 BOOL groupWithNext() { return mGroupWithNext; }
00511
00512 protected:
00513 S32 mPos;
00514 BOOL mGroupWithNext;
00515 };
00516
00517
00518 #endif // LL_TEXTEDITOR_