| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338 |
- #include <QtWidgets>
- #include "veditarea.h"
- #include "veditwindow.h"
- #include "vedittab.h"
- #include "vnote.h"
- #include "vconfigmanager.h"
- VEditArea::VEditArea(VNote *vnote, QWidget *parent)
- : QWidget(parent), vnote(vnote), curWindowIndex(0)
- {
- setupUI();
- }
- void VEditArea::setupUI()
- {
- splitter = new QSplitter(this);
- // Add a window
- insertSplitWindow(0);
- setCurrentWindow(0, true);
- QHBoxLayout *mainLayout = new QHBoxLayout();
- mainLayout->addWidget(splitter);
- mainLayout->setContentsMargins(0, 0, 0, 0);
- setLayout(mainLayout);
- }
- void VEditArea::insertSplitWindow(int idx)
- {
- VEditWindow *win = new VEditWindow(vnote);
- splitter->insertWidget(idx, win);
- connect(win, &VEditWindow::tabStatusChanged,
- this, &VEditArea::curTabStatusChanged);
- connect(win, &VEditWindow::requestSplitWindow,
- this, &VEditArea::handleSplitWindowRequest);
- connect(win, &VEditWindow::requestRemoveSplit,
- this, &VEditArea::handleRemoveSplitRequest);
- connect(win, &VEditWindow::getFocused,
- this, &VEditArea::handleWindowFocused);
- connect(win, &VEditWindow::outlineChanged,
- this, &VEditArea::handleOutlineChanged);
- connect(win, &VEditWindow::curHeaderChanged,
- this, &VEditArea::handleCurHeaderChanged);
- int nrWin = splitter->count();
- if (nrWin == 1) {
- // Disable removing split
- win->setRemoveSplitEnable(false);
- } else {
- // Enable removing split
- for (int i = 0; i < nrWin; ++i) {
- getWindow(i)->setRemoveSplitEnable(true);
- }
- }
- }
- void VEditArea::removeSplitWindow(VEditWindow *win)
- {
- if (!win) {
- return;
- }
- win->hide();
- // Should be deleted later
- win->deleteLater();
- int nrWin = splitter->count();
- if (nrWin == 2) {
- // Disable removing split
- getWindow(0)->setRemoveSplitEnable(false);
- getWindow(1)->setRemoveSplitEnable(false);
- } else {
- // Enable removing split
- for (int i = 0; i < nrWin; ++i) {
- getWindow(i)->setRemoveSplitEnable(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.
- void VEditArea::openFile(QJsonObject fileJson)
- {
- if (fileJson.isEmpty()) {
- return;
- }
- QString notebook = fileJson["notebook"].toString();
- QString relativePath = fileJson["relative_path"].toString();
- int mode = OpenFileMode::Read;
- if (fileJson.contains("mode")) {
- mode = fileJson["mode"].toInt();
- }
- qDebug() << "open notebook" << notebook << "path" << relativePath << mode;
- // Find if it has been opened already
- int winIdx, tabIdx;
- bool setFocus = false;
- auto tabs = findTabsByFile(notebook, relativePath);
- if (!tabs.empty()) {
- // Current window first
- winIdx = tabs[0].first;
- tabIdx = tabs[0].second;
- for (int i = 0; i < tabs.size(); ++i) {
- if (tabs[i].first == curWindowIndex) {
- winIdx = tabs[i].first;
- tabIdx = tabs[i].second;
- break;
- }
- }
- setFocus = true;
- goto out;
- }
- // Open it in current window
- winIdx = curWindowIndex;
- tabIdx = openFileInWindow(winIdx, notebook, relativePath, mode);
- out:
- setCurrentTab(winIdx, tabIdx, setFocus);
- }
- QVector<QPair<int, int> > VEditArea::findTabsByFile(const QString ¬ebook, const QString &relativePath)
- {
- QVector<QPair<int, int> > tabs;
- int nrWin = splitter->count();
- for (int winIdx = 0; winIdx < nrWin; ++winIdx) {
- VEditWindow *win = getWindow(winIdx);
- int tabIdx = win->findTabByFile(notebook, relativePath);
- if (tabIdx != -1) {
- QPair<int, int> match;
- match.first = winIdx;
- match.second = tabIdx;
- tabs.append(match);
- }
- }
- return tabs;
- }
- int VEditArea::openFileInWindow(int windowIndex, const QString ¬ebook, const QString &relativePath,
- int mode)
- {
- Q_ASSERT(windowIndex < splitter->count());
- VEditWindow *win = getWindow(windowIndex);
- return win->openFile(notebook, relativePath, mode);
- }
- void VEditArea::setCurrentTab(int windowIndex, int tabIndex, bool setFocus)
- {
- VEditWindow *win = getWindow(windowIndex);
- win->setCurrentIndex(tabIndex);
- setCurrentWindow(windowIndex, setFocus);
- }
- void VEditArea::setCurrentWindow(int windowIndex, bool setFocus)
- {
- if (curWindowIndex == windowIndex) {
- goto out;
- }
- qDebug() << "current window" << windowIndex;
- curWindowIndex = windowIndex;
- if (setFocus) {
- getWindow(windowIndex)->focusWindow();
- }
- out:
- // Update status
- updateWindowStatus();
- }
- void VEditArea::updateWindowStatus()
- {
- VEditWindow *win = getWindow(curWindowIndex);
- win->requestUpdateTabStatus();
- win->requestUpdateOutline();
- win->requestUpdateCurHeader();
- }
- bool VEditArea::closeFile(QJsonObject fileJson)
- {
- if (fileJson.isEmpty()) {
- return true;
- }
- QString notebook = fileJson["notebook"].toString();
- QString relativePath = fileJson["relative_path"].toString();
- bool isForced = fileJson["is_forced"].toBool();
- int nrWin = splitter->count();
- bool ret = false;
- for (int i = 0; i < nrWin; ++i) {
- VEditWindow *win = getWindow(i);
- ret = ret || win->closeFile(notebook, relativePath, isForced);
- }
- return ret;
- }
- void VEditArea::editFile()
- {
- VEditWindow *win = getWindow(curWindowIndex);
- win->editFile();
- }
- void VEditArea::saveFile()
- {
- VEditWindow *win = getWindow(curWindowIndex);
- win->saveFile();
- }
- void VEditArea::readFile()
- {
- VEditWindow *win = getWindow(curWindowIndex);
- win->readFile();
- }
- void VEditArea::saveAndReadFile()
- {
- VEditWindow *win = getWindow(curWindowIndex);
- win->saveAndReadFile();
- }
- void VEditArea::handleNotebookRenamed(const QVector<VNotebook> ¬ebooks,
- const QString &oldName, const QString &newName)
- {
- int nrWin = splitter->count();
- for (int i = 0; i < nrWin; ++i) {
- VEditWindow *win = getWindow(i);
- win->handleNotebookRenamed(notebooks, oldName, newName);
- }
- updateWindowStatus();
- }
- void VEditArea::handleDirectoryRenamed(const QString ¬ebook, const QString &oldRelativePath,
- const QString &newRelativePath)
- {
- int nrWin = splitter->count();
- for (int i = 0; i < nrWin; ++i) {
- VEditWindow *win = getWindow(i);
- win->handleDirectoryRenamed(notebook, oldRelativePath, newRelativePath);
- }
- updateWindowStatus();
- }
- void VEditArea::handleFileRenamed(const QString ¬ebook,
- const QString &oldRelativePath, const QString &newRelativePath)
- {
- int nrWin = splitter->count();
- for (int i = 0; i < nrWin; ++i) {
- VEditWindow *win = getWindow(i);
- win->handleFileRenamed(notebook, oldRelativePath, newRelativePath);
- }
- updateWindowStatus();
- }
- void VEditArea::handleSplitWindowRequest(VEditWindow *curWindow)
- {
- if (!curWindow) {
- return;
- }
- int idx = splitter->indexOf(curWindow);
- qDebug() << "window" << idx << "requests split itself";
- insertSplitWindow(++idx);
- setCurrentWindow(idx, true);
- }
- void VEditArea::handleRemoveSplitRequest(VEditWindow *curWindow)
- {
- if (!curWindow) {
- return;
- }
- int idx = splitter->indexOf(curWindow);
- removeSplitWindow(curWindow);
- if (idx >= splitter->count()) {
- idx = splitter->count() - 1;
- }
- // At least one split window left
- Q_ASSERT(idx >= 0);
- setCurrentWindow(idx, true);
- }
- void VEditArea::mousePressEvent(QMouseEvent *event)
- {
- return;
- qDebug() << "VEditArea press event" << event;
- QPoint pos = event->pos();
- int nrWin = splitter->count();
- for (int i = 0; i < nrWin; ++i) {
- VEditWindow *win = getWindow(i);
- if (win->geometry().contains(pos, true)) {
- setCurrentWindow(i, true);
- break;
- }
- }
- QWidget::mousePressEvent(event);
- }
- void VEditArea::handleWindowFocused()
- {
- QObject *winObject = sender();
- int nrWin = splitter->count();
- for (int i = 0; i < nrWin; ++i) {
- if (splitter->widget(i) == winObject) {
- setCurrentWindow(i, false);
- break;
- }
- }
- }
- void VEditArea::handleOutlineChanged(const VToc &toc)
- {
- QObject *winObject = sender();
- if (splitter->widget(curWindowIndex) == winObject) {
- emit outlineChanged(toc);
- }
- }
- void VEditArea::handleCurHeaderChanged(const VAnchor &anchor)
- {
- QObject *winObject = sender();
- if (splitter->widget(curWindowIndex) == winObject) {
- emit curHeaderChanged(anchor);
- }
- }
- void VEditArea::handleOutlineItemActivated(const VAnchor &anchor)
- {
- // Notice current window
- getWindow(curWindowIndex)->scrollCurTab(anchor);
- }
- bool VEditArea::isFileOpened(const QString ¬ebook, const QString &relativePath)
- {
- return !findTabsByFile(notebook, relativePath).isEmpty();
- }
|