veditarea.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. #ifndef VEDITAREA_H
  2. #define VEDITAREA_H
  3. #include <QWidget>
  4. #include <QJsonObject>
  5. #include <QString>
  6. #include <QFileInfo>
  7. #include <QDir>
  8. #include <QVector>
  9. #include <QPair>
  10. #include <QSplitter>
  11. #include <QStack>
  12. #include "vnotebook.h"
  13. #include "veditwindow.h"
  14. #include "vnavigationmode.h"
  15. #include "vfilesessioninfo.h"
  16. class VFile;
  17. class VDirectory;
  18. class VFindReplaceDialog;
  19. class QLabel;
  20. class VVim;
  21. class VEditArea : public QWidget, public VNavigationMode
  22. {
  23. Q_OBJECT
  24. public:
  25. explicit VEditArea(QWidget *parent = 0);
  26. // Whether @p_file has been opened in edit area.
  27. bool isFileOpened(const VFile *p_file);
  28. bool closeAllFiles(bool p_forced);
  29. bool closeFile(const VFile *p_file, bool p_forced);
  30. bool closeFile(const VDirectory *p_dir, bool p_forced);
  31. bool closeFile(const VNotebook *p_notebook, bool p_forced);
  32. // Return current edit window.
  33. VEditWindow *getCurrentWindow() const;
  34. // Return current edit tab.
  35. VEditTab *getCurrentTab() const;
  36. // Return the @p_tabIdx tab in the @p_winIdx window.
  37. VEditTab *getTab(int p_winIdx, int p_tabIdx) const;
  38. // Return VEditTabInfo of all edit tabs.
  39. QVector<VEditTabInfo> getAllTabsInfo() const;
  40. // Return the count of VEditWindow.
  41. int windowCount() const;
  42. // Returns the index of @p_window.
  43. int windowIndex(const VEditWindow *p_window) const;
  44. // Move tab widget @p_widget from window @p_fromIdx to @p_toIdx.
  45. // @p_widget has been removed from the original window.
  46. // If fail, just delete the p_widget.
  47. void moveTab(QWidget *p_widget, int p_fromIdx, int p_toIdx);
  48. VFindReplaceDialog *getFindReplaceDialog() const;
  49. // Return selected text of current edit tab.
  50. QString getSelectedText();
  51. void splitCurrentWindow();
  52. void removeCurrentWindow();
  53. // Focus next window (curWindowIndex + p_biaIdx).
  54. // Return the new current window index, otherwise, return -1.
  55. int focusNextWindow(int p_biaIdx);
  56. void moveCurrentTabOneSplit(bool p_right);
  57. // Implementations for VNavigationMode.
  58. void registerNavigation(QChar p_majorKey) Q_DECL_OVERRIDE;
  59. void showNavigation() Q_DECL_OVERRIDE;
  60. void hideNavigation() Q_DECL_OVERRIDE;
  61. bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE;
  62. // Open files @p_files.
  63. int openFiles(const QVector<VFileSessionInfo> &p_files);
  64. // Record a closed file in the stack.
  65. void recordClosedFile(const VFileSessionInfo &p_file);
  66. signals:
  67. // Emit when current window's tab status updated.
  68. void tabStatusUpdated(const VEditTabInfo &p_info);
  69. // Emit when current window's tab's outline changed.
  70. void outlineChanged(const VTableOfContent &p_outline);
  71. // Emit when current window's tab's current header changed.
  72. void currentHeaderChanged(const VHeaderPointer &p_header);
  73. // Emit when want to show message in status bar.
  74. void statusMessage(const QString &p_msg);
  75. // Emit when Vim status updated.
  76. void vimStatusUpdated(const VVim *p_vim);
  77. protected:
  78. void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
  79. public slots:
  80. // Open @p_file in mode @p_mode.
  81. // If @p_file has already been opened, change its mode to @p_mode only if
  82. // @p_forceMode is true.
  83. // A given file can be opened in multiple split windows. A given file could be
  84. // opened at most in one tab inside a window.
  85. VEditTab *openFile(VFile *p_file, OpenFileMode p_mode, bool p_forceMode = false);
  86. void editFile();
  87. void saveFile();
  88. void readFile();
  89. void saveAndReadFile();
  90. // Scroll current tab to @p_header.
  91. void scrollToHeader(const VHeaderPointer &p_header);
  92. void handleFileUpdated(const VFile *p_file, UpdateAction p_act);
  93. void handleDirectoryUpdated(const VDirectory *p_dir, UpdateAction p_act);
  94. void handleNotebookUpdated(const VNotebook *p_notebook);
  95. private slots:
  96. // Split @curWindow via inserting a new window around it.
  97. // @p_right: insert the new window on the right side.
  98. void splitWindow(VEditWindow *p_window, bool p_right = true);
  99. void handleRemoveSplitRequest(VEditWindow *curWindow);
  100. void handleWindowFocused();
  101. void handleWindowOutlineChanged(const VTableOfContent &p_outline);
  102. void handleWindowCurrentHeaderChanged(const VHeaderPointer &p_header);
  103. void handleFindTextChanged(const QString &p_text, uint p_options);
  104. void handleFindOptionChanged(uint p_options);
  105. void handleFindNext(const QString &p_text, uint p_options, bool p_forward);
  106. void handleReplace(const QString &p_text, uint p_options,
  107. const QString &p_replaceText, bool p_findNext);
  108. void handleReplaceAll(const QString &p_text, uint p_options,
  109. const QString &p_replaceText);
  110. void handleFindDialogClosed();
  111. // Hanle the status update of current tab within a VEditWindow.
  112. void handleWindowTabStatusUpdated(const VEditTabInfo &p_info);
  113. // Handle the statusMessage signal of VEditWindow.
  114. void handleWindowStatusMessage(const QString &p_msg);
  115. // Handle the vimStatusUpdated signal of VEditWindow.
  116. void handleWindowVimStatusUpdated(const VVim *p_vim);
  117. // Handle the timeout signal of file timer.
  118. void handleFileTimerTimeout();
  119. private:
  120. void setupUI();
  121. QVector<QPair<int, int> > findTabsByFile(const VFile *p_file);
  122. int openFileInWindow(int windowIndex, VFile *p_file, OpenFileMode p_mode);
  123. void setCurrentTab(int windowIndex, int tabIndex, bool setFocus);
  124. void setCurrentWindow(int windowIndex, bool setFocus);
  125. VEditWindow *getWindow(int windowIndex) const;
  126. void insertSplitWindow(int idx);
  127. void removeSplitWindow(VEditWindow *win);
  128. // Update status of current window.
  129. void updateWindowStatus();
  130. // Init targets for Captain mode.
  131. void registerCaptainTargets();
  132. // Check whether opened files have been changed outside.
  133. void checkFileChangeOutside();
  134. // Captain mode functions.
  135. // Activate tab @p_idx.
  136. static bool activateTabByCaptain(void *p_target, void *p_data, int p_idx);
  137. static bool alternateTabByCaptain(void *p_target, void *p_data);
  138. static bool showOpenedFileListByCaptain(void *p_target, void *p_data);
  139. static bool activateSplitLeftByCaptain(void *p_target, void *p_data);
  140. static bool activateSplitRightByCaptain(void *p_target, void *p_data);
  141. static bool moveTabSplitLeftByCaptain(void *p_target, void *p_data);
  142. static bool moveTabSplitRightByCaptain(void *p_target, void *p_data);
  143. static bool activateNextTabByCaptain(void *p_target, void *p_data);
  144. static bool activatePreviousTabByCaptain(void *p_target, void *p_data);
  145. static bool verticalSplitByCaptain(void *p_target, void *p_data);
  146. static bool removeSplitByCaptain(void *p_target, void *p_data);
  147. // Evaluate selected text or the word on cursor as magic words.
  148. static bool evaluateMagicWordsByCaptain(void *p_target, void *p_data);
  149. // Prompt for user to apply a snippet.
  150. static bool applySnippetByCaptain(void *p_target, void *p_data);
  151. // End Captain mode functions.
  152. int curWindowIndex;
  153. // Splitter holding multiple split windows
  154. QSplitter *splitter;
  155. VFindReplaceDialog *m_findReplace;
  156. // Last closed files stack.
  157. QStack<VFileSessionInfo> m_lastClosedFiles;
  158. };
  159. inline VEditWindow* VEditArea::getWindow(int windowIndex) const
  160. {
  161. Q_ASSERT(windowIndex < splitter->count());
  162. return dynamic_cast<VEditWindow *>(splitter->widget(windowIndex));
  163. }
  164. inline int VEditArea::windowCount() const
  165. {
  166. return splitter->count();
  167. }
  168. inline VFindReplaceDialog *VEditArea::getFindReplaceDialog() const
  169. {
  170. return m_findReplace;
  171. }
  172. #endif // VEDITAREA_H