mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
713 lines
21 KiB
C++
713 lines
21 KiB
C++
#include "mainwindow.h"
|
|
|
|
#include <QFileInfo>
|
|
#include <QDebug>
|
|
#include <QResizeEvent>
|
|
#include <QSplitter>
|
|
#include <QDockWidget>
|
|
#include <QVariant>
|
|
#include <QTextEdit>
|
|
#include <QStatusBar>
|
|
#include <QCloseEvent>
|
|
#include <QVBoxLayout>
|
|
#include <QTabBar>
|
|
#include <QVariant>
|
|
#include <QCoreApplication>
|
|
#include <QApplication>
|
|
#include <QShortcut>
|
|
#include <QSystemTrayIcon>
|
|
#include <QWindowStateChangeEvent>
|
|
#include <QTimer>
|
|
|
|
#include "toolbox.h"
|
|
#include "notebookexplorer.h"
|
|
#include "vnotex.h"
|
|
#include "notebookmgr.h"
|
|
#include "buffermgr.h"
|
|
#include "viewarea.h"
|
|
#include <core/configmgr.h>
|
|
#include <core/sessionconfig.h>
|
|
#include <core/coreconfig.h>
|
|
#include <core/mainconfig.h>
|
|
#include <core/widgetconfig.h>
|
|
#include <core/events.h>
|
|
#include <core/fileopenparameters.h>
|
|
#include <widgets/dialogs/exportdialog.h>
|
|
#include "viewwindow.h"
|
|
#include "outlineviewer.h"
|
|
#include <utils/widgetutils.h>
|
|
#include "navigationmodemgr.h"
|
|
#include "messageboxhelper.h"
|
|
#include "systemtrayhelper.h"
|
|
#include "titletoolbar.h"
|
|
#include "locationlist.h"
|
|
#include "searchpanel.h"
|
|
#include "snippetpanel.h"
|
|
#include "historypanel.h"
|
|
#include <notebook/notebook.h>
|
|
#include "searchinfoprovider.h"
|
|
#include <vtextedit/spellchecker.h>
|
|
#include <utils/docsutils.h>
|
|
#include <utils/iconutils.h>
|
|
#include <core/thememgr.h>
|
|
#include "dialogs/updater.h"
|
|
|
|
using namespace vnotex;
|
|
|
|
MainWindow::MainWindow(QWidget *p_parent)
|
|
: QMainWindow(p_parent),
|
|
m_toolBarHelper(this),
|
|
m_statusBarHelper(this),
|
|
m_dockWidgetHelper(this)
|
|
{
|
|
VNoteX::getInst().setMainWindow(this);
|
|
|
|
NavigationModeMgr::init(this);
|
|
|
|
setupUI();
|
|
|
|
setupShortcuts();
|
|
|
|
loadStateAndGeometry();
|
|
|
|
m_dockWidgetHelper.postSetup();
|
|
|
|
// The signal is particularly useful if your application has to do some last-second cleanup.
|
|
// Note that no user interaction is possible in this state.
|
|
connect(qApp, &QCoreApplication::aboutToQuit,
|
|
this, &MainWindow::closeOnQuit);
|
|
|
|
connect(&VNoteX::getInst(), &VNoteX::exportRequested,
|
|
this, &MainWindow::exportNotes);
|
|
}
|
|
|
|
MainWindow::~MainWindow()
|
|
{
|
|
// Should be desturcted before status bar.
|
|
delete m_viewArea;
|
|
m_viewArea = nullptr;
|
|
}
|
|
|
|
void MainWindow::kickOffOnStart(const QStringList &p_paths)
|
|
{
|
|
QTimer::singleShot(300, [this, p_paths]() {
|
|
// Need to load the state of dock widgets again after the main window is shown.
|
|
loadStateAndGeometry(true);
|
|
|
|
VNoteX::getInst().initLoad();
|
|
|
|
setupSpellCheck();
|
|
|
|
// Do necessary stuffs before emitting this signal.
|
|
emit mainWindowStarted();
|
|
|
|
emit layoutChanged();
|
|
|
|
checkNotebooksFailedToLoad();
|
|
|
|
demoWidget();
|
|
|
|
openFiles(p_paths);
|
|
|
|
if (MainConfig::isVersionChanged()) {
|
|
const auto file = DocsUtils::getDocFile(QStringLiteral("welcome.md"));
|
|
if (!file.isEmpty()) {
|
|
auto paras = QSharedPointer<FileOpenParameters>::create();
|
|
paras->m_readOnly = true;
|
|
emit VNoteX::getInst().openFileRequested(file, paras);
|
|
}
|
|
}
|
|
|
|
if (ConfigMgr::getInst().getCoreConfig().isCheckForUpdatesOnStartEnabled()) {
|
|
QTimer::singleShot(5 * 60 * 1000, this, &MainWindow::checkForUpdates);
|
|
}
|
|
});
|
|
}
|
|
|
|
void MainWindow::openFiles(const QStringList &p_files)
|
|
{
|
|
for (const auto &file : p_files) {
|
|
emit VNoteX::getInst().openFileRequested(file, QSharedPointer<FileOpenParameters>::create());
|
|
}
|
|
}
|
|
|
|
void MainWindow::setupUI()
|
|
{
|
|
setupCentralWidget();
|
|
setupDocks();
|
|
setupToolBar();
|
|
setupStatusBar();
|
|
setupTipsArea();
|
|
setupSystemTray();
|
|
|
|
m_dockWidgetHelper.activateDock(DockWidgetHelper::NavigationDock);
|
|
}
|
|
|
|
void MainWindow::setupStatusBar()
|
|
{
|
|
m_statusBarHelper.setupStatusBar();
|
|
connect(&VNoteX::getInst(), &VNoteX::statusMessageRequested,
|
|
statusBar(), &QStatusBar::showMessage);
|
|
}
|
|
|
|
void MainWindow::setupTipsArea()
|
|
{
|
|
connect(&VNoteX::getInst(), &VNoteX::tipsRequested,
|
|
this, &MainWindow::showTips);
|
|
}
|
|
|
|
void MainWindow::createTipsArea()
|
|
{
|
|
if (m_tipsLabel) {
|
|
return;
|
|
}
|
|
|
|
m_tipsLabel = new QLabel(this);
|
|
m_tipsLabel->setObjectName("MainWindowTipsLabel");
|
|
m_tipsLabel->hide();
|
|
|
|
m_tipsTimer = new QTimer(this);
|
|
m_tipsTimer->setSingleShot(true);
|
|
m_tipsTimer->setInterval(3000);
|
|
connect(m_tipsTimer, &QTimer::timeout,
|
|
this, [this]() {
|
|
setTipsAreaVisible(false);
|
|
});
|
|
}
|
|
|
|
void MainWindow::setupCentralWidget()
|
|
{
|
|
m_viewArea = new ViewArea(this);
|
|
NavigationModeMgr::getInst().registerNavigationTarget(m_viewArea);
|
|
connect(&VNoteX::getInst().getBufferMgr(), &BufferMgr::bufferRequested,
|
|
m_viewArea, &ViewArea::openBuffer);
|
|
|
|
connect(m_viewArea, &ViewArea::statusWidgetChanged,
|
|
this, [this](QWidget *p_widget) {
|
|
if (m_viewAreaStatusWidget) {
|
|
// Will hide it.
|
|
statusBar()->removeWidget(m_viewAreaStatusWidget);
|
|
}
|
|
|
|
m_viewAreaStatusWidget = p_widget;
|
|
if (m_viewAreaStatusWidget) {
|
|
statusBar()->addPermanentWidget(m_viewAreaStatusWidget);
|
|
m_viewAreaStatusWidget->show();
|
|
}
|
|
});
|
|
connect(m_viewArea, &ViewArea::currentViewWindowChanged,
|
|
this, [this]() {
|
|
setWindowTitle(getViewAreaTitle());
|
|
});
|
|
connect(m_viewArea, &ViewArea::currentViewWindowUpdated,
|
|
this, [this]() {
|
|
setWindowTitle(getViewAreaTitle());
|
|
});
|
|
|
|
{
|
|
auto ¬ebookMgr = VNoteX::getInst().getNotebookMgr();
|
|
connect(¬ebookMgr, &NotebookMgr::notebookAboutToClose,
|
|
this, [this](const Notebook *p_notebook) {
|
|
m_viewArea->close(p_notebook, true);
|
|
});
|
|
connect(¬ebookMgr, &NotebookMgr::notebookAboutToRemove,
|
|
this, [this](const Notebook *p_notebook) {
|
|
m_viewArea->close(p_notebook, true);
|
|
});
|
|
}
|
|
|
|
setCentralWidget(m_viewArea);
|
|
}
|
|
|
|
void MainWindow::setupDocks()
|
|
{
|
|
setupNotebookExplorer(this);
|
|
|
|
setupOutlineViewer();
|
|
|
|
setupHistoryPanel();
|
|
|
|
setupSearchPanel();
|
|
|
|
setupSnippetPanel();
|
|
|
|
setupLocationList();
|
|
|
|
m_dockWidgetHelper.setupDocks();
|
|
|
|
NavigationModeMgr::getInst().registerNavigationTarget(&m_dockWidgetHelper);
|
|
}
|
|
|
|
void MainWindow::setupSearchPanel()
|
|
{
|
|
m_searchPanel = new SearchPanel(
|
|
QSharedPointer<SearchInfoProvider>::create(m_viewArea,
|
|
m_notebookExplorer,
|
|
&VNoteX::getInst().getNotebookMgr()),
|
|
this);
|
|
m_searchPanel->setObjectName("SearchPanel.vnotex");
|
|
}
|
|
|
|
void MainWindow::setupSnippetPanel()
|
|
{
|
|
m_snippetPanel = new SnippetPanel(this);
|
|
m_snippetPanel->setObjectName("SnippetPanel.vnotex");
|
|
connect(m_snippetPanel, &SnippetPanel::applySnippetRequested,
|
|
this, [this](const QString &p_name) {
|
|
auto viewWindow = m_viewArea->getCurrentViewWindow();
|
|
if (viewWindow) {
|
|
viewWindow->applySnippet(p_name);
|
|
viewWindow->setFocus();
|
|
}
|
|
});
|
|
}
|
|
|
|
void MainWindow::setupHistoryPanel()
|
|
{
|
|
m_historyPanel = new HistoryPanel(this);
|
|
m_historyPanel->setObjectName("HistoryPanel.vnotex");
|
|
}
|
|
|
|
void MainWindow::setupLocationList()
|
|
{
|
|
m_locationList = new LocationList(this);
|
|
m_locationList->setObjectName("LocationList.vnotex");
|
|
|
|
NavigationModeMgr::getInst().registerNavigationTarget(m_locationList->getNavigationModeWrapper());
|
|
}
|
|
|
|
void MainWindow::setupNotebookExplorer(QWidget *p_parent)
|
|
{
|
|
m_notebookExplorer = new NotebookExplorer(p_parent);
|
|
connect(&VNoteX::getInst(), &VNoteX::newNotebookRequested,
|
|
m_notebookExplorer, &NotebookExplorer::newNotebook);
|
|
connect(&VNoteX::getInst(), &VNoteX::newNotebookFromFolderRequested,
|
|
m_notebookExplorer, &NotebookExplorer::newNotebookFromFolder);
|
|
connect(&VNoteX::getInst(), &VNoteX::importNotebookRequested,
|
|
m_notebookExplorer, &NotebookExplorer::importNotebook);
|
|
connect(&VNoteX::getInst(), &VNoteX::newFolderRequested,
|
|
m_notebookExplorer, &NotebookExplorer::newFolder);
|
|
connect(&VNoteX::getInst(), &VNoteX::newNoteRequested,
|
|
m_notebookExplorer, &NotebookExplorer::newNote);
|
|
connect(&VNoteX::getInst(), &VNoteX::importFileRequested,
|
|
m_notebookExplorer, &NotebookExplorer::importFile);
|
|
connect(&VNoteX::getInst(), &VNoteX::importFolderRequested,
|
|
m_notebookExplorer, &NotebookExplorer::importFolder);
|
|
connect(&VNoteX::getInst(), &VNoteX::importLegacyNotebookRequested,
|
|
m_notebookExplorer, &NotebookExplorer::importLegacyNotebook);
|
|
connect(&VNoteX::getInst(), &VNoteX::locateNodeRequested,
|
|
this, [this](Node *p_node) {
|
|
m_dockWidgetHelper.activateDock(DockWidgetHelper::NavigationDock);
|
|
m_notebookExplorer->locateNode(p_node);
|
|
});
|
|
|
|
auto ¬ebookMgr = VNoteX::getInst().getNotebookMgr();
|
|
connect(¬ebookMgr, &NotebookMgr::notebooksUpdated,
|
|
m_notebookExplorer, &NotebookExplorer::loadNotebooks);
|
|
connect(¬ebookMgr, &NotebookMgr::notebookUpdated,
|
|
m_notebookExplorer, &NotebookExplorer::reloadNotebook);
|
|
connect(¬ebookMgr, &NotebookMgr::currentNotebookChanged,
|
|
m_notebookExplorer, &NotebookExplorer::setCurrentNotebook);
|
|
connect(m_notebookExplorer, &NotebookExplorer::notebookActivated,
|
|
¬ebookMgr, &NotebookMgr::setCurrentNotebook);
|
|
}
|
|
|
|
void MainWindow::closeEvent(QCloseEvent *p_event)
|
|
{
|
|
const int toTray = ConfigMgr::getInst().getSessionConfig().getMinimizeToSystemTray();
|
|
bool isExit = m_requestQuit > -1 || toTray == 0;
|
|
const int exitCode = m_requestQuit;
|
|
m_requestQuit = -1;
|
|
|
|
#if defined(Q_OS_MACOS)
|
|
// Do not support minimized to tray on macOS.
|
|
isExit = true;
|
|
#endif
|
|
|
|
bool needShowMessage = false;
|
|
if(!isExit && toTray == -1){
|
|
int ret = MessageBoxHelper::questionYesNo(MessageBoxHelper::Question,
|
|
tr("Do you want to minimize %1 to system tray "
|
|
"instead of quitting when closed?").arg(qApp->applicationName()),
|
|
tr("You could change the option in Settings later."),
|
|
QString(),
|
|
this);
|
|
if (ret == QMessageBox::Yes) {
|
|
ConfigMgr::getInst().getSessionConfig().setMinimizeToSystemTray(true);
|
|
needShowMessage = true;
|
|
} else if (ret == QMessageBox::No) {
|
|
ConfigMgr::getInst().getSessionConfig().setMinimizeToSystemTray(false);
|
|
isExit = true;
|
|
} else {
|
|
p_event->ignore();
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (isVisible()) {
|
|
saveStateAndGeometry();
|
|
}
|
|
|
|
if (isExit || !m_trayIcon->isVisible()) {
|
|
// Signal out the close event.
|
|
auto event = QSharedPointer<Event>::create();
|
|
event->m_response = true;
|
|
emit mainWindowClosed(event);
|
|
if (!event->m_response.toBool()) {
|
|
// Stop the close.
|
|
p_event->ignore();
|
|
return;
|
|
}
|
|
|
|
QMainWindow::closeEvent(p_event);
|
|
qApp->exit(exitCode > -1 ? exitCode : 0);
|
|
} else {
|
|
hide();
|
|
p_event->ignore();
|
|
if (needShowMessage) {
|
|
m_trayIcon->showMessage(ConfigMgr::c_appName, tr("%1 is still running here.").arg(ConfigMgr::c_appName));
|
|
}
|
|
}
|
|
}
|
|
|
|
void MainWindow::saveStateAndGeometry()
|
|
{
|
|
if (m_layoutReset) {
|
|
return;
|
|
}
|
|
|
|
SessionConfig::MainWindowStateGeometry sg;
|
|
sg.m_mainState = saveState();
|
|
sg.m_mainGeometry = saveGeometry();
|
|
sg.m_visibleDocksBeforeExpand = m_visibleDocksBeforeExpand;
|
|
|
|
auto& sessionConfig = ConfigMgr::getInst().getSessionConfig();
|
|
sessionConfig.setMainWindowStateGeometry(sg);
|
|
}
|
|
|
|
void MainWindow::loadStateAndGeometry(bool p_stateOnly)
|
|
{
|
|
const auto& sessionConfig = ConfigMgr::getInst().getSessionConfig();
|
|
const auto sg = sessionConfig.getMainWindowStateGeometry();
|
|
|
|
if (!p_stateOnly && !sg.m_mainGeometry.isEmpty()) {
|
|
restoreGeometry(sg.m_mainGeometry);
|
|
}
|
|
|
|
if (!sg.m_mainState.isEmpty()) {
|
|
// Will also restore the state of dock widgets.
|
|
restoreState(sg.m_mainState);
|
|
}
|
|
|
|
if (!p_stateOnly) {
|
|
m_visibleDocksBeforeExpand = sg.m_visibleDocksBeforeExpand;
|
|
if (m_visibleDocksBeforeExpand.isEmpty()) {
|
|
// Init (or init again if there is no visible dock).
|
|
m_visibleDocksBeforeExpand = m_dockWidgetHelper.getVisibleDocks();
|
|
}
|
|
}
|
|
}
|
|
|
|
void MainWindow::resetStateAndGeometry()
|
|
{
|
|
if (m_layoutReset) {
|
|
return;
|
|
}
|
|
|
|
m_layoutReset = true;
|
|
SessionConfig::MainWindowStateGeometry sg;
|
|
auto& sessionConfig = ConfigMgr::getInst().getSessionConfig();
|
|
sessionConfig.setMainWindowStateGeometry(sg);
|
|
}
|
|
|
|
void MainWindow::setContentAreaExpanded(bool p_expanded)
|
|
{
|
|
if (p_expanded) {
|
|
// Store the state and hide.
|
|
m_visibleDocksBeforeExpand = m_dockWidgetHelper.hideDocks();
|
|
} else {
|
|
// Restore the state.
|
|
m_dockWidgetHelper.restoreDocks(m_visibleDocksBeforeExpand);
|
|
}
|
|
}
|
|
|
|
bool MainWindow::isContentAreaExpanded() const
|
|
{
|
|
return !m_dockWidgetHelper.isAnyDockVisible();
|
|
}
|
|
|
|
void MainWindow::demoWidget()
|
|
{
|
|
}
|
|
|
|
QString MainWindow::getViewAreaTitle() const
|
|
{
|
|
QString title;
|
|
const auto win = m_viewArea->getCurrentViewWindow();
|
|
if (win) {
|
|
title = win->getName();
|
|
}
|
|
return title.isEmpty() ? QString() : QString("%1 - %2").arg(title, ConfigMgr::c_appName);
|
|
}
|
|
|
|
void MainWindow::setupOutlineViewer()
|
|
{
|
|
// Do not provide title here since there is one in the dock title.
|
|
m_outlineViewer = new OutlineViewer(QString(), this);
|
|
m_outlineViewer->setObjectName("OutlineViewer.vnotex");
|
|
|
|
NavigationModeMgr::getInst().registerNavigationTarget(m_outlineViewer->getNavigationModeWrapper());
|
|
|
|
connect(m_viewArea, &ViewArea::currentViewWindowChanged,
|
|
this, [this]() {
|
|
auto win = m_viewArea->getCurrentViewWindow();
|
|
m_outlineViewer->setOutlineProvider(win ? win->getOutlineProvider() : nullptr);
|
|
});
|
|
connect(m_outlineViewer, &OutlineViewer::focusViewArea,
|
|
this, &MainWindow::focusViewArea);
|
|
}
|
|
|
|
const QVector<QDockWidget *> &MainWindow::getDocks() const
|
|
{
|
|
return m_dockWidgetHelper.getDocks();
|
|
}
|
|
|
|
void MainWindow::focusViewArea()
|
|
{
|
|
m_viewArea->focus();
|
|
}
|
|
|
|
void MainWindow::setupToolBar()
|
|
{
|
|
const int sz = ConfigMgr::getInst().getCoreConfig().getToolBarIconSize();
|
|
const QSize iconSize(sz, sz);
|
|
if (!ConfigMgr::getInst().getSessionConfig().getSystemTitleBarEnabled()) {
|
|
// Use unified tool bar as title bar.
|
|
auto framelessFlags = Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint
|
|
| Qt::WindowCloseButtonHint | Qt::WindowFullscreenButtonHint;
|
|
|
|
auto winFlags = windowFlags();
|
|
winFlags |= Qt::CustomizeWindowHint | Qt::FramelessWindowHint;
|
|
winFlags &= ~framelessFlags;
|
|
setWindowFlags(winFlags);
|
|
|
|
auto toolBar = new TitleToolBar(tr("Global"), this);
|
|
toolBar->setIconSize(iconSize);
|
|
m_toolBarHelper.setupToolBars(toolBar);
|
|
toolBar->addTitleBarIcons(ToolBarHelper::generateIcon(QStringLiteral("minimize.svg")),
|
|
ToolBarHelper::generateIcon(QStringLiteral("maximize.svg")),
|
|
ToolBarHelper::generateIcon(QStringLiteral("maximize_restore.svg")),
|
|
ToolBarHelper::generateDangerousIcon(QStringLiteral("close.svg")));
|
|
} else {
|
|
auto toolBar = new QToolBar(tr("Global"), this);
|
|
toolBar->setIconSize(iconSize);
|
|
m_toolBarHelper.setupToolBars(toolBar);
|
|
}
|
|
|
|
// Disable the context menu above tool bar.
|
|
setContextMenuPolicy(Qt::NoContextMenu);
|
|
}
|
|
|
|
void MainWindow::closeOnQuit()
|
|
{
|
|
// No user interaction is available.
|
|
emit mainWindowClosedOnQuit();
|
|
}
|
|
|
|
void MainWindow::setupShortcuts()
|
|
{
|
|
}
|
|
|
|
void MainWindow::setStayOnTop(bool p_enabled)
|
|
{
|
|
bool shown = isVisible();
|
|
Qt::WindowFlags flags = windowFlags();
|
|
|
|
const Qt::WindowFlags magicFlag = Qt::WindowStaysOnTopHint;
|
|
if (p_enabled) {
|
|
setWindowFlags(flags | magicFlag);
|
|
} else {
|
|
setWindowFlags(flags ^ magicFlag);
|
|
}
|
|
|
|
if (shown) {
|
|
show();
|
|
}
|
|
}
|
|
|
|
void MainWindow::setupSystemTray()
|
|
{
|
|
m_trayIcon = SystemTrayHelper::setupSystemTray(this);
|
|
m_trayIcon->show();
|
|
}
|
|
|
|
void MainWindow::restart()
|
|
{
|
|
m_requestQuit = RESTART_EXIT_CODE;
|
|
close();
|
|
}
|
|
|
|
void MainWindow::changeEvent(QEvent *p_event)
|
|
{
|
|
if (p_event->type() == QEvent::WindowStateChange) {
|
|
QWindowStateChangeEvent *eve = static_cast<QWindowStateChangeEvent *>(p_event);
|
|
m_windowOldState = eve->oldState();
|
|
}
|
|
|
|
QMainWindow::changeEvent(p_event);
|
|
}
|
|
|
|
void MainWindow::showMainWindow()
|
|
{
|
|
if (isMinimized()) {
|
|
if (m_windowOldState & Qt::WindowMaximized) {
|
|
showMaximized();
|
|
} else if (m_windowOldState & Qt::WindowFullScreen) {
|
|
showFullScreen();
|
|
} else {
|
|
showNormal();
|
|
}
|
|
} else {
|
|
show();
|
|
// Need to call raise() in macOS.
|
|
raise();
|
|
}
|
|
|
|
activateWindow();
|
|
}
|
|
|
|
void MainWindow::quitApp()
|
|
{
|
|
m_requestQuit = 0;
|
|
close();
|
|
}
|
|
|
|
void MainWindow::updateDockWidgetTabBar()
|
|
{
|
|
m_dockWidgetHelper.updateDockWidgetTabBar();
|
|
}
|
|
|
|
void MainWindow::exportNotes()
|
|
{
|
|
auto currentNotebook = m_notebookExplorer->currentNotebook().data();
|
|
auto viewWindow = m_viewArea->getCurrentViewWindow();
|
|
auto folderNode = m_notebookExplorer->currentExploredFolderNode();
|
|
if (folderNode && (folderNode->isRoot() || currentNotebook->isRecycleBinNode(folderNode))) {
|
|
folderNode = nullptr;
|
|
}
|
|
auto noteNode = m_notebookExplorer->currentExploredNode();
|
|
if (noteNode && !noteNode->hasContent()) {
|
|
noteNode = nullptr;
|
|
}
|
|
auto dialog = new ExportDialog(currentNotebook,
|
|
folderNode,
|
|
noteNode,
|
|
viewWindow ? viewWindow->getBuffer() : nullptr,
|
|
nullptr);
|
|
connect(dialog, &QDialog::finished,
|
|
this, [this, dialog]() {
|
|
dialog->deleteLater();
|
|
});
|
|
// Let it be able to run at background.
|
|
dialog->show();
|
|
}
|
|
|
|
void MainWindow::showTips(const QString &p_message, int p_timeoutMilliseconds)
|
|
{
|
|
createTipsArea();
|
|
|
|
m_tipsTimer->stop();
|
|
|
|
setTipsAreaVisible(false);
|
|
|
|
if (p_message.isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
m_tipsLabel->setText(p_message);
|
|
setTipsAreaVisible(true);
|
|
|
|
m_tipsTimer->start(p_timeoutMilliseconds);
|
|
}
|
|
|
|
void MainWindow::setTipsAreaVisible(bool p_visible)
|
|
{
|
|
Q_ASSERT(m_tipsLabel);
|
|
if (p_visible) {
|
|
m_tipsLabel->adjustSize();
|
|
int labelW = m_tipsLabel->width();
|
|
int labelH = m_tipsLabel->height();
|
|
int x = (width() - labelW) / 2;
|
|
int y = (height() - labelH) / 2;
|
|
if (x < 0) {
|
|
x = 0;
|
|
}
|
|
if (y < 0) {
|
|
y = 0;
|
|
}
|
|
|
|
m_tipsLabel->move(x, y);
|
|
m_tipsLabel->show();
|
|
} else {
|
|
m_tipsLabel->hide();
|
|
}
|
|
}
|
|
|
|
LocationList *MainWindow::getLocationList() const
|
|
{
|
|
return m_locationList;
|
|
}
|
|
|
|
void MainWindow::setLocationListVisible(bool p_visible)
|
|
{
|
|
if (p_visible) {
|
|
m_dockWidgetHelper.activateDock(DockWidgetHelper::LocationListDock);
|
|
} else {
|
|
m_dockWidgetHelper.getDock(DockWidgetHelper::LocationListDock)->hide();
|
|
}
|
|
}
|
|
|
|
void MainWindow::toggleLocationListVisible()
|
|
{
|
|
bool visible = m_dockWidgetHelper.getDock(DockWidgetHelper::LocationListDock)->isVisible();
|
|
setLocationListVisible(!visible);
|
|
}
|
|
|
|
void MainWindow::setupSpellCheck()
|
|
{
|
|
const auto &configMgr = ConfigMgr::getInst();
|
|
vte::SpellChecker::addDictionaryCustomSearchPaths(
|
|
QStringList() << configMgr.getUserDictsFolder() << configMgr.getAppDictsFolder());
|
|
}
|
|
|
|
void MainWindow::checkForUpdates()
|
|
{
|
|
Updater::checkForUpdates(this, [this](bool p_hasUpdate, const QString &p_version, const QString &p_errMsg) {
|
|
if (p_version.isEmpty()) {
|
|
statusBar()->showMessage(tr("Failed to check for updates (%1)").arg(p_errMsg), 3000);
|
|
} else if (p_hasUpdate) {
|
|
statusBar()->showMessage(tr("Updates available: %1").arg(p_version));
|
|
}
|
|
});
|
|
}
|
|
|
|
void MainWindow::checkNotebooksFailedToLoad()
|
|
{
|
|
auto ¬ebookMgr = VNoteX::getInst().getNotebookMgr();
|
|
const auto ¬ebooks = notebookMgr.getNotebooksFailedToLoad();
|
|
if (notebooks.isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
int ret = MessageBoxHelper::questionYesNo(MessageBoxHelper::Warning,
|
|
tr("Failed to load %n notebook(s).", "", notebooks.size()),
|
|
tr("These notebooks may be moved or deleted. It is recommended to remove "
|
|
"them from configuration and open them with the correct root folder path later.\n"
|
|
"Remove them from the configuration?"),
|
|
notebooks.join(QLatin1Char('\n')),
|
|
this);
|
|
if (ret == QMessageBox::Yes) {
|
|
notebookMgr.clearNotebooksFailedToLoad();
|
|
}
|
|
}
|