/* QAD - Qt ADvanced Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #ifndef QCODEEDIT_H #define QCODEEDIT_H #include "qad_widgets_export.h" #include #include #include namespace Ui { class QCodeEdit; } class QPlainTextEdit; class QCodeEditCompleter; class IconedLabel; class _QCE_Viewport; class QAD_WIDGETS_EXPORT QCodeEdit: public QWidget { Q_OBJECT Q_PROPERTY(QString text READ text WRITE setText) Q_PROPERTY(bool showSpaces READ showSpaces WRITE setShowSpaces) Q_PROPERTY(bool showLineNumbers READ showLineNumbers WRITE setShowLineNumbers) Q_PROPERTY(bool wordCompletitionEnabled READ wordCompletitionEnabled WRITE setWordCompletitionEnabled) Q_PROPERTY(QFont editorFont READ editorFont WRITE setEditorFont) friend class QCodeEditCompleter; friend class _QCE_Viewport; public: QCodeEdit(QWidget * parent = nullptr); ~QCodeEdit() override; enum ACClassType { Keyword, Function, Namespace }; struct QAD_WIDGETS_EXPORT ACEntry { ACEntry(const QString & t = QString(), const QString & n = QString(), const QString & h = QString()): type(t), name(n), hint(h) { declaration_pos = -1; } bool isNull() const { return type.isEmpty() && name.isEmpty(); } QString declaration() const; ACEntry & addHint(QString h) { hint = h; return *this; } ACEntry & addHelpHRef(QUrl h) { help_href = h; return *this; } ACEntry & addCustomData(QVariant d) { custom_data = d; return *this; } QString type; QString name; QString hint; int declaration_pos; QString declaration_file; QUrl help_href; QVariant custom_data; }; QTextCursor textCursor() const; QTextDocument * document() const; void setDocument(QTextDocument * doc); void setTextCursor(const QTextCursor & c); void centerCursor(); void insertText(const QString & text); void appendText(const QString & text); void setCustomExtraSelection(const QList & es); QRect cursorRect() const; QRect cursorRect(const QTextCursor & cursor) const; QString text() const; QStringList cursorScope() const; bool showSpaces() const { return spaces_; } bool showLineNumbers() const; void setHelpHintVisible(bool on); bool isHelpHintVisible() const; QString commentText() const; void setCommentText(QString t); void setEditorFont(QFont f); QFont editorFont() const; QPlainTextEdit * textEdit() const; void registerAutoCompletitionClass(int id, ACClassType ac_class, const QString & name, const QIcon & icon = QIcon()); bool wordCompletitionEnabled() const { return word_complete; } bool isDarkTheme() const { return is_dark_theme; } static QBrush invertedBrush(const QBrush & b); static QTextCharFormat invertedFormat(const QTextCharFormat & f); protected: typedef QPair StringsPair; typedef QPair> ACSection; // section, ACClass.id -> list of entries typedef QList ACList; // list of sections virtual ACList autoCompletitionList(const QStringList & scope, const QString & written) const { return ACList(); } virtual void parse() {} virtual void documentUnset() {} virtual void documentChanged(QTextDocument * d) {} virtual void linkClicked(ACEntry entry) {} virtual bool linkValidate(ACEntry e) { return true; } QString selectArg(QString s, int arg); void raiseHelp(QTextCursor tc, int arg = -1); QTextCursor functionStart(QTextCursor tc, int * arg); ACList wordsCompletitionList(const QString & written) const; QPair getScope(QTextCursor tc, bool * ok = nullptr); static int skipRange(const QString & s, int pos, QChar oc, QChar cc, QChar sc = QChar()); static int skipCWord(const QString & s, int pos); static bool matchWritten(QString s, QString w); static QChar pairChar(QChar c); private slots: void _activateLink(QCodeEdit::ACEntry e) { linkClicked(e); } void gotoHelpHRef(QCodeEdit::ACEntry e); void resizeOverlay(); void syncScrolls(); void scrollUp(); void scrollDown(); void hideHelp(); void deleteLine(); void copyLineUp(); void copyLineDown(); void moveLineUp(); void moveLineDown(); void indent(); void deindent(); void autoIndent(); void showLink(); void hideLink(); void gotoLink(); void invokeAutoCompletition(bool force = false); void commitCompletition(); void searchAll(); void search_triggered(); void textEdit_cursorPositionChanged(); void textEdit_textChanged(); void textEdit_selectionChanged(); void textEdit_redoAvailable(bool available); void on_comboSearch_currentTextChanged(const QString & t); void on_buttonReplace_clicked(); void on_buttonReplaceSearch_clicked(); void on_buttonReplaceAll_clicked(); public slots: void updateLines(); void scrollToTop(); void newLine(); void newLineBefore(); void setFocus(); void setText(const QString & t); void setShowSpaces(bool yes); void setShowLineNumbers(bool yes); void search(const QString & t); void searchNext(bool next); void searchNext() { searchNext(true); } void searchPrevious(); void hideSearch(); void setWordCompletitionEnabled(bool on) { word_complete = on; } signals: void textChanged(); void parseRequest(); private: struct QAD_WIDGETS_EXPORT ACClass { ACClass(int i = -2, ACClassType c = QCodeEdit::Keyword, const QString & n = QString(), const QIcon & ic = QIcon()) : id(i) , class_(c) , name(n) , icon(ic) {} int id; ACClassType class_; QString name; QIcon icon; }; enum LabelHelpType { lhMain, lhHint, lhF1, lh_last }; bool eventFilter(QObject * o, QEvent * e) override; void showEvent(QShowEvent *) override; void timerEvent(QTimerEvent *) override; void leaveEvent(QEvent *) override; void changeEvent(QEvent * e) override; bool codeKeyEvent(QKeyEvent * ke); void toggleComment(); void highlightBrackets(); void applyExtraSelection(); void clearSearch(); void moveToSearch(); int searchIndFromCursor(); QRect cursorRect(); QRect blockSelectionRect(); QVector blockSelectionCursors(QRect bsr); void repaintCursor(); void drawCursor(); bool hasBlockSelection() const; void startBlockSelection(); void cancelBlockSelection(); void switchBlockSelection(QKeyEvent * ke = nullptr); bool removeBlockSelection(bool is_del); void insertBlockSelection(QString text); void createBlockSelection(); void cancelDragCursor(); ACEntry findEntryOnCursor(QTextCursor tc, int arg = -1, ACClass * acc = nullptr, QPair * scope = nullptr); void detectTheme(); Ui::QCodeEdit * ui; QCodeEditCompleter * completer; IconedLabel * lbl_help[3]; QFrame * widget_help; _QCE_Viewport * overlay; QTextEdit::ExtraSelection es_line, es_cursor, es_bracket, es_range, es_search, es_link; QList es_selected, es_custom, es_brackets, es_search_list, es_blockselection; QMap ac_classes; QStringList cursor_scope; QString comment_text; ACEntry link_entry, help_entry; QTextCursor block_start_cursor, drag_cursor; int prev_lc, auto_comp_pl, timer_parse, timer_blink, cur_search_ind, pos_press, pos_el_press; int cursor_width; bool is_dark_theme = false; bool spaces_, _ignore_focus_out, _first, _destructor, _replacing; bool word_complete, help_visible, cursor_state, block_sel_state; }; #endif // QCODEEDIT_H