diff --git a/README.md b/README.md index 32438f01..b10f5c9a 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # vnote -A pleasant note-taking platform. +![CI-Windows](https://github.com/vnotex/vnote/workflows/CI-Windows/badge.svg) ![CI-Linux](https://github.com/vnotex/vnote/workflows/CI-Linux/badge.svg) ![CI-MacOS](https://github.com/vnotex/vnote/workflows/CI-MacOS/badge.svg) -![CI-Windows](https://github.com/vnotex/vnote/workflows/CI-Windows/badge.svg) ![CI-Linux](https://github.com/vnotex/vnote/workflows/CI-Linux/badge.svg) +A pleasant note-taking platform. > At early 2019, I decided to refactor VNote as VNoteX. Now a fresh VNote is ready! > VNoteX is closed source and is intended to keep several premium features compared to VNote. Most of VNoteX's code base will be open source as VNote 3.0, so VNote will share most of the code base with VNoteX and continue to be open source from 3.0. @@ -28,22 +28,24 @@ Utilizing Qt, VNote could run on **Linux**, **Windows**, and **macOS**. ## Downloads Continuous builds on `master` branch could be found at the [Continuous Build](https://github.com/vnotex/vnote/releases/tag/continuous-build) release. -Latest stable builds could be found at the [latest release](https://github.com/vnotex/vnote/releases/latest). +Latest stable builds could be found at the [latest release](https://github.com/vnotex/vnote/releases/latest). Alternative download services are available: + +* [Tianyi Netdisk](https://cloud.189.cn/t/Av67NvmEJVBv) ## Supports -- [GitHub Issues](https://github.com/vnotex/vnote/issues); -- Email: `tamlokveer at gmail.com`; -- [Slack](https://join.slack.com/t/vnote/shared_invite/enQtNDg2MzY0NDg3NzI4LTVhMzBlOTY0YzVhMmQyMTFmZDdhY2M3MDQxYTBjOTA2Y2IxOGRiZjg2NzdhMjkzYmUyY2VkMWJlZTNhMTQyODU); -- [Telegram](https://t.me/vnotex); -- WeChat Public Account: vnotex; +* [GitHub Issues](https://github.com/vnotex/vnote/issues); +* Email: `tamlokveer at gmail.com`; +* [Slack](https://join.slack.com/t/vnote/shared_invite/enQtNDg2MzY0NDg3NzI4LTVhMzBlOTY0YzVhMmQyMTFmZDdhY2M3MDQxYTBjOTA2Y2IxOGRiZjg2NzdhMjkzYmUyY2VkMWJlZTNhMTQyODU); +* [Telegram](https://t.me/vnotex); +* WeChat Public Account: vnotex; ## Donate You could help VNote's development in many ways. -- Keep monitoring VNote and sending feedback for improvement. -- Spread and promote VNote to your friends. Popularity is a strong power to drive developers. -- Participate in the development of VNote and send [Pull Request](https://github.com/vnotex/vnote/pulls) to make VNote perfect. -- Last, really appreciate your donate to VNote if VNote does help. +* Keep monitoring VNote and sending feedback for improvement. +* Spread and promote VNote to your friends. Popularity is a strong power to drive developers. +* Participate in the development of VNote and send [Pull Request](https://github.com/vnotex/vnote/pulls) to make VNote perfect. +* Last, really appreciate your donate to VNote if VNote does help. **PayPal**: [PayPal.Me/vnotemd](https://www.paypal.me/vnotemd) diff --git a/src/data/core/core.qrc b/src/data/core/core.qrc index 4287b954..e348781a 100644 --- a/src/data/core/core.qrc +++ b/src/data/core/core.qrc @@ -7,6 +7,7 @@ icons/import_notebook.svg icons/import_notebook_of_vnote2.svg icons/new_notebook.svg + icons/notebook_menu.svg icons/new_notebook_from_folder.svg icons/discard_editor.svg icons/edit_editor.svg @@ -19,7 +20,10 @@ icons/help.svg icons/menu.svg icons/settings.svg + icons/settings_menu.svg icons/whatsthis.svg + icons/help_menu.svg + icons/import_export_menu.svg icons/native_notebook_default.svg icons/notebook_default.svg icons/file_node.svg diff --git a/src/data/core/icons/help_menu.svg b/src/data/core/icons/help_menu.svg new file mode 100644 index 00000000..8494d36f --- /dev/null +++ b/src/data/core/icons/help_menu.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/src/data/core/icons/import_export_menu.svg b/src/data/core/icons/import_export_menu.svg new file mode 100644 index 00000000..cfdda573 --- /dev/null +++ b/src/data/core/icons/import_export_menu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/data/core/icons/notebook_menu.svg b/src/data/core/icons/notebook_menu.svg new file mode 100644 index 00000000..f7ba80b7 --- /dev/null +++ b/src/data/core/icons/notebook_menu.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/src/data/core/icons/settings_menu.svg b/src/data/core/icons/settings_menu.svg new file mode 100644 index 00000000..734a2747 --- /dev/null +++ b/src/data/core/icons/settings_menu.svg @@ -0,0 +1,18 @@ + + + + + + diff --git a/src/widgets/mainwindow.cpp b/src/widgets/mainwindow.cpp index d2822a54..803092e3 100644 --- a/src/widgets/mainwindow.cpp +++ b/src/widgets/mainwindow.cpp @@ -49,6 +49,10 @@ MainWindow::MainWindow(QWidget *p_parent) loadStateAndGeometry(); +#if defined(Q_OS_MACOS) || defined(Q_OS_MAC) + QApplication::setQuitOnLastWindowClosed(false); +#endif + connect(qApp, &QCoreApplication::aboutToQuit, this, &MainWindow::closeOnQuit); } diff --git a/src/widgets/markdownviewwindow.cpp b/src/widgets/markdownviewwindow.cpp index d8d8717e..de2817d1 100644 --- a/src/widgets/markdownviewwindow.cpp +++ b/src/widgets/markdownviewwindow.cpp @@ -279,8 +279,6 @@ void MarkdownViewWindow::setupToolBar() addAction(toolBar, ViewWindowToolBarHelper::TypeImage); addAction(toolBar, ViewWindowToolBarHelper::TypeTable); - toolBar->addSeparator(); - ToolBarHelper::addSpacer(toolBar); addAction(toolBar, ViewWindowToolBarHelper::FindAndReplace); addAction(toolBar, ViewWindowToolBarHelper::Outline); diff --git a/src/widgets/notebookexplorer.cpp b/src/widgets/notebookexplorer.cpp index 1a496d0e..94bf9998 100644 --- a/src/widgets/notebookexplorer.cpp +++ b/src/widgets/notebookexplorer.cpp @@ -77,59 +77,6 @@ TitleBar *NotebookExplorer::setupTitleBar(QWidget *p_parent) p_parent); titleBar->setWhatsThis(tr("This title bar contains buttons and menu to manage notebooks and notes.")); - titleBar->addMenuSeparator(); - auto newNoteAct = titleBar->addMenuAction(QStringLiteral("new_note.svg"), - tr("New N&ote"), - titleBar, - []() { - emit VNoteX::getInst().newNoteRequested(); - }); - WidgetUtils::addActionShortcutText(newNoteAct, - ConfigMgr::getInst().getCoreConfig().getShortcut(CoreConfig::Shortcut::NewNote)); - - titleBar->addMenuSeparator(); - auto newFolderAct = titleBar->addMenuAction(QStringLiteral("new_folder.svg"), - tr("New &Folder"), - titleBar, - []() { - emit VNoteX::getInst().newFolderRequested(); - }); - - connect(this, &NotebookExplorer::updateTitleBarMenuActions, - this, [=]() { - newFolderAct->setEnabled(m_currentNotebook); - newNoteAct->setEnabled(m_currentNotebook); - }); - - titleBar->addMenuSeparator(); - titleBar->addMenuAction(QStringLiteral("new_notebook.svg"), - tr("New &Notebook"), - titleBar, - []() { - emit VNoteX::getInst().newNotebookRequested(); - }); - - titleBar->addMenuAction(QStringLiteral("new_notebook_from_folder.svg"), - tr("N&ew Notebook From Folder"), - titleBar, - []() { - emit VNoteX::getInst().newNotebookFromFolderRequested(); - }); - - titleBar->addMenuAction(QStringLiteral("import_notebook.svg"), - tr("&Import Notebook"), - titleBar, - []() { - emit VNoteX::getInst().importNotebookRequested(); - }); - - titleBar->addMenuAction(QStringLiteral("import_notebook_of_vnote2.svg"), - tr("Import Legacy Notebook Of &VNote 2.0"), - titleBar, - []() { - emit VNoteX::getInst().importLegacyNotebookRequested(); - }); - titleBar->addMenuAction(QStringLiteral("manage_notebooks.svg"), tr("&Manage Notebooks"), titleBar, @@ -139,19 +86,6 @@ TitleBar *NotebookExplorer::setupTitleBar(QWidget *p_parent) dialog.exec(); }); - titleBar->addMenuSeparator(); - titleBar->addMenuAction(tr("Import File"), - titleBar, - [this]() { - emit VNoteX::getInst().importFileRequested(); - }); - - titleBar->addMenuAction(tr("Import Folder"), - titleBar, - [this]() { - emit VNoteX::getInst().importFolderRequested(); - }); - return titleBar; } diff --git a/src/widgets/textviewwindow.cpp b/src/widgets/textviewwindow.cpp index 8a8f0c54..4de19a0f 100644 --- a/src/widgets/textviewwindow.cpp +++ b/src/widgets/textviewwindow.cpp @@ -65,8 +65,6 @@ void TextViewWindow::setupToolBar() addAction(toolBar, ViewWindowToolBarHelper::Attachment); - toolBar->addSeparator(); - ToolBarHelper::addSpacer(toolBar); addAction(toolBar, ViewWindowToolBarHelper::FindAndReplace); } diff --git a/src/widgets/toolbarhelper.cpp b/src/widgets/toolbarhelper.cpp index 95e5f4de..e4c1322c 100644 --- a/src/widgets/toolbarhelper.cpp +++ b/src/widgets/toolbarhelper.cpp @@ -20,6 +20,7 @@ #include #include #include +#include "propertydefs.h" #include "dialogs/settings/settingsdialog.h" using namespace vnotex; @@ -39,7 +40,53 @@ QToolBar *ToolBarHelper::setupFileToolBar(MainWindow *p_win, QToolBar *p_toolBar tb = createToolBar(p_win, MainWindow::tr("File"), "FileToolBar"); } - // New. + // Notebook. + { + auto act = tb->addAction(generateIcon("notebook_menu.svg"), MainWindow::tr("Notebook")); + + auto toolBtn = dynamic_cast(tb->widgetForAction(act)); + Q_ASSERT(toolBtn); + toolBtn->setPopupMode(QToolButton::InstantPopup); + toolBtn->setProperty(PropertyDefs::s_toolButtonWithoutMenuIndicator, true); + + auto newMenu = WidgetsFactory::createMenu(tb); + toolBtn->setMenu(newMenu); + + newMenu->addAction(generateIcon("new_notebook.svg"), + MainWindow::tr("New Notebook"), + newMenu, + []() { + emit VNoteX::getInst().newNotebookRequested(); + }); + + // New notebook from folder. + newMenu->addAction(generateIcon("new_notebook_from_folder.svg"), + MainWindow::tr("New Notebook From Folder"), + newMenu, + []() { + emit VNoteX::getInst().newNotebookFromFolderRequested(); + }); + + newMenu->addSeparator(); + + // Import notebook. + newMenu->addAction(generateIcon("import_notebook.svg"), + MainWindow::tr("Import Notebook"), + newMenu, + []() { + emit VNoteX::getInst().importNotebookRequested(); + }); + + // Import notebook of VNote 2.0. + newMenu->addAction(generateIcon("import_notebook_of_vnote2.svg"), + MainWindow::tr("Import Legacy Notebook Of VNote 2.0"), + newMenu, + []() { + emit VNoteX::getInst().importLegacyNotebookRequested(); + }); + } + + // New Note. { const auto &coreConfig = ConfigMgr::getInst().getCoreConfig(); @@ -63,8 +110,6 @@ QToolBar *ToolBarHelper::setupFileToolBar(MainWindow *p_win, QToolBar *p_toolBar // To hide the shortcut text shown in button. newBtn->setText(MainWindow::tr("New Note")); - newMenu->addSeparator(); - // New folder. newMenu->addAction(generateIcon("new_folder.svg"), MainWindow::tr("New Folder"), @@ -75,56 +120,6 @@ QToolBar *ToolBarHelper::setupFileToolBar(MainWindow *p_win, QToolBar *p_toolBar newMenu->addSeparator(); - // New notebook. - newMenu->addAction(generateIcon("new_notebook.svg"), - MainWindow::tr("New Notebook"), - newMenu, - []() { - emit VNoteX::getInst().newNotebookRequested(); - }); - - // New notebook from folder. - newMenu->addAction(generateIcon("new_notebook_from_folder.svg"), - MainWindow::tr("New Notebook From Folder"), - newMenu, - []() { - emit VNoteX::getInst().newNotebookFromFolderRequested(); - }); - - // Import notebook. - newMenu->addAction(generateIcon("import_notebook.svg"), - MainWindow::tr("Import Notebook"), - newMenu, - []() { - emit VNoteX::getInst().importNotebookRequested(); - }); - - // Import notebook of VNote 2.0. - newMenu->addAction(generateIcon("import_notebook_of_vnote2.svg"), - MainWindow::tr("Import Legacy Notebook Of VNote 2.0"), - newMenu, - []() { - emit VNoteX::getInst().importLegacyNotebookRequested(); - }); - - newMenu->addSeparator(); - - // Import file. - newMenu->addAction(MainWindow::tr("Import File"), - newMenu, - []() { - emit VNoteX::getInst().importFileRequested(); - }); - - // Import folder. - newMenu->addAction(MainWindow::tr("Import Folder"), - newMenu, - []() { - emit VNoteX::getInst().importFolderRequested(); - }); - - newMenu->addSeparator(); - // Open file. newMenu->addAction(MainWindow::tr("Open File"), newMenu, @@ -147,6 +142,33 @@ QToolBar *ToolBarHelper::setupFileToolBar(MainWindow *p_win, QToolBar *p_toolBar tb->addWidget(newBtn); } + // Import and export. + { + auto act = tb->addAction(generateIcon("import_export_menu.svg"), MainWindow::tr("Import And Export")); + + auto btn = dynamic_cast(tb->widgetForAction(act)); + Q_ASSERT(btn); + btn->setPopupMode(QToolButton::InstantPopup); + btn->setProperty(PropertyDefs::s_toolButtonWithoutMenuIndicator, true); + + auto newMenu = WidgetsFactory::createMenu(tb); + btn->setMenu(newMenu); + + // Import file. + newMenu->addAction(MainWindow::tr("Import File"), + newMenu, + []() { + emit VNoteX::getInst().importFileRequested(); + }); + + // Import folder. + newMenu->addAction(MainWindow::tr("Import Folder"), + newMenu, + []() { + emit VNoteX::getInst().importFolderRequested(); + }); + } + return tb; } @@ -176,9 +198,11 @@ QToolBar *ToolBarHelper::setupSettingsToolBar(MainWindow *p_win, QToolBar *p_too auto btn = WidgetsFactory::createToolButton(tb); - auto expandAct = new QAction(generateIcon("expand.svg"), - MainWindow::tr("Expand Content Area"), - btn); + auto menu = WidgetsFactory::createMenu(tb); + btn->setMenu(menu); + + auto expandAct = menu->addAction(generateIcon("expand.svg"), + MainWindow::tr("Expand Content Area")); WidgetUtils::addActionShortcut(expandAct, coreConfig.getShortcut(CoreConfig::Shortcut::ExpandContentArea)); expandAct->setCheckable(true); @@ -190,9 +214,6 @@ QToolBar *ToolBarHelper::setupSettingsToolBar(MainWindow *p_win, QToolBar *p_too }); btn->setDefaultAction(expandAct); - auto menu = WidgetsFactory::createMenu(tb); - btn->setMenu(menu); - auto fullScreenAct = new FullScreenToggleAction(p_win, generateIcon("fullscreen.svg"), menu); @@ -221,7 +242,11 @@ QToolBar *ToolBarHelper::setupSettingsToolBar(MainWindow *p_win, QToolBar *p_too { const auto &coreConfig = ConfigMgr::getInst().getCoreConfig(); - auto btn = WidgetsFactory::createToolButton(tb); + auto act = tb->addAction(generateIcon("settings_menu.svg"), MainWindow::tr("Settings")); + auto btn = dynamic_cast(tb->widgetForAction(act)); + Q_ASSERT(btn); + btn->setPopupMode(QToolButton::InstantPopup); + btn->setProperty(PropertyDefs::s_toolButtonWithoutMenuIndicator, true); auto menu = WidgetsFactory::createMenu(tb); btn->setMenu(menu); @@ -235,7 +260,6 @@ QToolBar *ToolBarHelper::setupSettingsToolBar(MainWindow *p_win, QToolBar *p_too }); WidgetUtils::addActionShortcut(settingsAct, coreConfig.getShortcut(CoreConfig::Shortcut::Settings)); - btn->setDefaultAction(settingsAct); menu->addSeparator(); @@ -279,13 +303,15 @@ QToolBar *ToolBarHelper::setupSettingsToolBar(MainWindow *p_win, QToolBar *p_too [p_win]() { p_win->resetStateAndGeometry(); }); - - tb->addWidget(btn); } - // WhatsThis. + // Help. { - auto btn = WidgetsFactory::createToolButton(tb); + auto act = tb->addAction(generateIcon("help_menu.svg"), MainWindow::tr("Help")); + auto btn = dynamic_cast(tb->widgetForAction(act)); + Q_ASSERT(btn); + btn->setPopupMode(QToolButton::InstantPopup); + btn->setProperty(PropertyDefs::s_toolButtonWithoutMenuIndicator, true); auto menu = WidgetsFactory::createMenu(tb); btn->setMenu(menu); @@ -297,7 +323,6 @@ QToolBar *ToolBarHelper::setupSettingsToolBar(MainWindow *p_win, QToolBar *p_too QWhatsThis::enterWhatsThisMode(); }); whatsThisAct->setToolTip(MainWindow::tr("Enter WhatsThis mode and click somewhere to show help information")); - btn->setDefaultAction(whatsThisAct); menu->addSeparator(); @@ -327,6 +352,14 @@ QToolBar *ToolBarHelper::setupSettingsToolBar(MainWindow *p_win, QToolBar *p_too menu->addSeparator(); + menu->addAction(MainWindow::tr("Feedback And Discussions"), + menu, + []() { + WidgetUtils::openUrlByDesktop(QUrl("https://github.com/vnotex/vnote/discussions")); + }); + + menu->addSeparator(); + menu->addAction(MainWindow::tr("About"), menu, [p_win]() { @@ -340,8 +373,6 @@ QToolBar *ToolBarHelper::setupSettingsToolBar(MainWindow *p_win, QToolBar *p_too aboutQtAct->setMenuRole(QAction::AboutQtRole); MainWindow::connect(aboutQtAct, &QAction::triggered, qApp, &QApplication::aboutQt); - - tb->addWidget(btn); } return tb;