// ____ ______ __ // / __ \ / ____// / // / /_/ // / / / // / ____// /___ / /___ PixInsight Class Library // /_/ \____//_____/ PCL 2.4.23 // ---------------------------------------------------------------------------- // pcl/CodeEditor.h - Released 2022-03-12T18:59:29Z // ---------------------------------------------------------------------------- // This file is part of the PixInsight Class Library (PCL). // PCL is a multiplatform C++ framework for development of PixInsight modules. // // Copyright (c) 2003-2022 Pleiades Astrophoto S.L. All Rights Reserved. // // Redistribution and use in both source and binary forms, with or without // modification, is permitted provided that the following conditions are met: // // 1. All redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // 2. All redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // 3. Neither the names "PixInsight" and "Pleiades Astrophoto", nor the names // of their contributors, may be used to endorse or promote products derived // from this software without specific prior written permission. For written // permission, please contact info@pixinsight.com. // // 4. All products derived from this software, in any form whatsoever, must // reproduce the following acknowledgment in the end-user documentation // and/or other materials provided with the product: // // "This product is based on software from the PixInsight project, developed // by Pleiades Astrophoto and its contributors (https://pixinsight.com/)." // // Alternatively, if that is where third-party acknowledgments normally // appear, this acknowledgment must be reproduced in the product itself. // // THIS SOFTWARE IS PROVIDED BY PLEIADES ASTROPHOTO AND ITS CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PLEIADES ASTROPHOTO OR ITS // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, BUSINESS // INTERRUPTION; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; AND LOSS OF USE, // DATA OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // ---------------------------------------------------------------------------- #ifndef __PCL_CodeEditor_h #define __PCL_CodeEditor_h /// \file pcl/CodeEditor.h #include #include #ifndef __PCL_BUILDING_PIXINSIGHT_APPLICATION #include #include #endif // !__PCL_BUILDING_PIXINSIGHT_APPLICATION namespace pcl { // ---------------------------------------------------------------------------- /*! * \namespace pcl::FindMode * \brief Flags to control text find and replacement operations. * * * * * * * * * *
FindMode::RegExp Search with a regular expression instead of a literal substring.
FindMode::Backward Search toward the beginning of the document.
FindMode::CaseSensitive Perform a case-sensitive search.
FindMode::WholeWords Search for whole words only.
FindMode::SelectionOnly Search and replace within the current text selection only
FindMode::Incremental Perform an incremental text find operation. The search begins after a previously matched text block.
FindMode::Default The default text find mode, equal to FindMode::CaseSensitive|FindMode::WholeWords.
*/ namespace FindMode { enum mask_type { RegExp = 0x00000001, // Search with a regular expression Backward = 0x00000010, // Search toward the beginning of text CaseSensitive = 0x00000020, // Case-sensitive search WholeWords = 0x00000040, // Search for whole words SelectionOnly = 0x00000100, // Replace within the current selection Incremental = 0x00000200, // Perform an incremental find operation Default = CaseSensitive|WholeWords }; } /*! * A combination of text find and replacement mode flags. */ typedef Flags FindModes; // ---------------------------------------------------------------------------- #ifndef __PCL_BUILDING_PIXINSIGHT_APPLICATION // ---------------------------------------------------------------------------- /*! * \class CodeEditor * \brief Client-side interface to a PixInsight %CodeEditor control. * * ### TODO: Write a detailed description for %CodeEditor. */ class PCL_CLASS CodeEditor : public Control { public: /*! * Constructs a %CodeEditor control. * * \param parent The parent control of this object. The default value is * a null control. */ CodeEditor( Control& parent = Control::Null() ); /*! * Destroys a %CodeEditor control. */ virtual ~CodeEditor() { } /*! * Returns a reference to a line numbers control for this code * editor. * * A line numbers control provides a visual index of the text lines * currently displayed by a code editor. Typically, a code editor and its * line numbers control are packed side by side in a HorizontalSizer. */ Control& LineNumbersControl(); /*! * Returns the absolute file path associated with this code editor, or an * empty string if this object has not been associated with a file. */ String FilePath() const; /*! * Sets the file path associated with this code editor. * * If the specified \a path includes a file name suffix (also known as file * name \e extension), the control will use it to identify a programming * language to perform automatic syntax highlighting of the text in the * editor. Currently the following file suffixes and source code languages * are supported: * * * * * * * * * *
.js .jsh JavaScript source files
.scp Command-line script files
.cpp .h .cxx .hpp .hxx .c .cc C/C++ source files
.py Python source files
.xml .xhtml .html .xosm .xpsm (among others) XML source files
.pidoc PixInsight documentation source files
.pm .pmath PixelMath source files
* * Unrecognized (or absent) file suffixes effectively disable the automatic * syntax highlighting feature. The default value of this parameter is an * empty string. */ void SetFilePath( const String& path ); /*! * Returns the current text in this code editor in UTF-16 format. */ String Text() const; /*! * Sets the current text in this code editor in UTF-16 format. */ void SetText( const String& text ); /*! * Returns an encoded 8-bit representation of the text in this code editor. * * \param encoding The desired text encoding. Currently only the "UTF-8" * and "ISO-8859-1" encodings are supported. The default * value is "UTF-8". */ IsoString EncodedText( const IsoString& encoding = "UTF-8" ) const; /*! * Returns the text in this code editor encoded in UTF-8 format. * * This is a convenience function, equivalent to: * * \code EncodedText( "UTF-8" ); \endcode */ IsoString TextUTF8() const { return EncodedText( "UTF-8" ); } /*! * Returns the text in this code editor encoded in ISO 8859-1 format. * * This is a convenience function, equivalent to: * * \code EncodedText( "ISO-8859-1" ); \endcode */ IsoString TextISO88591() const { return EncodedText( "ISO-8859-1" ); } /*! * Sets the current text in this code editor, encoded in an 8-bit format. * * \param text The encoded 8-bit text. * * \param encoding The text encoding. Currently only the "UTF-8" and * "ISO-8859-1" encodings are supported. The default value * is "UTF-8". */ void SetEncodedText( const IsoString& text, const IsoString& encoding = "UTF-8" ); /*! * Sets the current text in this code editor, encoded in UTF-8 format. * * This is a convenience function, equivalent to: * * \code SetEncodedText( text, "UTF-8" ); \endcode */ void SetTextUTF8( const IsoString& text ) { SetEncodedText( text, "UTF-8" ); } /*! * Sets the current text in this code editor, encoded in ISO 8859-1 format. * * This is a convenience function, equivalent to: * * \code SetEncodedText( text, "ISO-8859-1" ); \endcode */ void SetTextISO88591( const IsoString& text ) { SetEncodedText( text, "ISO-8859-1" ); } /*! * Clears all the text in this code editor. Also clears all undo/redo * buffers, so this action is irreversible. */ void ClearText(); /*! * Returns true iff this code editor is in read-only mode. A * read-only editor does not allow any command that can modify its text * contents as a result of a direct user interaction. The text can only be * changed programmatically for a read-only code editor. */ bool IsReadOnly() const; /*! * Enables the read-only mode for this code editor. A read-only editor does * not allow any command that can modify its text contents as a result of a * direct user interaction. The text can only be changed programmatically * for a read-only code editor. * * \param readOnly Whether to enable or disable the read-only mode for * this code editor. */ void SetReadOnly( bool readOnly = true ); /*! * Writes the text in this code editor to the specified file, encoded in an * 8-bit format. * * \param filePath Path to the destination file. * * \param encoding The desired text encoding. Currently only the "UTF-8" * and "ISO-8859-1" encodings are supported. The default * value is "UTF-8". * * Returns true if the file was successfully written; false in the event of * error. * * \warning Upon successful completion, this function will overwrite an * existing file at the specified path, whose previous contents will be * lost. */ bool Save( const String& filePath, const IsoString& encoding = "UTF-8" ); /*! * Writes the text in this code editor to the specified file, encoded in * UTF-8 format. * * This is a convenience function, equivalent to: * * \code Save( filePath, "UTF-8" ); \endcode */ bool SaveUTF8( const String& filePath ) { return Save( filePath, "UTF-8" ); } /*! * Writes the text in this code editor to the specified file, encoded in * ISO 8859-1 format. * * This is a convenience function, equivalent to: * * \code Save( filePath, "ISO-8859-1" ); \endcode */ bool SaveISO88591( const String& filePath ) { return Save( filePath, "ISO-8859-1" ); } /*! * Reads an encoded 8-bit text file and loads it in this code editor. * * \param filePath Path to the source file. * * \param encoding The text encoding. Currently only the "UTF-8" and * "ISO-8859-1" encodings are supported. The default * value is "UTF-8". * * Returns true if the file was successfully read; false in the event of * error. */ bool Load( const String& filePath, const IsoString& encoding = "UTF-8" ); /*! * Reads a text file encoded in UTF-8 format, and loads it in this code * editor. * * This is a convenience function, equivalent to: * * \code Load( filePath, "UTF-8" ); \endcode */ bool LoadUTF8( const String& filePath ) { return Load( filePath, "UTF-8" ); } /*! * Reads a text file encoded in ISO 8859-1 format, and loads it in this code * editor. * * This is a convenience function, equivalent to: * * \code Load( filePath, "ISO-8859-1" ); \endcode */ bool LoadISO88591( const String& filePath ) { return Load( filePath, "ISO-8859-1" ); } /*! * Returns the number of text lines (including empty lines) in this code * editor. */ int NumberOfLines() const; /*! * Returns the total number of characters in the current text of this code * editor. */ int NumberOfCharacters() const; /*! * Returns the current cursor position in visual coordinates. The returned * object stores the current line and column of the cursor in its Point::y * and Point::x public data members, respectively. * * Line and column coordinates are counted from zero. Line numbers range * from zero to the number of existing text lines minus one. There is no * specific limit for the number of text characters in a text line. */ Point CursorPosition() const; /*! * Returns the line number of the current cursor position. */ int CursorLine() const { return CursorPosition().y; } /*! * Returns the column number of the current cursor position. */ int CursorColumn() const { return CursorPosition().x; } /*! * Sets the current cursor position in this code editor to the specified * \a line and \a column. See CursorPosition() for more information on * visual text coordinates. */ void SetCursorPosition( int line, int column ); /*! * Sets the current cursor position in this code editor through the * coordinates of a Point object. The new cursor line will be set to * \a pos.y and the new cursor column to \a pos.x, respectively. */ void SetCursorPosition( const Point& pos ) { SetCursorPosition( pos.y, pos.x ); } /*! * Returns true iff this code editor is in insert text mode. Returns * false if the editor is in replace text mode. * * In insert mode, newly generated text by direct user interaction is * inserted at the current cursor location. In replace mode, newly generated * text replaces existing characters starting at the current cursor * location. The insert text mode is always enabled by default. */ bool IsInsertMode() const; /*! * Enables the insert text mode for this code editor. * * \param insert Whether to enable the insert text mode (if true) or the * replace text mode (if false). The default value is true. */ void SetInsertMode( bool insert = true ); /*! * Enables the replace text mode for this code editor. * * \param replace Whether to enable the replace text mode (if true) or the * insert text mode (if false). The default value is true. */ void SetReplaceMode( bool replace = true ) { SetInsertMode( !replace ); } /*! * Returns true iff this code editor is in block selection mode; * false if it is in line selection mode. * * In block selection mode, the user can select rectangular areas of text * across multiple text lines. In line selection mode, text * selections can only include entire text lines except for the first and * last lines in a selection. The line selection mode is always enabled by * default. */ bool IsBlockSelectionMode() const; /*! * Enables the block selection mode for this code editor. * * \param blockMode Whether to enable the block selection mode (if true) or * the line selection mode (if false). The default value * is true. */ void SetBlockSelectionMode( bool blockMode = true ); /*! * Enables the line selection mode for this code editor. * * \param lineMode Whether to enable the line selection mode (if true) or * the block selection mode (if false). The default value * is true. */ void SetLineSelectionMode( bool lineMode = true ) { SetBlockSelectionMode( !lineMode ); } /*! * Returns true iff this code editor is in dynamic word wrap mode. * * In dynamic word wrap mode, long text lines extending beyond the visible * width of the editor's viewport are automatically truncated and continued * on successive editor lines, so that the user can always see the entire * contents of all text lines, and a horizontal scroll bar is never shown. * * When the dynamic word wrap mode is disabled, long text lines are never * truncated and the editor shows a horizontal scroll bar when necessary. * The dynamic word wrap mode is always disabled by default. */ bool IsDynamicWordWrapMode() const; /*! * Enables the dynamic word wrap mode for this code editor. * * \param wrapMode Whether to enable the dynamic word wrap mode. */ void SetDynamicWordWrapMode( bool wrapMode = true ); /*! * Returns the number of \e undo steps available for this code editor. */ int UndoSteps() const; /*! * Returns the number of \e redo steps available for this code editor. */ int RedoSteps() const; /*! * Returns true iff this code editor has a text selection defined. */ bool HasSelection() const; /*! * Returns the visual coordinates of the current selection in this code * editor. The selection coordinates are stored in the returned rectangle as * follows: * * \li Rect::y0 - Starting line of the current text selection. * \li Rect::x0 - Starting column of the current text selection. * \li Rect::y1 - Ending line of the current text selection. * \li Rect::x1 - Ending column of the current text selection. */ Rect Selection() const; /*! * Sets a new text selection defined by its visual coordinates. * * \param fromLine Starting line of the new text selection. * \param fromCol Starting column of the new text selection. * \param toLine Ending line of the new text selection. * \param toCol Ending column of the new text selection. */ void SetSelection( int fromLine, int fromCol, int toLine, int toCol ); /*! * Sets a new text selection defined by its visual coordinates. * * This is a convenience function, equivalent to: * * \code SetSelection( r.y0, r.x0, r.y1, r.x1 ); \endcode */ void SetSelection( const Rect& r ) { SetSelection( r.y0, r.x0, r.y1, r.x1 ); } /*! * Returns the currently selected text in this code editor, or an empty * string if this editor has no selection currently defined. */ String SelectedText() const; /*! * Inserts the specified \a text at the current cursor location. * * If there is a selection defined, the selected text is replaced with the * inserted \a text. */ void InsertText( const String& text ); /*! * Undoes the last editor action. If no action can be undone, this function * has no effect. */ void Undo(); /*! * Redoes the last editor action. If no action can be redone, this function * has no effect. */ void Redo(); /*! * Copies the current text selection to the clipboard and removes the * selected text. If no selection is defined, this function has no effect. */ void Cut(); /*! * Copies the current text selection to the clipboard. If no selection is * defined, this function has no effect. */ void Copy(); /*! * Inserts the contents of the clipboard at the current cursor location. If * the clipboard is empty, or if its contents cannot be converted to plain * text, this function has no effect. */ void Paste(); /*! * Removes the currently selected text. If there is no text selection * defined, this function has no effect. */ void Delete(); /*! * Selects all the text in this code editor. */ void SelectAll(); /*! * Clears the current text selection, if any. This function simply unselects * the text; it does not remove the selected text. */ void Unselect(); /*! * If the cursor points to a bracket or parenthesis character, look for a * matching pair and move the cursor to the corresponding location. * * Returns true iff a matching pair could be found. If there is no bracket or * parenthesis at the current cursor location, or if a matched pair couldn't * be found, this function returns false and the cursor is not moved. */ bool GotoMatchedParenthesis(); /*! * Highlights all occurrences of a literal text string or a regular * expression. * * \param toFind The text or regular expression to search for, depending on * the specified \a mode flags. * * \param mode An OR'ed combination of flags to control the text find * operation. Valid flags are enumerated in the pcl::FindMode * namespace. * * The operation takes place on the whole text document, ignoring the * FindMode::Backward and FindMode::SelectionOnly flags. Returns the number * of matches found. */ int HighlightAllMatches( const String& toFind, FindModes mode ); /*! * Clears all text highlightings. This function does not remove the * highlighted text; it simply clears the visual highlight indications. */ void ClearMatches(); /*! * Finds an occurrence of a literal text string or a regular expression. * * \param toFind The text or regular expression to search for, depending on * the specified \a mode flags. * * \param mode An OR'ed combination of flags to control the text find * operation. Valid flags are enumerated in the pcl::FindMode * namespace. * * Returns true iff a match was found. */ bool Find( const String& toFind, FindModes mode ); /*! * Replaces the current selection with the specified text. * * \param replaceWith The text that will replace the current selection. * Can be an empty string (to delete the current * selection). * * If there is some text selected in this editor, this function returns * true after performing the replacement operation. If there is no text * currently selected, this function is ignored and false is returned. */ bool ReplaceSelection( const String& replaceWith ); /*! * Replaces all occurrences of a literal text string or a regular * expression with the specified text. * * \param toFind The text or regular expression to search for, depending on * the specified \a mode flags. * * \param replaceWith The text that will replace all matches found. Can be * an empty string (to delete all matched occurrences). * * \param mode An OR'ed combination of flags to control the text find and * replace operation. Valid flags are enumerated in the * pcl::FindMode namespace. * * Returns the number of matches found and replaced. * */ int ReplaceAll( const String& toFind, const String& replaceWith, FindModes mode ); /*! * \defgroup code_editor_event_handlers CodeEditor Event Handlers */ /*! * Defines the prototype of an editor event handler. * * An editor event is generated when a %CodeEditor instance changes its * state or contents due to direct user interaction. * * \param sender The control that sends an editor event. * * \ingroup code_editor_event_handlers */ typedef void (Control::*editor_event_handler)( CodeEditor& sender ); /*! * Defines the prototype of a cursor event handler. * * A cursor event is generated when the cursor position changes in a * %CodeEditor instance due to direct user interaction. * * \param sender The control that sends a cursor event. * * \param line Line number of the new cursor position (>= 0). * * \param col Column number of the new cursor position (>= 0). * * \ingroup code_editor_event_handlers */ typedef void (Control::*cursor_event_handler)( CodeEditor& sender, int line, int col ); /*! * Defines the prototype of a selection event handler. * * A selection event is generated when the text selection changes in a * %CodeEditor instance due to direct user interaction. * * \param sender The control that sends a selection event. * * \param fromLine Line number of the starting position of the new text * selection. * * \param fromCol Column number of the starting position of the new text * selection. * * \param toLine Line number of the ending position of the new text * selection. * * \param toCol Column number of the ending position of the new text * selection. * * \ingroup code_editor_event_handlers */ typedef void (Control::*selection_event_handler)( CodeEditor& sender, int fromLine, int fromCol, int toLine, int toCol ); /*! * Defines the prototype of a state event handler. * * A state event is generated when a Boolean property changes in a * %CodeEditor instance due to direct user interaction. * * \param sender The control that sends a cursor event. * * \param state New property state. * * \ingroup code_editor_event_handlers */ typedef void (Control::*state_event_handler)( CodeEditor& sender, bool state ); /*! * Sets the handler for text updated events generated by this code * editor. A text updated event is generated each time the text changes in * this editor as a result of a direct user interaction. * * \param handler The event handler. Must be a member function of the * \a receiver object's class. * * \param receiver The control that will receive text updated events from * this code editor. * * \ingroup code_editor_event_handlers */ void OnTextUpdated( editor_event_handler handler, Control& receiver ); /*! * Sets the handler for cursor position updated events generated by * this code editor. A cursor position updated event is generated each time * the text cursor (also known as \e caret) moves in this editor as a result * of a direct user interaction. * * \param handler The event handler. Must be a member function of the * \a receiver object's class. * * \param receiver The control that will receive cursor position updated * events from this code editor. * * \ingroup code_editor_event_handlers */ void OnCursorPositionUpdated( cursor_event_handler handler, Control& receiver ); /*! * Sets the handler for selection updated events generated by this * code editor. A selection updated event is generated each time the text * selection is changed in this editor as a result of a direct user * interaction. * * \param handler The event handler. Must be a member function of the * \a receiver object's class. * * \param receiver The control that will receive selection updated events * from this code editor. * * \ingroup code_editor_event_handlers */ void OnSelectionUpdated( selection_event_handler handler, Control& receiver ); /*! * Sets the handler for overwrite mode updated events generated by * this code editor. An overwrite mode updated event is generated each time * the overwrite mode is enabled or disabled in this editor (i.e., from * overwrite mode to replace mode or vice-versa) as a result of a direct * user interaction. * * \param handler The event handler. Must be a member function of the * \a receiver object's class. * * \param receiver The control that will receive overwrite mode updated * events from this code editor. * * \ingroup code_editor_event_handlers */ void OnOverwriteModeUpdated( state_event_handler handler, Control& receiver ); /*! * Sets the handler for selection mode updated events generated by * this code editor. A selection mode updated event is generated each time * the selection mode is changed in this editor (i.e., from line selection * mode to block selection mode or vice-versa) as a result of a direct user * interaction. * * \param handler The event handler. Must be a member function of the * \a receiver object's class. * * \param receiver The control that will receive selection mode updated * events from this code editor. * * \ingroup code_editor_event_handlers */ void OnSelectionModeUpdated( state_event_handler handler, Control& receiver ); /*! * Sets the handler for dynamic word wrap mode updated events * generated by this code editor. A dynamic word wrap mode updated event is * generated each time the dynamic word wrap mode is enabled or disabled in * this editor as a result of a direct user interaction. * * \param handler The event handler. Must be a member function of the * \a receiver object's class. * * \param receiver The control that will receive dynamic word wrap mode * updated events from this code editor. * * \ingroup code_editor_event_handlers */ void OnDynamicWordWrapModeUpdated( state_event_handler handler, Control& receiver ); private: struct EventHandlers { editor_event_handler onTextUpdated = nullptr; cursor_event_handler onCursorPositionUpdated = nullptr; selection_event_handler onSelectionUpdated = nullptr; state_event_handler onOverwriteModeUpdated = nullptr; state_event_handler onSelectionModeUpdated = nullptr; state_event_handler onDynamicWordWrapModeUpdated = nullptr; EventHandlers() = default; EventHandlers( const EventHandlers& ) = default; EventHandlers& operator =( const EventHandlers& ) = default; }; AutoPointer m_handlers; Control m_lineNumbers; friend class CodeEditorEventDispatcher; }; // ---------------------------------------------------------------------------- #endif // __PCL_BUILDING_PIXINSIGHT_APPLICATION } // pcl #endif // __PCL_CodeEditor_h // ---------------------------------------------------------------------------- // EOF pcl/CodeEditor.h - Released 2022-03-12T18:59:29Z