diff --git a/kiwix-desktop.pro b/kiwix-desktop.pro
index 1e993414..32903431 100644
--- a/kiwix-desktop.pro
+++ b/kiwix-desktop.pro
@@ -34,13 +34,18 @@ DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += \
+ src/choiceitem.cpp \
src/contentmanagerdelegate.cpp \
src/contentmanagerheader.cpp \
src/contentmanagermodel.cpp \
src/contenttypefilter.cpp \
src/descriptionnode.cpp \
src/findinpagebar.cpp \
+ src/flowlayout.cpp \
+ src/kiwixchoicebox.cpp \
src/kiwixconfirmbox.cpp \
+ src/kiwixlineedit.cpp \
+ src/kiwixlistwidget.cpp \
src/kiwixloader.cpp \
src/rownode.cpp \
src/suggestionlistworker.cpp \
@@ -74,6 +79,7 @@ SOURCES += \
src/zimview.cpp \
HEADERS += \
+ src/choiceitem.h \
src/contentmanagerdelegate.h \
src/contentmanagerheader.h \
src/contentmanagermodel.h \
@@ -81,7 +87,11 @@ HEADERS += \
src/contenttypefilter.h \
src/descriptionnode.h \
src/findinpagebar.h \
+ src/flowlayout.h \
+ src/kiwixchoicebox.h \
src/kiwixconfirmbox.h \
+ src/kiwixlineedit.h \
+ src/kiwixlistwidget.h \
src/kiwixloader.h \
src/node.h \
src/rownode.h \
@@ -116,8 +126,10 @@ HEADERS += \
src/zimview.h \
FORMS += \
+ src/choiceitem.ui \
src/contentmanagerview.ui \
src/findinpagebar.ui \
+ ui/kiwixchoicebox.ui \
ui/kiwixconfirmbox.ui \
ui/mainwindow.ui \
ui/about.ui \
diff --git a/resources/css/_contentManager.css b/resources/css/_contentManager.css
index 93e31adc..f2e2a3bb 100644
--- a/resources/css/_contentManager.css
+++ b/resources/css/_contentManager.css
@@ -1,3 +1,7 @@
+#contentmanagerside {
+ background-color: red;
+}
+
QTreeView::branch:open:has-children {
image: url(:/icons/caret-down-solid.svg);
padding: 6px;
@@ -64,14 +68,3 @@ QMenu::item {
QMenu::item:selected {
background-color: #cccccc;
}
-
-QLineEdit {
- font-family: 'Selawik';
- padding: 4px;
- border: none;
- border-bottom: 1px solid #cccccc;
- color: #666666;
- font-size: 16px;
- height: 32px;
- line-height: 24px;
-}
diff --git a/resources/css/choiceBox.css b/resources/css/choiceBox.css
new file mode 100644
index 00000000..20d85dea
--- /dev/null
+++ b/resources/css/choiceBox.css
@@ -0,0 +1,71 @@
+QListWidget::item {
+ padding: 0;
+ padding-top: 6px;
+ padding-bottom: 6px;
+ padding-left: 2px;
+}
+
+QListWidget {
+ padding: 0;
+ border: 1px solid #ccc;
+}
+
+QListWidget::item::selected {
+ color: #444444;
+ background-color: transparent;
+}
+
+QLineEdit {
+ padding: 4px;
+ border: 0;
+}
+
+#choiceLabel {
+ font-size: 16px;
+}
+
+#currentChoices {
+ margin: 0;
+ padding: 0;
+ border: 1px solid #ccc;
+ border-radius: 1px;
+}
+
+#closeButton {
+ margin: 0;
+ background: transparent;
+ color: #eaecf0;
+ font-size: 12px;
+}
+
+ChoiceItem > QFrame {
+ border: 1px solid #ccc;
+ border-radius: 2px;
+ padding: 0;
+ background-color: #666;
+ padding-left: 2px;
+ padding-right: 2px;
+ margin:0;
+}
+
+#itemLabel {
+ margin: 0;
+ height: 6px;
+ background-color: #666;
+ color: #eaecf0;
+ font-size: 13px;
+}
+
+#clearButton {
+ background-color: white;
+ color: #3366cc;
+ padding: 4px;
+ font: bold;
+ font-size: 14px;
+ border-radius: 4px;
+}
+
+#clearButton:hover {
+ background-color: #3366cc;
+ color: white;
+}
diff --git a/resources/css/contentmanagerside.css b/resources/css/contentmanagerside.css
new file mode 100644
index 00000000..df16f702
--- /dev/null
+++ b/resources/css/contentmanagerside.css
@@ -0,0 +1,23 @@
+#searcher {
+ font-family: 'Selawik';
+ padding: 4px;
+ border: none;
+ border-bottom: 1px solid #cccccc;
+ color: #666666;
+ font-size: 16px;
+ height: 32px;
+ line-height: 24px;
+}
+
+QScrollArea {
+ border: 0;
+}
+
+#allFileButton, #localFileButton, #contentTypeButton {
+ padding-left: 2px;
+}
+
+#allFileButton::indicator, #localFileButton::indicator, #contentTypeButton::indicator {
+ height: 0;
+ width: 0;
+}
diff --git a/resources/i18n/en.json b/resources/i18n/en.json
index bcae634b..6f493455 100644
--- a/resources/i18n/en.json
+++ b/resources/i18n/en.json
@@ -90,8 +90,8 @@
"fullscreen-notification":"You are now in full screen mode. Press ESC to quit!",
"online-files":"Online Files",
"local-files":"Local Files",
- "browse-by-category":"Browse By Category",
- "browse-by-language":"Browse By Language",
+ "category":"Category",
+ "language":"Language",
"hide":"Hide",
"open-in-browser":"Open in browser",
"start-kiwix-server":"Start Kiwix Server",
@@ -154,5 +154,12 @@
"couldnt-open-location-text": "Kiwix is not able to open folder {{FOLDER}}",
"move-files-to-trash": "Move deleted files to trash",
"move-files-to-trash-text": "This action will move the file to trash.",
- "perma-delete-files-text": "This action will permanently delete the file."
+ "perma-delete-files-text": "This action will permanently delete the file.",
+ "clear-filter": "Clear the currently set filters",
+ "language-searcher-placeholder": "Filter language",
+ "category-searcher-placeholder": "Filter category",
+ "content-type-searcher-placeholder": "Filter content type",
+ "no-details": "Introduction only",
+ "no-pictures": "No Pictures",
+ "no-videos": "No Videos"
}
diff --git a/resources/icons/xmark-solid.svg b/resources/icons/xmark-solid.svg
new file mode 100644
index 00000000..c693bd00
--- /dev/null
+++ b/resources/icons/xmark-solid.svg
@@ -0,0 +1 @@
+
diff --git a/resources/kiwix.qrc b/resources/kiwix.qrc
index c25bd435..05a2e32c 100644
--- a/resources/kiwix.qrc
+++ b/resources/kiwix.qrc
@@ -61,5 +61,6 @@
icons/caret-up-solid.svg
icons/kiwix-logo.svg
icons/check-solid.svg
+ icons/xmark-solid.svg
diff --git a/resources/style.qrc b/resources/style.qrc
index 565b93fa..bb0bef4f 100644
--- a/resources/style.qrc
+++ b/resources/style.qrc
@@ -4,5 +4,7 @@
css/popup.css
css/localServer.css
css/confirmBox.css
+ css/contentmanagerside.css
+ css/choiceBox.css
diff --git a/src/choiceitem.cpp b/src/choiceitem.cpp
new file mode 100644
index 00000000..e6346458
--- /dev/null
+++ b/src/choiceitem.cpp
@@ -0,0 +1,32 @@
+#include "choiceitem.h"
+#include "ui_choiceitem.h"
+#include
+#include
+#include "kiwixapp.h"
+
+ChoiceItem::ChoiceItem(QString key, QString value, QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::ChoiceItem),
+ m_key(key),
+ m_value(value)
+{
+ ui->setupUi(this);
+ this->setStyleSheet(KiwixApp::instance()->parseStyleFromFile(":/css/choiceBox.css"));
+ ui->itemLabel->setText(key);
+ ui->itemLabel->setToolTip(key);
+ connect(ui->closeButton, &QPushButton::clicked, [=](){
+ emit(closeButtonClicked(ui->itemLabel->text()));
+ });
+ ui->closeButton->setCursor(Qt::PointingHandCursor);
+}
+
+ChoiceItem::~ChoiceItem()
+{
+ delete ui;
+}
+
+void ChoiceItem::mousePressEvent(QMouseEvent *event)
+{
+ Q_UNUSED(event);
+ return;
+}
diff --git a/src/choiceitem.h b/src/choiceitem.h
new file mode 100644
index 00000000..b03b11db
--- /dev/null
+++ b/src/choiceitem.h
@@ -0,0 +1,32 @@
+#ifndef CHOICEITEM_H
+#define CHOICEITEM_H
+
+#include
+
+namespace Ui {
+class ChoiceItem;
+}
+
+class ChoiceItem : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit ChoiceItem(QString key, QString value, QWidget *parent = nullptr);
+ ~ChoiceItem();
+ QString getKey() { return m_key; }
+ QString getValue() { return m_value; }
+
+protected:
+ void mousePressEvent(QMouseEvent *event) override;
+
+private:
+ Ui::ChoiceItem *ui;
+ QString m_key;
+ QString m_value;
+
+signals:
+ void closeButtonClicked(QString);
+};
+
+#endif // CHOICEITEM_H
diff --git a/src/choiceitem.ui b/src/choiceitem.ui
new file mode 100644
index 00000000..19aae85c
--- /dev/null
+++ b/src/choiceitem.ui
@@ -0,0 +1,143 @@
+
+
+ ChoiceItem
+
+
+
+ 0
+ 0
+ 119
+ 35
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 30
+
+
+
+ Form
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 3
+
+
+ 3
+
+
+ 3
+
+
+ 3
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+ TextLabel
+
+
+
+ -
+
+
+ true
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 10
+ 16777215
+
+
+
+
+
+
+
+ :/icons/xmark-solid.svg:/icons/xmark-solid.svg
+
+
+
+ 10
+ 20
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/contentmanager.cpp b/src/contentmanager.cpp
index 1c454676..c71ef8e2 100644
--- a/src/contentmanager.cpp
+++ b/src/contentmanager.cpp
@@ -56,7 +56,9 @@ ContentManager::ContentManager(Library* library, kiwix::Downloader* downloader,
treeView->setColumnWidth(5, 120);
// TODO: set width for all columns based on viewport
- setCurrentLanguage(QLocale().name().split("_").at(0));
+ setCurrentLanguage(KiwixApp::instance()->getSettingsManager()->getLanguageList());
+ setCurrentCategoryFilter(KiwixApp::instance()->getSettingsManager()->getCategoryList());
+ setCurrentContentTypeFilter(KiwixApp::instance()->getSettingsManager()->getContentType());
connect(mp_library, &Library::booksChanged, this, [=]() {emit(this->booksChanged());});
connect(this, &ContentManager::filterParamsChanged, this, &ContentManager::updateLibrary);
connect(this, &ContentManager::booksChanged, this, [=]() {
@@ -184,7 +186,6 @@ void ContentManager::setCategories()
QStringList categories;
if (m_local) {
auto categoryData = mp_library->getKiwixLibrary().getBooksCategories();
- categories.push_back("all");
for (auto category : categoryData) {
auto categoryName = QString::fromStdString(category);
categories.push_back(categoryName);
@@ -618,32 +619,52 @@ QStringList ContentManager::getDownloadIds()
return list;
}
-void ContentManager::setCurrentLanguage(QString language)
+void ContentManager::setCurrentLanguage(FilterList langPairList)
{
- if (language.length() == 2) {
- try {
- language = QString::fromStdString(
- kiwix::converta2toa3(language.toStdString()));
- } catch (std::out_of_range&) {}
+ QStringList languageList;
+ for (auto &langPair : langPairList) {
+ languageList.append(langPair.second);
+ }
+ languageList.sort();
+ for (auto &language : languageList) {
+ if (language.length() == 2) {
+ try {
+ language = QString::fromStdString(
+ kiwix::converta2toa3(language.toStdString()));
+ } catch (std::out_of_range&) {}
+ }
}
- if (m_currentLanguage == language)
+ auto newLanguage = languageList.join(",");
+ if (m_currentLanguage == newLanguage)
return;
- m_currentLanguage = language;
+ m_currentLanguage = newLanguage;
+ KiwixApp::instance()->getSettingsManager()->setLanguage(langPairList);
emit(currentLangChanged());
emit(filterParamsChanged());
}
-void ContentManager::setCurrentCategoryFilter(QString category)
+void ContentManager::setCurrentCategoryFilter(FilterList categoryPairList)
{
- if (m_categoryFilter == category)
+ QStringList categoryList;
+ for (auto &catPair : categoryPairList) {
+ categoryList.append(catPair.second);
+ }
+ categoryList.sort();
+ if (m_categoryFilter == categoryList.join(","))
return;
- m_categoryFilter = category.toLower();
+ m_categoryFilter = categoryList.join(",");
+ KiwixApp::instance()->getSettingsManager()->setCategory(categoryPairList);
emit(filterParamsChanged());
}
-void ContentManager::setCurrentContentTypeFilter(QList& contentTypeFilters)
+void ContentManager::setCurrentContentTypeFilter(FilterList contentTypeFiltersPairList)
{
+ QStringList contentTypeFilters;
+ for (auto &ctfPair : contentTypeFiltersPairList) {
+ contentTypeFilters.append(ctfPair.second);
+ }
m_contentTypeFilters = contentTypeFilters;
+ KiwixApp::instance()->getSettingsManager()->setContentType(contentTypeFiltersPairList);
emit(filterParamsChanged());
}
@@ -686,7 +707,6 @@ void ContentManager::updateLanguages(const QString& content) {
void ContentManager::updateCategories(const QString& content) {;
auto categories = kiwix::readCategoriesFromFeed(content.toStdString());
QStringList tempCategories;
- tempCategories.push_back("all");
for (auto catg : categories) {
tempCategories.push_back(QString::fromStdString(catg));
}
@@ -704,32 +724,18 @@ QStringList ContentManager::getBookIds()
{
kiwix::Filter filter;
std::vector acceptTags, rejectTags;
- if (m_categoryFilter != "all" && m_categoryFilter != "other") {
- acceptTags.push_back("_category:"+m_categoryFilter.toStdString());
- }
- if (m_categoryFilter == "other") {
- for (auto& category: m_categories) {
- if (category != "other" && category != "all") {
- rejectTags.push_back("_category:"+category.toStdString());
- }
- }
- }
for (auto &contentTypeFilter : m_contentTypeFilters) {
- auto state = contentTypeFilter->checkState();
- auto filter = contentTypeFilter->getName();
- if (state == Qt::PartiallyChecked) {
- acceptTags.push_back("_" + filter.toStdString() +":yes");
- } else if (state == Qt::Checked) {
- acceptTags.push_back("_" + filter.toStdString() +":no");
- }
+ acceptTags.push_back(contentTypeFilter.toStdString());
}
filter.acceptTags(acceptTags);
filter.rejectTags(rejectTags);
filter.query(m_searchQuery.toStdString());
- if (m_currentLanguage != "*")
+ if (m_currentLanguage != "")
filter.lang(m_currentLanguage.toStdString());
+ if (m_categoryFilter != "")
+ filter.category(m_categoryFilter.toStdString());
if (m_local) {
filter.local(true);
diff --git a/src/contentmanager.h b/src/contentmanager.h
index ae283a2e..b7f1051d 100644
--- a/src/contentmanager.h
+++ b/src/contentmanager.h
@@ -15,20 +15,20 @@ class ContentManager : public QObject
Q_OBJECT
Q_PROPERTY(QStringList bookIds READ getBookIds NOTIFY booksChanged)
Q_PROPERTY(QStringList downloadIds READ getDownloadIds NOTIFY downloadsChanged)
- Q_PROPERTY(QString currentLanguage MEMBER m_currentLanguage WRITE setCurrentLanguage NOTIFY currentLangChanged)
Q_PROPERTY(bool isLocal MEMBER m_local READ isLocal WRITE setLocal NOTIFY localChanged)
public:
typedef QList> LanguageList;
+ typedef QList> FilterList;
explicit ContentManager(Library* library, kiwix::Downloader *downloader, QObject *parent = nullptr);
virtual ~ContentManager() {}
ContentManagerView* getView() { return mp_view; }
void setLocal(bool local);
QStringList getDownloadIds();
- void setCurrentLanguage(QString language);
- void setCurrentCategoryFilter(QString category);
- void setCurrentContentTypeFilter(QList& contentTypeFilter);
+ void setCurrentLanguage(FilterList languageList);
+ void setCurrentCategoryFilter(FilterList category);
+ void setCurrentContentTypeFilter(FilterList contentTypeFilter);
bool isLocal() const { return m_local; }
QStringList getCategories() const { return m_categories; }
LanguageList getLanguages() const { return m_languages; }
@@ -43,7 +43,7 @@ class ContentManager : public QObject
QString m_currentLanguage;
QString m_searchQuery;
QString m_categoryFilter = "all";
- QList m_contentTypeFilters;
+ QStringList m_contentTypeFilters;
kiwix::supportedListSortBy m_sortBy = kiwix::UNSORTED;
bool m_sortOrderAsc = true;
LanguageList m_languages;
diff --git a/src/contentmanagerside.cpp b/src/contentmanagerside.cpp
index d2da4bc5..0bde3a96 100644
--- a/src/contentmanagerside.cpp
+++ b/src/contentmanagerside.cpp
@@ -1,7 +1,7 @@
#include "contentmanagerside.h"
#include "ui_contentmanagerside.h"
#include "kiwixapp.h"
-
+#include "kiwixchoicebox.h"
#include
#include
@@ -11,7 +11,10 @@ ContentManagerSide::ContentManagerSide(QWidget *parent) :
QWidget(parent),
mp_ui(new Ui::contentmanagerside)
{
+ setFocusPolicy(Qt::FocusPolicy::StrongFocus);
mp_ui->setupUi(this);
+ this->setStyleSheet(KiwixApp::instance()->parseStyleFromFile(":/css/contentmanagerside.css"));
+
mp_ui->buttonGroup->setId(mp_ui->allFileButton, CatalogButtonId::ALL);
mp_ui->buttonGroup->setId(mp_ui->localFileButton, CatalogButtonId::LOCAL);
connect(mp_ui->buttonGroup, QOverload::of(&QButtonGroup::buttonClicked), [=](QAbstractButton *btn) {
@@ -28,70 +31,35 @@ ContentManagerSide::ContentManagerSide(QWidget *parent) :
mp_ui->allFileButton->setText(gt("online-files"));
mp_ui->localFileButton ->setText(gt("local-files"));
- mp_ui->languageButton->setText(gt("browse-by-language"));
- mp_ui->categoryButton->setText(gt("browse-by-category"));
- mp_ui->contentTypeButton->setText(gt("content-type"));
-
- mp_languageButton = mp_ui->languageButton;
- mp_languageSelector = mp_ui->languageSelector;
- connect(mp_languageButton, &QCheckBox::toggled, this, [=](bool checked) { mp_languageSelector->setHidden(!checked); });
- mp_languageSelector->setHidden(true);
-
- mp_categoryButton = mp_ui->categoryButton;
- mp_categorySelector = mp_ui->categorySelector;
- connect(mp_categoryButton, &QCheckBox::toggled, this, [=](bool checked) { mp_categorySelector->setHidden(!checked); });
- mp_categorySelector->setHidden(true);
-
- mp_contentTypeButton = mp_ui->contentTypeButton;
- connect(mp_contentTypeButton, &QCheckBox::toggled, this, [=](bool checked) { mp_ui->contentTypeSelector->setHidden(!checked); });
- mp_ui->contentTypeSelector->setHidden(true);
-
- mp_ui->contentTypeAllButton->setText(gt("all"));
- mp_ui->contentTypeAllButton->setStyleSheet("*{font-weight: bold}");
- connect(mp_ui->contentTypeAllButton, &QCheckBox::clicked, this, [=](bool checked) {
- Q_UNUSED(checked);
- mp_ui->contentTypeAllButton->setStyleSheet("*{font-weight: bold}");
- for (auto &contentTypeFilter : m_contentTypeFilters) {
- contentTypeFilter->setCheckState(Qt::Unchecked);
- }
- mp_contentManager->setCurrentContentTypeFilter(m_contentTypeFilters);
- });
+
+ mp_categories = mp_ui->categories;
+ mp_categories->setType("category");
+
+ mp_languages = mp_ui->languages;
+ mp_languages->setType("language");
+
+ mp_contentType = mp_ui->contentType;
+ mp_contentType->setType("content-type");
auto searcher = mp_ui->searcher;
searcher->setPlaceholderText(gt("search-files"));
- QFile file(QString::fromUtf8(":/css/_contentManager.css"));
- file.open(QFile::ReadOnly);
- QString styleSheet = QString(file.readAll());
- searcher->setStyleSheet(styleSheet);
QIcon searchIcon = QIcon(":/icons/search.svg");
+
searcher->addAction(searchIcon, QLineEdit::LeadingPosition);
connect(searcher, &QLineEdit::textChanged, [searcher](){
KiwixApp::instance()->getContentManager()->setSearch(searcher->text());
});
-
- ContentTypeFilter* videosFilter = new ContentTypeFilter("pictures", this);
- ContentTypeFilter* picturesFilter = new ContentTypeFilter("videos", this);
- ContentTypeFilter* detailsFilter = new ContentTypeFilter("details", this);
- m_contentTypeFilters.push_back(videosFilter);
- m_contentTypeFilters.push_back(picturesFilter);
- m_contentTypeFilters.push_back(detailsFilter);
-
- auto layout = static_cast(mp_ui->contentTypeSelector->layout());
- for (auto &contentTypeFilter : m_contentTypeFilters) {
- layout->addWidget(contentTypeFilter, 0, Qt::AlignTop);
- connect(contentTypeFilter, &QCheckBox::clicked, this, [=](bool checked) {
- Q_UNUSED(checked);
- bool activeFilter = false;
- for (auto &contentTypeFilter : m_contentTypeFilters) {
- if (contentTypeFilter->checkState() != Qt::Unchecked) {
- activeFilter = true;
- break;
- }
- }
- mp_ui->contentTypeAllButton->setStyleSheet(activeFilter ? "" : "*{font-weight: bold}");
- mp_contentManager->setCurrentContentTypeFilter(m_contentTypeFilters);
- });
- }
+
+ FilterList contentTypeList = {
+ {"_pictures:yes", gt("pictures")},
+ {"_pictures:no", gt("no-pictures")},
+ {"_videos:yes", gt("videos")},
+ {"_videos:no", gt("no-videos")},
+ {"_details:yes", gt("details")},
+ {"_details:no", gt("no-details")}
+ };
+
+ mp_contentType->setSelections(contentTypeList, KiwixApp::instance()->getSettingsManager()->getContentType());
setCategories(KiwixApp::instance()->getContentManager()->getCategories());
setLanguages(KiwixApp::instance()->getContentManager()->getLanguages());
@@ -111,69 +79,23 @@ void ContentManagerSide::setContentManager(ContentManager *contentManager)
const auto checkedButton = mp_ui->buttonGroup->button(isLocal == CatalogButtonId::LOCAL);
checkedButton->setChecked(true);
checkedButton->setStyleSheet("*{font-weight: bold}");
- connect(mp_languageSelector, &QListWidget::itemSelectionChanged,
- this, [=]() {
- auto item = mp_languageSelector->selectedItems().at(0);
- if (!item) return;
- auto lang = item->data(Qt::UserRole).toString();
- if (lang == "all") {
- mp_contentManager->setCurrentLanguage("*");
- return;
- }
- mp_contentManager->setCurrentLanguage(lang);
+ connect(mp_languages, &KiwixChoiceBox::choiceUpdated, this, [=](FilterList values) {
+ mp_contentManager->setCurrentLanguage(values);
});
- connect(mp_categorySelector, &QListWidget::itemSelectionChanged,
- this, [=]() {
- auto item = mp_categorySelector->selectedItems().at(0);
- if (!item) return;
- auto category = item->data(Qt::UserRole).toString();
- mp_contentManager->setCurrentCategoryFilter(category);
+ connect(mp_categories, &KiwixChoiceBox::choiceUpdated, this, [=](FilterList values) {
+ mp_contentManager->setCurrentCategoryFilter(values);
+ });
+ connect(mp_contentType, &KiwixChoiceBox::choiceUpdated, this, [=](FilterList values) {
+ mp_contentManager->setCurrentContentTypeFilter(values);
});
-}
-
-QString beautify(QString word)
-{
- word = word.replace("_", " ");
- word[0] = word[0].toUpper();
- return word;
}
void ContentManagerSide::setCategories(QStringList categories)
{
- mp_categorySelector->blockSignals(true);
- mp_categorySelector->setHidden(true);
- mp_categorySelector->clear();
- mp_categorySelector->blockSignals(false);
- for (auto category: categories)
- {
- auto item = new KListWidgetItem(beautify(category));
- item->setData(Qt::UserRole, category);
- mp_categorySelector->addItem(item);
- if (category == "all")
- {
- item->setSelected(true);
- }
- }
+ mp_categories->setSelections(categories, KiwixApp::instance()->getSettingsManager()->getCategoryList());
}
void ContentManagerSide::setLanguages(ContentManager::LanguageList langList)
{
- mp_languageSelector->blockSignals(true);
- mp_languageSelector->setHidden(true);
- mp_languageSelector->clear();
- mp_languageSelector->blockSignals(false);
- for(auto lang: langList)
- {
- auto currentLang = QLocale().language();
- auto item = new KListWidgetItem(lang.second);
- item->setData(Qt::UserRole, lang.first);
- mp_languageSelector->addItem(item);
- if (lang.second == QLocale::languageToString(currentLang)) {
- item->setSelected(true);
- }
- }
- mp_languageSelector->sortItems();
- auto item = new KListWidgetItem("All");
- item->setData(Qt::UserRole, "all");
- mp_languageSelector->insertItem(0, item);
+ mp_languages->setSelections(langList, KiwixApp::instance()->getSettingsManager()->getLanguageList());
}
diff --git a/src/contentmanagerside.h b/src/contentmanagerside.h
index 5af981d9..a751f616 100644
--- a/src/contentmanagerside.h
+++ b/src/contentmanagerside.h
@@ -11,6 +11,9 @@ namespace Ui {
class contentmanagerside;
}
+class KiwixChoiceBox;
+using FilterList = ContentManager::FilterList;
+
class ContentManagerSide : public QWidget
{
Q_OBJECT
@@ -28,12 +31,11 @@ class ContentManagerSide : public QWidget
private:
Ui::contentmanagerside *mp_ui;
ContentManager* mp_contentManager;
- QCheckBox* mp_languageButton;
- QListWidget* mp_languageSelector;
- QCheckBox* mp_categoryButton;
- QListWidget* mp_categorySelector;
+ KiwixChoiceBox *mp_categories;
+ KiwixChoiceBox *mp_languages;
+ KiwixChoiceBox *mp_contentType;
QCheckBox* mp_contentTypeButton;
- QList m_contentTypeFilters;
+ QStringList m_contentTypeFilters;
public slots:
void setCategories(QStringList);
diff --git a/src/contentmanagerside.ui b/src/contentmanagerside.ui
index 9dfd13b4..b06e1595 100644
--- a/src/contentmanagerside.ui
+++ b/src/contentmanagerside.ui
@@ -6,8 +6,8 @@
0
0
- 197
- 368
+ 300
+ 386
@@ -16,15 +16,21 @@
0
+
+
+ 250
+ 0
+
+
Form
+
+ true
+
-
- 0
-
- QLayout::SetMaximumSize
+ QLayout::SetNoConstraint
0
@@ -39,229 +45,174 @@
0
-
-
-
-
+
+
+ true
-
+
true
-
-
- 0
-
-
- QLayout::SetMinimumSize
-
-
- 0
-
-
- 0
+
+
+
+ 0
+ 0
+ 298
+ 384
+
-
- 0
-
-
- 0
-
-
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- All Files
-
-
- buttonGroup
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Local Files
-
-
- true
-
-
- buttonGroup
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Browse By Language
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- QFrame::NoFrame
-
-
- QFrame::Plain
-
-
- 0
-
-
- Qt::ScrollBarAlwaysOn
-
-
- Qt::ScrollBarAlwaysOff
-
-
- QAbstractScrollArea::AdjustToContents
-
-
-
- -
-
-
- true
-
-
-
- 0
- 0
-
-
-
- Browse By Category
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- QFrame::NoFrame
-
-
- QFrame::Plain
-
-
- 0
-
-
- Qt::ScrollBarAlwaysOff
-
-
- QAbstractScrollArea::AdjustToContents
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Content Type
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- QFrame::NoFrame
-
-
- QFrame::Sunken
-
-
- 0
-
-
-
- 0
+
+
+ 9
+
+
-
+
+
+
+ 0
+ 0
+
-
- 0
+
+ PointingHandCursor
+
+
+ All Files
+
+
+ buttonGroup
+
+
+
+ 0
+ 0
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
-
+
+ PointingHandCursor
+
+
+ Local Files
+
+
+ true
+
+
+ buttonGroup
+
+
+
+ -
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+
+
+
+ PointingHandCursor
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Sunken
+
+
0
-
-
-
-
-
- 0
- 0
-
-
-
- All
-
-
- false
-
-
-
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
-
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Expanding
+
+
+
+ 20
+ 0
+
+
+
+
+
+
+
+
+ KiwixChoiceBox
+ QWidget
+
+ 1
+
+
diff --git a/src/contentmanagerview.cpp b/src/contentmanagerview.cpp
index f3281eea..24ba1f9b 100644
--- a/src/contentmanagerview.cpp
+++ b/src/contentmanagerview.cpp
@@ -10,10 +10,7 @@ ContentManagerView::ContentManagerView(QWidget *parent)
{
mp_ui->setupUi(this);
mp_ui->m_view->setSortingEnabled(true);
- QFile file(QString::fromUtf8(":/css/_contentManager.css"));
- file.open(QFile::ReadOnly);
- QString styleSheet = QString(file.readAll());
- mp_ui->m_view->setStyleSheet(styleSheet);
+ mp_ui->m_view->setStyleSheet(KiwixApp::instance()->parseStyleFromFile(":/css/_contentManager.css"));
mp_ui->m_view->setContextMenuPolicy(Qt::CustomContextMenu);
auto managerDelegate = new ContentManagerDelegate();
mp_ui->m_view->setItemDelegate(managerDelegate);
diff --git a/src/contenttypefilter.cpp b/src/contenttypefilter.cpp
index 4a10f77d..97612c3c 100644
--- a/src/contenttypefilter.cpp
+++ b/src/contenttypefilter.cpp
@@ -11,11 +11,12 @@ ContentTypeFilter::ContentTypeFilter(QString name, QWidget *parent)
m_states[Qt::PartiallyChecked] = gt("yes");
m_states[Qt::Checked] = gt("no");
setText(gt(m_name) + " : " + m_states[checkState()]);
+ setStyleSheet("* { color: #666666; }");
connect(this, &QCheckBox::stateChanged, this, &ContentTypeFilter::onStateChanged);
}
void ContentTypeFilter::onStateChanged(int state)
{
setText(gt(m_name) + " : " + m_states[static_cast(state)]);
- setStyleSheet((state == 0) ? "" : "*{font-weight: bold}");
-}
\ No newline at end of file
+ setStyleSheet((state == 0) ? "*{color: #666666;}" : "*{font-weight: bold; color: black;}");
+}
diff --git a/src/flowlayout.cpp b/src/flowlayout.cpp
new file mode 100644
index 00000000..caea2849
--- /dev/null
+++ b/src/flowlayout.cpp
@@ -0,0 +1,230 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include
+
+#include "flowlayout.h"
+//! [1]
+FlowLayout::FlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing)
+ : QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing)
+{
+ setContentsMargins(margin, margin, margin, margin);
+}
+
+FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing)
+ : m_hSpace(hSpacing), m_vSpace(vSpacing)
+{
+ setContentsMargins(margin, margin, margin, margin);
+}
+//! [1]
+
+//! [2]
+FlowLayout::~FlowLayout()
+{
+ QLayoutItem *item;
+ while ((item = takeAt(0)))
+ delete item;
+}
+//! [2]
+
+//! [3]
+void FlowLayout::addItem(QLayoutItem *item)
+{
+ itemList.append(item);
+}
+//! [3]
+
+//! [4]
+int FlowLayout::horizontalSpacing() const
+{
+ if (m_hSpace >= 0) {
+ return m_hSpace;
+ } else {
+ return smartSpacing(QStyle::PM_LayoutHorizontalSpacing);
+ }
+}
+
+int FlowLayout::verticalSpacing() const
+{
+ if (m_vSpace >= 0) {
+ return m_vSpace;
+ } else {
+ return smartSpacing(QStyle::PM_LayoutVerticalSpacing);
+ }
+}
+//! [4]
+
+//! [5]
+int FlowLayout::count() const
+{
+ return itemList.size();
+}
+
+QLayoutItem *FlowLayout::itemAt(int index) const
+{
+ return itemList.value(index);
+}
+
+QLayoutItem *FlowLayout::takeAt(int index)
+{
+ if (index >= 0 && index < itemList.size())
+ return itemList.takeAt(index);
+ return nullptr;
+}
+//! [5]
+
+//! [6]
+Qt::Orientations FlowLayout::expandingDirections() const
+{
+ return { };
+}
+//! [6]
+
+//! [7]
+bool FlowLayout::hasHeightForWidth() const
+{
+ return true;
+}
+
+int FlowLayout::heightForWidth(int width) const
+{
+ int height = doLayout(QRect(0, 0, width, 0), true);
+ return height;
+}
+//! [7]
+
+//! [8]
+void FlowLayout::setGeometry(const QRect &rect)
+{
+ QLayout::setGeometry(rect);
+ doLayout(rect, false);
+}
+
+QSize FlowLayout::sizeHint() const
+{
+ return minimumSize();
+}
+
+QSize FlowLayout::minimumSize() const
+{
+ QSize size;
+ for (const QLayoutItem *item : qAsConst(itemList))
+ size = size.expandedTo(item->minimumSize());
+
+ const QMargins margins = contentsMargins();
+ size += QSize(margins.left() + margins.right(), margins.top() + margins.bottom());
+ return size;
+}
+//! [8]
+
+//! [9]
+int FlowLayout::doLayout(const QRect &rect, bool testOnly) const
+{
+ int left, top, right, bottom;
+ getContentsMargins(&left, &top, &right, &bottom);
+ QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom);
+ int x = effectiveRect.x();
+ int y = effectiveRect.y();
+ int lineHeight = 0;
+//! [9]
+
+//! [10]
+ for (QLayoutItem *item : qAsConst(itemList)) {
+ const QWidget *wid = item->widget();
+ int spaceX = horizontalSpacing();
+ if (spaceX == -1)
+ spaceX = wid->style()->layoutSpacing(
+ QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal);
+ int spaceY = verticalSpacing();
+ if (spaceY == -1)
+ spaceY = wid->style()->layoutSpacing(
+ QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical);
+//! [10]
+//! [11]
+ int nextX = x + item->sizeHint().width() + spaceX;
+ if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) {
+ x = effectiveRect.x();
+ y = y + lineHeight + spaceY;
+ nextX = x + item->sizeHint().width() + spaceX;
+ lineHeight = 0;
+ }
+
+ if (!testOnly)
+ item->setGeometry(QRect(QPoint(x, y), item->sizeHint()));
+
+ x = nextX;
+ lineHeight = qMax(lineHeight, item->sizeHint().height());
+ }
+ return y + lineHeight - rect.y() + bottom;
+}
+//! [11]
+//! [12]
+int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const
+{
+ QObject *parent = this->parent();
+ if (!parent) {
+ return -1;
+ } else if (parent->isWidgetType()) {
+ QWidget *pw = static_cast(parent);
+ return pw->style()->pixelMetric(pm, nullptr, pw);
+ } else {
+ return static_cast(parent)->spacing();
+ }
+}
+//! [12]
+
+void FlowLayout::insertWidget(int index, QWidget *w) {
+ addWidget(w);
+ if (index < 0)
+ index = 0;
+ if (index >= itemList.size())
+ index = itemList.size() - 1;
+ itemList.move(indexOf(w), index);
+}
diff --git a/src/flowlayout.h b/src/flowlayout.h
new file mode 100644
index 00000000..d98defca
--- /dev/null
+++ b/src/flowlayout.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FLOWLAYOUT_H
+#define FLOWLAYOUT_H
+
+#include
+#include
+#include
+//! [0]
+class FlowLayout : public QLayout
+{
+public:
+ explicit FlowLayout(QWidget *parent, int margin = -1, int hSpacing = -1, int vSpacing = -1);
+ explicit FlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1);
+ ~FlowLayout();
+
+ void addItem(QLayoutItem *item) override;
+ int horizontalSpacing() const;
+ int verticalSpacing() const;
+ Qt::Orientations expandingDirections() const override;
+ bool hasHeightForWidth() const override;
+ int heightForWidth(int) const override;
+ int count() const override;
+ QLayoutItem *itemAt(int index) const override;
+ QSize minimumSize() const override;
+ void setGeometry(const QRect &rect) override;
+ QSize sizeHint() const override;
+ QLayoutItem *takeAt(int index) override;
+ void insertWidget(int index, QWidget *w);
+
+private:
+ int doLayout(const QRect &rect, bool testOnly) const;
+ int smartSpacing(QStyle::PixelMetric pm) const;
+
+ QList itemList;
+ int m_hSpace;
+ int m_vSpace;
+};
+//! [0]
+
+#endif // FLOWLAYOUT_H
diff --git a/src/kiwixapp.cpp b/src/kiwixapp.cpp
index eff5b07c..a47274bc 100644
--- a/src/kiwixapp.cpp
+++ b/src/kiwixapp.cpp
@@ -72,13 +72,7 @@ void KiwixApp::init()
setApplicationName("Kiwix");
setDesktopFileName("kiwix.desktop");
-
- QFile styleFile(":/css/style.css");
- styleFile.open(QIODevice::ReadOnly);
- auto byteContent = styleFile.readAll();
- QString style(byteContent);
- setStyleSheet(style);
-
+ setStyleSheet(parseStyleFromFile(":/css/style.css"));
createAction();
mp_mainWindow = new MainWindow;
@@ -474,3 +468,12 @@ void KiwixApp::printVersions(std::ostream& out) {
out << std::endl;
zim::printVersions(out);
}
+
+QString KiwixApp::parseStyleFromFile(QString filePath)
+{
+ QFile file(filePath);
+ file.open(QFile::ReadOnly);
+ QString styleSheet = QString(file.readAll());
+ file.close();
+ return styleSheet;
+}
diff --git a/src/kiwixapp.h b/src/kiwixapp.h
index 212f1680..4a4befbb 100644
--- a/src/kiwixapp.h
+++ b/src/kiwixapp.h
@@ -86,6 +86,7 @@ class KiwixApp : public QtSingleApplication
QString getText(const QString &key) { return m_translation.getText(key); };
void setMonitorDir(const QString &dir);
bool isCurrentArticleBookmarked();
+ QString parseStyleFromFile(QString filePath);
public slots:
void openZimFile(const QString& zimfile="");
diff --git a/src/kiwixchoicebox.cpp b/src/kiwixchoicebox.cpp
new file mode 100644
index 00000000..68841837
--- /dev/null
+++ b/src/kiwixchoicebox.cpp
@@ -0,0 +1,290 @@
+#include "kiwixchoicebox.h"
+#include "ui_kiwixchoicebox.h"
+#include "klistwidgetitem.h"
+#include "kiwixapp.h"
+#include "choiceitem.h"
+#include
+#include "choiceitem.h"
+#include "kiwixapp.h"
+#include
+#include
+#include
+#include
+#include "kiwixlineedit.h"
+#include "kiwixlistwidget.h"
+
+KiwixChoiceBox::KiwixChoiceBox(QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::kiwixchoicebox)
+{
+ ui->setupUi(this);
+ auto styleSheet = KiwixApp::instance()->parseStyleFromFile(":/css/choiceBox.css");
+ this->setStyleSheet(styleSheet);
+ ui->clearButton->setText(gt("clear"));
+ ui->clearButton->setToolTip(gt("clear-filter"));
+
+ choiceLabel = ui->choiceLabel;
+ choiceLabel->setText(gt("undefined"));
+
+ choiceSelector = new KiwixListWidget(parent);
+ choiceSelector->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
+ choiceSelector->setMaximumWidth(250);
+ // allow maximum 6 elements
+ choiceSelector->setMaximumHeight(KListWidgetItem::getItemHeight() * 6);
+ choiceSelector->setCursor(Qt::PointingHandCursor);
+ choiceSelector->setVerticalScrollMode(QAbstractItemView::ScrollMode::ScrollPerPixel);
+ choiceSelector->setFocusPolicy(Qt::FocusPolicy::NoFocus);
+ choiceSelector->setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff);
+ choiceSelector->setStyleSheet(styleSheet);
+ choiceSelector->setSelectionMode(QAbstractItemView::SelectionMode::MultiSelection);
+
+ currentChoicesLayout = new FlowLayout(ui->currentChoices, 4, 2, 2);
+ searcher = new KiwixLineEdit();
+ searcher->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+ searcher->setFixedWidth(20);
+ currentChoicesLayout->addWidget(searcher);
+ connect(choiceSelector, &QListWidget::itemPressed, this, [=](QListWidgetItem *item) {
+ searcher->clear();
+ if (item->isSelected()) {
+ addSelection(item);
+ } else {
+ removeSelection(item);
+ }
+ });
+
+ connect(searcher, &QLineEdit::textChanged, [=](QString search) {
+ searcher->setStyleSheet("QLineEdit{color: #666;}");
+ QFontMetrics fm = searcher->fontMetrics();
+ auto w = fm.horizontalAdvance(search) + 20;
+ if (w + 4 < ui->currentChoices->width()) {
+ searcher->setFixedWidth(w);
+ ui->currentChoices->resize(ui->currentChoices->width(), currentChoicesLayout->minimumHeightForWidth(ui->currentChoices->width()));
+ }
+ int visibleItems = 0;
+ for (auto i = 0; i < choiceSelector->count(); i++) {
+ auto itemAtRow = choiceSelector->item(i);
+ itemAtRow->setHidden(!itemAtRow->text().contains(search, Qt::CaseSensitivity::CaseInsensitive));
+ visibleItems += !(itemAtRow->isHidden());
+ }
+ choiceSelector->setVisibleItems(visibleItems);
+ adjustSize();
+ choiceSelector->setVisible(true);
+ });
+
+ connect(searcher, &KiwixLineEdit::clicked, [=]() {
+ showOptions();
+ });
+
+ choiceSelector->setVisible(false);
+ searcher->setStyleSheet("QLineEdit{color: #999;}");
+
+ connect(searcher, &KiwixLineEdit::focusedOut, [=]() {
+ hideOptions();
+ });
+
+ connect(searcher, &KiwixLineEdit::focusedIn, [=]() {
+ showOptions();
+ });
+
+ ui->clearButton->setCursor(Qt::PointingHandCursor);
+ connect(ui->clearButton, &QPushButton::clicked, [=]() {
+ clearSelections();
+ emit(choiceUpdated(getCurrentSelected()));
+ hideOptions();
+ });
+
+ connect(this, &KiwixChoiceBox::choiceUpdated, [=]() {
+ if (choiceSelector->selectedItems().isEmpty())
+ showPlaceholder();
+ choiceSelector->setVisible(false);
+ });
+
+ connect(this, &KiwixChoiceBox::clicked, [=]() {
+ showOptions();
+ });
+}
+
+KiwixChoiceBox::~KiwixChoiceBox()
+{
+ delete ui;
+}
+
+/*
+When the lineEdit is currently focused,
+if the outer widget is pressed, lineEdit loses focus and hides the options.
+When mouseRelease event is called, it will create a flicker effect:
+ - Clicking and holding causes the lineEdit to lose focus and hide the options
+ - Release causes the options to show up again.
+Showing the options on a mousePress doesn't allow this
+*/
+void KiwixChoiceBox::mousePressEvent(QMouseEvent *event)
+{
+ if (event->button() == Qt::LeftButton) {
+ emit(clicked());
+ }
+}
+
+void KiwixChoiceBox::hideOptions()
+{
+ if (choiceSelector->selectedItems().isEmpty()) {
+ showPlaceholder();
+ }
+ searcher->setStyleSheet("QLineEdit{color: #999;}");
+ choiceSelector->setVisible(false);
+ ui->currentChoices->setStyleSheet("#currentChoices{border: 1px solid #ccc;}");
+ searcher->clearFocus();
+}
+
+void KiwixChoiceBox::showOptions()
+{
+ ui->currentChoices->setStyleSheet("#currentChoices{border: 2px solid #4e63ad;}");
+ adjustSize();
+ choiceSelector->setVisible(true);
+ choiceSelector->raise();
+ searcher->setPlaceholderText("");
+ searcher->setFocus();
+}
+
+void KiwixChoiceBox::keyPressEvent(QKeyEvent *event)
+{
+ if (event->key() == Qt::Key_Escape) {
+ hideOptions();
+ } else if (event->key() == Qt::Key_Down) {
+ if (!choiceSelector->isVisible())
+ showOptions();
+ choiceSelector->moveDown();
+ } else if (event->key() == Qt::Key_Up) {
+ choiceSelector->moveUp();
+ } else if ((event->key() == Qt::Key_Enter) || (event->key() == Qt::Key_Return)) {
+ choiceSelector->selectCurrent();
+ }
+}
+
+bool KiwixChoiceBox::addSelection(QListWidgetItem *item, bool updateRequired)
+{
+ auto key = item->text();
+ auto value = item->data(Qt::UserRole).toString();
+ auto chItem = new ChoiceItem(key, value);
+ connect(chItem, &ChoiceItem::closeButtonClicked, [=](QString text) {
+ auto selectionItems = choiceSelector->findItems(text, Qt::MatchExactly);
+ if (selectionItems.size() != 1) return;
+ removeSelection(selectionItems[0]);
+ });
+ chItem->setObjectName(key);
+ currentChoicesLayout->insertWidget(ui->currentChoices->children().count() - 2, chItem);
+ searcher->setFixedWidth(20);
+ // put on top of list
+ item = choiceSelector->takeItem(choiceSelector->row(item));
+ choiceSelector->insertItem(0, item);
+ item->setSelected(true);
+
+ searcher->setFixedWidth(20);
+ if (updateRequired) {
+ searcher->setFocus();
+ emit(choiceUpdated(getCurrentSelected()));
+ }
+ return true;
+}
+
+bool KiwixChoiceBox::removeSelection(QListWidgetItem *item)
+{
+ auto chItem = ui->currentChoices->findChild(item->text());
+ chItem->deleteLater();
+ // selected items are always shown at top, put it after the last selected item
+ item->setSelected(false);
+ auto selItems = choiceSelector->selectedItems();
+ item = choiceSelector->takeItem(choiceSelector->row(item));
+ choiceSelector->insertItem(selItems.size(), item);
+ emit(choiceUpdated(getCurrentSelected()));
+ return true;
+}
+
+void KiwixChoiceBox::clearSelections()
+{
+ for (auto &item : choiceSelector->selectedItems()) {
+ item->setSelected(false);
+ auto chItem = ui->currentChoices->findChild(item->text());
+ ui->currentChoices->layout()->removeWidget(chItem);
+ delete chItem;
+ }
+}
+
+void KiwixChoiceBox::showPlaceholder()
+{
+ searcher->clear();
+ searcher->setPlaceholderText(gt(m_type + "-searcher-placeholder"));
+ // Putting width based on placeholder contents
+ QFontMetrics fm = searcher->fontMetrics();
+ auto w = fm.boundingRect(gt(m_type + "-searcher-placeholder")).width();
+ searcher->setFixedWidth(w + 20);
+}
+
+QString beautifyString(QString word)
+{
+ word = word.replace("_", " ");
+ word[0] = word[0].toUpper();
+ return word;
+}
+
+void KiwixChoiceBox::setSelections(QStringList selections, SelectionList defaultSelection)
+{
+ SelectionList sList;
+ for (const auto &sel : selections) {
+ sList.append({sel, sel});
+ }
+ setSelections(sList, defaultSelection);
+}
+
+void KiwixChoiceBox::setSelections(SelectionList selections, SelectionList defaultSelection)
+{
+ clearSelections();
+ choiceSelector->clear();
+ for (const auto &selection: selections)
+ {
+ auto item = new KListWidgetItem(beautifyString(selection.second));
+ item->setData(Qt::UserRole, selection.first);
+ choiceSelector->addItem(item);
+ }
+
+ for (const auto &defSel : defaultSelection) {
+ auto itemList = choiceSelector->findItems(defSel.first, Qt::MatchExactly);
+ if (itemList.isEmpty()) {
+ auto item = new KListWidgetItem(defSel.first);
+ item->setData(Qt::UserRole, defSel.second);
+ choiceSelector->addItem(item);
+ addSelection(item, false);
+ } else {
+ addSelection(itemList[0], false);
+ }
+ }
+
+ if (choiceSelector->selectedItems().isEmpty())
+ showPlaceholder();
+ choiceSelector->setVisibleItems(choiceSelector->count());
+ adjustSize();
+}
+
+void KiwixChoiceBox::adjustSize()
+{
+ QWidget::adjustSize();
+ choiceSelector->adjustSize();
+ choiceSelector->setGeometry(this->x() + ui->currentChoices->x(),
+ this->y() + ui->currentChoices->y() + ui->currentChoices->height(),
+ choiceSelector->width(),
+ choiceSelector->getVisibleItems() * KListWidgetItem::getItemHeight() + 2); // 2 is for the border so that all elements are visible
+}
+
+void KiwixChoiceBox::setType(QString type)
+{
+ ui->choiceLabel->setText(gt(type));
+ m_type = type;
+}
+
+KiwixChoiceBox::SelectionList KiwixChoiceBox::getCurrentSelected()
+{
+ SelectionList selections;
+ for (auto &item : choiceSelector->selectedItems()) {
+ selections.append({item->text(), item->data(Qt::UserRole).toString()});
+ }
+ return selections;
+}
diff --git a/src/kiwixchoicebox.h b/src/kiwixchoicebox.h
new file mode 100644
index 00000000..18cc8cb0
--- /dev/null
+++ b/src/kiwixchoicebox.h
@@ -0,0 +1,63 @@
+#ifndef KIWIXCHOICEBOX_H
+#define KIWIXCHOICEBOX_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "flowlayout.h"
+#include
+#include
+
+class ChoiceItem;
+class KiwixLineEdit;
+class KiwixListWidget;
+
+namespace Ui {
+class kiwixchoicebox;
+}
+
+class KiwixChoiceBox : public QWidget
+{
+ Q_OBJECT
+
+ typedef QList> SelectionList;
+
+public:
+ explicit KiwixChoiceBox(QWidget *parent = nullptr);
+ void setType(QString type);
+ void setSelections(SelectionList selections, SelectionList defaultSelection);
+ void setSelections(QStringList selections, SelectionList defaultSelection);
+ ~KiwixChoiceBox();
+ void adjustSize();
+
+protected:
+ void keyPressEvent(QKeyEvent* event) override;
+ void mousePressEvent(QMouseEvent *event) override;
+
+signals:
+ void choiceUpdated(SelectionList);
+ void clicked();
+
+private:
+ Ui::kiwixchoicebox *ui;
+ QLabel *choiceLabel;
+ QLineEdit *choiceSearch;
+ KiwixListWidget *choiceSelector;
+ FlowLayout *currentChoicesLayout;
+ KiwixLineEdit *searcher;
+ SelectionList getCurrentSelected();
+ bool removeSelection(QListWidgetItem *item);
+ void clearSelections();
+ bool addSelection(QListWidgetItem *item, bool updateRequired = true);
+ void showOptions();
+ void hideOptions();
+ void showPlaceholder();
+ QString m_type;
+ bool m_sliderMoved = false;
+};
+
+#endif // KIWIXCHOICEBOX_H
diff --git a/src/kiwixconfirmbox.cpp b/src/kiwixconfirmbox.cpp
index 094339a1..d855669e 100644
--- a/src/kiwixconfirmbox.cpp
+++ b/src/kiwixconfirmbox.cpp
@@ -9,13 +9,7 @@ KiwixConfirmBox::KiwixConfirmBox(QString confirmTitle, QString confirmText, bool
{
ui->setupUi(this);
setWindowFlag(Qt::FramelessWindowHint, true);
-
- QFile styleFile(":/css/confirmBox.css");
- styleFile.open(QIODevice::ReadOnly);
- auto byteContent = styleFile.readAll();
- styleFile.close();
- QString style(byteContent);
- setStyleSheet(style);
+ setStyleSheet(KiwixApp::instance()->parseStyleFromFile(":/css/confirmBox.css"));
connect(ui->yesButton, &QPushButton::clicked, [=]() {
emit yesClicked();
});
diff --git a/src/kiwixlineedit.cpp b/src/kiwixlineedit.cpp
new file mode 100644
index 00000000..ca5ca1e4
--- /dev/null
+++ b/src/kiwixlineedit.cpp
@@ -0,0 +1,27 @@
+#include "kiwixlineedit.h"
+
+KiwixLineEdit::KiwixLineEdit(QWidget *parent) : QLineEdit(parent)
+{
+ installEventFilter(this);
+}
+
+KiwixLineEdit::~KiwixLineEdit()
+{
+}
+
+void KiwixLineEdit::resizeEvent(QResizeEvent *event)
+{
+ QLineEdit::resizeEvent(event);
+ adjustSize();
+}
+bool KiwixLineEdit::eventFilter(QObject* object, QEvent* event)
+{
+ if (event->type() == QEvent::MouseButtonPress) {
+ emit(clicked());
+ } else if (event->type() == QEvent::FocusIn) {
+ emit(focusedIn());
+ } else if (event->type() == QEvent::FocusOut) {
+ emit(focusedOut());
+ }
+ return false;
+}
diff --git a/src/kiwixlineedit.h b/src/kiwixlineedit.h
new file mode 100644
index 00000000..6b25b859
--- /dev/null
+++ b/src/kiwixlineedit.h
@@ -0,0 +1,20 @@
+#ifndef KIWIXLINEEDIT_H
+#define KIWIXLINEEDIT_H
+
+#include
+#include
+
+class KiwixLineEdit : public QLineEdit {
+ Q_OBJECT;
+public:
+ KiwixLineEdit(QWidget *parent = nullptr);
+ ~KiwixLineEdit();
+protected:
+ void resizeEvent(QResizeEvent *event) override;
+ bool eventFilter(QObject* object, QEvent* event) override;
+signals:
+ void clicked();
+ void focusedIn();
+ void focusedOut();
+};
+#endif // KIWIXLINEEDIT_H
diff --git a/src/kiwixlistwidget.cpp b/src/kiwixlistwidget.cpp
new file mode 100644
index 00000000..0d1f58bc
--- /dev/null
+++ b/src/kiwixlistwidget.cpp
@@ -0,0 +1,108 @@
+#include "kiwixlistwidget.h"
+#include
+#include
+#include
+#include
+#include "kiwixapp.h"
+#include "klistwidgetitem.h"
+
+KiwixListWidget::KiwixListWidget(QWidget *parent)
+ : QListWidget(parent), currRow(0), m_visibleItems(count())
+{
+ connect(this, &KiwixListWidget::currRowChanged, this, &KiwixListWidget::handleCurrRowChange);
+ setMouseTracking(true);
+}
+
+void KiwixListWidget::mousePressEvent(QMouseEvent *event)
+{
+ if (event->button() == Qt::LeftButton) {
+ selectCurrent(item(m_mouseIndex));
+ }
+}
+
+void KiwixListWidget::mouseMoveEvent(QMouseEvent *event)
+{
+ int oldRow = currRow;
+ m_mouseIndex = row(itemAt(event->pos()));
+ currRow = m_mouseIndex;
+ emit(currRowChanged(oldRow, currRow));
+}
+
+void KiwixListWidget::hideEvent(QHideEvent *event)
+{
+ auto currItem = dynamic_cast(item(currRow));
+ if (currItem)
+ currItem->disableHighlight();
+ QListWidget::hideEvent(event);
+}
+
+void KiwixListWidget::resizeEvent(QResizeEvent *e)
+{
+ int oldRow = currRow;
+ for (auto i = 0; i < count(); i++) {
+ auto itemAtRow = item(i);
+ if (!itemAtRow->isHidden() && !itemAtRow->isSelected()) {
+ currRow = i;
+ break;
+ }
+ }
+ emit(currRowChanged(oldRow, currRow));
+ QListWidget::resizeEvent(e);
+}
+
+void KiwixListWidget::handleCurrRowChange(int oldRow, int newRow)
+{
+ auto prevItem = dynamic_cast(item(oldRow));
+ if (prevItem) {
+ prevItem->disableHighlight();
+ }
+ auto currItem = dynamic_cast(item(newRow));
+ if (currItem) {
+ currItem->enableHighlight();
+ scrollToItem(currItem, QAbstractItemView::EnsureVisible);
+ }
+ emit(dataChanged(QModelIndex(), QModelIndex()));
+}
+
+void KiwixListWidget::moveUp()
+{
+ if (selectedItems().size() == count())
+ return;
+ KListWidgetItem *currItem = dynamic_cast(item(currRow));
+ int oldRow = currRow;
+ do {
+ currRow--;
+ if (currRow < 0) currRow = count() - 1;
+ currItem = dynamic_cast(item(currRow));
+ } while (currItem->isSelected() || currItem->isHidden());
+ emit(currRowChanged(oldRow, currRow));
+}
+
+void KiwixListWidget::moveDown()
+{
+ if (selectedItems().size() == count())
+ return;
+ KListWidgetItem *currItem = dynamic_cast(item(currRow));
+ int oldRow = currRow;
+ do {
+ currRow++;
+ if (currRow == count()) currRow = 0;
+ currItem = dynamic_cast(item(currRow));
+ } while (currItem->isSelected() || currItem->isHidden());
+ emit(currRowChanged(oldRow, currRow));
+}
+
+void KiwixListWidget::selectCurrent()
+{
+ selectCurrent(item(currRow));
+}
+
+void KiwixListWidget::selectCurrent(QListWidgetItem *item)
+{
+ auto currItem = dynamic_cast(item);
+ if (currItem && !currItem->isSelected() && !currItem->isHidden()) {
+ currItem->disableHighlight();
+ currItem->setSelected(!currItem->isSelected());
+ emit(itemPressed(currItem));
+ }
+}
diff --git a/src/kiwixlistwidget.h b/src/kiwixlistwidget.h
new file mode 100644
index 00000000..0f4cd078
--- /dev/null
+++ b/src/kiwixlistwidget.h
@@ -0,0 +1,36 @@
+#ifndef KIWIXLISTWIDGET_H
+#define KIWIXLISTWIDGET_H
+
+#include
+
+class KiwixListWidget : public QListWidget {
+ Q_OBJECT
+
+public:
+ KiwixListWidget(QWidget *parent = nullptr);
+ void moveUp();
+ void moveDown();
+ void selectCurrent();
+ void selectCurrent(QListWidgetItem *item);
+ void setVisibleItems(int visibleItems) { m_visibleItems = visibleItems; }
+ int getVisibleItems() { return m_visibleItems; }
+
+protected:
+ void hideEvent(QHideEvent *event) override;
+ void resizeEvent(QResizeEvent *event) override;
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
+
+signals:
+ void currRowChanged(int oldRow, int newRow);
+
+private slots:
+ void handleCurrRowChange(int oldRow, int newRow);
+
+private:
+ int currRow;
+ int m_visibleItems;
+ int m_mouseIndex;
+};
+
+#endif // KIWIXLISTWIDGET_H
diff --git a/src/klistwidgetitem.cpp b/src/klistwidgetitem.cpp
index 574626a4..b77ef607 100644
--- a/src/klistwidgetitem.cpp
+++ b/src/klistwidgetitem.cpp
@@ -1,18 +1,41 @@
#include "klistwidgetitem.h"
+int KListWidgetItem::m_itemHeight = 35;
+
KListWidgetItem::KListWidgetItem(QString text)
: QListWidgetItem (text)
{
+ setSizeHint(QSize(200, m_itemHeight));
+ setBackground(QColor("white"));
+ setForeground(QColor("#666666"));
+}
+
+void KListWidgetItem::disableHighlight()
+{
+ isHighlighted = false;
+}
+
+void KListWidgetItem::enableHighlight()
+{
+ isHighlighted = true;
}
QVariant KListWidgetItem::data(int role) const
{
QVariant v = QListWidgetItem::data(role);
- if( isSelected() && role == Qt::FontRole )
- {
- QFont font = v.value();
- font.setBold( true );
- v = QVariant::fromValue( font );
+ if( isSelected()) {
+ if (role == Qt::FontRole) {
+ QFont font = v.value();
+ font.setBold( true );
+ v = QVariant::fromValue( font );
+ }
+ }
+ if (isHighlighted) {
+ if (role == Qt::BackgroundRole) {
+ v = QVariant::fromValue(QColor("#4e63ad"));
+ } else if (role == Qt::ForegroundRole) {
+ v = QVariant::fromValue(QColor("white"));
+ }
}
return v;
}
diff --git a/src/klistwidgetitem.h b/src/klistwidgetitem.h
index 2208c20d..493fe073 100644
--- a/src/klistwidgetitem.h
+++ b/src/klistwidgetitem.h
@@ -8,6 +8,12 @@ class KListWidgetItem : public QListWidgetItem
public:
KListWidgetItem(QString text);
QVariant data(int role) const;
+ static int getItemHeight() { return m_itemHeight; };
+ void disableHighlight();
+ void enableHighlight();
+private:
+ static int m_itemHeight;
+ bool isHighlighted = false;
};
#endif // KLISTWIDGETITEM_H
diff --git a/src/opdsrequestmanager.cpp b/src/opdsrequestmanager.cpp
index 209ee3bf..8a243028 100644
--- a/src/opdsrequestmanager.cpp
+++ b/src/opdsrequestmanager.cpp
@@ -15,7 +15,7 @@ void OpdsRequestManager::doUpdate(const QString& currentLanguage, const QString&
QStringList excludeTags("_sw:yes");
// Add filter by language (if necessary)
- if (currentLanguage != "*") {
+ if (currentLanguage != "") {
query.addQueryItem("lang", currentLanguage);
}
@@ -23,20 +23,10 @@ void OpdsRequestManager::doUpdate(const QString& currentLanguage, const QString&
query.addQueryItem("count", QString::number(-1));
// Add filter by category (if necessary)
- if (categoryFilter != "all" && categoryFilter != "other") {
- query.addQueryItem("tag", "_category:"+categoryFilter);
+ if (categoryFilter != "") {
+ query.addQueryItem("category", categoryFilter);
}
- // Add "special negative" filter for "other" category (if necessary)
- if (categoryFilter == "other") {
- for (auto& category: KiwixApp::instance()->getContentManager()->getCategories()) {
- if (category != "other" && category != "all") {
- excludeTags += "_category:"+category;
- }
- }
- }
- query.addQueryItem("notag", excludeTags.join(";"));
-
auto mp_reply = opdsResponseFromPath("/catalog/search", query);
connect(mp_reply, &QNetworkReply::finished, this, [=]() {
receiveContent(mp_reply);
diff --git a/src/searchbar.cpp b/src/searchbar.cpp
index d82a688e..c7a643c0 100644
--- a/src/searchbar.cpp
+++ b/src/searchbar.cpp
@@ -71,12 +71,7 @@ SearchBar::SearchBar(QWidget *parent) :
m_completer.setMaxVisibleItems(16);
setCompleter(&m_completer);
- QFile styleFile(":/css/popup.css");
- styleFile.open(QIODevice::ReadOnly);
- auto byteContent = styleFile.readAll();
- styleFile.close();
- QString style(byteContent);
- m_completer.popup()->setStyleSheet(style);
+ m_completer.popup()->setStyleSheet(KiwixApp::instance()->parseStyleFromFile(":/css/popup.css"));
qRegisterMetaType>("QVector");
connect(mp_typingTimer, &QTimer::timeout, this, &SearchBar::updateCompletion);
diff --git a/src/settingsmanager.cpp b/src/settingsmanager.cpp
index a0a7605c..b77657e6 100644
--- a/src/settingsmanager.cpp
+++ b/src/settingsmanager.cpp
@@ -4,6 +4,8 @@
#include
#include
#include
+#include
+
SettingsManager::SettingsManager(QObject *parent)
: QObject(parent),
m_settings("Kiwix", "Kiwix-desktop"),
@@ -96,6 +98,47 @@ void SettingsManager::setMoveToTrash(bool moveToTrash)
emit(moveToTrashChanged(m_moveToTrash));
}
+QList SettingsManager::flattenPair(FilterList pairList)
+{
+ QList res;
+ for (auto &pair : pairList) {
+ res.push_back(pair.first+"|"+pair.second);
+ }
+ return res;
+}
+
+SettingsManager::FilterList SettingsManager::deducePair(QList variantList)
+{
+ FilterList pairList;
+ for (auto &variant : variantList) {
+ QString str = variant.toString();
+ auto pairs = str.split('|');
+ pairList.push_back({pairs[0], pairs[1]});
+ }
+ return pairList;
+}
+
+void SettingsManager::setLanguage(FilterList langList)
+{
+ m_langList = flattenPair(langList);
+ setSettings("language", m_langList);
+ emit(languageChanged(m_langList));
+}
+
+void SettingsManager::setCategory(FilterList categoryList)
+{
+ m_categoryList = flattenPair(categoryList);
+ setSettings("category", m_categoryList);
+ emit(categoryChanged(m_categoryList));
+}
+
+void SettingsManager::setContentType(FilterList contentTypeList)
+{
+ m_contentTypeList = flattenPair(contentTypeList);
+ setSettings("contentType", m_contentTypeList);
+ emit(contentTypeChanged(m_contentTypeList));
+}
+
void SettingsManager::initSettings()
{
m_kiwixServerPort = m_settings.value("localKiwixServer/port", 8080).toInt();
@@ -104,4 +147,8 @@ void SettingsManager::initSettings()
m_kiwixServerIpAddress = m_settings.value("localKiwixServer/ipAddress", QString("0.0.0.0")).toString();
m_monitorDir = m_settings.value("monitor/dir", QString("")).toString();
m_moveToTrash = m_settings.value("moveToTrash", true).toBool();
+ QVariant defaultLang = QVariant::fromValue(QLocale::languageToString(QLocale().language()) + '|' + QLocale().name().split("_").at(0));
+ m_langList = m_settings.value("language", {defaultLang}).toList();
+ m_categoryList = m_settings.value("category", {}).toList();
+ m_contentTypeList = m_settings.value("contentType", {}).toList();
}
diff --git a/src/settingsmanager.h b/src/settingsmanager.h
index 501fe7eb..5646008d 100644
--- a/src/settingsmanager.h
+++ b/src/settingsmanager.h
@@ -13,6 +13,7 @@ class SettingsManager : public QObject
Q_PROPERTY(QString downloadDir MEMBER m_downloadDir WRITE setDownloadDir NOTIFY downloadDirChanged)
public:
+ typedef QList> FilterList;
explicit SettingsManager(QObject *parent = nullptr);
virtual ~SettingsManager() {};
@@ -28,6 +29,9 @@ class SettingsManager : public QObject
QString getDownloadDir() const { return m_downloadDir; }
QString getMonitorDir() const { return m_monitorDir; }
bool getMoveToTrash() const { return m_moveToTrash; }
+ FilterList getLanguageList() { return deducePair(m_langList); }
+ FilterList getCategoryList() { return deducePair(m_categoryList); }
+ FilterList getContentType() { return deducePair(m_contentTypeList); }
public slots:
void setKiwixServerPort(int port);
@@ -36,8 +40,13 @@ public slots:
void setDownloadDir(QString downloadDir);
void setMonitorDir(QString monitorDir);
void setMoveToTrash(bool moveToTrash);
+ void setLanguage(FilterList langList);
+ void setCategory(FilterList categoryList);
+ void setContentType(FilterList contentTypeList);
private:
void initSettings();
+ QList flattenPair(FilterList pairList);
+ FilterList deducePair(QList);
signals:
void portChanged(int port);
@@ -45,6 +54,9 @@ public slots:
void downloadDirChanged(QString downloadDir);
void monitorDirChanged(QString monitorDir);
void moveToTrashChanged(bool moveToTrash);
+ void languageChanged(QList langList);
+ void categoryChanged(QList categoryList);
+ void contentTypeChanged(QList contentTypeList);
private:
QSettings m_settings;
@@ -55,6 +67,9 @@ public slots:
QString m_downloadDir;
QString m_monitorDir;
bool m_moveToTrash;
+ QList m_langList;
+ QList m_categoryList;
+ QList m_contentTypeList;
};
#endif // SETTINGSMANAGER_H
diff --git a/src/settingsview.cpp b/src/settingsview.cpp
index 30f608b0..7b59b1a0 100644
--- a/src/settingsview.cpp
+++ b/src/settingsview.cpp
@@ -9,10 +9,7 @@ SettingsView::SettingsView(QWidget *parent)
, ui(new Ui::Settings)
{
ui->setupUi(this);
- QFile file(QString::fromUtf8(":/css/_settingsManager.css"));
- file.open(QFile::ReadOnly);
- QString styleSheet = QString(file.readAll());
- ui->widget->setStyleSheet(styleSheet);
+ ui->widget->setStyleSheet(KiwixApp::instance()->parseStyleFromFile(":/css/_settingsManager.css"));
connect(ui->zoomPercentSpinBox, QOverload::of(&QSpinBox::valueChanged), this, &SettingsView::setZoom);
connect(ui->moveToTrashToggle, &QCheckBox::clicked, this, &SettingsView::setMoveToTrash);
connect(ui->browseButton, &QPushButton::clicked, this, &SettingsView::browseDownloadDir);
diff --git a/ui/kiwixchoicebox.ui b/ui/kiwixchoicebox.ui
new file mode 100644
index 00000000..4d78a3a7
--- /dev/null
+++ b/ui/kiwixchoicebox.ui
@@ -0,0 +1,115 @@
+
+
+ kiwixchoicebox
+
+
+
+ 0
+ 0
+ 268
+ 54
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+
+
+
+ Form
+
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Plain
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ TextLabel
+
+
+
+ -
+
+
+
+ 50
+ 16777215
+
+
+
+ Clear
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 250
+ 0
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Expanding
+
+
+
+ 20
+ 5
+
+
+
+
+
+
+
+
+