| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- #ifndef VIEWAREA_H
- #define VIEWAREA_H
- #include <QWidget>
- #include <QSharedPointer>
- #include <functional>
- #include <buffer/buffer.h>
- #include "global.h"
- #include "navigationmode.h"
- #include "viewsplit.h"
- #include "viewareasession.h"
- class QLayout;
- class QSplitter;
- namespace vnotex
- {
- class Buffer;
- class ViewWindow;
- class Event;
- class Notebook;
- struct FileOpenParameters;
- // Hold a list of ViewWindow. A ViewSplit could display any ViewWorkspace.
- // A ViewWorkspace could only be displayed by one ViewSplit at a time.
- // If a ViewWorkspace is visible, it is managed by its ViewSplit and
- // its state may not reflect the real fact.
- struct ViewWorkspace
- {
- explicit ViewWorkspace(ID p_id)
- : m_id(p_id)
- {
- }
- ~ViewWorkspace()
- {
- Q_ASSERT(m_viewWindows.isEmpty());
- }
- void clear()
- {
- m_visible = false;
- m_viewWindows.clear();
- m_currentViewWindowIndex = 0;
- }
- const ID m_id = 0;
- // Whether it is displayed by a ViewSplit now.
- bool m_visible = false;
- QVector<ViewWindow *> m_viewWindows;
- int m_currentViewWindowIndex = 0;
- };
- // ViewArea -- ViewSplit -- ViewWindow.
- // ViewSplit may be put within a splitter.
- // There may be multiple ViewWindow for the same buffer.
- class ViewArea : public QWidget, public NavigationMode
- {
- Q_OBJECT
- public:
- explicit ViewArea(QWidget *p_parent = nullptr);
- ~ViewArea();
- QSize sizeHint() const Q_DECL_OVERRIDE;
- // Not all Workspace. Just all ViewSplits.
- QList<Buffer *> getAllBuffersInViewSplits() const;
- ViewWindow *getCurrentViewWindow() const;
- public slots:
- void openBuffer(Buffer *p_buffer, const QSharedPointer<FileOpenParameters> &p_paras);
- bool close(const Notebook *p_notebook, bool p_force);
- void focus();
- // NavigationMode.
- protected:
- QVector<void *> getVisibleNavigationItems() Q_DECL_OVERRIDE;
- void placeNavigationLabel(int p_idx, void *p_item, QLabel *p_label) Q_DECL_OVERRIDE;
- void handleTargetHit(void *p_item) Q_DECL_OVERRIDE;
- void clearNavigation() Q_DECL_OVERRIDE;
- protected:
- // To accept specific drop.
- void dragEnterEvent(QDragEnterEvent *p_event) Q_DECL_OVERRIDE;
- // Drop the data.
- void dropEvent(QDropEvent *p_event) Q_DECL_OVERRIDE;
- signals:
- // Status widget of ViewArea is changed.
- // MainWindow should set the corresponding status widget accordingly.
- void statusWidgetChanged(QWidget *p_widget);
- // Count of ViewSplit is chagned.
- // Used internally.
- void viewSplitsCountChanged();
- void currentViewWindowChanged();
- // State of current view window has update.
- void currentViewWindowUpdated();
- private slots:
- // Return true if @p_win is closed.
- // @p_removeSplitIfEmpty: whether remove the workspace and split if @p_win is that only ViewWindow left.
- bool closeViewWindow(ViewWindow *p_win, bool p_force, bool p_removeSplitIfEmpty);
- void maximizeViewSplit(ViewSplit *p_split);
- void distributeViewSplits();
- void newWorkspaceInViewSplit(ViewSplit *p_split);
- // @p_insertNew: whether to find an available workspace for @p_split after removal.
- // Return true if removed.
- bool removeWorkspaceInViewSplit(ViewSplit *p_split, bool p_insertNew);
- void handleViewSplitsCountChange();
- bool close(bool p_force);
- void handleNodeChange(Node *p_node, const QSharedPointer<Event> &p_event);
- void loadSession();
- void saveSession() const;
- private:
- enum class SplitType
- {
- Vertical,
- Horizontal
- };
- enum class Direction
- {
- Left,
- Down,
- Up,
- Right
- };
- void setupUI();
- // Find given @p_buffer among all view splits.
- // Does not search invisible work spaces.
- QVector<ViewWindow *> findBufferInViewSplits(const Buffer *p_buffer) const;
- ViewSplit *createViewSplit(QWidget *p_parent, ID p_viewSplitId = InvalidViewSplitId);
- // A Scene widget will be used when there is no split.
- // Usually it is used to show some help message.
- void showSceneWidget();
- void hideSceneWidget();
- void addFirstViewSplit();
- // Close all the ViewWindows in @p_split if @p_removeWorkspace is true.
- // Otherwise, detach the Workpace from it and remove the split.
- void removeViewSplit(ViewSplit *p_split, bool p_removeWorkspace);
- void setCurrentViewWindow(ViewWindow *p_win);
- ViewSplit *getCurrentViewSplit() const;
- void setCurrentViewSplit(ViewSplit *p_split, bool p_focus);
- QSharedPointer<ViewWorkspace> createWorkspace();
- void splitViewSplit(ViewSplit *p_split, SplitType p_type);
- QSplitter *tryGetParentSplitter(const QWidget *p_widget) const;
- // Distribute all splits within @p_splitter recursively.
- void distributeViewSplitsOfSplitter(QSplitter *p_splitter);
- void unwrapSplitter(QSplitter *p_splitter);
- void maximizeWidgetOfSplitter(QWidget *p_widget);
- QSplitter *createSplitter(Qt::Orientation p_orientation, QWidget *p_parent) const;
- // Do not use the reference since it will remove the value in @m_workspaces.
- // Should have done the clean up of ViewWindow before calling this.
- void removeWorkspace(QSharedPointer<ViewWorkspace> p_workspace);
- bool shouldUseGlobalStatusWidget() const;
- // Iterate through all ViewWindows including both ViewSplits and Workspaces.
- // Should NOT use this function to close ViewWindow.
- void forEachViewWindow(const ViewSplit::ViewWindowSelector &p_func);
- void setupShortcuts();
- // Close all ViewWindows related to @p_node.
- bool close(Node *p_node, bool p_force);
- // Go through all ViewWindows and judge whether to close it by @p_func.
- bool closeIf(bool p_force,
- const ViewSplit::ViewWindowSelector &p_func,
- bool p_closeEmptySplit);
- void checkCurrentViewWindowChange();
- QVector<ViewWindow *> getAllViewWindows(ViewSplit *p_split, const ViewSplit::ViewWindowSelector &p_func) const;
- QVector<ViewWindow *> getAllViewWindows(ViewSplit *p_split) const;
- void takeSnapshot(ViewAreaSession &p_session) const;
- void postFirstViewSplit();
- void loadSplitterFromSession(const ViewAreaSession::Node &p_node, QSplitter *p_splitter);
- void openViewWindowFromSession(const ViewWindowSession &p_session);
- void focusSplitByDirection(Direction p_direction);
- SplitType checkSplitType(const QSplitter *p_splitter) const;
- void flashViewSplit(ViewSplit *p_split);
- QLayout *m_mainLayout = nullptr;
- QWidget *m_sceneWidget = nullptr;
- QVector<ViewSplit *> m_splits;
- QVector<QSharedPointer<ViewWorkspace>> m_workspaces;
- ViewSplit *m_currentSplit = nullptr;
- ViewWindow *m_currentWindow = nullptr;
- // Current global status widget.
- // When there is no split window, we will make the status widget global.
- // Otherwise, we will display the status widget at the bottom of each view window.
- QSharedPointer<QWidget> m_currentStatusWidget;
- QVector<ViewSplit::ViewWindowNavigationModeInfo> m_navigationItems;
- // Timer to check file change outside periodically.
- QTimer *m_fileCheckTimer = nullptr;
- ID m_nextViewSplitId = InvalidViewSplitId + 1;
- };
- } // ns vnotex
- #endif // VIEWAREA_H
|