1 /*
2 * This file is part of OctoPkg, an open-source GUI for pkgng.
3 * Copyright (C) 2015 Alexandre Albuquerque Arnt
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21 /*
22 * This is MainWindow's refresh UI components related code
23 */
24
25 #include "mainwindow.h"
26 #include "searchlineedit.h"
27 #include "ui_mainwindow.h"
28 #include "strconstants.h"
29 #include "uihelper.h"
30 #include "globals.h"
31 #include "src/ui/octopkgtabinfo.h"
32 #include <iostream>
33 #include <cassert>
34
35 #include <QElapsedTimer>
36 #include <QLabel>
37 #include <QProgressBar>
38 #include <QComboBox>
39 #include <QTextBrowser>
40 #include <QStandardItem>
41 #include <QFutureWatcher>
42 #include <QMutableListIterator>
43 #include <QtConcurrent/QtConcurrentRun>
44
45 /*
46 * If we have some outdated packages, let's put an angry red face icon in this app!
47 */
refreshAppIcon()48 void MainWindow::refreshAppIcon()
49 {
50 bool enableSystemUpgrade=false;
51
52 if ((m_outdatedStringList->count() > 0))
53 {
54 setWindowIcon(IconHelper::getIconOctopiRed());
55
56 if(!isThereAPendingTransaction())
57 enableSystemUpgrade=true;
58 }
59 else
60 {
61 setWindowIcon(IconHelper::getIconOctopiGreen());
62 }
63
64 ui->actionSystemUpgrade->setEnabled(enableSystemUpgrade);
65 }
66
67 /*
68 * Inserts the group names into the Groups treeView
69 */
refreshGroupsWidget()70 void MainWindow::refreshGroupsWidget()
71 {
72 /*
73 disconnect(ui->twGroups, SIGNAL(itemSelectionChanged()), this, SLOT(groupItemSelected()));
74
75 QList<QTreeWidgetItem *> items;
76 ui->twGroups->clear();
77
78 items.append(new QTreeWidgetItem((QTreeWidget*)0, QStringList("<" + StrConstants::getDisplayAllCategories() + ">")));
79 m_AllGroupsItem = items.at(0);
80 const QStringList*const packageGroups = Package::getPackageGroups();
81 for(QString group: *packageGroups)
82 {
83 items.append(new QTreeWidgetItem((QTreeWidget*)0, QStringList(group)));
84 }
85 m_packageRepo.checkAndSetGroups(*packageGroups); // update Package Repository as well
86 delete packageGroups;
87
88 ui->twGroups->insertTopLevelItems(0, items);
89 ui->twGroups->setCurrentItem(items.at(0));
90 connect(ui->twGroups, SIGNAL(itemSelectionChanged()), this, SLOT(groupItemSelected()));
91 */
92 }
93
94 /*
95 * User clicked AUR tool button in the toolbar
96 */
remoteSearchClicked()97 void MainWindow::remoteSearchClicked()
98 {
99 if (m_commandExecuting != ectn_NONE && m_commandExecuting != ectn_LOCAL_PKG_REFRESH) return;
100
101 static bool lastPkgButtonClickedWasRemote = false;
102
103 if (lastPkgButtonClickedWasRemote && m_actionSwitchToRemoteSearch->isChecked())
104 {
105 disconnect(m_actionGroupSearch, SIGNAL(triggered(QAction*)), this, SLOT(remoteSearchClicked()));
106 m_actionSwitchToRemoteSearch->setChecked(false);
107 //m_actionSwitchToLocalSearch->setChecked(true);
108 connect(m_actionGroupSearch, SIGNAL(triggered(QAction*)), this, SLOT(remoteSearchClicked()));
109 }
110 else/* if (!lastPkgButtonClickedWasRemote && m_actionSwitchToLocalSearch->isChecked())*/
111 {
112 disconnect(m_actionGroupSearch, SIGNAL(triggered(QAction*)), this, SLOT(remoteSearchClicked()));
113 //m_actionSwitchToLocalSearch->setChecked(false);
114 m_actionSwitchToRemoteSearch->setChecked(true);
115 connect(m_actionGroupSearch, SIGNAL(triggered(QAction*)), this, SLOT(remoteSearchClicked()));
116 }
117
118 //m_leFilterPackage->clear();
119
120 if (m_actionSwitchToRemoteSearch->isChecked())
121 {
122 m_packageModel->setShowColumnInstalledOn(false);
123 m_leFilterPackage->setPlaceholderText(StrConstants::getLineEditTextRemote());
124 m_leFilterPackage->setToolTip(StrConstants::getRemotePackageSearchTip());
125 ui->menuSearch->setEnabled(false);
126 }
127 else
128 {
129 m_packageModel->setShowColumnInstalledOn(true);
130 m_leFilterPackage->setPlaceholderText(StrConstants::getLineEditTextLocal());
131 m_leFilterPackage->setToolTip("");
132 ui->menuSearch->setEnabled(true);
133 }
134
135 m_selectedRepository = "";
136
137 if (m_commandExecuting == ectn_NONE)
138 m_refreshPackageLists = false;
139 else if (m_commandExecuting == ectn_LOCAL_PKG_REFRESH)
140 m_refreshPackageLists = true;
141
142 metaBuildPackageList();
143 m_cachedPackageInInfo = "";
144 m_cachedPackageInFiles = "";
145 invalidateTabs();
146
147 if (m_commandExecuting == ectn_LOCAL_PKG_REFRESH)
148 {
149 connect(this, SIGNAL(buildPackageListDone()), this, SLOT(resetTransaction()));
150 }
151
152 if (m_actionSwitchToRemoteSearch->isChecked())
153 {
154 lastPkgButtonClickedWasRemote = true;
155 }
156 else
157 {
158 lastPkgButtonClickedWasRemote = false;
159 }
160 }
161
162 /*
163 * Whenever user selects another package group...
164 */
groupItemSelected()165 void MainWindow::groupItemSelected()
166 {
167 //Let us select ALL pkgs from ALL repos!
168 switchToViewAllPackages();
169 m_selectedRepository = "";
170 m_actionRepositoryAll->setChecked(true);
171
172 if (isAllCategoriesSelected())
173 {
174 m_refreshPackageLists = false;
175 }
176 else
177 {
178 m_refreshPackageLists = true;
179 }
180
181 m_leFilterPackage->clear();
182 metaBuildPackageList();
183 }
184
185 /*
186 * Given the package name that owns the file user has just searched, goes to that package in the list
187 */
positionInPkgListSearchByFile()188 void MainWindow::positionInPkgListSearchByFile()
189 {
190 if (m_cic) {
191 delete m_cic;
192 m_cic = NULL;
193 }
194
195 QString pkgName = g_fwPackageOwnsFile.result();
196
197 if (!pkgName.isEmpty())
198 {
199 QModelIndex searchColumn = m_packageModel->index(0,
200 PackageModel::ctn_PACKAGE_NAME_COLUMN,
201 QModelIndex());
202 QModelIndexList fi = m_packageModel->match(searchColumn, Qt::DisplayRole, pkgName, -1, Qt::MatchExactly);
203
204 if (fi.count() >= 1)
205 {
206 ui->tvPackages->setCurrentIndex(fi.at(0));
207 ui->tvPackages->scrollTo(fi.at(0), QAbstractItemView::PositionAtCenter);
208 }
209 }
210 else //The pkg was not found, so we position on the first item of the list!
211 {
212 ui->tvPackages->setCurrentIndex(m_packageModel->index(0,0,QModelIndex()));
213 }
214 }
215
216 /*
217 * Populates the list of available packages from the given groupName
218 */
buildPackagesFromGroupList(const QString group)219 void MainWindow::buildPackagesFromGroupList(const QString group)
220 {
221 CPUIntensiveComputing cic;
222 const QList<QString>*const list = m_listOfPackagesFromGroup.get();
223 QList<QString>::const_iterator it = list->begin();
224
225 m_progressWidget->setRange(0, list->count());
226 m_progressWidget->setValue(0);
227 m_progressWidget->show();
228
229 int installedCount = 0;
230 int counter=0;
231
232 while(it != list->end())
233 {
234 if (isPackageInstalled(*it)) {
235 ++installedCount;
236 }
237
238 counter++;
239 m_progressWidget->setValue(counter);
240 ++it;
241 }
242
243 counter = list->count();
244 m_progressWidget->setValue(counter);
245 m_progressWidget->close();
246
247 m_packageRepo.checkAndSetMembersOfGroup(group, *list);
248 m_packageModel->applyFilter(m_selectedViewOption, m_selectedRepository, isAllCategories(group) ? "" : group);
249
250 //Refresh counters
251 m_numberOfInstalledPackages = installedCount;
252 //Refresh statusbar widget
253 refreshStatusBar();
254
255 reapplyPackageFilter();
256
257 QModelIndex maux = m_packageModel->index(0, 0, QModelIndex());
258 ui->tvPackages->setCurrentIndex(maux);
259 ui->tvPackages->scrollTo(maux, QAbstractItemView::PositionAtCenter);
260 ui->tvPackages->setCurrentIndex(maux);
261
262 m_listOfPackagesFromGroup.reset();
263 invalidateTabs();
264 ui->tvPackages->setFocus();
265
266 refreshToolBar();
267 //refreshStatusBarToolButtons();
268
269 tvPackagesSelectionChanged(QItemSelection(),QItemSelection());
270 }
271
272 /*
273 * Executes QFuture to retrieve list of locked packages
274 */
retrieveLockedPackageList()275 void MainWindow::retrieveLockedPackageList()
276 {
277 QEventLoop el;
278 QFuture<QSet<QString> *> f;
279 f = QtConcurrent::run(searchLockedPkgPackages);
280 connect(&g_fwLockedPkg, SIGNAL(finished()), this, SLOT(preBuildLockedPackageList()));
281 connect(&g_fwLockedPkg, SIGNAL(finished()), &el, SLOT(quit()));
282 g_fwLockedPkg.setFuture(f);
283 el.exec();
284 }
285
286 /*
287 * Executes QFuture to retrive Unrequired Pacman list of packages
288 */
retrieveUnrequiredPackageList()289 void MainWindow::retrieveUnrequiredPackageList()
290 {
291 QEventLoop el;
292 QFuture<QSet<QString> *> f;
293 f = QtConcurrent::run(searchUnrequiredPacmanPackages);
294 connect(&g_fwUnrequiredPacman, SIGNAL(finished()), this, SLOT(preBuildUnrequiredPackageList()));
295 connect(&g_fwUnrequiredPacman, SIGNAL(finished()), &el, SLOT(quit()));
296 g_fwUnrequiredPacman.setFuture(f);
297 el.exec();
298 assert(m_unrequiredPackageList != NULL);
299 }
300
301 /*
302 * Helper method to assign QFuture for Locked Pkg list of packages
303 */
preBuildLockedPackageList()304 void MainWindow::preBuildLockedPackageList()
305 {
306 m_lockedPackageList = g_fwLockedPkg.result();
307
308 if(m_debugInfo)
309 std::cout << "Time elapsed obtaining Locked pkgs from 'ALL group' list: " << m_time->elapsed() << " mili seconds." << std::endl << std::endl;
310 }
311
312 /*
313 * Helper method to assign QFuture for Unrequired Pacman list of packages
314 */
preBuildUnrequiredPackageList()315 void MainWindow::preBuildUnrequiredPackageList()
316 {
317 m_unrequiredPackageList = g_fwUnrequiredPacman.result();
318
319 if(m_debugInfo)
320 std::cout << "Time elapsed obtaining Unrequired pkgs from 'ALL group' list: " << m_time->elapsed() << " mili seconds." << std::endl << std::endl;
321 }
322
323 /*
324 * Helper method to deal with the QFutureWatcher result before calling
325 * Pacman package list building method
326 */
preBuildPackageList()327 void MainWindow::preBuildPackageList()
328 {
329 m_listOfPackages.reset(g_fwPkg.result());
330
331 if(m_debugInfo)
332 std::cout << "Time elapsed obtaining pkgs from 'ALL group' list: " << m_time->elapsed() << " mili seconds." << std::endl;
333
334 buildPackageList();
335 toggleSystemActions(true);
336
337 if (!m_initializationCompleted)
338 {
339 //remoteSearchClicked();
340 m_initializationCompleted = true;
341 }
342 }
343
344 /*
345 * Helper method to deal with the QFutureWatcher result before calling
346 * Pacman packages from group list building method
347 */
preBuildPackagesFromGroupList()348 void MainWindow::preBuildPackagesFromGroupList()
349 {
350 GroupMemberPair result = g_fwPacmanGroup.result();
351 m_listOfPackagesFromGroup.reset(result.second);
352 buildPackagesFromGroupList(result.first);
353
354 toggleSystemActions(true);
355
356 emit buildPackagesFromGroupListDone();
357 }
358
359 /*
360 * Slot to fire the search for all installed packages
361 */
searchForPkgPackages()362 void MainWindow::searchForPkgPackages()
363 {
364 QFuture<QList<PackageListData> *> f;
365 f = QtConcurrent::run(searchPkgPackages);
366 disconnect(&g_fwPkg, SIGNAL(finished()), this, SLOT(preBuildPackageList()));
367 connect(&g_fwPkg, SIGNAL(finished()), this, SLOT(preBuildPackageList()));
368 g_fwPkg.setFuture(f);
369 }
370
371 /*
372 * Decides which SLOT to call: buildPackageList, buildAURPackageList or buildPackagesFromGroupList
373 */
metaBuildPackageList()374 void MainWindow::metaBuildPackageList()
375 {
376 m_time->start();
377
378 if (isSearchByFileSelected())
379 m_leFilterPackage->setRefreshValidator(ectn_FILE_VALIDATOR);
380 else if (isRemoteSearchSelected())
381 m_leFilterPackage->setRefreshValidator(ectn_AUR_VALIDATOR);
382 else
383 m_leFilterPackage->setRefreshValidator(ectn_DEFAULT_VALIDATOR);
384
385 ui->tvPackages->setSelectionMode(QAbstractItemView::ExtendedSelection);
386
387 //if (ui->twGroups->topLevelItemCount() == 0 || isAllCategoriesSelected())
388 if (m_actionSwitchToRemoteSearch->isChecked())
389 {
390 ui->actionSearchByFile->setEnabled(false);
391 //disconnect(m_leFilterPackage, SIGNAL(textChanged(QString)), this, SLOT(reapplyPackageFilter()));
392 clearStatusBar();
393
394 m_cic = new CPUIntensiveComputing();
395
396 if(!m_leFilterPackage->text().isEmpty())
397 {
398 m_toolButtonPacman->hide();
399 disconnect(&g_fwRemoteMeta, SIGNAL(finished()), this, SLOT(preBuildRemotePackageListMeta()));
400
401 QFuture<QList<PackageListData> *> f;
402 f = QtConcurrent::run(searchRemotePackages, m_leFilterPackage->text());
403 connect(&g_fwRemoteMeta, SIGNAL(finished()), this, SLOT(preBuildRemotePackageListMeta()));
404 g_fwRemoteMeta.setFuture(f);
405 }
406 else
407 {
408 m_listOfRemotePackages = new QList<PackageListData>();
409 buildRemotePackageList();
410 delete m_cic;
411 m_cic = 0;
412 m_leFilterPackage->setFocus();
413 }
414 }
415 else
416 {
417 ui->actionSearchByFile->setEnabled(true);
418 ui->actionSearchByName->setChecked(true);
419
420 //disconnect(m_leFilterPackage, SIGNAL(textChanged(QString)), this, SLOT(reapplyPackageFilter()));
421 //connect(m_leFilterPackage, SIGNAL(textChanged(QString)), this, SLOT(reapplyPackageFilter()));
422 disconnect(&g_fwPkg, SIGNAL(finished()), this, SLOT(preBuildPackageList()));
423
424 if (m_refreshPackageLists)
425 {
426 QFuture<QMap<QString, OutdatedPackageInfo> *> f;
427 f = QtConcurrent::run(getOutdatedList);
428 disconnect(&g_fwOutdatedList, SIGNAL(finished()), this, SLOT(searchForPkgPackages()));
429 connect(&g_fwOutdatedList, SIGNAL(finished()), this, SLOT(searchForPkgPackages()));
430 g_fwOutdatedList.setFuture(f);
431 }
432 else
433 {
434 searchForPkgPackages();
435 }
436
437 if(m_debugInfo)
438 std::cout << m_packageModel->getPackageCount() << " pkgs => " <<
439 "Time elapsed building pkgs from 'ALL group' list: " << m_time->elapsed() << " mili seconds." << std::endl << std::endl;
440 }
441 /*
442 else //pkg category clicked!
443 {
444 ui->actionSearchByFile->setEnabled(false);
445 toggleSystemActions(false);
446 disconnect(m_leFilterPackage, SIGNAL(textChanged(QString)), this, SLOT(reapplyPackageFilter()));
447 connect(m_leFilterPackage, SIGNAL(textChanged(QString)), this, SLOT(reapplyPackageFilter()));
448 reapplyPackageFilter();
449 disconnect(&g_fwPacmanGroup, SIGNAL(finished()), this, SLOT(preBuildPackagesFromGroupList()));
450
451 QEventLoop el;
452 QFuture<GroupMemberPair> f;
453 f = QtConcurrent::run(searchPacmanPackagesFromGroup, getSelectedCategory());
454 connect(&g_fwPacmanGroup, SIGNAL(finished()), this, SLOT(preBuildPackagesFromGroupList()));
455 disconnect(this, SIGNAL(buildPackagesFromGroupListDone()), &el, SLOT(quit()));
456 connect(this, SIGNAL(buildPackagesFromGroupListDone()), &el, SLOT(quit()));
457
458 g_fwPacmanGroup.setFuture(f);
459 el.exec();
460
461 if(m_debugInfo)
462 std::cout << m_packageModel->getPackageCount() << " pkgs => " <<
463 "Time elapsed building pkgs from '" << getSelectedCategory().toLatin1().data() << " group' list: " << m_time->elapsed() << " mili seconds." << std::endl << std::endl;
464 }
465 */
466 }
467
468 /*
469 * Helper method to deal with the QFutureWatcher result before calling
470 * AUR package list building method
471 */
preBuildRemotePackageListMeta()472 void MainWindow::preBuildRemotePackageListMeta()
473 {
474 m_listOfRemotePackages = g_fwRemoteMeta.result();
475
476 //Let's iterate over those found packages to change their status
477 for (QList<PackageListData>::iterator it = m_listOfRemotePackages->begin();
478 it != m_listOfRemotePackages->end(); ++it)
479 {
480 const PackageRepository::PackageData*const package =
481 m_packageRepo.getFirstPackageByName((*it).name);
482
483 if (package != NULL)
484 {
485 (*it).status = package->status;
486 }
487 }
488
489 buildRemotePackageList();
490
491 if (m_cic) {
492 delete m_cic;
493 m_cic = 0;
494 }
495
496 //if (m_packageModel->getPackageCount() == 0)
497 {
498 m_leFilterPackage->setFocus();
499 }
500 }
501
502 /*
503 * Helper method to deal with the QFutureWatcher result before calling
504 * AUR package list building method
505 */
preBuildRemotePackageList()506 void MainWindow::preBuildRemotePackageList()
507 {
508 m_listOfRemotePackages = g_fwRemote.result();
509
510 if (m_commandExecuting == ectn_NONE)
511 {
512 //Let's iterate over those found packages to change their status
513 for (QList<PackageListData>::iterator it = m_listOfRemotePackages->begin();
514 it != m_listOfRemotePackages->end(); ++it)
515 {
516 const PackageRepository::PackageData*const package =
517 m_packageRepo.getFirstPackageByName((*it).name);
518
519 if (package != NULL)
520 {
521 (*it).status = package->status;
522 }
523 }
524 }
525
526 buildRemotePackageList();
527
528 if (m_cic) {
529 delete m_cic;
530 m_cic = NULL;
531 }
532
533 m_leFilterPackage->setFocus();
534 emit buildRemotePackageListDone();
535 }
536
537 /*
538 * Populates the list of found AUR packages (installed [+ non-installed])
539 * given the searchString parameter passed.
540 *
541 */
buildRemotePackageList()542 void MainWindow::buildRemotePackageList()
543 {
544 ui->actionSearchByDescription->setChecked(true);
545 m_leFilterPackage->setRefreshValidator(ectn_AUR_VALIDATOR);
546 m_progressWidget->show();
547
548 const QSet<QString>*const unrequiredPackageList = Package::getUnrequiredPackageList();
549 QList<PackageListData> *list = m_listOfRemotePackages;
550
551 m_progressWidget->setRange(0, list->count());
552 m_progressWidget->setValue(0);
553 int counter=0;
554 int installedCount = 0;
555 QList<PackageListData>::const_iterator it = list->begin();
556
557 while(it != list->end())
558 {
559 if (isPackageInstalled(it->name)) {
560 ++installedCount;
561 }
562 counter++;
563 m_progressWidget->setValue(counter);
564 ++it;
565 }
566
567 m_packageRepo.setAURData(list, *unrequiredPackageList);
568 m_packageModel->applyFilter(PackageModel::ctn_PACKAGE_DESCRIPTION_FILTER_NO_COLUMN);
569 m_packageModel->applyFilter(ectn_ALL_PKGS, "", "NONE");
570
571 if (ui->tvPackages->model() != m_packageModel.get())
572 {
573 ui->tvPackages->setModel(m_packageModel.get());
574 initPackageTreeView();
575 }
576
577 if (list->count() > 0)
578 {
579 QModelIndex maux = m_packageModel->index(0, 0, QModelIndex());
580 ui->tvPackages->setCurrentIndex(maux);
581 ui->tvPackages->scrollTo(maux, QAbstractItemView::PositionAtCenter);
582 ui->tvPackages->setCurrentIndex(maux);
583
584 refreshTabInfo();
585 refreshTabFiles();
586
587 if (isPackageTreeViewVisible())
588 {
589 ui->tvPackages->setFocus();
590 }
591 }
592
593 list->clear();
594
595 //Refresh counters
596 m_numberOfInstalledPackages = installedCount;
597
598 if (isRemoteSearchSelected())
599 {
600 m_leFilterPackage->initStyleSheet();
601 QString search = Package::parseSearchString(m_leFilterPackage->text());
602 m_packageModel->applyFilter(search);
603
604 ui->tvPackages->selectionModel()->clear();
605 QModelIndex mi = m_packageModel->index(0, PackageModel::ctn_PACKAGE_NAME_COLUMN, QModelIndex());
606 ui->tvPackages->setCurrentIndex(mi);
607 ui->tvPackages->scrollTo(mi);
608 invalidateTabs();
609 }
610 else
611 {
612 reapplyPackageFilter();
613 }
614
615 //Refresh statusbar widget
616 refreshStatusBar();
617
618 //Refresh application icon
619 refreshAppIcon();
620
621 counter = list->count();
622 m_progressWidget->setValue(counter);
623 m_progressWidget->close();
624
625 //ui->tvPackages->setColumnHidden(PackageModel::ctn_PACKAGE_REPOSITORY_COLUMN, true);
626
627 refreshToolBar();
628 //refreshStatusBarToolButtons();
629
630 //If we found no packages, let's make another search, this time 'by name'...
631 if (!m_leFilterPackage->text().isEmpty() &&
632 (!m_leFilterPackage->text().contains(QRegularExpression("\\s"))) &&
633 m_packageModel->getPackageCount() == 0 &&
634 ui->actionSearchByDescription->isChecked())
635 {
636 if (m_cic != NULL)
637 {
638 delete m_cic;
639 m_cic = 0;
640 }
641
642 ui->actionSearchByName->setChecked(true);
643 metaBuildPackageList();
644 }
645
646 emit buildPackageListDone();
647 }
648
649 /*
650 * Outputs a list of packages that don't have a description
651 */
showPackagesWithNoDescription()652 void MainWindow::showPackagesWithNoDescription()
653 {
654 bool printHeader = false;
655 QList<PackageListData> *list = Package::getPackageList();
656 QList<PackageListData>::const_iterator it = list->begin();
657
658 while(it != list->end())
659 {
660 PackageListData pld = *it;
661
662 if (pld.description == (pld.name + " "))
663 {
664 if (!printHeader)
665 {
666 std::cout << std::endl << "List of packages without description:" << std::endl << std::endl;
667 printHeader=true;
668 }
669
670 std::cout << pld.name.toLatin1().data() << std::endl;
671 }
672
673 ++it;
674 }
675 }
676
677 /*
678 * Populates the list of available packages (installed [+ non-installed])
679 *
680 * It's called Only: when the selected group is <All> !
681 */
buildPackageList()682 void MainWindow::buildPackageList()
683 {
684 CPUIntensiveComputing cic;
685 /*static QStandardItemModel emptyModel;
686 if (!m_initializationCompleted)
687 {
688 ui->tvPackages->setModel(&emptyModel);
689 removePackageTreeViewConnections();
690 }*/
691
692 static bool firstTime = true;
693
694 if(m_refreshPackageLists) //If it's not the starting of the app...
695 {
696 //Let's get outdatedPackages list again!
697 m_outdatedStringList->clear();
698 m_outdatedList = g_fwOutdatedList.result(); //Package::getOutdatedStringList();
699
700 if(m_debugInfo)
701 std::cout << "Time elapsed retrieving outdated pkgs from 'ALL group' list: " << m_time->elapsed() << " mili seconds." << std::endl;
702
703 for(QString k: m_outdatedList->keys())
704 {
705 m_outdatedStringList->append(k);
706 }
707
708 if(m_debugInfo)
709 std::cout << "Time elapsed refreshing outdated pkgs from 'ALL group' list: " << m_time->elapsed() << " mili seconds." << std::endl;
710
711 m_numberOfOutdatedPackages = m_outdatedStringList->count();
712
713 delete m_lockedPackageList;
714 m_lockedPackageList = NULL;
715 m_lockedPackageList = Package::getLockedPackageList();
716
717 delete m_unrequiredPackageList;
718 m_unrequiredPackageList = NULL;
719 m_unrequiredPackageList = Package::getUnrequiredPackageList();
720
721 if(m_debugInfo)
722 std::cout << "Time elapsed obtaining unrequired pkgs from 'ALL group' list: " << m_time->elapsed() << " mili seconds." << std::endl;
723 }
724
725 // Fetch package list
726 QList<PackageListData> *list;
727 list = m_listOfPackages.release();
728
729 //qDebug() << "PASSED...";
730
731 m_progressWidget->setRange(0, list->count());
732 m_progressWidget->setValue(0);
733 m_progressWidget->show();
734
735 int counter=0;
736 QList<PackageListData>::const_iterator it = list->begin();
737
738 while(it != list->end())
739 {
740 counter++;
741 m_progressWidget->setValue(counter);
742 ++it;
743 }
744
745 if(m_debugInfo)
746 std::cout << "Time elapsed iterating over all pkgs from 'ALL group' list: " << m_time->elapsed() << " mili seconds." << std::endl;
747
748 counter = list->count();
749 m_progressWidget->setValue(counter);
750 m_progressWidget->close();
751 m_packageRepo.setData(list, *m_unrequiredPackageList);
752
753 if(m_debugInfo)
754 std::cout << "Time elapsed setting the list to the treeview: " << m_time->elapsed() << " mili seconds." << std::endl;
755
756 if (ui->actionSearchByDescription->isChecked())
757 {
758 m_packageModel->applyFilter(PackageModel::ctn_PACKAGE_DESCRIPTION_FILTER_NO_COLUMN);
759 }
760 else
761 {
762 m_packageModel->applyFilter(PackageModel::ctn_PACKAGE_NAME_COLUMN);
763 }
764
765 delete list;
766 list = NULL;
767
768 if (g_fwLockedPkg.isFinished())
769 {
770 for(QString locked: *m_lockedPackageList)
771 {
772 PackageRepository::PackageData* package = m_packageRepo.getFirstPackageByNameEx(locked);
773 if (package != NULL)
774 {
775 package->status = ectn_LOCKED;
776 }
777 }
778 }
779
780 if(!firstTime && g_fwOutdatedList.isFinished())
781 {
782 for(QString k: m_outdatedList->keys())
783 {
784 OutdatedPackageInfo opi = m_outdatedList->value(k);
785 PackageRepository::PackageData* package = m_packageRepo.getFirstPackageByNameEx(k);
786 if (package != NULL)
787 {
788 package->status = ectn_OUTDATED;
789 package->outdatedVersion = opi.oldVersion;
790 }
791 }
792 }
793
794 if (isAllCategoriesSelected()) m_packageModel->applyFilter(m_selectedViewOption, m_selectedRepository, "");
795
796 reapplyPackageFilter();
797
798 QModelIndex maux = m_packageModel->index(0, 0, QModelIndex());
799 ui->tvPackages->setCurrentIndex(maux);
800 ui->tvPackages->scrollTo(maux, QAbstractItemView::PositionAtCenter);
801 ui->tvPackages->setCurrentIndex(maux);
802
803 if (m_initializationCompleted)
804 {
805 invalidateTabs();
806 }
807
808 if (isPackageTreeViewVisible())
809 {
810 ui->tvPackages->setFocus();
811 }
812
813 //Refresh statusbar widget
814 refreshStatusBar();
815
816 //Refresh application icon
817 refreshAppIcon();
818
819 if (firstTime)
820 {
821 getOutdatedPackageListThreaded();
822
823 if (isPackageTreeViewVisible())
824 {
825 m_leFilterPackage->setFocus();
826 }
827
828 //m_initializationCompleted = true;
829 firstTime = false;
830
831 if (m_callSystemUpgrade)
832 {
833 //First, let us throw away that 'wainting cursor'...
834 QApplication::restoreOverrideCursor();
835 doSystemUpgrade();
836 }
837 else if (m_callSystemUpgradeNoConfirm)
838 {
839 //First, let us throw away that 'wainting cursor'...
840 QApplication::restoreOverrideCursor();
841 doSystemUpgrade(ectn_NOCONFIRM_OPT);
842 }
843 else if (m_packagesToInstallList.count() > 0)
844 {
845 //First, let us throw away that 'wainting cursor'...
846 QApplication::restoreOverrideCursor();
847 doInstallLocalPackages();
848 }
849 }
850
851 //ui->tvPackages->setColumnWidth(PackageModel::ctn_PACKAGE_SIZE_COLUMN, 10);
852 refreshToolBar();
853 //refreshStatusBarToolButtons();
854 m_refreshPackageLists = true;
855
856 emit buildPackageListDone();
857 m_leFilterPackage->setFocus();
858 }
859
860 /*
861 * Whenever horizontal splitter handler is moved
862 */
horizontalSplitterMoved(int pos,int index)863 void MainWindow::horizontalSplitterMoved(int pos, int index)
864 {
865 Q_UNUSED(index)
866
867 QList<int> l, rl;
868 rl = ui->splitterHorizontal->sizes();
869
870 if (pos == 0 && rl[0] == 0)
871 {
872 ui->twProperties->tabBar()->hide();
873 //ui->mainToolBar->hide();
874 }
875 else
876 {
877 ui->twProperties->tabBar()->show();
878 //ui->mainToolBar->show();
879 }
880 }
881
882 /*
883 * Refreshes toolbar in order to insert/remove AUR tool button
884 */
refreshToolBar()885 void MainWindow::refreshToolBar()
886 {
887 /*m_hasAURTool =
888 UnixCommand::hasTheExecutable(StrConstants::getForeignRepositoryToolName()) && !UnixCommand::isRootRunning();
889
890 if (m_hasAURTool)
891 {
892 if (!ui->mainToolBar->actions().contains(m_actionSwitchToPkgSearch))
893 {
894 ui->mainToolBar->insertAction(m_dummyAction, m_actionSwitchToPkgSearch);
895 m_separatorForActionPkgSearch = ui->mainToolBar->insertSeparator(m_actionSwitchToPkgSearch);
896 }
897 }
898 else
899 {
900 if (ui->mainToolBar->actions().contains(m_actionSwitchToPkgSearch))
901 {
902 bool wasChecked = (m_actionSwitchToPkgSearch->isChecked());
903
904 ui->mainToolBar->removeAction(m_actionSwitchToPkgSearch);
905 ui->mainToolBar->removeAction(m_separatorForActionPkgSearch);
906
907 if (wasChecked)
908 {
909 m_actionSwitchToPkgSearch->setChecked(false);
910 ui->twGroups->setEnabled(true);
911 groupItemSelected();
912 }
913 }
914 }*/
915 }
916
917 /*
918 * Refreshes the toolButtons which indicate outdated packages
919 */
refreshStatusBarToolButtons()920 void MainWindow::refreshStatusBarToolButtons()
921 {
922 if (!isSearchByFileSelected() && !m_actionSwitchToRemoteSearch->isChecked())
923 ui->twGroups->setEnabled(true);
924 }
925
926 /*
927 * Prints the values of the package counters at the left of the statusBar
928 */
refreshStatusBar()929 void MainWindow::refreshStatusBar()
930 {
931 m_lblSelCounter->setVisible(true);
932 m_lblTotalCounters->setVisible(true);
933 QString text;
934 ui->statusBar->removeWidget(m_toolButtonPacman);
935
936 int numberOfInstalledPackages = m_packageModel->getInstalledPackagesCount();
937
938 if(numberOfInstalledPackages > 0)
939 {
940 text = StrConstants::getNumberInstalledPackages(numberOfInstalledPackages);
941 }
942 else if (m_leFilterPackage->text().isEmpty() && !m_packageModel->isFiltered())
943 {
944 text = StrConstants::getNumberInstalledPackages(m_numberOfInstalledPackages);
945 }
946 else
947 {
948 if (isRemoteSearchSelected())
949 {
950 if (m_packageModel->getPackageCount() == 0)
951 {
952 m_lblSelCounter->setText("");
953 m_lblSelCounter->setVisible(false);
954 m_lblTotalCounters->setVisible(false);
955 }
956 }
957
958 text = StrConstants::getNumberInstalledPackages(0);
959 }
960
961 m_lblTotalCounters->setText(text);
962 ui->statusBar->addWidget(m_lblTotalCounters);
963
964 if (g_fwOutdatedList.isFinished() && m_numberOfOutdatedPackages > 0)
965 {
966 m_toolButtonPacman->show();
967
968 if (m_numberOfOutdatedPackages == 1)
969 {
970 m_toolButtonPacman->setText("(1)");
971 m_toolButtonPacman->setToolTip(StrConstants::getOneNewUpdate());
972 }
973 else
974 {
975 m_toolButtonPacman->setText("(" + QString::number(m_numberOfOutdatedPackages) + ")");
976 m_toolButtonPacman->setToolTip(StrConstants::getNewUpdates(m_numberOfOutdatedPackages));
977 }
978
979 ui->statusBar->addWidget(m_toolButtonPacman);
980 }
981 else
982 {
983 m_toolButtonPacman->hide();
984 m_toolButtonPacman->setText("");
985 m_toolButtonPacman->setToolTip("");
986 }
987 }
988
989 /*
990 * Clears the counters at the left of the Statusbar
991 */
clearStatusBar()992 void MainWindow::clearStatusBar()
993 {
994 m_lblSelCounter->clear();
995 m_lblTotalCounters->clear();
996 }
997
998 /*
999 * Re-populates the HTML view with 'pkgName' package information (tab ONE)
1000 */
refreshTabInfo(QString pkgName)1001 void MainWindow::refreshTabInfo(QString pkgName)
1002 {
1003 const PackageRepository::PackageData*const package = m_packageRepo.getFirstPackageByName(pkgName);
1004 if (package == NULL)
1005 return;
1006
1007 CPUIntensiveComputing cic;
1008 QTextBrowser *text = ui->twProperties->widget(
1009 ctn_TABINDEX_INFORMATION)->findChild<QTextBrowser*>("textBrowser");
1010
1011 if (text)
1012 {
1013 text->clear();
1014 text->setHtml(OctopkgTabInfo::formatTabInfo(*package, *m_outdatedList));
1015 text->scrollToAnchor(OctopkgTabInfo::anchorBegin);
1016
1017 //We have to clear the cached Info contents...
1018 m_cachedPackageInInfo = "";
1019 }
1020 }
1021
1022 /*
1023 * Re-populates the HTML view with selected package's information (tab ONE)
1024 */
refreshTabInfo(bool clearContents,bool neverQuit)1025 void MainWindow::refreshTabInfo(bool clearContents, bool neverQuit)
1026 {
1027 if(neverQuit == false &&
1028 (ui->twProperties->currentIndex() != ctn_TABINDEX_INFORMATION || !isPropertiesTabWidgetVisible() || !m_initializationCompleted)) return;
1029
1030 QItemSelectionModel*const selectionModel = ui->tvPackages->selectionModel();
1031 if (clearContents || selectionModel == NULL ||
1032 selectionModel->selectedRows(PackageModel::ctn_PACKAGE_NAME_COLUMN).count() == 0)
1033 {
1034 QTextBrowser *text =
1035 ui->twProperties->widget(ctn_TABINDEX_INFORMATION)->findChild<QTextBrowser*>("textBrowser");
1036
1037 if (text)
1038 {
1039 text->clear();
1040 }
1041
1042 m_cachedPackageInInfo = "";
1043 return;
1044 }
1045
1046 QModelIndex item = selectionModel->selectedRows(PackageModel::ctn_PACKAGE_NAME_COLUMN).first();
1047 const PackageRepository::PackageData*const package = m_packageModel->getData(item);
1048 if (package == NULL) {
1049 assert(false);
1050 return;
1051 }
1052
1053 //If we are trying to refresh an already displayed package...
1054 if (m_cachedPackageInInfo == package->repository+"#"+package->name+"#"+package->version)
1055 {
1056 if (neverQuit)
1057 {
1058 changeTabWidgetPropertiesIndex(ctn_TABINDEX_INFORMATION);
1059 }
1060
1061 return;
1062 }
1063
1064 CPUIntensiveComputing cic;
1065
1066 /* Appends all info from the selected package! */
1067 QTextBrowser *text = ui->twProperties->widget(
1068 ctn_TABINDEX_INFORMATION)->findChild<QTextBrowser*>("textBrowser");
1069 if (text)
1070 {
1071 text->clear();
1072 text->setHtml(OctopkgTabInfo::formatTabInfo(*package, *m_outdatedList));
1073 text->scrollToAnchor(OctopkgTabInfo::anchorBegin);
1074 }
1075
1076 m_cachedPackageInInfo = package->repository+"#"+package->name+"#"+package->version;
1077
1078 if (neverQuit)
1079 {
1080 changeTabWidgetPropertiesIndex(ctn_TABINDEX_INFORMATION);
1081 }
1082 }
1083
1084 /*
1085 * Re-populates the treeview which contains the file list of selected package (tab TWO)
1086 */
refreshTabFiles(bool clearContents,bool neverQuit)1087 void MainWindow::refreshTabFiles(bool clearContents, bool neverQuit)
1088 {
1089 if (m_progressWidget->isVisible() || !m_initializationCompleted) return;
1090
1091 if(neverQuit == false &&
1092 (ui->twProperties->currentIndex() != ctn_TABINDEX_FILES || !isPropertiesTabWidgetVisible()))
1093 {
1094 return;
1095 }
1096
1097 bool filterHasFocus = m_leFilterPackage->hasFocus();
1098 bool tvPackagesHasFocus = ui->tvPackages->hasFocus();
1099
1100 QItemSelectionModel*const selectionModel = ui->tvPackages->selectionModel();
1101 if (clearContents || selectionModel == NULL ||
1102 selectionModel->selectedRows(PackageModel::ctn_PACKAGE_NAME_COLUMN).count() == 0)
1103 {
1104 QTreeView*const tvPkgFileList =
1105 ui->twProperties->widget(ctn_TABINDEX_FILES)->findChild<QTreeView*>("tvPkgFileList");
1106
1107 if(tvPkgFileList)
1108 {
1109 QStandardItemModel*const modelPkgFileList = qobject_cast<QStandardItemModel*>(tvPkgFileList->model());
1110 modelPkgFileList->clear();
1111 m_cachedPackageInFiles = "";
1112 closeTabFilesSearchBar();
1113
1114 if (filterHasFocus) m_leFilterPackage->setFocus();
1115 else if (tvPackagesHasFocus) ui->tvPackages->setFocus();
1116
1117 return;
1118 }
1119 }
1120
1121 QModelIndex item = selectionModel->selectedRows(PackageModel::ctn_PACKAGE_NAME_COLUMN).first();
1122 const PackageRepository::PackageData*const package = m_packageModel->getData(item);
1123
1124 if (package == NULL) {
1125 assert(false);
1126 return;
1127 }
1128
1129 //If we are trying to refresh an already displayed package...
1130 if (m_cachedPackageInFiles == package->repository+"#"+package->name+"#"+package->version)
1131 {
1132 if (neverQuit)
1133 {
1134 changeTabWidgetPropertiesIndex(ctn_TABINDEX_FILES);
1135 selectFirstItemOfPkgFileList();
1136 }
1137 else
1138 {
1139 QTreeView*const tv = ui->twProperties->currentWidget()->findChild<QTreeView *>("tvPkgFileList") ;
1140 if (tv)
1141 tv->scrollTo(tv->currentIndex());
1142 }
1143
1144 return;
1145 }
1146
1147 //Maybe this is a non-installed package...
1148 bool nonInstalled = (package->installed() == false);
1149
1150 QTreeView*const tvPkgFileList =
1151 ui->twProperties->widget(ctn_TABINDEX_FILES)->findChild<QTreeView*>("tvPkgFileList");
1152
1153 if (tvPkgFileList)
1154 {
1155 QString pkgName = package->name;
1156 QStringList fileList;
1157 QStandardItemModel *fakeModelPkgFileList = new QStandardItemModel(this);
1158 QStandardItemModel *modelPkgFileList = qobject_cast<QStandardItemModel*>(tvPkgFileList->model());
1159
1160 modelPkgFileList->clear();
1161 QStandardItem *fakeRoot = fakeModelPkgFileList->invisibleRootItem();
1162 QStandardItem *root = modelPkgFileList->invisibleRootItem();
1163 QStandardItem *lastDir, *item, *lastItem=root, *parent;
1164 bool first=true;
1165 lastDir = root;
1166 QEventLoop el;
1167 QFuture<QStringList> f;
1168 QFutureWatcher<QStringList> fwPackageContents;
1169 f = QtConcurrent::run(Package::getContents, pkgName, !nonInstalled);
1170 connect(&fwPackageContents, SIGNAL(finished()), &el, SLOT(quit()));
1171 fwPackageContents.setFuture(f);
1172
1173 //Let's wait before we get the pkg file list from the other thread...
1174 el.exec();
1175 fileList = fwPackageContents.result();
1176 QString fullPath;
1177 bool isSymLinkToDir = false;
1178
1179 int counter = 0;
1180 m_progressWidget->setRange(0, fileList.count());
1181 m_progressWidget->setValue(0);
1182 m_progressWidget->show();
1183
1184 for ( QString file: fileList )
1185 {
1186 bool isDir = file.endsWith('/');
1187 isSymLinkToDir = false;
1188 QString baseFileName = extractBaseFileName(file);
1189
1190 //Let's test if it is not a symbolic link to a dir
1191 if(!isDir)
1192 {
1193 QFileInfo fiTestForSymLink(file);
1194 if(fiTestForSymLink.isSymLink())
1195 {
1196 QFileInfo fiTestForDir(fiTestForSymLink.symLinkTarget());
1197 isSymLinkToDir = fiTestForDir.isDir();
1198 }
1199 }
1200
1201 if(isDir){
1202 if ( first == true ){
1203 item = new QStandardItem ( IconHelper::getIconFolder(), baseFileName );
1204 item->setAccessibleDescription("directory " + item->text());
1205 fakeRoot->appendRow ( item );
1206 }
1207 else{
1208 fullPath = utils::showFullPathOfItem(lastDir->index());
1209 //std::cout << "Testing if " << file.toLatin1().data() << " contains " << fullPath.toLatin1().data() << std::endl;
1210 if ( file.contains ( fullPath )) {
1211 //std::cout << "It contains !!! So " << fullPath.toLatin1().data() << " is its parent." << std::endl;
1212 item = new QStandardItem ( IconHelper::getIconFolder(), baseFileName );
1213 item->setAccessibleDescription("directory " + item->text());
1214 lastDir->appendRow ( item );
1215 }
1216 else{
1217 //std::cout << "It doens't contain..." << std::endl;
1218 parent = lastItem->parent();
1219 if (parent != 0) fullPath = utils::showFullPathOfItem(parent->index());
1220
1221 do{
1222 //if (parent != 0) std::cout << "Testing if " << file.toLatin1().data() << " contains " << fullPath.toLatin1().data() << std::endl;
1223 if ( parent == 0 || file.contains ( fullPath )) break;
1224 parent = parent->parent();
1225 if (parent != 0) fullPath = utils::showFullPathOfItem(parent->index());
1226 }
1227 while ( parent != fakeRoot );
1228
1229 item = new QStandardItem ( IconHelper::getIconFolder(), baseFileName );
1230 item->setAccessibleDescription("directory " + item->text());
1231
1232 if ( parent != 0 )
1233 {
1234 //std::cout << item->text().toLatin1().data() << " is son of " << fullPath.toLatin1().data() << std::endl;
1235 parent->appendRow ( item );
1236 }
1237 else
1238 {
1239 //std::cout << item->text().toLatin1().data() << " is son of <FAKEROOT>" << std::endl;
1240 fakeRoot->appendRow ( item );
1241 }
1242 }
1243 }
1244
1245 lastDir = item;
1246 }
1247 else if (isSymLinkToDir)
1248 {
1249 item = new QStandardItem ( IconHelper::getIconFolder(), baseFileName );
1250 item->setAccessibleDescription("directory " + item->text());
1251 parent = lastDir;
1252 if (parent != 0) fullPath = utils::showFullPathOfItem(parent->index());
1253
1254 do{
1255 if ( parent == 0 || file.contains ( fullPath )) break;
1256 parent = parent->parent();
1257 if (parent != 0) fullPath = utils::showFullPathOfItem(parent->index());
1258 }
1259 while ( parent != fakeRoot );
1260
1261 if (parent != 0)
1262 {
1263 parent->appendRow ( item );
1264 }
1265 else
1266 {
1267 fakeRoot->appendRow ( item );
1268 }
1269 }
1270 else
1271 {
1272 item = new QStandardItem ( IconHelper::getIconBinary(), baseFileName );
1273 item->setAccessibleDescription("file " + item->text());
1274 parent = lastDir;
1275 if (parent != 0) fullPath = utils::showFullPathOfItem(parent->index());
1276
1277 do{
1278 if ( parent == 0 || file.contains ( fullPath )) break;
1279 parent = parent->parent();
1280 if (parent != 0) fullPath = utils::showFullPathOfItem(parent->index());
1281 }
1282 while ( parent != fakeRoot );
1283
1284 parent->appendRow ( item );
1285 }
1286
1287 lastItem = item;
1288 first = false;
1289
1290 counter++;
1291 m_progressWidget->setValue(counter);
1292 //qApp->processEvents();
1293 }
1294
1295 m_progressWidget->close();
1296 root = fakeRoot;
1297 fakeModelPkgFileList->sort(0);
1298 modelPkgFileList = fakeModelPkgFileList;
1299 tvPkgFileList->setModel(modelPkgFileList);
1300 tvPkgFileList->header()->setDefaultAlignment( Qt::AlignCenter );
1301 modelPkgFileList->setHorizontalHeaderLabels( QStringList() << StrConstants::getContentsOf().arg(pkgName));
1302 }
1303
1304 m_cachedPackageInFiles = package->repository+"#"+package->name+"#"+package->version;
1305
1306 if (neverQuit)
1307 {
1308 changeTabWidgetPropertiesIndex(ctn_TABINDEX_FILES);
1309 selectFirstItemOfPkgFileList();
1310 }
1311
1312 closeTabFilesSearchBar();
1313
1314 if (filterHasFocus) m_leFilterPackage->setFocus();
1315 else if (tvPackagesHasFocus) ui->tvPackages->setFocus();
1316 }
1317
1318 /*
1319 * This SLOT is called every time we press a key at FilterLineEdit
1320 */
reapplyPackageFilter()1321 void MainWindow::reapplyPackageFilter()
1322 {
1323 if (m_actionSwitchToRemoteSearch->isChecked())
1324 {
1325 if (m_leFilterPackage->text() == "")
1326 {
1327 m_packageModel->applyFilter("ççç");
1328 refreshStatusBar();
1329 }
1330 return;
1331 }
1332
1333 if (!isSearchByFileSelected())
1334 {
1335 bool isFilterPackageSelected = m_leFilterPackage->hasFocus();
1336 QString search = Package::parseSearchString(m_leFilterPackage->text());
1337 m_packageModel->applyFilter(search);
1338
1339 int numPkgs = m_packageModel->getPackageCount();
1340
1341 if (m_leFilterPackage->text() != ""){
1342 if (numPkgs > 0) m_leFilterPackage->setFoundStyle();
1343 else m_leFilterPackage->setNotFoundStyle();
1344 }
1345 else{
1346 m_leFilterPackage->initStyleSheet();
1347 m_packageModel->applyFilter("");
1348 }
1349
1350 if (isFilterPackageSelected || numPkgs == 0)
1351 {
1352 m_leFilterPackage->setFocus();
1353 }
1354
1355 if (numPkgs == 0)
1356 tvPackagesSelectionChanged(QItemSelection(),QItemSelection());
1357
1358 ui->tvPackages->selectionModel()->clear();
1359 QModelIndex mi = m_packageModel->index(0, PackageModel::ctn_PACKAGE_NAME_COLUMN, QModelIndex());
1360 ui->tvPackages->setCurrentIndex(mi);
1361 ui->tvPackages->scrollTo(mi);
1362 invalidateTabs();
1363 }
1364 //If we are using "Search By file...
1365 else
1366 {
1367 disconnect(m_leFilterPackage, SIGNAL(textChanged(QString)), this, SLOT(reapplyPackageFilter()));
1368
1369 m_leFilterPackage->initStyleSheet();
1370
1371 //We need to provide QCompleter data to the SearchLineEdit...
1372 if (!m_leFilterPackage->text().isEmpty())
1373 m_leFilterPackage->refreshCompleterData();
1374
1375 connect(m_leFilterPackage, SIGNAL(textChanged(QString)), this, SLOT(reapplyPackageFilter()));
1376 }
1377 }
1378
1379 /*
1380 * Whenever user selects View/All we show him all the available packages
1381 */
selectedAllPackagesMenu()1382 void MainWindow::selectedAllPackagesMenu()
1383 {
1384 m_selectedViewOption = ectn_ALL_PKGS;
1385 changePackageListModel(ectn_ALL_PKGS, m_selectedRepository);
1386 }
1387
1388 /*
1389 * Whenever user selects View/Installed we show him only the installed packages
1390 */
selectedInstalledPackagesMenu()1391 void MainWindow::selectedInstalledPackagesMenu()
1392 {
1393 m_selectedViewOption = ectn_INSTALLED_PKGS;
1394 changePackageListModel(ectn_INSTALLED_PKGS, m_selectedRepository);
1395 }
1396
1397 /*
1398 * Whenever user selects View/Non Installed we show him only the non installed packages
1399 */
selectedNonInstalledPackagesMenu()1400 void MainWindow::selectedNonInstalledPackagesMenu()
1401 {
1402 m_selectedViewOption = ectn_NON_INSTALLED_PKGS;
1403 changePackageListModel(ectn_NON_INSTALLED_PKGS, m_selectedRepository);
1404 }
1405
1406 /*
1407 * Whenever user selects any of the available repositories in View/Repository submenu,
1408 * we filter the packages from that chosen repo
1409 */
selectedRepositoryMenu(QAction * actionRepoSelected)1410 void MainWindow::selectedRepositoryMenu(QAction *actionRepoSelected)
1411 {
1412 if (actionRepoSelected->text() == StrConstants::getAll())
1413 m_selectedRepository = "";
1414 else
1415 m_selectedRepository = actionRepoSelected->text();
1416
1417 changePackageListModel(m_selectedViewOption, m_selectedRepository);
1418 }
1419