File indexing completed on 2022-09-27 16:24:29

0001 /***************************************************************************
0002  *   Copyright (C) 2009-2011 by Daniel Nicoletti                           *
0003  *   dantti12@gmail.com                                                    *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU General Public License     *
0016  *   along with this program; see the file COPYING. If not, write to       *
0017  *   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,  *
0018  *   Boston, MA 02110-1301, USA.                                           *
0019  ***************************************************************************/
0020 
0021 #include <config.h>
0022 
0023 #include "FiltersMenu.h"
0024 
0025 #include <KConfig>
0026 #include <KConfigGroup>
0027 #include <KLocalizedString>
0028 
0029 FiltersMenu::FiltersMenu(QWidget *parent)
0030  : QMenu(parent)
0031 {
0032     // Loads the filter menu settings
0033     KConfig config(QLatin1String("apper"));
0034     KConfigGroup filterMenuGroup(&config, "FilterMenu");
0035 
0036     auto menuCollections = new QMenu(i18n("Collections"), this);
0037     connect(menuCollections, &QMenu::triggered, this, &FiltersMenu::filtersChanged);
0038 
0039     QAction *action = addMenu(menuCollections);
0040     connect(this, &FiltersMenu::enableCollections, action, &QAction::setVisible);
0041 
0042     auto collectionGroup = new QActionGroup(menuCollections);
0043     collectionGroup->setExclusive(true);
0044 
0045     QAction *collectionTrue = new QAction(i18n("Only collections"), collectionGroup);
0046     collectionTrue->setCheckable(true);
0047     m_filtersAction[collectionTrue] = Transaction::FilterCollections;
0048     collectionGroup->addAction(collectionTrue);
0049     menuCollections->addAction(collectionTrue);
0050     m_actions << collectionTrue;
0051 
0052     auto collectionFalse = new QAction(i18n("Exclude collections"), collectionGroup);
0053     collectionFalse->setCheckable(true);
0054     m_filtersAction[collectionFalse] = Transaction::FilterNotCollections;
0055     collectionGroup->addAction(collectionFalse);
0056     menuCollections->addAction(collectionFalse);
0057     m_actions << collectionFalse;
0058 
0059     // Installed
0060     auto menuInstalled = new QMenu(i18n("Installed"), this);
0061     connect(menuInstalled, &QMenu::triggered, this, &FiltersMenu::filtersChanged);
0062     connect(this, &FiltersMenu::enableInstalled, addMenu(menuInstalled), &QAction::setVisible);
0063     addMenu(menuInstalled);
0064     auto installedGroup = new QActionGroup(menuInstalled);
0065     installedGroup->setExclusive(true);
0066 
0067     auto installedTrue = new QAction(i18n("Only installed"), installedGroup);
0068     installedTrue->setCheckable(true);
0069     m_filtersAction[installedTrue] = Transaction::FilterInstalled;
0070     installedGroup->addAction(installedTrue);
0071     menuInstalled->addAction(installedTrue);
0072     m_actions << installedTrue;
0073 
0074     auto installedFalse = new QAction(i18n("Only available"), installedGroup);
0075     installedFalse->setCheckable(true);
0076     m_filtersAction[installedFalse] = Transaction::FilterNotInstalled;
0077     installedGroup->addAction(installedFalse);
0078     menuInstalled->addAction(installedFalse);
0079     m_actions << installedFalse;
0080 
0081     auto installedNone = new QAction(i18n("No filter"), installedGroup);
0082     installedNone->setCheckable(true);
0083     installedNone->setChecked(true);
0084     installedGroup->addAction(installedNone);
0085     menuInstalled->addAction(installedNone);
0086     m_actions << installedNone;
0087 
0088     // Development
0089     auto menuDevelopment = new QMenu(i18n("Development"), this);
0090     connect(menuDevelopment, &QMenu::triggered, this, &FiltersMenu::filtersChanged);
0091     connect(this, &FiltersMenu::enableDevelopment, addMenu(menuDevelopment), &QAction::setVisible);
0092     addMenu(menuDevelopment);
0093     auto developmentGroup = new QActionGroup(menuDevelopment);
0094     developmentGroup->setExclusive(true);
0095 
0096     auto developmentTrue = new QAction(i18n("Only development"), developmentGroup);
0097     developmentTrue->setCheckable(true);
0098     m_filtersAction[developmentTrue] = Transaction::FilterDevel;
0099     developmentGroup->addAction(developmentTrue);
0100     menuDevelopment->addAction(developmentTrue);
0101     m_actions << developmentTrue;
0102 
0103     auto developmentFalse = new QAction(i18n("Only end user files"), developmentGroup);
0104     developmentFalse->setCheckable(true);
0105     m_filtersAction[developmentFalse] = Transaction::FilterNotDevel;
0106     developmentGroup->addAction(developmentFalse);
0107     menuDevelopment->addAction(developmentFalse);
0108     m_actions << developmentFalse;
0109 
0110     auto developmentNone = new QAction(i18n("No filter"), developmentGroup);
0111     developmentNone->setCheckable(true);
0112     developmentNone->setChecked(true);
0113     developmentGroup->addAction(developmentNone);
0114     menuDevelopment->addAction(developmentNone);
0115     m_actions << developmentNone;
0116 
0117     // Graphical
0118     auto menuGui = new QMenu(i18n("Graphical"), this);
0119     connect(menuGui, &QMenu::triggered, this, &FiltersMenu::filtersChanged);
0120     connect(this, &FiltersMenu::enableGraphical, addMenu(menuGui), &QAction::setVisible);
0121     addMenu(menuGui);
0122     auto guiGroup = new QActionGroup(menuGui);
0123     guiGroup->setExclusive(true);
0124 
0125     auto guiTrue = new QAction(i18n("Only graphical"), guiGroup);
0126     guiTrue->setCheckable(true);
0127     m_filtersAction[guiTrue] = Transaction::FilterGui;
0128     guiGroup->addAction(guiTrue);
0129     menuGui->addAction(guiTrue);
0130     m_actions << guiTrue;
0131 
0132     auto guiFalse = new QAction(i18n("Only text"), guiGroup);
0133     guiFalse->setCheckable(true);
0134     m_filtersAction[guiFalse] = Transaction::FilterNotGui;
0135     guiGroup->addAction(guiFalse);
0136     menuGui->addAction(guiFalse);
0137     m_actions << guiFalse;
0138 
0139     auto guiNone = new QAction(i18n("No filter"), guiGroup);
0140     guiNone->setCheckable(true);
0141     guiNone->setChecked(true);
0142     guiGroup->addAction(guiNone);
0143     menuGui->addAction(guiNone);
0144     m_actions << guiNone;
0145 
0146     // Free
0147     auto menuFree = new QMenu(i18nc("Filter for free packages", "Free"), this);
0148     connect(menuFree, &QMenu::triggered, this, &FiltersMenu::filtersChanged);
0149     connect(this, &FiltersMenu::enableFree, addMenu(menuFree), &QAction::setVisible);
0150     addMenu(menuFree);
0151     auto freeGroup = new QActionGroup(menuFree);
0152     freeGroup->setExclusive(true);
0153 
0154     auto freeTrue = new QAction(i18n("Only free software"), freeGroup);
0155     freeTrue->setCheckable(true);
0156     m_filtersAction[freeTrue] = Transaction::FilterFree;
0157     freeGroup->addAction(freeTrue);
0158     menuFree->addAction(freeTrue);
0159     m_actions << freeTrue;
0160 
0161     auto freeFalse = new QAction(i18n("Only non-free software"), freeGroup);
0162     freeFalse->setCheckable(true);
0163     m_filtersAction[freeFalse] = Transaction::FilterNotFree;
0164     freeGroup->addAction(freeFalse);
0165     menuFree->addAction(freeFalse);
0166     m_actions << freeFalse;
0167 
0168     auto freeNone = new QAction(i18n("No filter"), freeGroup);
0169     freeNone->setCheckable(true);
0170     freeNone->setChecked(true);
0171     freeGroup->addAction(freeNone);
0172     menuFree->addAction(freeNone);
0173     m_actions << freeNone;
0174 
0175     // Supported
0176     auto menuSupported = new QMenu(i18nc("Filter for supported packages", "Supported"), this);
0177     connect(menuSupported, &QMenu::triggered, this, &FiltersMenu::filtersChanged);
0178     connect(this, &FiltersMenu::enableSupported, addMenu(menuSupported), &QAction::setVisible);
0179     addMenu(menuSupported);
0180     auto supportedGroup = new QActionGroup(menuSupported);
0181     supportedGroup->setExclusive(true);
0182 
0183     auto supportedTrue = new QAction(i18n("Only supported software"), supportedGroup);
0184     supportedTrue->setCheckable(true);
0185     m_filtersAction[supportedTrue] = Transaction::FilterSupported;
0186     supportedGroup->addAction(supportedTrue);
0187     menuSupported->addAction(supportedTrue);
0188     m_actions << supportedTrue;
0189 
0190     auto supportedFalse = new QAction(i18n("Only non-supported software"), supportedGroup);
0191     supportedFalse->setCheckable(true);
0192     m_filtersAction[supportedFalse] = Transaction::FilterNotSupported;
0193     supportedGroup->addAction(supportedFalse);
0194     menuSupported->addAction(supportedFalse);
0195     m_actions << supportedFalse;
0196 
0197     auto supportedNone = new QAction(i18n("No filter"), supportedGroup);
0198     supportedNone->setCheckable(true);
0199     supportedNone->setChecked(true);
0200     supportedGroup->addAction(supportedNone);
0201     menuSupported->addAction(supportedNone);
0202     m_actions << supportedNone;
0203 
0204     // Source
0205     auto menuSource = new QMenu(i18nc("Filter for source packages", "Source"), this);
0206     connect(menuSource, &QMenu::triggered, this, &FiltersMenu::filtersChanged);
0207     connect(this, &FiltersMenu::enableSource, addMenu(menuSource), &QAction::setVisible);
0208     addMenu(menuSource);
0209     auto sourceGroup = new QActionGroup(menuSource);
0210     sourceGroup->setExclusive(true);
0211 
0212     auto sourceTrue = new QAction(i18n("Only sourcecode"), sourceGroup);
0213     sourceTrue->setCheckable(true);
0214     m_filtersAction[sourceTrue] = Transaction::FilterSource;
0215     sourceGroup->addAction(sourceTrue);
0216     menuSource->addAction(sourceTrue);
0217     m_actions << sourceTrue;
0218 
0219     auto sourceFalse = new QAction(i18n("Only non-sourcecode"), sourceGroup);
0220     sourceFalse->setCheckable(true);
0221     m_filtersAction[sourceFalse] = Transaction::FilterNotSource;
0222     sourceGroup->addAction(sourceFalse);
0223     menuSource->addAction(sourceFalse);
0224     m_actions << sourceFalse;
0225 
0226     auto sourceNone = new QAction(i18n("No filter"), sourceGroup);
0227     sourceNone->setCheckable(true);
0228     sourceNone->setChecked(true);
0229     sourceGroup->addAction(sourceNone);
0230     menuSource->addAction(sourceNone);
0231     m_actions << sourceNone;
0232 
0233     // Basename, Newest, Arch separator
0234     connect(this, &FiltersMenu::enableBasenameNewestArchSeparator, addSeparator(), &QAction::setVisible);
0235 
0236     auto basename = new QAction(i18n("Hide Subpackages"), this);
0237     connect(basename, &QAction::triggered, this, &FiltersMenu::filtersChanged);
0238     connect(this, &FiltersMenu::enableBasename, basename, &QAction::setVisible);
0239     basename->setCheckable(true);
0240     basename->setToolTip(i18n("Only show one package, not subpackages"));
0241     m_filtersAction[basename] = Transaction::FilterBasename;
0242     m_actions << basename;
0243 
0244     auto newest = new QAction(i18n("Only Newest Packages"), this);
0245     connect(newest, &QAction::triggered, this, &FiltersMenu::filtersChanged);
0246     connect(this, &FiltersMenu::enableNewest, newest, &QAction::setVisible);
0247     newest->setCheckable(true);
0248     newest->setChecked(filterMenuGroup.readEntry("FilterNewest", true));
0249     newest->setToolTip(i18n("Only show the newest available package"));
0250     m_filtersAction[newest] = Transaction::FilterNewest;
0251     m_actions << newest;
0252 
0253     auto native = new QAction(i18n("Only Native Packages"), this);
0254     connect(native, &QAction::triggered, this, &FiltersMenu::filtersChanged);
0255     connect(this, &FiltersMenu::enableArch, native, &QAction::setVisible);
0256     native->setCheckable(true);
0257     native->setChecked(filterMenuGroup.readEntry("FilterNative", true));
0258     native->setToolTip(i18n("Only show packages matching the machine architecture"));
0259     m_filtersAction[native] = Transaction::FilterArch;
0260     m_actions << native;
0261 
0262 #ifdef HAVE_APPSTREAM
0263     addSeparator();
0264     m_applications = new QAction(i18n("Only Show Applications"), this);
0265     m_applications->setCheckable(true);
0266     m_applications->setChecked(filterMenuGroup.readEntry("HidePackages", false));
0267     m_applications->setToolTip(i18n("Hide packages that are not applications"));
0268     addAction(m_applications);
0269     connect(m_applications, SIGNAL(triggered(bool)),
0270             this, SIGNAL(filterApplications(bool)));
0271 #endif // HAVE_APPSTREAM
0272 }
0273 
0274 FiltersMenu::~FiltersMenu()
0275 {
0276     KConfig config(QLatin1String("apper"));
0277     KConfigGroup filterMenuGroup(&config, "FilterMenu");
0278 
0279     // For usability we will only save ViewInGroups settings and Newest filter,
0280     // - The user might get angry when he does not find any packages because he didn't
0281     //   see that a filter is set by config
0282 
0283     // This entry does not depend on the backend it's ok to call this pointer
0284 //     filterMenuGroup.writeEntry("ViewInGroups", m_filtersMenu->actionGrouped());
0285 
0286     // This entry does not depend on the backend it's ok to call this pointer
0287     filterMenuGroup.writeEntry("FilterNewest",
0288                                static_cast<bool>(filters() & Transaction::FilterNewest));
0289     // This entry does not depend on the backend it's ok to call this pointer
0290     filterMenuGroup.writeEntry("FilterNative",
0291                                static_cast<bool>(filters() & Transaction::FilterArch));
0292 #ifdef HAVE_APPSTREAM
0293     filterMenuGroup.writeEntry("HidePackages", m_applications->isChecked());
0294 #endif // HAVE_APPSTREAM
0295 }
0296 
0297 void FiltersMenu::setFilters(Transaction::Filters filters)
0298 {
0299     emit enableCollections(filters & Transaction::FilterCollections || filters & Transaction::FilterNotCollections);
0300     emit enableInstalled(filters & Transaction::FilterInstalled || filters & Transaction::FilterNotInstalled);
0301     emit enableDevelopment(filters & Transaction::FilterDevel || filters & Transaction::FilterNotDevel);
0302     emit enableGraphical(filters & Transaction::FilterGui || filters & Transaction::FilterNotGui);
0303     emit enableFree(filters & Transaction::FilterFree || filters & Transaction::FilterNotFree);
0304     emit enableSupported(filters & Transaction::FilterSupported || filters & Transaction::FilterNotSupported);
0305     emit enableSource(filters & Transaction::FilterSource || filters & Transaction::FilterNotSource);
0306     emit enableBasenameNewestArchSeparator(filters & Transaction::FilterBasename ||
0307                                            filters & Transaction::FilterNewest ||
0308                                            filters & Transaction::FilterArch);
0309     emit enableBasename(filters & Transaction::FilterBasename);
0310     emit enableNewest(filters & Transaction::FilterNewest);
0311     emit enableArch(filters & Transaction::FilterArch);
0312 }
0313 
0314 bool FiltersMenu::filterApplications() const
0315 {
0316 #ifdef HAVE_APPSTREAM
0317     return m_applications->isChecked();
0318 #else
0319     return false;
0320 #endif // HAVE_APPSTREAM
0321 }
0322 
0323 Transaction::Filters FiltersMenu::filters() const
0324 {
0325     Transaction::Filters filters;
0326     bool filterSet = false;
0327     const QVector<QAction*> actions = m_actions;
0328     for (QAction * const action : actions) {
0329         if (action->isChecked()) {
0330             if (m_filtersAction.contains(action)) {
0331                 filters |= m_filtersAction[action];
0332                 filterSet = true;
0333             }
0334         }
0335     }
0336     if (!filterSet) {
0337         filters = Transaction::FilterNone;
0338     }
0339     return filters;
0340 }
0341 
0342 #include "moc_FiltersMenu.cpp"