From b4bbefa5aff9298f73f2885caed37844aeda4ac8 Mon Sep 17 00:00:00 2001 From: ShaopengLin Date: Sun, 28 Jul 2024 15:18:13 -0400 Subject: [PATCH 1/5] Add reading list export Added Menu button to export reading list to file --- resources/i18n/en.json | 4 +++- resources/i18n/qqq.json | 4 +++- src/kiwixapp.cpp | 2 ++ src/kiwixapp.h | 1 + src/mainmenu.cpp | 1 + src/readinglistbar.cpp | 18 ++++++++++++++++++ src/readinglistbar.h | 1 + 7 files changed, 29 insertions(+), 2 deletions(-) diff --git a/resources/i18n/en.json b/resources/i18n/en.json index c6fcf6e..b5f19a6 100644 --- a/resources/i18n/en.json +++ b/resources/i18n/en.json @@ -173,5 +173,7 @@ "file-not-found-text": "ZIM file doesn't exist or is not readable", "zim-id": "Zim Id", "zim-name": "Zim Name", - "zim-path": "Zim File Path" + "zim-path": "Zim File Path", + "export-reading-list": "Export reading list", + "export-reading-list-error": "An error has occured during export of the reading list." } diff --git a/resources/i18n/qqq.json b/resources/i18n/qqq.json index 6b670f0..14d8378 100644 --- a/resources/i18n/qqq.json +++ b/resources/i18n/qqq.json @@ -180,5 +180,7 @@ "file-not-found-text": "Error description text for when the desktop application cannot find the Zim file needed to display the web page.", "zim-id": "The term for the unique identifier of a zim file.", "zim-name": "The term for the name of a Zim file", - "zim-path": "The term for the path of a Zim file" + "zim-path": "The term for the path of a Zim file", + "export-reading-list": "Represents the action of exporting the reading list to a file.", + "export-reading-list-error": "Error description text for when exporting the reading list to a file failed." } diff --git a/src/kiwixapp.cpp b/src/kiwixapp.cpp index 2df37e8..4f44caa 100644 --- a/src/kiwixapp.cpp +++ b/src/kiwixapp.cpp @@ -461,6 +461,8 @@ void KiwixApp::createActions() CREATE_ACTION_ONOFF_ICON_SHORTCUT(ToggleReadingListAction, "reading-list-active", "reading-list", gt("reading-list"), QKeySequence(Qt::CTRL | Qt::Key_B)); + CREATE_ACTION(ExportReadingListAction, gt("export-reading-list")); + CREATE_ACTION_ONOFF_ICON_SHORTCUT(ToggleAddBookmarkAction, "star-active", "star", gt("add-bookmark"), QKeySequence(Qt::CTRL | Qt::Key_D)); CREATE_ACTION_SHORTCUTS(ZoomInAction, gt("zoom-in"), QList({QKeySequence::ZoomIn, QKeySequence(Qt::CTRL | Qt::Key_Equal)})); diff --git a/src/kiwixapp.h b/src/kiwixapp.h index 898d2f3..cd87787 100644 --- a/src/kiwixapp.h +++ b/src/kiwixapp.h @@ -62,6 +62,7 @@ public: SettingAction, DonateAction, ExitAction, + ExportReadingListAction, MAX_ACTION }; diff --git a/src/mainmenu.cpp b/src/mainmenu.cpp index 2c0f155..c42f218 100644 --- a/src/mainmenu.cpp +++ b/src/mainmenu.cpp @@ -24,6 +24,7 @@ MainMenu::MainMenu(QWidget *parent) : m_fileMenu.ADD_ACTION(BrowseLibraryAction); m_fileMenu.ADD_ACTION(OpenFileAction); m_fileMenu.ADD_ACTION(OpenRecentAction); + m_fileMenu.ADD_ACTION(ExportReadingListAction); /* TODO See https://github.com/kiwix/kiwix-desktop/issues/77 m_fileMenu.ADD_ACTION(SavePageAsAction); diff --git a/src/readinglistbar.cpp b/src/readinglistbar.cpp index a5ff301..f1d1b20 100644 --- a/src/readinglistbar.cpp +++ b/src/readinglistbar.cpp @@ -5,6 +5,7 @@ #include "zim/item.h" #include +#include ReadingListBar::ReadingListBar(QWidget *parent) : QWidget(parent), @@ -28,6 +29,9 @@ ReadingListBar::ReadingListBar(QWidget *parent) : setupList(); + auto app = KiwixApp::instance(); + auto exportAction = app->getAction(KiwixApp::ExportReadingListAction); + connect(exportAction, &QAction::triggered, this, &ReadingListBar::onExport); ui->label->setText(gt("reading-list-title")); } @@ -104,6 +108,20 @@ void ReadingListBar::onItemActivated(QListWidgetItem* item, Qt::MouseButtons but } } +void ReadingListBar::onExport() +{ + auto app = KiwixApp::instance(); + auto kiwixLibrary = app->getLibrary()->getKiwixLibrary(); + QString fileName = QFileDialog::getSaveFileName(app->getMainWindow(), + gt("save-file-as-window-title"), + "kiwix_readinglist.xml", "(*.xml)"); + if (fileName.isEmpty()) + return; + + if (!kiwixLibrary->writeBookmarksToFile(fileName.toStdString())) + app->showMessage(gt("export-reading-list-error"), gt("error-title"), QMessageBox::Information); +} + void ReadingListBar::openUrl(QListWidgetItem* item, bool newTab) { int index = ui->listWidget->row(item); diff --git a/src/readinglistbar.h b/src/readinglistbar.h index 5a2f295..e9e0e6d 100644 --- a/src/readinglistbar.h +++ b/src/readinglistbar.h @@ -22,6 +22,7 @@ public slots: void onItemDoubleClicked(QListWidgetItem *item); void onItemPressed(QListWidgetItem* item, Qt::MouseButtons buttons); void onItemActivated(QListWidgetItem *item, Qt::MouseButtons buttons); + void onExport(); private: Ui::readinglistbar *ui; int clickKind; From 0f89b34b0e4e7296a45c2efde253e3e9682ed16f Mon Sep 17 00:00:00 2001 From: ShaopengLin Date: Sat, 10 Aug 2024 13:36:32 -0400 Subject: [PATCH 2/5] Add Reading List Import Add menu button to import/append reading list from file --- resources/i18n/en.json | 4 +++- resources/i18n/qqq.json | 4 +++- src/kiwixapp.cpp | 2 ++ src/kiwixapp.h | 1 + src/library.cpp | 10 ++++++++++ src/library.h | 1 + src/mainmenu.cpp | 1 + src/readinglistbar.cpp | 16 ++++++++++++++++ src/readinglistbar.h | 1 + 9 files changed, 38 insertions(+), 2 deletions(-) diff --git a/resources/i18n/en.json b/resources/i18n/en.json index b5f19a6..b0e3d06 100644 --- a/resources/i18n/en.json +++ b/resources/i18n/en.json @@ -175,5 +175,7 @@ "zim-name": "Zim Name", "zim-path": "Zim File Path", "export-reading-list": "Export reading list", - "export-reading-list-error": "An error has occured during export of the reading list." + "export-reading-list-error": "An error has occured during export of the reading list.", + "import-reading-list": "Import reading list", + "import-reading-list-error": "An error has occured during import of the reading list." } diff --git a/resources/i18n/qqq.json b/resources/i18n/qqq.json index 14d8378..cce75fc 100644 --- a/resources/i18n/qqq.json +++ b/resources/i18n/qqq.json @@ -182,5 +182,7 @@ "zim-name": "The term for the name of a Zim file", "zim-path": "The term for the path of a Zim file", "export-reading-list": "Represents the action of exporting the reading list to a file.", - "export-reading-list-error": "Error description text for when exporting the reading list to a file failed." + "export-reading-list-error": "Error description text for when exporting the reading list to a file failed.", + "import-reading-list": "Represents the action of importing a reading list from a file.", + "import-reading-list-error": "Error description text for when importing a reading list from a file failed." } diff --git a/src/kiwixapp.cpp b/src/kiwixapp.cpp index 4f44caa..628cf0c 100644 --- a/src/kiwixapp.cpp +++ b/src/kiwixapp.cpp @@ -463,6 +463,8 @@ void KiwixApp::createActions() CREATE_ACTION(ExportReadingListAction, gt("export-reading-list")); + CREATE_ACTION(ImportReadingListAction, gt("import-reading-list")); + CREATE_ACTION_ONOFF_ICON_SHORTCUT(ToggleAddBookmarkAction, "star-active", "star", gt("add-bookmark"), QKeySequence(Qt::CTRL | Qt::Key_D)); CREATE_ACTION_SHORTCUTS(ZoomInAction, gt("zoom-in"), QList({QKeySequence::ZoomIn, QKeySequence(Qt::CTRL | Qt::Key_Equal)})); diff --git a/src/kiwixapp.h b/src/kiwixapp.h index cd87787..8c74229 100644 --- a/src/kiwixapp.h +++ b/src/kiwixapp.h @@ -63,6 +63,7 @@ public: DonateAction, ExitAction, ExportReadingListAction, + ImportReadingListAction, MAX_ACTION }; diff --git a/src/library.cpp b/src/library.cpp index a79bcd7..8dd1763 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -209,6 +209,16 @@ Library::QStringSet Library::getLibraryZimsFromDir(QString dir) const return zimsInDir; } +bool Library::readBookMarksFile(const std::string &filename) +{ + kiwix::Manager manager(mp_library); + if (!manager.readBookmarkFile(filename)) + return false; + + emit bookmarksChanged(); + return true; +} + const kiwix::Book &Library::getBookById(QString id) const { return mp_library->getBookById(id.toStdString()); diff --git a/src/library.h b/src/library.h index 0ca75fb..e101d13 100644 --- a/src/library.h +++ b/src/library.h @@ -45,6 +45,7 @@ public: void removeBookFromLibraryById(const QString& id); void addBookmark(kiwix::Bookmark& bookmark); void removeBookmark(const QString& zimId, const QString& url); + bool readBookMarksFile(const std::string& filename); void save(); kiwix::LibraryPtr getKiwixLibrary() { return mp_library; } public slots: diff --git a/src/mainmenu.cpp b/src/mainmenu.cpp index c42f218..53adeb4 100644 --- a/src/mainmenu.cpp +++ b/src/mainmenu.cpp @@ -25,6 +25,7 @@ MainMenu::MainMenu(QWidget *parent) : m_fileMenu.ADD_ACTION(OpenFileAction); m_fileMenu.ADD_ACTION(OpenRecentAction); m_fileMenu.ADD_ACTION(ExportReadingListAction); + m_fileMenu.ADD_ACTION(ImportReadingListAction); /* TODO See https://github.com/kiwix/kiwix-desktop/issues/77 m_fileMenu.ADD_ACTION(SavePageAsAction); diff --git a/src/readinglistbar.cpp b/src/readinglistbar.cpp index f1d1b20..718d685 100644 --- a/src/readinglistbar.cpp +++ b/src/readinglistbar.cpp @@ -31,7 +31,9 @@ ReadingListBar::ReadingListBar(QWidget *parent) : auto app = KiwixApp::instance(); auto exportAction = app->getAction(KiwixApp::ExportReadingListAction); + auto importAction = app->getAction(KiwixApp::ImportReadingListAction); connect(exportAction, &QAction::triggered, this, &ReadingListBar::onExport); + connect(importAction, &QAction::triggered, this, &ReadingListBar::onImport); ui->label->setText(gt("reading-list-title")); } @@ -122,6 +124,20 @@ void ReadingListBar::onExport() app->showMessage(gt("export-reading-list-error"), gt("error-title"), QMessageBox::Information); } +void ReadingListBar::onImport() +{ + auto app = KiwixApp::instance(); + auto library = app->getLibrary(); + QString fileName = QFileDialog::getOpenFileName(app->getMainWindow(), + gt("open-file"), + QString(), "(*.xml)"); + if (fileName.isEmpty()) + return; + + if (!library->readBookMarksFile(fileName.toStdString())) + app->showMessage(gt("import-reading-list-error"), gt("error-title"), QMessageBox::Information); +} + void ReadingListBar::openUrl(QListWidgetItem* item, bool newTab) { int index = ui->listWidget->row(item); diff --git a/src/readinglistbar.h b/src/readinglistbar.h index e9e0e6d..2811354 100644 --- a/src/readinglistbar.h +++ b/src/readinglistbar.h @@ -23,6 +23,7 @@ public slots: void onItemPressed(QListWidgetItem* item, Qt::MouseButtons buttons); void onItemActivated(QListWidgetItem *item, Qt::MouseButtons buttons); void onExport(); + void onImport(); private: Ui::readinglistbar *ui; int clickKind; From a5f225aff123a2704085b63b47f2f61e33d627e2 Mon Sep 17 00:00:00 2001 From: ShaopengLin Date: Sat, 10 Aug 2024 13:37:27 -0400 Subject: [PATCH 3/5] Bookmark Button Reflect Bookmark Change --- src/searchbar.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/searchbar.cpp b/src/searchbar.cpp index 69620c5..b213141 100644 --- a/src/searchbar.cpp +++ b/src/searchbar.cpp @@ -12,6 +12,9 @@ BookmarkButton::BookmarkButton(QWidget *parent) : connect(this, &QToolButton::triggered, this, &BookmarkButton::on_buttonClicked); connect(this, &QToolButton::triggered, this, &BookmarkButton::update_display); setDefaultAction(KiwixApp::instance()->getAction(KiwixApp::Actions::ToggleAddBookmarkAction)); + + auto library = KiwixApp::instance()->getLibrary(); + connect(library, &Library::bookmarksChanged, this, &BookmarkButton::update_display); } void BookmarkButton::update_display() From a324fd9a3ac2e317903d6cccdc49111a112d353e Mon Sep 17 00:00:00 2001 From: ShaopengLin Date: Sat, 10 Aug 2024 13:41:52 -0400 Subject: [PATCH 4/5] Added Ex/Import UI on Reading List --- resources/css/style.css | 15 ++++++++ resources/icons/more-vertical.svg | 1 + resources/kiwix.qrc | 1 + src/readinglistbar.cpp | 5 +++ src/readinglistbar.ui | 61 +++++++++++++++++++++++++------ 5 files changed, 72 insertions(+), 11 deletions(-) create mode 100644 resources/icons/more-vertical.svg diff --git a/resources/css/style.css b/resources/css/style.css index 54a2f1a..05ed9f6 100644 --- a/resources/css/style.css +++ b/resources/css/style.css @@ -329,3 +329,18 @@ ContentTypeFilter { font-size: 16px; margin-bottom: 10px; } + +#readinglistbar QPushButton { + margin-left: 4px; +} + +#readinglistbar QPushButton::hover { + border: 1px solid #3366CC; + background-color: #D9E9FF; + border-radius: 3px; +} + +#readinglistbar QPushButton::menu-indicator { + width: 0; + height: 0; +} diff --git a/resources/icons/more-vertical.svg b/resources/icons/more-vertical.svg new file mode 100644 index 0000000..cb5185c --- /dev/null +++ b/resources/icons/more-vertical.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/kiwix.qrc b/resources/kiwix.qrc index f96ea58..fd08d1b 100644 --- a/resources/kiwix.qrc +++ b/resources/kiwix.qrc @@ -64,5 +64,6 @@ icons/check-solid.svg icons/xmark-solid.svg icons/home-button.svg + icons/more-vertical.svg diff --git a/src/readinglistbar.cpp b/src/readinglistbar.cpp index 718d685..8808f6b 100644 --- a/src/readinglistbar.cpp +++ b/src/readinglistbar.cpp @@ -35,6 +35,11 @@ ReadingListBar::ReadingListBar(QWidget *parent) : connect(exportAction, &QAction::triggered, this, &ReadingListBar::onExport); connect(importAction, &QAction::triggered, this, &ReadingListBar::onImport); ui->label->setText(gt("reading-list-title")); + + QMenu *portMenu = new QMenu(this); + portMenu->addAction(exportAction); + portMenu->addAction(importAction); + ui->readingListMenuButton->setMenu(portMenu); } ReadingListBar::~ReadingListBar() diff --git a/src/readinglistbar.ui b/src/readinglistbar.ui index f7762b1..18859f3 100644 --- a/src/readinglistbar.ui +++ b/src/readinglistbar.ui @@ -27,16 +27,53 @@ 0 - - - - 16 - - - - Reading List - - + + + + + + 16 + + + + Reading List + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + :/icons/more-vertical.svg:/icons/more-vertical.svg + + + + 30 + 30 + + + + true + + + + @@ -68,6 +105,8 @@ - + + + From 3f046466d5154618ac8ee087c6ff484a6a051d3f Mon Sep 17 00:00:00 2001 From: ShaopengLin Date: Sat, 10 Aug 2024 13:44:02 -0400 Subject: [PATCH 5/5] Add default folder for bookmark ex/import Document folder is the default folder to ex/import. --- src/readinglistbar.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/readinglistbar.cpp b/src/readinglistbar.cpp index 8808f6b..b7fd566 100644 --- a/src/readinglistbar.cpp +++ b/src/readinglistbar.cpp @@ -6,6 +6,9 @@ #include #include +#include + +const QString documentsDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); ReadingListBar::ReadingListBar(QWidget *parent) : QWidget(parent), @@ -119,9 +122,10 @@ void ReadingListBar::onExport() { auto app = KiwixApp::instance(); auto kiwixLibrary = app->getLibrary()->getKiwixLibrary(); + auto suggestedFilePath = documentsDir + "/kiwix_readinglist.xml"; QString fileName = QFileDialog::getSaveFileName(app->getMainWindow(), gt("save-file-as-window-title"), - "kiwix_readinglist.xml", "(*.xml)"); + suggestedFilePath, "(*.xml)"); if (fileName.isEmpty()) return; @@ -135,7 +139,7 @@ void ReadingListBar::onImport() auto library = app->getLibrary(); QString fileName = QFileDialog::getOpenFileName(app->getMainWindow(), gt("open-file"), - QString(), "(*.xml)"); + documentsDir, "(*.xml)"); if (fileName.isEmpty()) return;