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/i18n/en.json b/resources/i18n/en.json index c6fcf6e..b0e3d06 100644 --- a/resources/i18n/en.json +++ b/resources/i18n/en.json @@ -173,5 +173,9 @@ "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.", + "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 6b670f0..cce75fc 100644 --- a/resources/i18n/qqq.json +++ b/resources/i18n/qqq.json @@ -180,5 +180,9 @@ "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.", + "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/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/kiwixapp.cpp b/src/kiwixapp.cpp index 2df37e8..628cf0c 100644 --- a/src/kiwixapp.cpp +++ b/src/kiwixapp.cpp @@ -461,6 +461,10 @@ 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(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 898d2f3..8c74229 100644 --- a/src/kiwixapp.h +++ b/src/kiwixapp.h @@ -62,6 +62,8 @@ public: SettingAction, 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 2c0f155..53adeb4 100644 --- a/src/mainmenu.cpp +++ b/src/mainmenu.cpp @@ -24,6 +24,8 @@ MainMenu::MainMenu(QWidget *parent) : m_fileMenu.ADD_ACTION(BrowseLibraryAction); 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 a5ff301..b7fd566 100644 --- a/src/readinglistbar.cpp +++ b/src/readinglistbar.cpp @@ -5,6 +5,10 @@ #include "zim/item.h" #include +#include +#include + +const QString documentsDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); ReadingListBar::ReadingListBar(QWidget *parent) : QWidget(parent), @@ -28,7 +32,17 @@ ReadingListBar::ReadingListBar(QWidget *parent) : setupList(); + 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")); + + QMenu *portMenu = new QMenu(this); + portMenu->addAction(exportAction); + portMenu->addAction(importAction); + ui->readingListMenuButton->setMenu(portMenu); } ReadingListBar::~ReadingListBar() @@ -104,6 +118,35 @@ void ReadingListBar::onItemActivated(QListWidgetItem* item, Qt::MouseButtons but } } +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"), + suggestedFilePath, "(*.xml)"); + if (fileName.isEmpty()) + return; + + if (!kiwixLibrary->writeBookmarksToFile(fileName.toStdString())) + 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"), + documentsDir, "(*.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 5a2f295..2811354 100644 --- a/src/readinglistbar.h +++ b/src/readinglistbar.h @@ -22,6 +22,8 @@ public slots: void onItemDoubleClicked(QListWidgetItem *item); void onItemPressed(QListWidgetItem* item, Qt::MouseButtons buttons); void onItemActivated(QListWidgetItem *item, Qt::MouseButtons buttons); + void onExport(); + void onImport(); private: Ui::readinglistbar *ui; int clickKind; 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 @@ - + + + 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()