1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Contrib. demo
4 // Author: Aleksandras Gluchovas
8 // Copyright: (c) Aleskandars Gluchovas
9 // Licence: GNU General Public License
10 /////////////////////////////////////////////////////////////////////////////
12 // This program is free software; you can redistribute it and/or modify
13 // it under the terms of the GNU General Public License as published by
14 // the Free Software Foundation; either version 2 of the License, or
15 // (at your option) any later version.
17 // This program is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 // GNU General Public License for more details.
22 // You should have received a copy of the GNU General Public License
23 // along with this program; if not, write to the Free Software
24 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 /////////////////////////////////////////////////////////////////////////////
32 // should be compiled with wxSTL-v.1.2 (or higher)
34 #include "wxstldefs.h"
36 #if defined( wxUSE_TEMPLATE_STL )
44 #include "wx/window.h"
45 #include "wx/scrolbar.h"
47 #include "sourcepainter.h"
49 #define NPOS ((size_t)(-1))
51 class wxTextEditorModel
;
52 class wxTextEditorView
;
55 * class represents column-row position in the source text,
56 * may refere to the column past the end-of-line,
57 * but should not point past the last-line in the text
66 inline TPosition() : mRow(0), mCol(0) {}
68 inline TPosition( size_t row
, size_t col
)
70 : mRow( row
), mCol( col
) {}
72 inline bool operator>( const TPosition
& rhs
) const
74 if ( mRow
== rhs
.mRow
) return mCol
> rhs
.mCol
;
76 return mRow
> rhs
.mRow
;
79 inline bool operator<( const TPosition
& rhs
) const
81 if ( mRow
== rhs
.mRow
) return mCol
< rhs
.mCol
;
83 return mRow
< rhs
.mRow
;
94 TRange( const TPosition
& from
, const TPosition
& till
)
95 : mFrom( from
), mTill( till
)
99 inline bool operator==( const TPosition
& lhs
, const TPosition
& rhs
)
101 return lhs
.mRow
== rhs
.mRow
&& lhs
.mCol
== rhs
.mCol
;
104 // FOR NOW:: bigger ones...
106 #define MAX_BLOCK_LEN (1024*164)
107 #define BALANCED_BLOCK_LEN (1024*152)
108 #define FILLED_BLOCK_LEN (1024*148)
111 #define T_ASSERT( x ) if ( !(x) ) throw;
113 // to speed up debug v. :
115 #define is_eol_char( ch ) ( ch == (char)10 )
116 #define is_DOS_eol_char( ch ) ( ch == (char)13 )
118 // the target-platfrom eol-marking is selected when
119 // new text document is created or auto-detection
120 // failed to determine the text-format (e.g. no EOLs found at all)
122 #if defined(__WINDOWS__) || defined(__WXMSW__)
124 #define IS_UNIX_TEXT_BY_DEFAULT FALSE
126 #define IS_UNIX_TEXT_BY_DEFAULT TRUE
129 //inline bool is_eol_char( char ch ) { return ch == 10 && ch == 13 ; }
132 * Class contains single fragment of the source text, which
133 * may grow or shrink in the process of editing. Blocks always
134 * start at the begining of the line and end at eol, i.e. lines
135 * are not broken among blocks
141 char mBuf
[MAX_BLOCK_LEN
];
145 TBlock() : mTextLen(0), mRowCount(0) { mBuf
[0] = '\0'; }
147 void RecalcBlockProperties();
149 bool operator==( const TBlock
& blk
) const { return this == &blk
; }
151 bool operator!=( const TBlock
& blk
) const { return this != &blk
; }
153 bool operator<( const TBlock
& blk
) const { return TRUE
; }
155 bool operator>( const TBlock
& blk
) const { return FALSE
; }
159 * captures info about mutable command
166 TCommand() : mType(-1) {}
167 TCommand( int type
) : mType( type
) {}
176 // positions of cursor before and after executions of this command
182 enum TEXT_EDITOR_COMMAND
188 enum TEXT_CHANGE_TYPE
195 class wxTextEditorView
;
197 // STL-list is used for managing blocks, since it's alg. collects
198 // removed elements into a free-list, from which they
199 // can be reclaimed later, that way heap-fragmentation may be reduced
201 #if defined( wxUSE_TEMPLATE_STL )
202 typedef list
<TBlock
> TBlockListT
;
203 typedef vector
<TCommand
*> TCommandListT
;
204 typedef vector
<wxTextEditorView
*> TextViewListT
;
206 typedef WXSTL_LIST( TBlock
) TBlockListT
;
208 typedef TCommand
* TCommandPtrT
;
209 typedef WXSTL_VECTOR_SHALLOW_COPY( TCommandPtrT
) TCommandListT
;
211 typedef wxTextEditorView
* TextViewPtrT
;
212 typedef WXSTL_VECTOR_SHALLOW_COPY( TextViewPtrT
) TextViewListT
;
215 typedef TBlockListT::iterator TBlockIteratorT
;
219 * class shields the higher-level operations from direct access
220 * to blocks of fragmented in-memory buffers
226 TBlockIteratorT mBlockIter
;
227 TBlockIteratorT mEndOfListIter
;
231 size_t mFirstRowInBlock
;
243 int GetDistFromEol();
250 void ToStartOfLine();
252 bool IsInLastBlock();
257 TPosition
GetPosition();
259 char* GetClosestPos();
260 char* GotoClosestPos();
262 inline char* GetBlockStart() { return (*mBlockIter
).mBuf
; }
263 inline char* GetBlockEnd() { return (*mBlockIter
).mBuf
+ (*mBlockIter
).mTextLen
; }
265 bool DetectUnixText();
267 // adjust this member to add specific separators,
268 // the default value is : ",.()[]\t\\+-*/|=<>:;\t\n~?!%"
270 static string mSeparators
;
272 static bool IsSeparator( char ch
);
275 class wxTextEditorModel
;
277 class TTextChangeListenerBase
280 virtual void OnTextChanged( wxTextEditorModel
* pModel
, size_t atRow
, size_t nRows
, TEXT_CHANGE_TYPE ct
) = 0;
283 class TCppJavaHighlightListener
: public TTextChangeListenerBase
286 wxTextEditorModel
* mpModel
; // is set up temporarely
288 enum { IN_COMMENT_STATE
, OUT_OF_COMMENT_STATE
};
291 virtual void OnTextChanged( wxTextEditorModel
* pModel
, size_t atRow
, size_t nRows
, TEXT_CHANGE_TYPE ct
);
296 * Base class for user-defined "bookmarks" within the source-text, bookmarks
297 * are automatically repositioned or deleted as the text is edited. Class
298 * can be subclassed to add pin-specific data (e.g. breakpoint information)
309 : mTypeCode(-1), mRow(NPOS
) {}
311 TPinBase( int typeCode
, size_t row
)
312 : mTypeCode( typeCode
), mRow( row
) {}
314 size_t GetRow() { return mRow
; }
315 int GetTypeCode() { return mTypeCode
; }
317 virtual ~TPinBase() {}
320 // "recommened" type-code ranges for custom pins
322 #define HIHGLIGHTING_PINS_TC_STARRT 50
323 #define OTHER_PINS_TC_START 100
325 inline bool operator<( const TPinBase
& lhs
, TPinBase
& rhs
)
327 { return lhs
.mRow
< rhs
.mRow
; }
329 #if defined( wxUSE_TEMPLATE_STL )
331 typedef vector
<TPinBase
*> PinListT
;
332 typedef vector
<TTextChangeListenerBase
*> ChangeListenerListT
;
334 typedef TPinBase
* TPinBasePtrT
;
335 typedef WXSTL_VECTOR_SHALLOW_COPY( TPinBasePtrT
) PinListT
;
337 typedef TTextChangeListenerBase
* TTextChangeListenerBasePtrT
;
338 typedef WXSTL_VECTOR_SHALLOW_COPY( TTextChangeListenerBasePtrT
) ChangeListenerListT
;
343 struct TPinBaseCompareFunctor
345 inline int operator()(const TPinBasePtrT* x, const TPinBasePtrT*& y ) const
347 return x->mLine < y->mLine;
351 typedef WXSTL_MULTIMAP( TPinBasePtrT, TPinBasePtrT, TPinBaseCompareFunctor ) PinMapT;
352 typedef PinMapT::iterator PinIteratorT;
356 * Class manages access and manpulation of in-memory text. Can
357 * be accessed by multiple views, only one of which can be active
361 class wxTextEditorModel
366 TCommandListT mCommands
;
369 TextViewListT mViews
;
370 wxTextEditorView
* mpActiveView
;
375 ChangeListenerListT mChangeListeners
;
378 /*** public properties ***/
381 size_t mChangedFromRow
;
382 size_t mChangedTillRow
;
384 bool mWasChanged
; // TRUE, if any content has been changed
386 TPosition mCursorPos
;
388 TPosition mPrevSelectionStart
;
389 TPosition mPrevSelectionEnd
;
390 TPosition mPrevCursorPos
;
392 TPosition mSelectionStart
;
393 TPosition mSelectionEnd
;
396 bool mIsReadOnly
; // default: FALSE
398 bool mInsertMode
; // default: TRUE
399 bool mAutoIndentMode
; // default: TRUE
400 bool mSmartIndentMode
; // default: TRUE
402 bool mIsSelectionEditMode
; // default: TRUE
403 size_t mTabSize
; // default: 4
405 StrListT mSearchExprList
;
406 string mLastFindExpr
;
408 bool mCheckPointDestroyed
;
409 size_t mCheckPointCmdNo
;
413 size_t GetLineCountInRange( char* from
, char* till
);
415 // two lowest-level operations
416 void DoInsertText ( const TPosition
& pos
, char* text
, size_t len
, TRange
& actualRange
);
417 void DoDeleteRange( const TPosition
& from
, const TPosition
& till
, TRange
& actualRange
);
419 void DoExecuteNewCommand( TCommand
& cmd
);
421 void DoReexecuteCommand( TCommand
& cmd
);
422 void DoUnexecuteCommand( TCommand
& cmd
);
425 void ExecuteCommand( TCommand
* pCmd
);
427 // to methods enabling grouping of undo-able commands
428 bool CanPrependCommand( TCommand
* pCmd
);
429 void PrependCommand( TCommand
* pCmd
);
431 void SetPostPos( const TPosition
& pos
);
439 void CheckSelection();
440 void TrackSelection();
443 void NotifyAllViews();
445 void NotifyTextChanged( size_t atRow
, size_t nRows
, TEXT_CHANGE_TYPE ct
);
446 void NotifyTextChanged( TPosition from
, TPosition till
, TEXT_CHANGE_TYPE ct
);
448 void ArrangePositions( TPosition
& upper
, TPosition
& lower
);
449 void ArrangePositions( size_t& upper
, size_t& lower
);
451 void MergeChange( size_t fromRow
, size_t nRows
);
453 void PrepreForCommand();
455 size_t TextToScrColumn( const TPosition
& pos
);
456 size_t ScrToTextColumn( TPosition pos
);
458 void DoMoveCursor( int rows
, int cols
);
462 virtual ~wxTextEditorModel();
466 char* AllocCharacters( size_t n
);
467 char* AllocCharacters( size_t n
, const char* srcBuf
);
468 void FreeCharacters( char* buf
);
470 void DeleteSelection();
471 TTextIterator
CreateIterator( const TPosition
& pos
);
473 void DeleteRange( const TPosition
& from
, const TPosition
& till
);
474 void InsertText( const TPosition
& pos
, const char* text
, size_t len
);
475 void GetTextFromRange( const TPosition
& from
, const TPosition
& till
, char** text
, size_t& textLen
);
476 void LoadTextFromFile( const wxString
& fname
);
477 void SaveTextToFile( const wxString
& fname
);
478 void ResetSelection();
479 void ClearUndoBuffer();
482 void DeleteAllText();
483 void GetAllText( char** text
, size_t& textLen
);
485 void SetSelectionEditMode( bool editIsOn
);
487 /*** user-level commands ***/
489 // mutable (undoable) commands
491 void OnInsertChar( char ch
);
496 void OnShiftSelectionIndent( bool left
);
498 // clipboard functions
523 void OnMoveToPosition( const TPosition
& pos
);
526 void OnStartOfLine();
531 void OnStartOfText();
539 void OnToggleBookmark();
540 void OnNextBookmark();
541 void OnPreviousBookmark();
547 bool OnFindPrevious();
548 void OnGotoLine( int line
, int col
);
559 void SetCheckpoint();
560 bool CheckpointModified();
564 TPosition
GetStartOfSelection();
565 TPosition
GetEndOfSelection();
566 TPosition
GetCursor();
568 size_t GetTotalRowCount();
569 bool SelectionIsEmpty();
570 bool IsLastLine( const TPosition
& pos
);
572 bool IsUnixText() { return mIsUnixText
; }
574 void GetSelection( char** text
, size_t& textLen
);
576 void SetStartOfSelection( const TPosition
& pos
);
577 void SetEndOfSelection( const TPosition
& pos
);
578 void SetCursor( const TPosition
& pos
);
580 void AddView( wxTextEditorView
* pView
);
581 void RemoveView( wxTextEditorView
* pView
);
582 void SetActiveView( wxTextEditorView
* pView
);
583 wxTextEditorView
* GetActiveView();
585 void SetRowsPerPage( size_t n
);
587 void AddPin( TPinBase
* pPin
);
590 // returns NPOS, if non
591 size_t FindFirstPinInRange( size_t fromRow
, size_t tillRow
);
592 size_t FindNextPinFrom( size_t fromRow
);
593 size_t FindPreviousPinFrom( size_t fromRow
);
595 size_t GetPinNoAt( size_t row
, int pinTypeCode
);
596 TPinBase
* GetPinAt( size_t row
, int pinTypeCode
);
597 void RemovePinAt( size_t row
, int pinTypeCode
);
599 void AddChangeListener( TTextChangeListenerBase
* pListener
);
603 class wxTextEditorView
;
605 class TPinPainterBase
: public wxObject
611 TPinPainterBase( int pinTc
) : mPinTypeCode( pinTc
) {}
612 TPinPainterBase() : mPinTypeCode( -1 ) {}
614 inline int GetPinTypeCode() { return mPinTypeCode
; }
616 virtual void DrawPin( TPinBase
* pPin
, wxTextEditorView
& view
, wxDC
& dc
,
617 const wxPoint
& pos
, const wxSize
& dim
) = 0;
621 * a couple very common ping objects/painters
624 #define BOOKMARK_PIN_TC (OTHER_PINS_TC_START)
625 #define BRKPOINT_PIN_TC (BOOKMARK_PIN_TC + 1)
627 class TBookmarkPainter
: public TPinPainterBase
635 virtual void DrawPin( TPinBase
* pPin
, wxTextEditorView
& view
, wxDC
& dc
,
636 const wxPoint
& pos
, const wxSize
& dim
);
639 class TBookmarkPin
: public TPinBase
642 TBookmarkPin( size_t row
)
643 : TPinBase( BOOKMARK_PIN_TC
, row
)
646 static int GetPinTypeCode() { return BOOKMARK_PIN_TC
; }
649 class TBreakpointPainter
: public TPinPainterBase
655 TBreakpointPainter();
657 virtual void DrawPin( TPinBase
* pPin
, wxTextEditorView
& view
, wxDC
& dc
,
658 const wxPoint
& pos
, const wxSize
& dim
);
661 class TBreakpointPin
: public TPinBase
664 TBreakpointPin( size_t row
)
665 : TPinBase( BRKPOINT_PIN_TC
, row
)
668 static int GetPinTypeCode() { return BRKPOINT_PIN_TC
; }
672 #if defined( wxUSE_TEMPLATE_STL )
673 typedef vector
<TPinPainterBase
*> PinPainterListT
;
675 typedef TPinPainterBase
* TPinPainterBasePtrT
;
676 typedef WXSTL_VECTOR_SHALLOW_COPY( TPinPainterBasePtrT
) PinPainterListT
;
680 * Class displays graphical view of data contained in wxTextModel
683 class wxTextEditorView
: public wxScrolledWindow
687 wxTextEditorModel
* mpModel
;
688 TPosition mSelectionStart
;
689 TPosition mSelectionEnd
;
690 TPosition mCursorPos
;
692 TPosition mLastViewStart
;
693 size_t mLastRowsTotal
;
698 static char* mpLineBuffer
;
699 static size_t mpLineBufferLen
;
701 bool mFullRefreshPending
;
702 bool mAdjustScrollPending
;
706 bool mScrollingOn
; // default: TRUE
707 bool mCursorOn
; // default: TRUE;
709 bool mLTMode
; // line-tracking mode
710 // (when the whole line is coloured,
711 // instead of showing blinking cursor position)
713 wxColour mLTColour
; // fill-colour for LT-mode
720 wxString mFragment
; // reused heap-buffer
721 // for coloured fragments
722 SourcePainter
* mpPainter
;
723 PinPainterListT mPinPainters
;
724 TTextIterator mCashedIter
;
726 static TCursorTimer
* mpTimer
;
728 public: /*** public properties ***/
730 int mLeftMargin
; // default: 20
731 int mRightMargin
; // default: 0
732 int mTopMargin
; // default: 0
733 int mBottomMargin
; // default: 0
734 int mMaxColumns
; // default: 500
738 // color-scheme properties
740 wxColour mNormalTextCol
;
741 wxColour mIndentifierTextCol
;
742 wxColour mReservedWordTextCol
;
743 wxColour mCommentTextCol
;
745 wxColour mNormalBkCol
;
746 wxColour mSelectionFgCol
;
747 wxColour mSelectionBkCol
;
749 wxBrush mNormalBkBrush
;
750 wxBrush mSelectedBkBrush
;
754 TPosition mCursorScrPos
;
759 char* GetLineBuffer( size_t len
);
761 virtual void PaintDecorations( size_t fromRow
, size_t tillRow
, wxDC
& dc
, TTextIterator
& iter
);
762 virtual void PaintRows( size_t fromRow
, size_t tillRow
, wxDC
& dc
);
764 void ObtainFontProperties();
767 void SetTextDefaults();
768 void RecalcPagingInfo();
770 TPinPainterBase
* FindPainterForPin( TPinBase
& pin
);
773 wxTextEditorView( wxWindow
* parent
, wxWindowID id
= -1,
774 wxTextEditorModel
* pModel
= NULL
,
775 int wndStyle
= wxSUNKEN_BORDER
,
776 bool ownsModel
= TRUE
);
779 /*** setup methods ***/
781 void SetModel( wxTextEditorModel
* pModel
);
783 // sets custom syntax-higlighting implementation
784 void SetSourcePainter( SourcePainter
* pPainter
);
785 void AddPinPainter( TPinPainterBase
* pPainter
);
787 void SetDefaultFont( const wxFont
& font
);
788 wxFont
& GetDefaultFont();
790 wxSize
GetCharacterSize() { return mCharDim
; }
792 size_t GetRowsPerPage() { return mRowsPerPage
; }
793 void SetRowsPerPage( size_t n
);
794 void SetMaxColumns( size_t n
);
796 void SetLineTrackingMode( bool on
, const wxColour
& col
= wxColour(255,255,0) );
798 void EnableCursor( bool enable
);
799 void EnableScrollbars( bool enable
);
801 void SetColours( const wxColour
& normalBkCol
,
802 const wxColour
& selectedBkCol
,
803 const wxColour
& selectedTextCol
);
805 void SetHeighlightingColours( const wxColour
& normalTextCol
,
806 const wxColour
& identifierTextCol
,
807 const wxColour
& reservedWordTextCol
,
808 const wxColour
& commentTextCol
);
810 void SetMargins( int top
, int left
, int bottom
, int right
);
812 // notifications from editor-model:
814 void OnModelChanged();
815 void ScrollView( int rows
, int cols
);
824 #if (( wxVERSION_NUMBER < 2100 ) || (( wxVERSION_NUMBER == 2100 ) && (wxBETA_NUMBER <= 4)))
825 void OnScroll( wxScrollEvent
& event
);
827 void OnScroll( wxScrollWinEvent
& event
);
829 void OnPaint ( wxPaintEvent
& event
);
830 void OnSize ( wxSizeEvent
& event
);
831 void OnEraseBackground( wxEraseEvent
& event
);
833 void OnLButtonDown( wxMouseEvent
& event
);
834 void OnLButtonUp ( wxMouseEvent
& event
);
835 void OnMotion ( wxMouseEvent
& event
);
836 void OnDblClick ( wxMouseEvent
& event
);
838 void OnSetFocus( wxFocusEvent
& event
);
839 void OnKillFocus( wxFocusEvent
& event
);
841 // requests editor to keep cursor blinking, even when
842 // the window has lost it's focus
844 void HoldCursor( bool hold
);
846 // FOR NOW:: hard-coded key-bindings
848 void OnChar( wxKeyEvent
& event
);
849 void OnKeyDown( wxKeyEvent
& event
);
853 virtual void SyncViewPortPosition();
854 virtual void SyncScrollbars();
855 virtual void PositionCursor();
857 void TextPosToScreenPos( const TPosition
& txtPos
, TPosition
& scrPos
);
858 void ScreenPosToTextPos( const TPosition
& scrPos
, TPosition
& txtPos
);
859 void ScreenPosToPixels ( const TPosition
& scrPos
, int& x
, int& y
);
860 void PixelsToScrPos ( int x
, int y
, int& scrRow
, int& scrCol
);
861 void PixelsToTextPos ( int x
, int y
, TPosition
& textPos
);
863 bool IsClipboardCmd( wxKeyEvent
& key
);
865 TPosition
GetPagePos() { return mPagePos
; }
867 DECLARE_EVENT_TABLE()
870 // TODO:: mutex class should be used to avoid race on updates
872 class TCursorTimer
: public wxTimer
875 wxTextEditorView
* mpView
;
876 volatile bool mIsLocked
;
877 volatile bool mIsShown
;
878 volatile bool mStarted
;
882 int mBlinkInterval
; // default: 500mills
891 virtual void Notify();
893 void SetView( wxTextEditorView
* pView
);
894 wxTextEditorView
* GetView();
895 void HideCursor( bool forceHide
= FALSE
);
896 void ShowCursor( bool forceShow
= FALSE
);
898 void SetIsShown( bool isShown
);
903 #endif // __TDEFS_G__