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 #ifdef MYDEF_GTK_EXISTS
27 #include <QDBusConnection>
28 #include <QDBusInterface>
29 #include <phonon/AudioOutput>
30 #include <phonon/MediaObject>
36 #include "mainwindow.h"
38 #include "ui_mainwindow.h"
39 #include "aaptinterface.h"
40 #include "packageview.h"
41 #include "confirmdialog.h"
47 #include "rotatingbackground.h"
48 #include "dpkginterface.h"
51 MainWindow::MainWindow(QWidget *parent) :
53 ui(new Ui::MainWindow)
57 iAptInterface = new AAptInterface(this);
58 iWinPackageView = new PackageView(this);
59 iWinPackageView->setAptInterface(iAptInterface);
60 iWinRepoView = new RepoView(this);
61 iWinRepoView->setAptInterface(iAptInterface);
62 iSettings = new Settings(this);
63 iSettings->setAptInterface(iAptInterface);
64 iSettings->setPackageView(iWinPackageView);
65 iWinPackageView->setSettings(iSettings);
66 iAptInterface->setSettings(iSettings);
67 iDpkgInterface = new DpkgInterface(this);
69 iWinPackageView->setSortOrder( (PackageView::sortOrder)iSettings->qsettings()->value("default_sort_order",0).toInt() );
71 iWinPackageView->setSearchOptions( iSettings->qsettings()->value("search_pkgnames",true).toBool(),
72 iSettings->qsettings()->value("search_displaynames",true).toBool(),
73 iSettings->qsettings()->value("search_descshort",true).toBool(),
74 iSettings->qsettings()->value("search_desclong",false).toBool() );
77 this->setAttribute(Qt::WA_Maemo5StackedWindow);
78 if( !iSettings->qsettings()->value("disable_autorotation",false).toBool() ) {
79 this->setAttribute(Qt::WA_Maemo5AutoOrientation);
81 this->setAttribute(Qt::WA_Maemo5LandscapeOrientation);
85 iDimmer = new dimmer(this);
87 iReposAutoUpdating = false;
88 iUpgradeAutoUpdate = true;
89 iNextOperation = OpNone;
91 ui->centralWidget->loadWallpaper();
93 QString stylesheet_mainscreen =
95 "border-radius: 16px;"
97 "border-color: palette(light);"
98 "border-style: outset;"
99 "padding-right: 10px;"
100 "padding-left: 10px;"
101 "color: palette(buttontext);"
102 "background: rgba(255,255,255,80);"
104 "QPushButton:pressed {"
105 "border-style: inset;"
106 "background-color: rgba(255,255,255,150);"
109 if( ((QApplication*)QApplication::instance())->styleSheet().isEmpty() )
111 QString stylesheet_file;
112 QFile f("/root/.fapman/style.css");
113 if( f.open(QIODevice::ReadOnly | QIODevice::Text ) )
116 stylesheet_file += f.readLine().trimmed();
121 if( stylesheet_file.isEmpty() ) {
122 ui->centralWidget->setStyleSheet(stylesheet_mainscreen);
124 ((QApplication*)QApplication::instance())->setStyleSheet(stylesheet_file);
132 QDBusConnection conn = QDBusConnection::connectToBus(QDBusConnection::SystemBus, "faster_application_manager");
134 QString service = "com.nokia.icd";
135 QString path = "/com/nokia/icd";
136 QString method = "connect";
138 QDBusInterface net(service, path, service, conn, this);
139 net.call(method,"[ANY]",0);
142 iMediaObject = new Phonon::MediaObject(this);
143 Phonon::AudioOutput* aout = new Phonon::AudioOutput(Phonon::NotificationCategory, this);
144 Phonon::createPath(iMediaObject, aout);
147 MainWindow::~MainWindow()
149 // save "need repo refresh" status
150 iSettings->qsettings()->setValue("need_repo_refresh", iAptInterface->needRepoRefresh());
152 delete iWinPackageView;
154 delete iAptInterface;
155 delete iDpkgInterface;
161 void MainWindow::changeEvent(QEvent *e)
163 QMainWindow::changeEvent(e);
165 case QEvent::LanguageChange:
166 ui->retranslateUi(this);
173 void MainWindow::on_btnRepos_clicked()
175 iWinRepoView->openWin();
178 void MainWindow::on_btnUpdate_clicked()
182 busyDialog(true, tr("Operation in progress"), tr("Updating catalogs"));
184 iAptInterface->addQueuedOperation(AAptInterface::ModeAptGetUpdate);
185 iAptInterface->run(iDimmer);
189 int MainWindow::top_application()
198 void MainWindow::dateFetchAsk()
200 if( !iSettings->qsettings()->value("firstrun_asked_fetch_dates",false).toBool() &&
201 !iSettings->qsettings()->value("fetch_dates",false).toBool() )
203 iSettings->qsettings()->setValue("firstrun_asked_fetch_dates", true);
204 ConfirmDialog d(true, this);
205 d.setText("Fetch date information?","Enable date information fetching for packages? You have to enable it in order to be "
206 "able to sort packages by date. The first fetch can be slow but the dates are cached for later use. You can later "
207 "change this selection from the options menu.");
209 iSettings->qsettings()->setValue("fetch_dates", true);
211 if( iSettings->qsettings()->value("fetch_dates",false).toBool() )
213 iSettings->qsettings()->setValue("firstrun_asked_fetch_dates", true); // don't ask if the option has already been enabled
214 if( !iAptInterface->dateCacheExists() )
216 ConfirmDialog d(false, this);
217 d.setText("Notice","Date information will be fetched only for packages from maemo.org and only for user categories.");
220 iAptInterface->addQueuedOperation(AAptInterface::ModeFetchDates);
224 void MainWindow::on_btnListInstallable_clicked()
230 if( iAptInterface->lastListUpdate() < QDateTime::currentDateTime().addSecs(-KListExpireTime) )
232 if( iAptInterface->lastDpkgUpdate() < QDateTime::currentDateTime().addSecs(-KListExpireTime) )
234 iAptInterface->setNeedRefresh(-1,listupd,dpkgupd,listupd);
236 iWinPackageView->setStatFilter( Package::PkgStatNotInstalled );
238 if( iAptInterface->needRepoRefresh() && !iSettings->qsettings()->value("no_catalogs_autoupdate",false).toBool() )
239 iAptInterface->addQueuedOperation(AAptInterface::ModeAptGetUpdate);
241 busyDialog(true, tr("Operation in progress"), tr("Reading package lists"));
243 iNextOperation = OpOpenPkgView;
244 iAptInterface->addQueuedOperation(AAptInterface::ModeReadPackages);
248 iAptInterface->run(iDimmer);
251 void MainWindow::on_btnUpgrade_clicked()
257 if( iAptInterface->lastListUpdate() < QDateTime::currentDateTime().addSecs(-KListExpireTime) )
259 if( iAptInterface->lastDpkgUpdate() < QDateTime::currentDateTime().addSecs(-KListExpireTime) )
261 iAptInterface->setNeedRefresh(-1,listupd,dpkgupd,listupd);
263 iWinPackageView->setStatFilter( Package::PkgStatUpgradeable );
265 if( iAptInterface->needRepoRefresh() && !iSettings->qsettings()->value("no_catalogs_autoupdate",false).toBool() )
266 iAptInterface->addQueuedOperation(AAptInterface::ModeAptGetUpdate);
268 busyDialog(true, tr("Operation in progress"), tr("Reading package lists"));
270 iNextOperation = OpOpenPkgView;
271 iAptInterface->addQueuedOperation(AAptInterface::ModeReadPackages);
275 iAptInterface->run(iDimmer);
278 void MainWindow::on_btnListInstalled_clicked()
282 if( !iSettings->qsettings()->value("remove_readfull",false).toBool() )
283 iAptInterface->setSkipListAndDates();
286 if( iAptInterface->lastDpkgUpdate() < QDateTime::currentDateTime().addSecs(-KListExpireTime) )
288 iAptInterface->setNeedRefresh(-1,-1,dpkgupd,-1);
290 iWinPackageView->setStatFilter( Package::PkgStatInstalled );
292 busyDialog(true, tr("Operation in progress"), tr("Reading package lists"));
294 iNextOperation = OpOpenPkgView;
295 iAptInterface->addQueuedOperation(AAptInterface::ModeReadPackages);
299 iAptInterface->run(iDimmer);
302 void MainWindow::operationQueueFinished(QList<AAptInterface::interfaceMode> lastModes, bool success, QString title, QStringList msgs)
304 if( lastModes.contains(AAptInterface::ModeAptGetSimulate) && success ) {
305 iNextOperation = OpPromptSimulated;
307 if( lastModes.contains(AAptInterface::ModeAptGetInstall) && success ) {
308 iWinPackageView->clearSelections();
310 iWinPackageView->close();
311 iNextOperation = OpNone;
313 GdkEventIconThemeReload();
316 QWidget* dialogParent = this;
317 if( iWinPackageView->isVisible() )
318 dialogParent = iWinPackageView;
320 if( iNextOperation == OpOpenPkgView && success )
322 iWinPackageView->openWin();
324 iNextOperation = OpNone;
325 } else if( iNextOperation == OpPromptSimulated && success )
327 QStringList inst,remv,instver,remvver;
328 QStringList all = iAptInterface->processPackages();
329 QStringList vers = iAptInterface->processPackageVersions();
330 for(int zyx=0; zyx<all.count(); zyx++)
332 if( all.at(zyx).endsWith('-') )
334 remv.append( all.at(zyx).left( all.at(zyx).size()-1 ) );
335 if( vers.count()>zyx )
336 remvver.append( vers.at(zyx) );
338 inst.append( all.at(zyx) );
339 if( vers.count()>zyx )
340 instver.append( vers.at(zyx) );
344 int total_dl_size = 0;
345 for( int i=0; i<inst.count(); i++ ) {
346 Package* pkg = iAptInterface->packagesAvailable()->value(inst.at(i),0);
348 total_dl_size += pkg->size()/1024;
353 pkglist = QString("<b>The following operations will be performed:</b><br>"
354 "%1 to install/upgrade, %2 to remove<br>").arg(inst.count()).arg(remv.count());
356 pkglist += QString("Total download size: %L1 kB<br>").arg(total_dl_size);
357 bool mismatch = false;
358 bool warn_system_package_remove = false;
359 bool warn_system_package_install = false;
361 if( remv.count()>0 ) {
362 pkglist += "<br><b><u>REMOVE:</u></b><br><font size=\"-1\">";
363 for( int i=0; i<remv.count(); i++ ) {
364 pkglist += "<b>" + remv.at(i) + "</b>";
365 Package* pkg = iAptInterface->packagesInstalled()->value(remv.at(i),0);
367 qDebug() << "Warning: unknown package" << remv.at(i);
368 pkglist += "<font color=\"red\">***UNKNOWN***</font>";
372 if( pkg && pkg->maemoDisplayName()=="Maemo 5" ) {
373 warn_system_package_remove = true;
376 if( remvver.count()>i ) {
377 pkglist += " " + remvver.at(i);
378 if( pkg && remvver.at(i) != pkg->version() ) {
379 qDebug() << "Version mismatch, database version is" << pkg->version() << "but removing" << remvver.at(i);
381 pkglist += " <font color=\"red\">***TRYING TO REMOVE " + pkg->version() + "***</font> ";
384 if( pkg && pkg->installedSize()>0 )
385 pkglist += QString(" (%L1 kB)").arg(pkg->installedSize());
389 pkglist += "</font>";
391 bool installing_blacklisted = false;
392 if( inst.count()>0 ) {
393 pkglist += "<br><b><u>INSTALL/UPGRADE:</u></b><br><font size=\"-1\">";
394 for( int i=0; i<inst.count(); i++ ) {
395 pkglist += "<b>" + inst.at(i) + "</b>";
396 Package* pkg = iAptInterface->packagesAvailable()->value(inst.at(i),0);
398 qDebug() << "Warning: unknown package" << inst.at(i);
399 pkglist += "<font color=\"red\">***NEW/UNKNOWN***</font>";
402 if( pkg && pkg->isBlacklisted() ) {
403 qDebug() << "Warning: installing blacklisted package" << inst.at(i);
404 pkglist += "<font color=\"red\">***BLACKLISTED***</font>";
405 installing_blacklisted = true;
408 if( pkg && pkg->maemoDisplayName()=="Maemo 5" ) {
409 warn_system_package_install = true;
412 if( instver.count()>i ) {
413 pkglist += " " + instver.at(i);
414 if( pkg && instver.at(i) != pkg->version() ) {
415 qDebug() << "Version mismatch, database version is" << pkg->version() << "but installing" << instver.at(i);
417 pkglist += " <font color=\"red\">***TRYING TO INSTALL " + pkg->version() + "***</font> ";
420 if( pkg && pkg->size()>0 ) {
421 pkglist += QString(" (%L1 kB)").arg(pkg->size()/1024);
426 pkglist += "</font>";
429 ConfirmDialog m(false, dialogParent);
430 m.setText("Warning", "There is a version mismatch between your original package selections and some of the packages being installed " \
431 "from the repositories. This could be due to your application catalogs being out of date.");
434 if( installing_blacklisted ) {
435 ConfirmDialog b(false, dialogParent);
436 b.setText("Warning","Blacklisted package(s) will be installed");
439 if( warn_system_package_remove ) {
440 ConfirmDialog s(false, dialogParent);
441 s.setText("Warning","You are about to remove a critical system package.");
444 if( warn_system_package_install ) {
445 ConfirmDialog s(false, dialogParent);
446 s.setText("Warning","You are trying to perform an install/upgrade operation on a critical system package. Doing a system upgrade with " \
447 "Faster Application Manager has not been tested and it could result in a horrible failure. You have been warned.");
452 ConfirmDialog d(true, dialogParent);
453 if( inst.count()==0 && remv.count()==0 )
455 pkglist = "None of the packages can be installed";
458 d.setText("Confirmation",pkglist);
460 iAptInterface->addQueuedOperation(AAptInterface::ModeAptGetInstall);
462 if( iSettings->qsettings()->value("enable_autoclean",true).toBool() && inst.count()>0 )
463 iAptInterface->addQueuedOperation(AAptInterface::ModeAptGetClean);
466 if( remv.count() > 0 )
467 busytext += QString("Remove %1 package(s)<br>").arg(remv.count());
468 if( inst.count() > 0 )
469 busytext += QString("Install %1 package(s)<br>").arg(inst.count());
470 busytext += "Preparing...";
471 busyDialog(true, "Operation in progress", busytext);
473 // "run" really does nothing here since the previous item should still be running
474 if( iWinPackageView->isVisible() ) {
475 iAptInterface->run(iWinPackageView->mydimmer());
477 iAptInterface->run(iDimmer);
480 iNextOperation = OpNone;
484 iNextOperation = OpNone;
486 if( iSettings->qsettings()->value("sound_notify",false).toBool() )
488 qDebug() << "playing sound";
489 iMediaObject->setCurrentSource( Phonon::MediaSource(iSettings->qsettings()->value("sound_file","/usr/share/sounds/ui-operation_ready.wav").toString()) );
490 iMediaObject->play();
493 QString text = "<br><b><u>Faster Application Manager</u></b><br>"
494 "<b>"+title+"</b><br>" + msgs.join("<br>") + "<br>";
496 QRect r = QApplication::desktop()->rect();
497 if(r.width() < r.height()) {
498 ConfirmDialog d(false, dialogParent);
499 d.setText(title,msgs.join("<br>"));
503 QMaemo5InformationBox::information(0, text, QMaemo5InformationBox::NoTimeout);
505 ConfirmDialog d(false, dialogParent);
506 d.setText(title,msgs.join("<br>"));
515 void MainWindow::busyDialog(bool show_, QString title, QString text)
518 iDimmer->setProgress(-1);
519 ui->menuMenu->setEnabled(false);
520 ui->centralWidget->setEnabled(false);
521 iWinPackageView->disableMenu();
522 iDimmer->resizeEvent(0);
523 iDimmer->dim(title, text);
524 iWinPackageView->mydimmer()->resizeEvent(0);
525 iWinPackageView->mydimmer()->dim(title, text);
528 iWinPackageView->mydimmer()->undim();
529 ui->menuMenu->setEnabled(true);
530 ui->centralWidget->setEnabled(true);
531 iWinPackageView->enableMenu();
535 void MainWindow::on_actionAbout_triggered()
537 ConfirmDialog d(false, this);
538 d.setText("About","Faster Application Manager<br>"
539 "<font size=\"-1\">Version " + PROGRAM_VERSION + "</font><br><br>"
540 "(C) Heikki Holstila 2010<br>Donate using "
541 "<a href=\"https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=6ZKRY5QFHL42A&lc=FI&item_name=Faster%20Application%20Manager"
542 "%20for%20Maemo5¤cy_code=EUR&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHosted\">PayPal</a>");
546 void MainWindow::on_actionClean_triggered()
548 //if( iOperation != OpNone ) return;
549 //iOperation = OpClean;
550 iAptInterface->addQueuedOperation(AAptInterface::ModeAptGetClean);
551 iAptInterface->run(iDimmer);
554 void MainWindow::closeEvent(QCloseEvent *event)
556 if( iDimmer->busy() ) {
557 iAptInterface->cancel();
564 void MainWindow::on_actionView_log_triggered()
566 QByteArray log = iAptInterface->readLogFile();
567 LogView l(log, this);
571 void MainWindow::on_actionOptions_triggered()
573 iSettings->openWin();
576 void MainWindow::notifyDialog(QString title, QString msg)
578 QWidget* dialogParent = this;
579 if( iWinPackageView->isVisible() )
580 dialogParent = iWinPackageView;
582 ConfirmDialog d(false, dialogParent);
583 d.setText(title, msg);
587 bool MainWindow::confirmDialog(QString title, QString msg)
589 QWidget* dialogParent = this;
590 if( iWinPackageView->isVisible() )
591 dialogParent = iWinPackageView;
593 ConfirmDialog d(true, dialogParent);
594 d.setText(title, msg);
598 void MainWindow::GdkEventIconThemeReload()
600 // DOES NOT EVEN WORK (at least not reliably) - disabled from the project file
602 #ifdef MYDEF_GTK_EXISTS
603 qDebug() << "Sending GDK icon theme reload event";
605 gdk_init((int*)QApplication::argc(),(gchar***)QApplication::argv());
607 // taken from hildon application manager
609 ev.type = GDK_CLIENT_EVENT;
611 ev.send_event = TRUE;
612 ev.message_type = gdk_atom_intern_static_string("_GTK_LOAD_ICONTHEMES");
614 gdk_event_send_clientmessage_toall((GdkEvent*)&ev);
616 while(gdk_events_pending()) {
617 g_main_context_iteration(NULL, true);
623 void MainWindow::on_actionLoad_file_triggered()
625 QStringList files = QFileDialog::getOpenFileNames(this, "Open files", "/", "Files (*.deb *.install)");
626 if( files.count() > 0 ) {
627 QStringList debs = files.filter(QRegExp(".*\\.deb$"));
628 QStringList installs = files.filter(QRegExp(".*\\.install$"));
629 if( debs.count()>0 && installs.count()>0 ) {
630 ConfirmDialog d(false, this);
631 d.setText("Error", "You can't mix different file types in your selection");
636 iDpkgInterface->loadDebFiles(debs);
637 else if( installs.count()>0 )
638 iAptInterface->loadInstallFiles(installs);