1 /* 2 SuperCollider Qt IDE 3 Copyright (c) 2012 Jakob Leben & Tim Blechmann 4 http://www.audiosynth.com 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #pragma once 22 23 #include <QWidget> 24 #include <QTabBar> 25 #include <QAction> 26 #include <QPushButton> 27 #include <QToolButton> 28 #include <QLineEdit> 29 #include <QCheckBox> 30 #include <QLabel> 31 #include <QGridLayout> 32 #include <QTextDocument> 33 #include <QSplitter> 34 35 namespace ScIDE { 36 37 class CodeEditorBox; 38 class Document; 39 class DocumentManager; 40 class GenericCodeEditor; 41 class Main; 42 class MultiSplitter; 43 struct Session; 44 class SignalMultiplexer; 45 46 namespace Settings { 47 class Manager; 48 } 49 50 class EditorTabBar : public QTabBar { 51 Q_OBJECT 52 53 public: 54 explicit EditorTabBar(QWidget* parent = nullptr); 55 56 private slots: 57 void onCloseTab(); 58 void onCloseOtherTabs(); 59 void onCloseTabsToTheRight(); 60 61 private: 62 void mousePressEvent(QMouseEvent* event) override final; 63 void mouseDoubleClickEvent(QMouseEvent* event) override final; 64 65 void showContextMenu(QMouseEvent* event); 66 67 int mTabUnderCursor; 68 }; 69 70 class MultiEditor : public QWidget { 71 Q_OBJECT 72 73 public: 74 enum ActionRole { 75 // Edit 76 Undo, 77 Redo, 78 Cut, 79 Copy, 80 Paste, 81 IndentLineOrRegion, 82 TriggerAutoCompletion, 83 TriggerMethodCallAid, 84 ToggleComment, 85 ToggleOverwriteMode, 86 87 CopyLineUp, 88 CopyLineDown, 89 MoveLineUp, 90 MoveLineDown, 91 DeleteWord, 92 93 GotoPreviousBlock, 94 GotoNextBlock, 95 SelectEnclosingBlock, 96 97 GotoPreviousRegion, 98 GotoNextRegion, 99 GotoPreviousEmptyLine, 100 GotoNextEmptyLine, 101 102 SelectRegion, 103 104 // View 105 DocClose, 106 EnlargeFont, 107 ShrinkFont, 108 ResetFontSize, 109 ShowWhitespace, 110 ShowLinenumber, 111 IndentWithSpaces, 112 ShowAutocompleteHelp, 113 114 NextDocument, 115 PreviousDocument, 116 SwitchDocument, 117 118 SplitHorizontally, 119 SplitVertically, 120 RemoveCurrentSplit, 121 RemoveAllSplits, 122 123 // Language 124 EvaluateCurrentDocument, 125 EvaluateRegion, 126 EvaluateLine, 127 128 ActionRoleCount 129 }; 130 131 MultiEditor(Main*, QWidget* parent = 0); 132 tabCount()133 int tabCount() { return mTabs->count(); } 134 Document* documentForTab(int index); 135 int tabForDocument(Document* doc); 136 137 GenericCodeEditor* currentEditor(); currentBox()138 CodeEditorBox* currentBox() { return mCurrentEditorBox; } 139 void split(Qt::Orientation direction); 140 action(ActionRole role)141 QAction* action(ActionRole role) { return mActions[role]; } 142 143 void saveSession(Session*); 144 void switchSession(Session*); 145 146 signals: 147 void currentDocumentChanged(Document*); 148 void splitViewActivated(); 149 void splitViewDeactivated(); 150 void updateDockletOrder(int, int); 151 152 public slots: 153 154 void setCurrent(Document*); 155 156 void showNextDocument(); 157 void showPreviousDocument(); 158 void switchDocument(); 159 splitHorizontally()160 void splitHorizontally() { split(Qt::Horizontal); } splitVertically()161 void splitVertically() { split(Qt::Vertical); } 162 void removeCurrentSplit(); 163 void removeAllSplits(); 164 165 void setShowWhitespace(bool on); 166 void setShowLinenumber(bool on); 167 168 void setShowAutocompleteHelp(bool on); 169 170 void updateTabsOrder(QList<Document*>); 171 172 private slots: 173 void applySettings(Settings::Manager*); 174 void onOpen(Document*, int initialCursorPosition, int selectionLength); 175 void onClose(Document*); 176 void show(Document*, int cursorPosition = -1, int selectionLenght = 0); 177 void update(Document*); 178 void onCloseRequest(int index); 179 void onCurrentTabChanged(int index); 180 void onCurrentEditorChanged(GenericCodeEditor*); 181 void onBoxActivated(CodeEditorBox*); 182 void onDocModified(Document*); 183 void updateDocOrder(int, int); 184 185 private: 186 void makeSignalConnections(); 187 void breakSignalConnections(); 188 void createActions(); 189 void updateActions(); 190 191 /** 192 * Put a new doc into the editor. If `doc` is already opened, this simply returns its current index. 193 * 194 * @param doc The doc to insert. 195 * @param insertIndex Index at which to insert. If negative, the doc is inserted after the current tab. 196 * @return The index of the tab. 197 */ 198 int insertTab(Document* doc, int insertIndex = -1); 199 CodeEditorBox* newBox(MultiSplitter*); 200 void setCurrentBox(CodeEditorBox*); 201 void setCurrentEditor(GenericCodeEditor*); 202 void loadBoxState(CodeEditorBox* box, const QVariantList& data, const QList<Document*>& documentList); 203 void loadSplitterState(MultiSplitter*, const QVariantMap& data, const QList<Document*>& documentList); 204 void showEditorTabs(bool); 205 void activateComboBoxWhenSplitting(); 206 void setMainComboBoxOption(); 207 208 QAction* mActions[ActionRoleCount]; 209 210 SignalMultiplexer* mEditorSigMux; 211 SignalMultiplexer* mBoxSigMux; 212 213 // gui 214 QTabBar* mTabs; 215 CodeEditorBox* mCurrentEditorBox; 216 MultiSplitter* mSplitter; 217 QIcon mDocModifiedIcon; 218 QVBoxLayout* multiEditorLayout; 219 }; 220 221 } // namespace ScIDE 222