vnote/src/veditarea.cpp
Le Tan 29a41e8285 change VEditor to VEditTab
Signed-off-by: Le Tan <tamlokveer@gmail.com>
2016-11-06 14:12:09 +08:00

281 lines
7.2 KiB
C++

#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);
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);
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 &notebook, 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 &notebook, 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 tab status
noticeTabStatus();
}
void VEditArea::noticeTabStatus()
{
QString notebook, relativePath;
bool editMode, modifiable;
getWindow(curWindowIndex)->getTabStatus(notebook, relativePath, editMode, modifiable);
emit curTabStatusChanged(notebook, relativePath, editMode, modifiable);
}
void VEditArea::closeFile(QJsonObject fileJson)
{
if (fileJson.isEmpty()) {
return;
}
QString notebook = fileJson["notebook"].toString();
QString relativePath = fileJson["relative_path"].toString();
int nrWin = splitter->count();
for (int i = 0; i < nrWin; ++i) {
VEditWindow *win = getWindow(i);
win->closeFile(notebook, relativePath);
}
}
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> &notebooks,
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);
}
}
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;
}
}
}