2 This file is part of Faster Application Manager.
4 Faster Application Manager is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 Faster Application Manager is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with Faster Application Manager. If not, see <http://www.gnu.org/licenses/>.
17 (C) Heikki Holstila 2010
20 #include "packageview.h"
21 #include "ui_packageview.h"
23 #include "filterselect.h"
24 #include "confirmdialog.h"
26 #include "packageselector.h"
28 #include "aaptinterface.h"
30 #include "sortselector.h"
32 #include "searchoptions.h"
33 #include "blacklistselect.h"
35 PackageListWidgetItem::PackageListWidgetItem(Package* p_, QString name_) : QListWidgetItem(name_)
41 void ListItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
46 QString name = index.data(UserRoleName).toString();
47 QString version = index.data(UserRoleVersion).toString();
48 QString desc = index.data(UserRoleDescShort).toString();
49 Package::operation marked = (Package::operation) index.data(UserRoleMarked).toInt();
50 bool installed = index.data(UserRoleInstalled).toBool();
51 bool upgradeable = index.data(UserRoleUpgradeable).toBool();
52 int statfilter = index.data(UserRoleCurrentStatFilter).toInt();
53 int catfilter = index.data(UserRoleCurrentCatFilter).toInt();
54 QString upg_version = index.data(UserRoleAvailVersion).toString();
55 BlacklistSelect::blackList blacklisted = static_cast<BlacklistSelect::blackList>( index.data(UserRoleBlacklisted).toInt() );
58 QRect r = option.rect;
60 QPixmap icon = index.data(Qt::DecorationRole).value<QPixmap>();
63 painter->drawPixmap( r.left()+6, r.top()+10, 48, 48, iDefaultIcon );
65 painter->drawPixmap( r.left()+6, r.top()+10, 48, 48, icon );
69 if( marked == Package::PkgOpNone )
71 if( installed && upgradeable )
72 statusicon = iIconPkgNoOpInstalledUpgradeable;
74 statusicon = iIconPkgNoOpInstalled;
76 statusicon = iIconPkgNoOpNotInstalled;
77 } else if( marked == Package::PkgOpInstallUpgrade ) {
79 statusicon = iIconPkgUpgrade;
81 statusicon = iIconPkgInstall;
82 } else if( marked == Package::PkgOpRemove ) {
83 statusicon = iIconPkgRemove;
87 if( upgradeable && (statfilter==Package::PkgStatUpgradeable ||
88 (statfilter==Package::PkgStatUnknown && marked==Package::PkgOpInstallUpgrade) ||
89 (catfilter==PackageView::CatFilterAllMarked && marked==Package::PkgOpInstallUpgrade) ))
91 showVer = upg_version;
97 if( QApplication::desktop()->width() > QApplication::desktop()->height() )
100 r.setTop( r.top()+6 );
101 r.setRight( r.right()-statusicon.width()-6 );
103 if( catfilter != PackageView::CatFilterBlacklisted ) {
104 painter->drawText(r, Qt::AlignTop|Qt::AlignRight, showVer, &r);
106 } else if( blacklisted==BlacklistSelect::BlacklistThis ) {
107 if( upgradeable && !upg_version.isEmpty() ) {
108 showVer = upg_version;
112 painter->drawText(r, Qt::AlignTop|Qt::AlignRight, showVer, &r);
118 r.setRight( r.right()-statusicon.width()-4-ver_w ); //does not work as it should?
119 QFont f = painter->font();
121 painter->drawText(r.left()+iDefaultIcon.width()+2, r.top()+5, r.width(), r.height(), Qt::AlignTop|Qt::AlignLeft, name, &r);
123 f.setPointSize( f.pointSize()-4 );
127 gray = QColor(156, 154, 156);
131 painter->setPen(gray);
132 r.setBottom(r.bottom()-10);
133 painter->drawText(r.left()+iDefaultIcon.width()+2, r.top(), r.width(), r.height(), Qt::AlignBottom|Qt::AlignLeft, desc, &r);
137 painter->drawPixmap(r.right()-statusicon.width()-2, r.top()+10, 24, 24, statusicon);
141 //if( t.elapsed()>=100 )
142 //qDebug() << name << t.elapsed();
145 void ListItemDelegate::loadIcons()
148 iDefaultIcon = QPixmap("/usr/share/icons/hicolor/64x64/hildon/tasklaunch_default_application.png");
150 iDefaultIcon = QPixmap(":/icons/icons/appdefault.png");
152 iIconPkgInstall = QPixmap(":/icons/icons/pkg_install.png");
153 iIconPkgUpgrade = QPixmap(":/icons/icons/pkg_upgrade.png");
154 iIconPkgRemove = QPixmap(":/icons/icons/pkg_remove.png");
155 iIconPkgNoOpInstalled = QPixmap(":/icons/icons/pkg_nop_installed.png");
156 iIconPkgNoOpNotInstalled = QPixmap(":/icons/icons/pkg_nop_notinstalled.png");
157 iIconPkgNoOpInstalledUpgradeable = QPixmap(":/icons/icons/pkg_nop_instupgr.png");
161 QSize ListItemDelegate::sizeHint(const QStyleOptionViewItem&, const QModelIndex&) const
163 return QSize(400, 70);
167 PackageView::PackageView(QWidget *parent) : QMainWindow(parent), ui(new Ui::PackageView)
169 iMainWindow = dynamic_cast<MainWindow*>(parent);
172 this->setAttribute(Qt::WA_Maemo5StackedWindow);
173 this->setWindowFlags(Qt::Window);
174 this->setAttribute(Qt::WA_Maemo5AutoOrientation);
179 connect(QApplication::desktop(), SIGNAL(resized(int)), this, SLOT(orientationChanged()));
182 << tr("All marked packages") // a special case
183 << tr("All user categories")
188 << tr("\tInternet & Networking")
189 << tr("\tLocation & Navigation")
190 << tr("\tMultimedia")
193 << tr("\tProgramming")
197 << tr("All packages (ADVANCED)")
198 << tr("Blacklisted packages"); // a special case
212 << "user/development"
219 iDefaultCatFilter = CatFilterAllUser;
220 iSelectedCatFilter = iDefaultCatFilter;
224 << tr("Not installed")
228 iSelectedStatFilter = Package::PkgStatUnknown;
229 iSortOrder = SortAlpha;
231 iDimmer = new dimmer(this);
233 ui->searchBar->hide();
235 iListCoverLabel = new QLabel(ui->listWidget);
236 iListCoverLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
237 iListCoverLabel->setAlignment(Qt::AlignCenter);
239 iKeyFilter = new KeyEventGrabber(this);
240 ui->listWidget->installEventFilter(iKeyFilter);
242 iSortNoticeShown = false;
244 iSearchPkgName = true;
245 iSearchDisplayName = true;
246 iSearchDescShort = true;
247 iSearchDescLong = false;
249 // fine-tune kinetic scrolling parameters
251 QAbstractKineticScroller* listscroller = ui->listWidget->property("kineticScroller").value<QAbstractKineticScroller*>();
254 //qDebug() << listscroller->dragInertia() << listscroller->decelerationFactor()
255 // << listscroller->minimumVelocity() << listscroller->maximumVelocity();
256 listscroller->setDecelerationFactor(0.75); // default is 0.85
257 listscroller->setDragInertia(0.60); // default is 0.85
258 listscroller->setMaximumVelocity(1800); // default is 3500
260 // not good because it alse sets horizontal overshoot:
261 //listscroller->setOvershootPolicy( QAbstractKineticScroller::OvershootAlwaysOn );
266 PackageView::~PackageView()
268 delete iListCoverLabel; iListCoverLabel=0;
269 delete iKeyFilter; iKeyFilter=0;
270 delete iDimmer; iDimmer=0;
274 void PackageView::orientationChanged()
276 ui->listWidget->scroll(1,1); // this causes all items to be repainted
277 iListCoverLabel->setGeometry( ui->listWidget->rect() );
280 void PackageView::resizeEvent(QResizeEvent* event)
283 iDimmer->resize( this->size() );
286 iListCoverLabel->setGeometry( ui->listWidget->rect() );
287 QWidget::resizeEvent(event);
290 bool PackageView::doFilterCategory(Package* pkg)
292 if( pkg->section()=="user/hidden" && iSelectedStatFilter!=Package::PkgStatInstalled && iSelectedStatFilter!=Package::PkgStatUnknown )
294 if( pkg->section()=="user/hidden" && !pkg->isInstalled() )
297 Package* upg_pkg = pkg->availablePackage();
299 if( iSelectedStatFilter==Package::PkgStatUpgradeable && iSelectedCatFilter!=CatFilterBlacklisted &&
300 pkg->isUpgradeable() && upg_pkg && upg_pkg->isBlacklisted() )
303 if( pkg->isBlacklisted() || (upg_pkg && upg_pkg->isBlacklisted()) )
305 if( iSelectedCatFilter == CatFilterBlacklisted )
307 if( pkg->isInstalled() && (iSelectedStatFilter==Package::PkgStatInstalled || iSelectedStatFilter==Package::PkgStatUnknown) )
309 if( pkg->isBlacklisted() && iSelectedCatFilter != CatFilterBlacklisted )
311 } else if( !pkg->isBlacklisted() && iSelectedCatFilter == CatFilterBlacklisted )
314 if( iSelectedCatFilter==CatFilterAllMarked ) {
315 if( pkg->isMarkedForOperation() )
320 if( pkg->section().startsWith( iCatFilterStrings.at(iSelectedCatFilter) ) )
326 QString PackageView::generateSortString(Package* pkg)
330 if( iSortOrder==SortAlpha ) {
331 sortstr = pkg->displayName();
333 else if( iSortOrder==SortDateDesc ) {
335 if( pkg->isUpgradeable() )
336 upg = pkg->availablePackage();
338 if( (!upg && pkg->date().isValid()) || iSelectedStatFilter==Package::PkgStatInstalled )
339 sortstr = pkg->date().toString("yyyy-MM-dd hh:mm:ss");
340 else if( upg && upg->date().isValid() ) {
341 sortstr = upg->date().toString("yyyy-MM-dd hh:mm:ss");
344 iPackagesEmptySort++;
347 else if( iSortOrder==SortSizeDesc ) {
348 if( pkg->isInstalled() )
349 sortstr = QString("%1").arg(pkg->installedSize()*1024, 12 );
351 sortstr = QString("%1").arg(pkg->size(), 12 );
354 //qDebug() << sortstr;
359 void PackageView::openWin()
361 ui->listWidget->clear();
362 ui->listWidget->setSortingEnabled(true);
363 iPackagesEmptySort = 0;
366 iMainWindow->busyDialog(false);
367 iListCoverLabel->setText("Loading...");
368 iListCoverLabel->setAutoFillBackground(true);
369 iListCoverLabel->show();
371 QApplication::processEvents();
374 if( iSortOrder==SortDateDesc || iSortOrder==SortSizeDesc )
375 ui->listWidget->sortItems(Qt::DescendingOrder);
377 ui->listWidget->sortItems(Qt::AscendingOrder);
379 delete ui->listWidget->itemDelegate();
380 ListItemDelegate* delegate = new ListItemDelegate(ui->listWidget);
381 delegate->loadIcons();
382 ui->listWidget->setItemDelegate( delegate );
384 if( !ui->searchBar->isVisible() )
386 if( iSelectedStatFilter == Package::PkgStatNotInstalled || iSelectedStatFilter == Package::PkgStatUnknown ||
387 iSelectedCatFilter == CatFilterAllMarked || iSelectedCatFilter == CatFilterBlacklisted )
389 QHashIterator<QString, Package*> i( *iAptInterface->packagesAvailable() );
393 Package* inst = iAptInterface->packagesInstalled()->value(i.value()->name(),0);
394 if( doFilterCategory(i.value()) && !inst )
395 addListItem(i.value(), generateSortString(i.value()));
398 if( iSelectedStatFilter == Package::PkgStatInstalled || iSelectedStatFilter == Package::PkgStatUpgradeable ||
399 iSelectedStatFilter == Package::PkgStatUnknown || iSelectedCatFilter == CatFilterAllMarked ||
400 iSelectedCatFilter == CatFilterBlacklisted )
402 QHashIterator<QString, Package*> i( *iAptInterface->packagesInstalled() );
406 if( iSelectedStatFilter == Package::PkgStatUpgradeable && iSelectedCatFilter != CatFilterBlacklisted ) {
407 if( i.value()->isUpgradeable() && doFilterCategory(i.value()) )
408 addListItem(i.value(), generateSortString(i.value()));
410 if( doFilterCategory(i.value()) )
411 addListItem(i.value(), generateSortString(i.value()));
416 for( int j=0; j<iSearchResults.count(); j++ )
418 addListItem(iSearchResults.at(j), generateSortString( iSearchResults.at(j) ));
422 iListCoverLabel->hide();
423 iListCoverLabel->setAutoFillBackground(false);
427 if( iSelectedStatFilter==Package::PkgStatUpgradeable && ui->listWidget->count()>0 &&
428 iSelectedCatFilter != CatFilterAllMarked && iSelectedCatFilter != CatFilterBlacklisted )
430 ui->actionUpgrade_all->setVisible(true);
432 ui->actionUpgrade_all->setVisible(false);
435 if( iSelectedCatFilter == CatFilterBlacklisted && ui->listWidget->count()>0 ) {
436 ui->actionRestore_all->setVisible(true);
438 ui->actionRestore_all->setVisible(false);
441 if( iSelectedStatFilter==Package::PkgStatInstalled ) {
442 ui->actionStore_list->setVisible(true);
444 ui->actionStore_list->setVisible(false);
449 if( !ui->searchBar->isVisible() ) {
450 ui->listWidget->setFocusPolicy(Qt::StrongFocus);
451 ui->listWidget->setFocus();
453 ui->listWidget->setFocusPolicy(Qt::NoFocus);
454 ui->lineEdit->setFocus();
457 if( ui->listWidget->count() == 0 )
459 iListCoverLabel->setGeometry( ui->listWidget->rect() );
460 iListCoverLabel->setText("No packages");
461 iListCoverLabel->show();
464 if( ui->listWidget->count()>1 && iPackagesEmptySort == ui->listWidget->count() && !iSortNoticeShown ) {
465 ConfirmDialog d(false, this);
466 QString msg = "No shown packages currently have the required information for sorting by this criterion. The list is unsorted.";
467 if( iSortOrder == SortDateDesc && !iSettings->qsettings()->value("fetch_dates",false).toBool() )
468 msg += " You can enable date fetching in the options menu.";
469 d.setText("Notice", msg);
471 iSortNoticeShown = true;
475 void PackageView::enableMenu()
477 ui->menuMenu->setEnabled(true);
480 void PackageView::disableMenu()
482 ui->menuMenu->setEnabled(false);
485 void PackageView::addListItem(Package* pkg_, QString listname_)
487 PackageListWidgetItem* p = new PackageListWidgetItem( pkg_, listname_ );
491 QString name = pkg_->name();
492 if( !pkg_->maemoDisplayName().isEmpty() )
493 name = pkg_->maemoDisplayName();
494 p->setData(UserRoleName, name);
496 p->setData(UserRoleName, listname_);
501 p->setData(UserRoleDescShort, pkg_->descShort());
502 p->setData(UserRoleVersion, pkg_->version());
503 p->setData(UserRoleMarked, static_cast<int>(pkg_->markedOperation()) );
504 p->setData(UserRoleInstalled, pkg_->isInstalled());
505 p->setData(UserRoleUpgradeable, pkg_->isUpgradeable());
506 p->setData(UserRoleAvailVersion, pkg_->upgradeableVersion());
507 p->setData(UserRoleCurrentStatFilter, iSelectedStatFilter);
508 p->setData(UserRoleCurrentCatFilter, iSelectedCatFilter);
510 if( pkg_->availablePackage() )
511 p->setData(UserRoleBlacklisted, static_cast<int>(pkg_->availablePackage()->blacklisted()) );
513 p->setData(UserRoleBlacklisted, static_cast<int>(pkg_->blacklisted()) );
515 //qDebug() << pkg_->name();
518 p->setData(Qt::DecorationRole, *pkg_->icon());
520 ui->listWidget->addItem( p );
523 void PackageView::closeEvent(QCloseEvent *event)
525 if( !iAptInterface ) {
530 if( iDimmer->busy() )
532 iAptInterface->cancel();
537 if( iAptInterface->numSelectedPackages() == 0 )
543 c.setNum( iAptInterface->numSelectedPackages() );
544 ConfirmDialog d(true, this);
545 d.setText("Returning to main menu", QString("Clear %1 package selection(s) and lose all the pending changes?").arg(iAptInterface->numSelectedPackages()));
555 void PackageView::changeEvent(QEvent *e)
557 QMainWindow::changeEvent(e);
559 case QEvent::LanguageChange:
560 ui->retranslateUi(this);
567 void PackageView::on_btn_Commit_clicked()
569 QStringList pkgnames;
571 QHashIterator<QString, Package*> i( *iAptInterface->packagesAvailable() );
576 if( i.value()->markedOperation() == Package::PkgOpInstallUpgrade )
577 pkgnames << i.value()->name();
578 if( i.value()->markedOperation() == Package::PkgOpRemove ) {
579 qDebug() << "warning: trying to add package marked from the wrong list";
580 //pkgnames << i.value()->name() + "-";
584 QHashIterator<QString, Package*> r( *iAptInterface->packagesInstalled() );
589 if( r.value()->markedOperation() == Package::PkgOpInstallUpgrade )
590 pkgnames << r.value()->name();
591 if( r.value()->markedOperation() == Package::PkgOpRemove )
592 pkgnames << r.value()->name() + "-";
595 iMainWindow->busyDialog(true, "Operation in progress", "Reading dependencies");
597 iAptInterface->setProcessPackages(pkgnames);
598 iAptInterface->addQueuedOperation(AAptInterface::ModeAptGetSimulate);
599 iAptInterface->run(iDimmer);
602 void PackageView::on_actionClear_selections_triggered()
605 c.setNum( iAptInterface->numSelectedPackages() );
606 ConfirmDialog d(true, this);
607 d.setText(tr("Confirmation"), tr("Clear ") + c + tr(" package selection(s) and lose all the pending changes?"));
615 void PackageView::clearSelections()
617 QHashIterator<QString, Package*> i( *iAptInterface->packagesInstalled() );
621 i.value()->setMarkedForOperation(Package::PkgOpNone);
623 QHashIterator<QString, Package*> a( *iAptInterface->packagesAvailable() );
627 a.value()->setMarkedForOperation(Package::PkgOpNone);
629 iAptInterface->setNumSelectedPackages(0);
632 void PackageView::on_listWidget_itemClicked(QListWidgetItem* item)
634 Package* pkg = dynamic_cast<PackageListWidgetItem*>(item)->package();
638 bool bl = pkg->isBlacklisted();
641 Package* upg_pkg = pkg->availablePackage();
643 bl_u = upg_pkg->isBlacklisted();
645 PackageSelector s(pkg, iAptInterface, iSettings, iMainWindow, this);
647 Package::operation op = s.selectedOperation();
649 QStringList confl = pkg->checkConflicts_RichText();
650 if( confl.count() > 0 && op != Package::PkgOpNone ) {
651 ConfirmDialog d(true, this);
652 QString t = "Package " + pkg->name() + " conflicts with another installed or marked package. Mark anyway?";
653 t += "<font size=\"-1\"><br><br>Conflicts: ";
654 t += confl.join(", ");
656 d.setText("Conflicting packages", t);
658 op = Package::PkgOpNone;
661 if( pkg->isPinned() && op != Package::PkgOpNone ) {
662 ConfirmDialog d(true, this);
663 d.setText("Warning","Package has been pinned in apt preferences. Operation might not go as expected. Mark anyway?");
665 op = Package::PkgOpNone;
668 pkg->setMarkedForOperation( op );
669 item->setData( UserRoleMarked, (int)op );
672 if( pkg->isBlacklisted() != bl ) {
675 else if( upg_pkg && upg_pkg->isBlacklisted() != bl_u ) {
680 void PackageView::updateLabel()
683 s.setNum( iAptInterface->numSelectedPackages() );
685 s2.setNum( ui->listWidget->count() );
686 QString statlabel = iStatFilterLabels.at(iSelectedStatFilter);
687 if( iSelectedCatFilter == CatFilterAllMarked || iSelectedCatFilter == CatFilterBlacklisted )
689 ui->label->setText("<font size=\"-2\"><b>" + s + "</b> package(s) marked<br>"
690 + "Showing: <b>" + statlabel + "</b><br>"
691 + "Filter: " + iCatFilterLabels.at(iSelectedCatFilter) + " - " + s2 + " package(s)</font>");
693 if( iAptInterface->numSelectedPackages()==0 ) {
694 ui->btn_Commit->setEnabled(false);
695 ui->actionClear_selections->setVisible(false);
696 ui->actionSave_selections->setVisible(false);
698 ui->btn_Commit->setEnabled(true);
699 ui->actionClear_selections->setVisible(true);
700 ui->actionSave_selections->setVisible(true);
704 void PackageView::on_btn_CategoryFilter_clicked()
706 FilterSelect f("Category filter", this);
707 f.setList( iCatFilterLabels, iSelectedCatFilter );
712 iSelectedCatFilter = f.selection();
714 if( iSelectedCatFilter == CatFilterAllMarked || iSelectedCatFilter == CatFilterBlacklisted ) {
715 ui->btn_StatusFilter->setEnabled(false);
717 ui->btn_StatusFilter->setEnabled(true);
721 iListCoverLabel->setText("Loading...");
722 iListCoverLabel->setAutoFillBackground(true);
723 iListCoverLabel->show();
724 QApplication::processEvents();
725 iSortNoticeShown = false;
729 if( iSelectedCatFilter==CatFilterBlacklisted && iAptInterface->needListOrDateRefresh() )
731 ConfirmDialog d(false, this);
732 d.setText("Notice","Since you don't have all package lists currently loaded, not all blacklisted "
733 "packages are necessarily shown");
739 void PackageView::setStatFilter(Package::packageStatus f_)
741 iSelectedStatFilter = f_;
744 void PackageView::on_btn_StatusFilter_clicked()
746 FilterSelect f("Status filter", this);
747 f.setList( iStatFilterLabels, iSelectedStatFilter );
749 int oldfilter = iSelectedStatFilter;
754 iSelectedStatFilter = (Package::packageStatus)f.selection();
756 iListCoverLabel->setText("Loading...");
757 iListCoverLabel->setAutoFillBackground(true);
758 iListCoverLabel->show();
759 QApplication::processEvents();
760 iSortNoticeShown = false;
764 if( oldfilter==Package::PkgStatInstalled && iSelectedStatFilter!=Package::PkgStatInstalled &&
765 iAptInterface->needListOrDateRefresh() )
767 iMainWindow->openNetworkConnection();
769 iMainWindow->setNextOperation(MainWindow::OpOpenPkgView);
770 iMainWindow->busyDialog(true,"Operation in progress","Reading the rest of the package lists");
772 if( iAptInterface->needRepoRefresh() && !iSettings->qsettings()->value("no_catalogs_autoupdate",false).toBool() )
773 iAptInterface->addQueuedOperation(AAptInterface::ModeAptGetUpdate);
775 iAptInterface->addQueuedOperation(AAptInterface::ModeReadPackages);
776 iAptInterface->addQueuedOperation(AAptInterface::ModeFetchDates);
777 iAptInterface->run(iDimmer);
782 void PackageView::resetWindow()
784 iAptInterface->writeBlacklist();
786 ui->btn_StatusFilter->setEnabled(true);
787 iSelectedCatFilter = iDefaultCatFilter;
788 //iSortOrder = SortAlpha;
789 iSortNoticeShown = false;
795 void PackageView::on_actionHelp_triggered()
801 void PackageView::on_btn_searchClose_clicked()
805 iListCoverLabel->setText("Loading...");
806 iListCoverLabel->setAutoFillBackground(true);
807 iListCoverLabel->show();
808 QApplication::processEvents();
813 void PackageView::clearSearch()
815 ui->lineEdit->clear();
816 ui->searchBar->hide();
818 ui->listWidget->setFocusPolicy(Qt::StrongFocus);
820 iSearchResults.clear();
823 void PackageView::on_actionSearch_triggered()
825 if( ui->searchBar->isVisible() )
828 ui->listWidget->setFocusPolicy(Qt::NoFocus);
829 ui->searchLabel->setText( QString("%1 results").arg(ui->listWidget->count()) );
831 ui->searchBar->show();
832 ui->lineEdit->setFocus();
833 iPrevSearchText = "";
836 void PackageView::on_lineEdit_textEdited(QString text)
838 if( !ui->searchBar->isVisible() )
841 if( text.isEmpty() ) {
842 on_btn_searchClose_clicked();
846 if( iPrevSearchText.length() > text.length() )
848 iListCoverLabel->setText("Loading...");
849 iListCoverLabel->setAutoFillBackground(true);
850 iListCoverLabel->show();
851 QApplication::processEvents();
853 ui->searchBar->hide();
855 ui->searchBar->show();
856 ui->toolBar->hide(); // ensure it stays hidden
857 ui->lineEdit->setFocus();
860 iPrevSearchText = text;
862 QList<Package*> packages;
863 iSearchResults.clear();
865 for( int i=0; i<(ui->listWidget->count()); i++ ) {
866 packages.append( dynamic_cast<PackageListWidgetItem*>( ui->listWidget->item(i) )->package() );
869 if( text.startsWith(":") ) {
870 for( int i=0; i<packages.count(); i++ ) {
871 if( packages.at(i) ) {
872 if( (iSearchPkgName && packages.at(i)->name().startsWith(text.mid(1), Qt::CaseInsensitive)) ||
873 (iSearchDisplayName && packages.at(i)->displayName().startsWith(text.mid(1), Qt::CaseInsensitive)) ||
874 (iSearchDescShort && packages.at(i)->descShort().startsWith(text.mid(1), Qt::CaseInsensitive)) ||
875 (iSearchDescLong && packages.at(i)->descLong().startsWith(text.mid(1), Qt::CaseInsensitive)) )
877 iSearchResults.append( packages.at(i) );
882 for( int i=0; i<packages.count(); i++ ) {
883 if( packages.at(i) ) {
884 if( (iSearchPkgName && packages.at(i)->name().contains(text, Qt::CaseInsensitive)) ||
885 (iSearchDisplayName && packages.at(i)->displayName().contains(text, Qt::CaseInsensitive)) ||
886 (iSearchDescShort && packages.at(i)->descShort().contains(text, Qt::CaseInsensitive)) ||
887 (iSearchDescLong && packages.at(i)->descLong().contains(text, Qt::CaseInsensitive)) )
889 iSearchResults.append( packages.at(i) );
895 ui->searchLabel->setText( QString("%1 results").arg( iSearchResults.count()) );
900 void PackageView::setSearchText(QString text)
902 ui->lineEdit->setText(text);
903 on_lineEdit_textEdited(text);
906 KeyEventGrabber::KeyEventGrabber(QObject* parent) : QObject(parent)
910 bool KeyEventGrabber::eventFilter(QObject *obj, QEvent *event)
912 if( event->type() == QEvent::KeyPress ) {
913 QString text = dynamic_cast<QKeyEvent*>(event)->text();
914 int key = dynamic_cast<QKeyEvent*>(event)->key();
915 if( (text.trimmed() != "" || text==" ") && key!=Qt::Key_Backspace ) {
916 dynamic_cast<PackageView*>(this->parent())->on_actionSearch_triggered();
917 dynamic_cast<PackageView*>(this->parent())->setSearchText( text );
921 return QObject::eventFilter(obj, event);
924 void PackageView::on_pushButton_searchOptions_clicked()
926 SearchOptions s(this);
927 s.setSelections(iSearchPkgName, iSearchDisplayName, iSearchDescShort, iSearchDescLong);
930 iSearchPkgName = s.searchPkgName();
931 iSearchDisplayName = s.searchDisplayName();
932 iSearchDescShort = s.searchDescShort();
933 iSearchDescLong = s.searchDescLong();
935 iPrevSearchText += " ";
936 on_lineEdit_textEdited( ui->lineEdit->text() );
940 void PackageView::setSearchOptions(bool pkgname, bool dispname, bool dshort, bool dlong)
942 iSearchPkgName = pkgname;
943 iSearchDisplayName = dispname;
944 iSearchDescShort = dshort;
945 iSearchDescLong = dlong;
948 void PackageView::on_actionUpgrade_all_triggered()
950 for( int i=0; i<ui->listWidget->count(); i++ )
952 Package* pkg = dynamic_cast<PackageListWidgetItem*>(ui->listWidget->item(i))->package();
953 if( pkg && pkg->isUpgradeable() ) {
954 pkg->setMarkedForOperation( Package::PkgOpInstallUpgrade );
955 ui->listWidget->item(i)->setData(UserRoleMarked, (int)Package::PkgOpInstallUpgrade);
961 void PackageView::on_actionView_log_triggered()
963 QByteArray log = iAptInterface->readLogFile();
964 LogView l(log, this);
968 void PackageView::on_btn_Sort_clicked()
970 SortSelector s(iSortOrder, this);
972 iSortOrder = s.selectedOperation();
973 iSortNoticeShown = false;
978 void PackageView::on_actionLoad_selections_triggered()
980 if( iAptInterface->numSelectedPackages() > 0 ) {
981 ConfirmDialog d(true, this);
982 d.setText("Confirmation", "Proceed loading selections? All current selections will be cleared.");
987 QString filename = QFileDialog::getOpenFileName(this, "Open selections list", KDefaultUserOpenSaveDir, "Selection lists (*.slist)");
988 if( filename.isNull() || filename.isEmpty() )
993 QStringList unknownList;
994 QStringList wrongverList;
995 QStringList wrongstatusList;
1000 if( f.open(QIODevice::ReadOnly | QIODevice::Text ) )
1003 QString line = f.readLine().trimmed();
1004 QStringList parts = line.split(' ');
1005 if( parts.count()==3 ) {
1006 Package* pkgAv = iAptInterface->packagesAvailable()->value(parts.at(0),0);
1007 Package* pkgIn = iAptInterface->packagesInstalled()->value(parts.at(0),0);
1008 if( parts.at(2)=="install" ) {
1009 if( !pkgAv && !pkgIn ) {
1010 unknownList << parts.at(0);
1013 wrongstatusList << parts.at(0);
1016 if( !pkgAv->isInstalled() )
1018 pkgAv->setMarkedForOperation(Package::PkgOpInstallUpgrade);
1020 if( pkgAv->version() != parts.at(1) ) {
1021 wrongverList << parts.at(0);
1024 wrongstatusList << parts.at(0);
1028 } else if( parts.at(2)=="upgrade" ) {
1029 if( !pkgAv && !pkgIn ) {
1030 unknownList << parts.at(0);
1032 else if( (pkgAv && !pkgIn) || (pkgIn && !pkgAv) ) {
1033 wrongstatusList << parts.at(0);
1035 else if( pkgIn && pkgAv ) {
1036 if( pkgIn->isInstalled() && pkgIn->isUpgradeable() )
1038 pkgIn->setMarkedForOperation(Package::PkgOpInstallUpgrade);
1040 if( pkgIn->version() != parts.at(1) ) {
1041 wrongverList << parts.at(0);
1044 wrongstatusList << parts.at(0);
1048 } else if( parts.at(2)=="remove" ) {
1049 if( !pkgAv && !pkgIn ) {
1050 unknownList << parts.at(0);
1052 else if( pkgAv && !pkgIn ) {
1053 wrongstatusList << parts.at(0);
1056 if( pkgIn->isInstalled() )
1058 pkgIn->setMarkedForOperation(Package::PkgOpRemove);
1060 if( pkgIn->version() != parts.at(1) ) {
1061 wrongverList << parts.at(0);
1064 wrongstatusList << parts.at(0);
1070 } else if( !line.isEmpty() ){
1077 ConfirmDialog d(false, this);
1079 msg += QString("<b>%1 successful</b><br>").arg(success);
1081 if( wrongverList.count() > 0 ) {
1082 msg += QString("%1 version mismatches (selected anyway):<br>").arg(wrongverList.count());
1083 msg += "<font size=\"-1\">";
1084 for( int i=0; i<wrongverList.count(); i++ ) {
1085 msg += wrongverList.at(i) + " ";
1087 msg += "</font><br>";
1090 if( wrongstatusList.count() > 0 ) {
1091 msg += QString("%1 status mismatches (packages ignored):<br>").arg(wrongstatusList.count());
1092 msg += "<font size=\"-1\">";
1093 for( int i=0; i<wrongstatusList.count(); i++ ) {
1094 msg += wrongstatusList.at(i) + " ";
1096 msg += "</font><br>";
1099 if( unknownList.count() > 0 ) {
1100 msg += QString("%1 unknown packages:<br>").arg(unknownList.count());
1101 msg += "<font size=\"-1\">";
1102 for( int i=0; i<unknownList.count(); i++ ) {
1103 msg += unknownList.at(i) + " ";
1105 msg += "</font><br>";
1108 if( errors>0 || (wrongstatusList.count()==0 && unknownList.count()==0) ) {
1109 msg += QString("%1 errors<br>").arg(errors);
1111 if( success==0 && wrongstatusList.count()==0 && unknownList.count()==0 )
1112 msg = "No stored selections";
1115 title = "Selections loaded";
1117 title = "No selections loaded";
1118 d.setText(title, msg);
1121 if( unknownList.count()>0 && iAptInterface->needListOrDateRefresh() )
1123 ConfirmDialog f(false, this);
1124 f.setText("About Unknown packages","You encountered unknown packages. You might want to try "
1125 "loading the selections again after loading the full package lists (by selecting install or upgrade view)");
1130 ui->btn_StatusFilter->setEnabled(false);
1131 iSelectedCatFilter = CatFilterAllMarked;
1136 void PackageView::on_actionSave_selections_triggered()
1138 if( iAptInterface->numSelectedPackages() == 0 )
1141 QString filename = QFileDialog::getSaveFileName(this, "Save selections to...", KDefaultUserOpenSaveDir, "Selection lists (*.slist)");
1142 if( filename.isNull() || filename.isEmpty() )
1145 if( !filename.endsWith(".slist") )
1146 filename.append(".slist");
1148 QFile f( filename );
1151 if( f.open(QIODevice::WriteOnly | QIODevice::Text) )
1153 QTextStream out(&f);
1155 QHashIterator<QString, Package*> i( *iAptInterface->packagesAvailable() );
1160 if( i.value()->markedOperation() == Package::PkgOpInstallUpgrade ) {
1161 out << i.value()->name() << " " << i.value()->version() << " install\n";
1164 if( i.value()->markedOperation() == Package::PkgOpRemove )
1165 qDebug() << "Warning: package is marked for removal in the wrong list";
1168 QHashIterator<QString, Package*> r( *iAptInterface->packagesInstalled() );
1173 if( r.value()->markedOperation() == Package::PkgOpInstallUpgrade ) {
1174 out << r.value()->name() << " " << r.value()->version() << " upgrade\n";
1177 if( r.value()->markedOperation() == Package::PkgOpRemove ) {
1178 out << r.value()->name() << " " << r.value()->version() << " remove\n";
1188 ConfirmDialog d(false, this);
1190 d.setText( "Error", "Failed to write package selections" );
1192 d.setText( "Selections stored", QString("Stored %1 selections").arg(count) );
1196 void PackageView::on_actionRestore_all_triggered()
1198 ConfirmDialog d(true, this);
1199 d.setText("Confirmation","Restore all shown blacklisted packages?");
1203 for( int i=0; i<ui->listWidget->count(); i++ )
1205 Package* pkg = dynamic_cast<PackageListWidgetItem*>(ui->listWidget->item(i))->package();
1206 Package* p1 = iAptInterface->packagesInstalled()->value(pkg->name(),0);
1207 Package* p2 = iAptInterface->packagesAvailable()->value(pkg->name(),0);
1208 if( p1 && p1->isBlacklisted() ) {
1209 BlacklistSelect::blackList old = p1->blacklisted();
1210 p1->setBlacklisted(BlacklistSelect::BlacklistNone);
1211 iAptInterface->removeFromBlacklist(p1, old);
1213 if( p2 && p2->isBlacklisted() ) {
1214 BlacklistSelect::blackList old = p2->blacklisted();
1215 p2->setBlacklisted(BlacklistSelect::BlacklistNone);
1216 iAptInterface->removeFromBlacklist(p2, old);
1219 iAptInterface->writeBlacklist();
1223 void PackageView::on_actionStore_list_triggered()
1225 QString filename = QFileDialog::getSaveFileName(this, "Save application list to...", KDefaultUserOpenSaveDir, "Selection lists (*.slist)");
1226 if( filename.isNull() || filename.isEmpty() )
1229 if( !filename.endsWith(".slist") )
1230 filename.append(".slist");
1232 QFile f( filename );
1235 if( f.open(QIODevice::WriteOnly | QIODevice::Text) )
1237 QTextStream out(&f);
1239 QHashIterator<QString, Package*> r( *iAptInterface->packagesInstalled() );
1244 if( r.value()->isInstalled() && r.value()->section().startsWith("user/") ) {
1245 out << r.value()->name() << " " << r.value()->version() << " install\n";
1255 ConfirmDialog d(false, this);
1257 d.setText( "Error", "Failed to write application list" );
1259 d.setText( "List stored", QString("Stored %1 selections.").arg(count) + "<br>"
1260 "The list can be used to restore removed applications later." );