1 /* 2 * This file is part of the Code::Blocks IDE and licensed under the GNU Lesser General Public License, version 3 3 * http://www.gnu.org/licenses/lgpl-3.0.html 4 */ 5 6 #ifndef CBEDITOR_H 7 #define CBEDITOR_H 8 9 #include <wx/hashmap.h> 10 #include <wx/datetime.h> 11 #include <wx/fontmap.h> 12 #include <wx/timer.h> 13 14 #include "settings.h" 15 #include "editorbase.h" 16 #include "printing_types.h" 17 18 extern const wxString g_EditorModified; 19 20 // forward decls 21 struct cbEditorInternalData; // this is the private data struct used by the editor. 22 class cbEditor; 23 class ProjectFile; 24 class EditorColourSet; 25 class wxSplitterWindow; 26 class LoaderBase; 27 class cbStyledTextCtrl; 28 class wxScintillaEvent; 29 class wxBoxSizer; 30 31 32 /** @brief A file editor 33 * 34 * This class represents one builtin editor in Code::Blocks. It holds all the necessary 35 * information about an editor. When you want to access a Code::Blocks editor, 36 * this is the class you want to get at ;)\n 37 * 38 * To do this, use Manager::Get()->GetEditorManager() functions. 39 * 40 * The actual editor component used is Scintilla and it can be accessed through 41 * the member function GetControl(). 42 */ 43 class DLLIMPORT cbEditor : public EditorBase 44 { 45 DECLARE_EVENT_TABLE() 46 friend class EditorManager; 47 48 protected: 49 /** cbEditor constructor. 50 * @param parent the parent notebook - you should use EditorManager::Get() 51 * @param filename the filename to open. If filename is empty, it creates a 52 * new, empty, editor. 53 * @param theme the initial colour set to use\n 54 * <em>Note: you cannot create a cbEditor object directly. Instead 55 * use EditorManager's methods to do it...</em> 56 */ 57 cbEditor(wxWindow* parent, const wxString& filename, EditorColourSet* theme); 58 cbEditor(wxWindow* parent, LoaderBase* fileLdr, const wxString& filename, EditorColourSet* theme); 59 /** cbEditor destructor. */ 60 ~cbEditor() override; 61 public: 62 enum SplitType 63 { 64 stNoSplit = 0, 65 stHorizontal, 66 stVertical 67 }; 68 69 /** Don't use this. It throws an exception if you do. */ 70 void operator=(cb_unused const cbEditor& rhs){ cbThrow(_T("Can't assign an cbEditor* !!!")); } 71 72 // properties 73 74 /** Returns a pointer to the underlying cbStyledTextCtrl object (which 75 * itself is the wxWindows implementation of Scintilla). If you want 76 * to mess with the actual contents of an editor, this is the object 77 * you want to get. 78 * @remarks If the editor is split, this function returns the control 79 * which currently has the keyboard focus. Don't save this pointer 80 * because it might be invalid at any later time... 81 */ 82 cbStyledTextCtrl* GetControl() const; 83 84 /** Returns a pointer to the left (or top) split-view cbStyledTextCtrl. 85 * This function always returns a valid pointer. 86 */ GetLeftSplitViewControl()87 cbStyledTextCtrl* GetLeftSplitViewControl() const { return m_pControl; } 88 89 /** Returns a pointer to the right (or bottom) split-view cbStyledTextCtrl. 90 * This function may return NULL if the editor is not split. 91 */ GetRightSplitViewControl()92 cbStyledTextCtrl* GetRightSplitViewControl() const { return m_pControl2; } 93 94 /** Returns the state of split-view for this editor. */ GetSplitType()95 SplitType GetSplitType() const { return m_SplitType; } 96 97 /** Returns true if editor is OK, i.e. constructor was called with a filename 98 * parameter and file was opened successfully. If it returns false, you 99 * should delete the editor... 100 */ IsOK()101 bool IsOK() const { return m_IsOK; } 102 103 /** Sets the editor title. For tabbed interface, it sets the corresponding 104 * tab text, while for MDI interface it sets the MDI window title... 105 */ 106 void SetEditorTitle(const wxString& title); 107 108 /** Returns true if editor is modified, false otherwise */ 109 bool GetModified() const override; 110 111 /** Set the editor's modification state to \c modified. */ 112 void SetModified(bool modified = true) override; 113 114 /** Set the ProjectFile pointer associated with this editor. All editors 115 * which belong to a project file, should have this set. All others should return NULL. 116 * Optionally you can preserve the "modified" flag of the file. 117 */ 118 void SetProjectFile(ProjectFile* project_file,bool preserve_modified = false); 119 120 /** Read the ProjectFile pointer associated with this editor. All editors 121 * which belong to a project file, have this set. All others return NULL. 122 */ GetProjectFile()123 ProjectFile* GetProjectFile() const { return m_pProjectFile; } 124 125 /** Updates the associated ProjectFile object with the editor's caret 126 * position, top visible line and its open state. Used in devProject 127 * layout information, so that each time the user opens a project 128 * file in the IDE, it opens exactly in the same state it was when last 129 * closed. 130 */ 131 void UpdateProjectFile(); 132 133 /** Save editor contents. Returns true on success, false otherwise. */ 134 bool Save() override; 135 136 /** Save editor contents under a different filename. Returns true on success, false otherwise. */ 137 bool SaveAs() override; 138 139 /** Save fold states within a new cbStyledTextCtrl. This saves the whole document, thus saving the fold states before the Fold Options Change*/ 140 bool SaveFoldState(); 141 142 /** Fix fold states by comparing foldBackup with m_pControl. This is a temp fix for the Scintilla bug*/ 143 bool FixFoldState(); 144 145 /** Fold all editor folds (hides blocks of code). */ 146 void FoldAll(); 147 148 /** Unfold all editor folds (shows blocks of code). */ 149 void UnfoldAll(); 150 151 /** Toggle all editor folds (inverts the show/hide state of blocks of code). */ 152 void ToggleAllFolds(); 153 154 /** Sets the type of folding indicator where id is one of the following: 0->Arrow, 1->Circle, 2->Square, 3->simple */ 155 void SetFoldingIndicator(int id); 156 157 /** Folds the block containing \c line. If \c line is -1, folds the block containing the caret. */ 158 void FoldBlockFromLine(int line = -1); 159 160 /** Unfolds the block containing \c line. If \c line is -1, unfolds the block containing the caret. */ 161 void UnfoldBlockFromLine(int line = -1); 162 163 /** Toggles folding of the block containing \c line. If \c line is -1, toggles folding of the block containing the caret. */ 164 void ToggleFoldBlockFromLine(int line = -1); 165 166 /** Set the colour set to use. */ 167 void SetColourSet(EditorColourSet* theme); 168 169 /** Get the colour set in use. */ GetColourSet()170 EditorColourSet* GetColourSet() const { return m_pTheme; } 171 172 /** Jumps to the matching brace (if there is one). */ 173 void GotoMatchingBrace(); 174 175 /** Highlights the brace pair (one of the braces must be under the cursor) */ 176 void HighlightBraces(); 177 178 /** Returns the specified line's (0-based) indentation (whitespace) in spaces. If line is -1, it uses the current line */ 179 int GetLineIndentInSpaces(int line = -1) const; 180 181 /** Returns the specified line's (0-based) indentation (whitespace) string. If line is -1, it uses the current line */ 182 wxString GetLineIndentString(int line = -1) const; 183 184 /** Returns the last modification time for the file. Used to detect modifications outside the editor. */ GetLastModificationTime()185 wxDateTime GetLastModificationTime() const { return m_LastModified; } 186 187 /** Sets the last modification time for the file to 'now'. Used to detect modifications outside the editor. */ 188 void Touch(); 189 190 /** Reloads the file from disk. @return True on success, False on failure. */ 191 bool Reload(bool detectEncoding = true); 192 193 /** Print the file. 194 * @param selectionOnly Should the selected text be printed only? 195 * @param pcm The colour mode to use when printing 196 * @param line_numbers Print the line numbers of file, too. 197 */ 198 void Print(bool selectionOnly, PrintColourMode pcm, bool line_numbers); 199 200 /** This method is obsolete, use the abbreviations plugin instead. */ 201 void AutoComplete(); 202 203 /** Move the caret at the specified line. 204 * @param line Line to move caret to. 205 * @param centerOnScreen If true (default), tries to bring the specified line to the centre of the editor.*/ 206 void GotoLine(int line, bool centerOnScreen = true) override; 207 208 /** Move the caret at the specified line. 209 * @param line Line to move caret to (where the token is). 210 * @param tokenName Token name (string) to highlight, if found 211 * @return Editor found, position set and token highlighted? */ 212 bool GotoTokenPosition(int line, const wxString& tokenName); 213 214 /** Add debugger breakpoint at specified line. If @c line is -1, use current line. */ 215 bool AddBreakpoint(int line = -1, bool notifyDebugger = true); 216 217 /** Remove debugger breakpoint at specified line. If @c line is -1, use current line. */ 218 bool RemoveBreakpoint(int line = -1, bool notifyDebugger = true); 219 220 /** Toggle debugger breakpoint at specified line. If @c line is -1, use current line. */ 221 virtual void ToggleBreakpoint(int line = -1, bool notifyDebugger = true); 222 223 /** Does @c line has debugger breakpoint? If @c line is -1, use current line. */ 224 virtual bool HasBreakpoint(int line) const; 225 226 /** Go to next debugger breakpoint. */ 227 virtual void GotoNextBreakpoint(); 228 229 /** Go to previous debugger breakpoint. */ 230 virtual void GotoPreviousBreakpoint(); 231 232 /** Refresh all markers for the breakpoints (only the markers for the current debugger will be shown) */ 233 virtual void RefreshBreakpointMarkers(); 234 235 /** Clear all bookmarks. */ 236 virtual void ClearAllBookmarks(); 237 238 /** Toggle bookmark at specified line. If @c line is -1, use current line. */ 239 virtual void ToggleBookmark(int line = -1); 240 241 /** Does @c line has bookmark? */ 242 virtual bool HasBookmark(int line) const; 243 244 /** Go to next bookmark. */ 245 virtual void GotoNextBookmark(); 246 247 /** Go to previous bookmark. */ 248 virtual void GotoPreviousBookmark(); 249 250 /** Highlight the line the debugger will execute next. */ 251 virtual void SetDebugLine(int line); 252 253 /** Highlight the specified line as error. */ 254 virtual void SetErrorLine(int line); 255 256 /** Split the editor window. 257 * @param split The type of split: horizontal or vertical. */ 258 void Split(SplitType split); 259 260 /** Unsplit the editor window. */ 261 void Unsplit(); 262 263 // the following functions, although self-explanatory, are documented 264 // in EditorBase. 265 void Undo() override; 266 void Redo() override; 267 void ClearHistory() override; 268 void GotoNextChanged() override; 269 void GotoPreviousChanged() override; 270 void SetChangeCollection(bool collectChange) override; 271 void Cut() override; 272 void Copy() override; 273 void Paste() override; 274 bool CanUndo() const override; 275 bool CanRedo() const override; 276 bool HasSelection() const override; 277 bool CanPaste() const override; 278 bool IsReadOnly() const override; 279 void SetReadOnly(bool readonly = true) override; 280 281 bool CanSelectAll() const override; 282 void SelectAll() override; 283 284 // Workaround for shift-tab bug in wx2.4.2 285 void DoIndent(); //!< Indents current line/block 286 void DoUnIndent(); //!< UnIndents current line/block 287 288 // misc. functions 289 wxMenu* CreateContextSubMenu(long id) override; 290 void AddToContextMenu(wxMenu* popup,ModuleType type,bool pluginsdone) override; 291 GetLanguage()292 HighlightLanguage GetLanguage( ) const { return m_lang; } 293 /// Sets the language for this editor. 294 /// @param lang The language for the editor. If you pass HL_AUTO the language would be 295 /// autodetected. 296 /// @param colourise Pass true if you want to apply the style. If you intend to do more 297 /// operations which would affect styling pass false. 298 void SetLanguage(HighlightLanguage lang, bool colourise); 299 300 wxFontEncoding GetEncoding( ) const; 301 wxString GetEncodingName( ) const; 302 void SetEncoding( wxFontEncoding encoding ); 303 304 bool GetUseBom() const; 305 void SetUseBom( bool bom ); 306 307 void SetZoom(int zoom, bool both = true); 308 309 /// Apply the editor defaults to any (possibly foreign) cbStyledTextCtrl. 310 static void ApplyStyles(cbStyledTextCtrl* control); 311 312 void AutoIndentDone(); 313 314 /// Applies the styles that match the filename of the editor. 315 /// Should be called after new file is created. Calling SaveAs does the same thing. 316 void SetEditorStyle(); 317 private: 318 cbEditor(cb_unused const cbEditor& rhs); // prevent copy construction 319 320 // functions 321 bool LineHasMarker(int marker, int line = -1) const; 322 void MarkerToggle(int marker, int line = -1); 323 void MarkerNext(int marker); 324 void MarkerPrevious(int marker); 325 void MarkLine(int marker, int line); 326 327 enum class FoldMode : int 328 { 329 contract = 0, // wxSCI_FOLDACTION_CONTRACT 330 expand = 1, // wxSCI_FOLDACTION_EXPAND, 331 toggle = 2, //wxSCI_FOLDACTION_TOGGLE 332 }; 333 enum FoldFlags : unsigned 334 { 335 none = 0x0, 336 ensureVisible = 0x2, 337 }; 338 339 void DoFoldAll(FoldMode fold); 340 void DoFoldBlockFromLine(int line, FoldMode fold, unsigned foldFlags); 341 void SetMarkerStyle(int marker, int markerType, wxColor fore, wxColor back); 342 void UnderlineFoldedLines(bool underline); 343 cbStyledTextCtrl* CreateEditor(); 344 void ConnectEvents(cbStyledTextCtrl* stc); 345 void SetEditorStyleBeforeFileOpen(); 346 void SetEditorStyleAfterFileOpen(); 347 static void InternalSetEditorStyleBeforeFileOpen(cbStyledTextCtrl* control); 348 static void InternalSetEditorStyleAfterFileOpen(cbStyledTextCtrl* control); 349 bool Open(bool detectEncoding = true); 350 void DoAskForCodeCompletion(); // relevant to code-completion plugins 351 void SetLanguageDependentColours(cbStyledTextCtrl &control); 352 void NotifyPlugins(wxEventType type, int intArg = 0, const wxString& strArg = wxEmptyString, int xArg = 0, int yArg = 0); 353 354 // events 355 void OnMarginClick(wxScintillaEvent& event); 356 void OnEditorUpdateUI(wxScintillaEvent& event); 357 void OnEditorChange(wxScintillaEvent& event); 358 void OnEditorCharAdded(wxScintillaEvent& event); 359 void OnEditorDwellStart(wxScintillaEvent& event); 360 void OnEditorDwellEnd(wxScintillaEvent& event); 361 void OnEditorModified(wxScintillaEvent& event); 362 void OnUserListSelection(wxScintillaEvent& event); 363 void OnZoom(wxScintillaEvent& event); 364 /** notify all the registered EditorHook functions 365 * @param event indicates which event is received by the cbEditor 366 * You should bind OnScintillaEvent to every wxScintillaEvent events, either directly or 367 * indirectly, see cbEditor::ConnectEvents() for more details. 368 */ 369 void OnScintillaEvent(wxScintillaEvent& event); 370 void OnClose(wxCloseEvent& event); 371 372 // one event handler for all popup menu entries 373 void OnContextMenuEntry(wxCommandEvent& event); 374 bool OnBeforeBuildContextMenu(const wxPoint& position, ModuleType type) override; 375 void OnAfterBuildContextMenu(ModuleType type) override; 376 377 void DestroySplitView(); 378 379 void DoInitializations(const wxString& filename, LoaderBase* fileLdr = nullptr); 380 381 void BreakpointMarkerToggle(int line); 382 383 // variables 384 bool m_IsOK; 385 wxSplitterWindow* m_pSplitter; 386 wxBoxSizer* m_pSizer; 387 cbStyledTextCtrl* m_pControl; 388 cbStyledTextCtrl* m_pControl2; 389 cbStyledTextCtrl* m_foldBackup; 390 SplitType m_SplitType; 391 bool m_Modified; 392 int m_Index; 393 wxTimer m_timerWait; 394 ProjectFile* m_pProjectFile; 395 EditorColourSet* m_pTheme; 396 HighlightLanguage m_lang; 397 wxDateTime m_LastModified; // to check if the file was modified outside the editor 398 bool m_autoIndentDone; 399 400 // DO NOT ADD ANY MORE VARIABLES HERE! 401 // ADD THEM IN cbEditorInternalData INSTEAD! 402 403 friend struct cbEditorInternalData; // allow cbEditorInternalData to access cbEditor 404 cbEditorInternalData* m_pData; 405 }; 406 407 #endif // CBEDITOR_H 408