vnote/src/veditarea.h

236 lines
7.5 KiB
C++

#ifndef VEDITAREA_H
#define VEDITAREA_H
#include <QWidget>
#include <QJsonObject>
#include <QString>
#include <QFileInfo>
#include <QDir>
#include <QVector>
#include <QPair>
#include <QSplitter>
#include <QStack>
#include "vnotebook.h"
#include "veditwindow.h"
#include "vnavigationmode.h"
#include "vfilesessioninfo.h"
class VFile;
class VDirectory;
class VFindReplaceDialog;
class QLabel;
class VVim;
class VEditArea : public QWidget, public VNavigationMode
{
Q_OBJECT
public:
explicit VEditArea(QWidget *parent = 0);
// Whether @p_file has been opened in edit area.
bool isFileOpened(const VFile *p_file);
bool closeAllFiles(bool p_forced);
bool closeFile(const VFile *p_file, bool p_forced);
bool closeFile(const VDirectory *p_dir, bool p_forced);
bool closeFile(const VNotebook *p_notebook, bool p_forced);
// Return current edit window.
VEditWindow *getCurrentWindow() const;
// Return current edit tab.
VEditTab *getCurrentTab() const;
// Return the @p_tabIdx tab in the @p_winIdx window.
VEditTab *getTab(int p_winIdx, int p_tabIdx) const;
// Return VEditTabInfo of all edit tabs.
QVector<VEditTabInfo> getAllTabsInfo() const;
// Return the count of VEditWindow.
int windowCount() const;
// Returns the index of @p_window.
int windowIndex(const VEditWindow *p_window) const;
// Move tab widget @p_widget from window @p_fromIdx to @p_toIdx.
// @p_widget has been removed from the original window.
// If fail, just delete the p_widget.
void moveTab(QWidget *p_widget, int p_fromIdx, int p_toIdx);
VFindReplaceDialog *getFindReplaceDialog() const;
// Return selected text of current edit tab.
QString getSelectedText();
void splitCurrentWindow();
void removeCurrentWindow();
// Focus next window (curWindowIndex + p_biaIdx).
// Return the new current window index, otherwise, return -1.
int focusNextWindow(int p_biaIdx);
void moveCurrentTabOneSplit(bool p_right);
// Implementations for VNavigationMode.
void registerNavigation(QChar p_majorKey) Q_DECL_OVERRIDE;
void showNavigation() Q_DECL_OVERRIDE;
void hideNavigation() Q_DECL_OVERRIDE;
bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE;
// Open files @p_files.
int openFiles(const QVector<VFileSessionInfo> &p_files);
// Record a closed file in the stack.
void recordClosedFile(const VFileSessionInfo &p_file);
signals:
// Emit when current window's tab status updated.
void tabStatusUpdated(const VEditTabInfo &p_info);
// Emit when current window's tab's outline changed.
void outlineChanged(const VTableOfContent &p_outline);
// Emit when current window's tab's current header changed.
void currentHeaderChanged(const VHeaderPointer &p_header);
// Emit when want to show message in status bar.
void statusMessage(const QString &p_msg);
// Emit when Vim status updated.
void vimStatusUpdated(const VVim *p_vim);
protected:
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
public slots:
// Open @p_file in mode @p_mode.
// If @p_file has already been opened, change its mode to @p_mode only if
// @p_forceMode is true.
// A given file can be opened in multiple split windows. A given file could be
// opened at most in one tab inside a window.
VEditTab *openFile(VFile *p_file, OpenFileMode p_mode, bool p_forceMode = false);
void editFile();
void saveFile();
void readFile();
void saveAndReadFile();
// Scroll current tab to @p_header.
void scrollToHeader(const VHeaderPointer &p_header);
void handleFileUpdated(const VFile *p_file);
void handleDirectoryUpdated(const VDirectory *p_dir);
void handleNotebookUpdated(const VNotebook *p_notebook);
private slots:
// Split @curWindow via inserting a new window around it.
// @p_right: insert the new window on the right side.
void splitWindow(VEditWindow *p_window, bool p_right = true);
void handleRemoveSplitRequest(VEditWindow *curWindow);
void handleWindowFocused();
void handleWindowOutlineChanged(const VTableOfContent &p_outline);
void handleWindowCurrentHeaderChanged(const VHeaderPointer &p_header);
void handleFindTextChanged(const QString &p_text, uint p_options);
void handleFindOptionChanged(uint p_options);
void handleFindNext(const QString &p_text, uint p_options, bool p_forward);
void handleReplace(const QString &p_text, uint p_options,
const QString &p_replaceText, bool p_findNext);
void handleReplaceAll(const QString &p_text, uint p_options,
const QString &p_replaceText);
void handleFindDialogClosed();
// Hanle the status update of current tab within a VEditWindow.
void handleWindowTabStatusUpdated(const VEditTabInfo &p_info);
// Handle the statusMessage signal of VEditWindow.
void handleWindowStatusMessage(const QString &p_msg);
// Handle the vimStatusUpdated signal of VEditWindow.
void handleWindowVimStatusUpdated(const VVim *p_vim);
// Handle the timeout signal of file timer.
void handleFileTimerTimeout();
private:
void setupUI();
QVector<QPair<int, int> > findTabsByFile(const VFile *p_file);
int openFileInWindow(int windowIndex, VFile *p_file, OpenFileMode p_mode);
void setCurrentTab(int windowIndex, int tabIndex, bool setFocus);
void setCurrentWindow(int windowIndex, bool setFocus);
VEditWindow *getWindow(int windowIndex) const;
void insertSplitWindow(int idx);
void removeSplitWindow(VEditWindow *win);
// Update status of current window.
void updateWindowStatus();
// Init targets for Captain mode.
void registerCaptainTargets();
// Check whether opened files have been changed outside.
void checkFileChangeOutside();
// Captain mode functions.
// Activate tab @p_idx.
static bool activateTabByCaptain(void *p_target, void *p_data, int p_idx);
static bool alternateTabByCaptain(void *p_target, void *p_data);
static bool showOpenedFileListByCaptain(void *p_target, void *p_data);
static bool activateSplitLeftByCaptain(void *p_target, void *p_data);
static bool activateSplitRightByCaptain(void *p_target, void *p_data);
static bool moveTabSplitLeftByCaptain(void *p_target, void *p_data);
static bool moveTabSplitRightByCaptain(void *p_target, void *p_data);
static bool activateNextTabByCaptain(void *p_target, void *p_data);
static bool activatePreviousTabByCaptain(void *p_target, void *p_data);
static bool verticalSplitByCaptain(void *p_target, void *p_data);
static bool removeSplitByCaptain(void *p_target, void *p_data);
// Evaluate selected text or the word on cursor as magic words.
static bool evaluateMagicWordsByCaptain(void *p_target, void *p_data);
// Prompt for user to apply a snippet.
static bool applySnippetByCaptain(void *p_target, void *p_data);
// End Captain mode functions.
int curWindowIndex;
// Splitter holding multiple split windows
QSplitter *splitter;
VFindReplaceDialog *m_findReplace;
// Last closed files stack.
QStack<VFileSessionInfo> m_lastClosedFiles;
};
inline VEditWindow* VEditArea::getWindow(int windowIndex) const
{
Q_ASSERT(windowIndex < splitter->count());
return dynamic_cast<VEditWindow *>(splitter->widget(windowIndex));
}
inline int VEditArea::windowCount() const
{
return splitter->count();
}
inline VFindReplaceDialog *VEditArea::getFindReplaceDialog() const
{
return m_findReplace;
}
#endif // VEDITAREA_H