Use of gcsDebug instead of qDebug
[meego-garage:garage-client-services.git] / src / applicationmanager.cpp
1 #include "applicationmanager.h"
2 #include "application.h"
3 #include "catalog.h"
4 #include "applicationstatusstorage.h"
5 #include "garagesettings.h"
6 #include "garageclientservices.h"
7 #include "utils.h"
8
9 #ifndef HAVE_NO_PACKAGEKIT
10 #include <QPackageKit>
11 #endif
12 #include <QMutableListIterator>
13 #include <QDir>
14 #include <QFile>
15 #include <QtDebug>
16
17 using namespace MeeGoGarage;
18
19 Application::Status mapActionToQueuedStatus(ApplicationManager::ActionType actionType);
20 Application::Status mapActionToRunningStatus(ApplicationManager::ActionType actionType);
21 Application::Status mapActionToFinishedStatus(ApplicationManager::ActionType actionType);
22
23 //#define PKENUM_DAEMONERROR_STRING(v)   GCS_ENUM_STRING(PackageKit::Client,DaemonError,(v))
24 #define PKENUM_DAEMONERROR_STRING(v)   _daemonErrorStr[(v)]
25 #define PKENUM_ROLE_STRING(v)       GCS_ENUM_STRING(PackageKit::Enum,Role,(v))
26 #define PKENUM_STATUS_STRING(v)     GCS_ENUM_STRING(PackageKit::Enum,Status,(v))
27 #define PKENUM_EXIT_STRING(v)       GCS_ENUM_STRING(PackageKit::Enum,Exit,(v))
28 #define PKENUM_NETWORK_STRING(v)    GCS_ENUM_STRING(PackageKit::Enum,Network,(v))
29 #define PKENUM_ERROR_STRING(v)      GCS_ENUM_STRING(PackageKit::Enum,Error,(v))
30 #define PKENUM_MESSAGE_STRING(v)    GCS_ENUM_STRING(PackageKit::Enum,Message,(v))
31 #define PKENUM_INFO_STRING(v)       GCS_ENUM_STRING(PackageKit::Enum,Info,(v))
32 #define PKENUM_MEDIATYPE_STRING(v)  GCS_ENUM_STRING(PackageKit::Enum,MediaType,(v))
33 #define PKENUM_RESTART_STRING(v)    GCS_ENUM_STRING(PackageKit::Enum,Restart,(v))
34
35 #ifndef HAVE_NO_PACKAGEKIT
36
37 static const char * _daemonErrorStr[PackageKit::Client::LastDaemonError] = {
38     "NoError",
39     "UnkownError",
40     "ErrorFailed",
41     "ErrorFailedAuth",
42     "ErrorNoTid",
43     "ErrorAlreadyTid",
44     "ErrorRoleUnkown",
45     "ErrorCannotStartDaemon",
46     "ErrorInvalidInput",
47     "ErrorInvalidFile",
48     "ErrorFunctionNotSupported",
49     "ErrorDaemonUnreachable"
50 };
51
52 #endif
53
54 ApplicationManager* ApplicationManager::m_instance = 0;
55
56 ApplicationManager* ApplicationManager::instance()
57 {
58     if (!m_instance) {
59         m_instance = new ApplicationManager(0);
60
61         // configure packagekit
62         //QStringList hints;
63         //hints << "locale=en_US.UTF-8";
64         //hints << "background=false";
65         //hints << "interactive=true";
66         //PackageKit::Client::instance()->setHints(hints);
67     }
68
69     return m_instance;
70 }
71
72 ApplicationManager::ApplicationManager(QObject *parent) :
73     QObject(parent),
74     m_currentTransaction(0),
75     m_statusStorage(new ApplicationStatusStorage())
76 {
77 #ifndef HAVE_NO_PACKAGEKIT
78     PackageKit::Client * client = PackageKit::Client::instance();
79     connect(client, SIGNAL(error(PackageKit::Client::DaemonError)),
80             this, SLOT(onError(PackageKit::Client::DaemonError)));
81 #endif
82
83     connect(GarageClientServices::instance(), SIGNAL(onlineStateChanged(bool)), this, SLOT(onOnlineStateChanged(bool)));
84 }
85
86 ApplicationManager::~ApplicationManager()
87 {
88     if (m_statusStorage) {
89         delete m_statusStorage;
90         m_statusStorage = 0;
91     }
92 }
93
94 void ApplicationManager::install(Application * app)
95 {
96     queueAction(InstallAction, app);
97 }
98
99 void ApplicationManager::install(ApplicationList apps)
100 {
101     queueAction(InstallAction, apps);
102 }
103
104 void ApplicationManager::remove(Application * app)
105 {
106     queueAction(RemoveAction, app);
107 }
108
109 void ApplicationManager::remove(ApplicationList apps)
110 {
111     queueAction(RemoveAction, apps);
112 }
113
114 void ApplicationManager::update(Application * app)
115 {
116     queueAction(UpdateAction, app);
117 }
118
119 void ApplicationManager::update(ApplicationList apps)
120 {
121     queueAction(UpdateAction, apps);
122 }
123
124 void ApplicationManager::resolve(Application * app)
125 {
126     queueAction(ResolveAction, app);
127 }
128
129 void ApplicationManager::resolve(ApplicationList apps)
130 {
131 #if 1
132     QListIterator<Application*> i(apps);
133     while(i.hasNext()) {
134         Application * application = i.next();
135         if (application) {
136             resolve(application);
137         }
138     }
139 #else
140     //queueAction(ResolveAction, apps);
141 #endif
142 }
143
144 void ApplicationManager::cancelAll(bool privateActionsToo)
145 {
146     // clear the queue of actions
147     m_actionList.clear();
148
149 #ifndef HAVE_NO_PACKAGEKIT
150     if (privateActionsToo) {
151         m_privateActionList.clear();
152     }
153
154     // cancel current transation
155     if (m_currentTransaction != 0 && m_currentTransaction->allowCancel()) {
156         if (privateActionsToo || !m_isCurrentActionPrivate)
157             m_currentTransaction->cancel();
158     }
159 #endif
160 }
161
162 bool ApplicationManager::canCancel() const
163 {
164     if (! m_actionList.isEmpty()) {
165         return true;
166     }
167
168 #ifndef HAVE_NO_PACKAGEKIT
169     if (m_currentTransaction != 0) {
170         return m_currentTransaction->allowCancel();
171     }
172 #endif
173     return false;
174 }
175
176 ApplicationManager::ActionType ApplicationManager::currentActionType() const
177 {
178     return m_currentAction.actionType;
179 }
180
181 ApplicationList ApplicationManager::currentApplicationList() const
182 {
183     return m_appsInProcess;
184     //return m_currentAction.applicationList;
185 }
186
187 bool ApplicationManager::isCurrentActionPrivate() const
188 {
189     return m_isCurrentActionPrivate;
190 }
191
192 int ApplicationManager::percentage() const
193 {
194     // return invalid if no actions running
195     if (numActionsQueued() <= 0 && m_currentTransaction == 0) {
196         return -1;
197     }
198
199     // returns percentage of total operations in the queue
200     int numTotal = numActionsTotal();
201     if (numTotal <= 0)
202         return 0;
203
204     int numDone = numActionsDone();
205     int percentTransaction = 0;
206
207 #ifndef HAVE_NO_PACKAGEKIT
208     if (m_currentTransaction) {
209         percentTransaction = m_currentTransaction->percentage() / numTotal;
210     }
211 #endif
212
213     return numDone * 100 / numTotal + percentTransaction;
214 }
215
216 int ApplicationManager::elapsedTime() const
217 {
218     // TODO
219 #ifndef HAVE_NO_PACKAGEKIT
220     if (m_currentTransaction->elapsedTime()) {
221         return m_currentTransaction->elapsedTime();
222     }
223 #endif
224     return 0;
225 }
226
227 int ApplicationManager::remainingTime() const
228 {
229     // TODO
230 #ifndef HAVE_NO_PACKAGEKIT
231     if (m_currentTransaction) {
232         return m_currentTransaction->remainingTime();
233     }
234 #endif
235     return 0;
236 }
237
238 ApplicationManager::ActionType ApplicationManager::actionQueuedForApplication(Application * app, bool includeCurrent) const
239 {
240     if (includeCurrent && m_currentAction.applicationList.contains(app)) {
241         return m_currentAction.actionType;
242     }
243
244     QList<Action>::const_iterator i;
245     for(i = m_actionList.constBegin();i != m_actionList.constEnd();i++) {
246         if ((*i).applicationList.contains(app)) {
247             return (*i).actionType;
248         }
249     }
250
251     for(i = m_privateActionList.begin();i != m_privateActionList.end();i++) {
252         if ((*i).applicationList.contains(app)) {
253             return (*i).actionType;
254         }
255     }
256
257     return NoAction;
258 }
259
260 ApplicationManager::ActionType ApplicationManager::actionQueuedForApplication(QList<Application *> apps, bool includeCurrent) const
261 {
262     ApplicationList::const_iterator i;
263     for(i = apps.constBegin();i != apps.constEnd();i++) {
264         ActionType actionType = actionQueuedForApplication(*i, includeCurrent);
265         if (actionType != NoAction) {
266             return actionType;
267         }
268     }
269
270     return NoAction;
271 }
272
273 void ApplicationManager::queueAction(ApplicationManager::ActionType actionType, Application * application)
274 {
275     Q_ASSERT(actionQueuedForApplication(application) == NoAction);
276
277     ApplicationList appList;
278     appList.append(application);
279     queueAction(actionType, appList);
280 }
281
282 void ApplicationManager::queueAction(ApplicationManager::ActionType actionType, ApplicationList applicationList)
283 {
284     gcsDebug() << "actionType=" << actionType <<
285             "appList=" << Utils::applicationListAsString(applicationList);
286     //Catalog::dumpApplicationList(applicationList);
287
288     Q_ASSERT(actionQueuedForApplication(applicationList) == NoAction);
289
290     if (actionType != ResolveAction) {
291         resolveIfNeeded(applicationList);
292     }
293
294     if (!m_currentTransaction && m_actionList.isEmpty()) {
295         m_numActionsTotal = 0;
296     }
297
298     ApplicationList::iterator i;
299     for(i = applicationList.begin();i != applicationList.end();i++) {
300         (*i)->setStatus( mapActionToQueuedStatus(actionType) );
301     }
302
303     Action action;
304     action.actionType = actionType;
305     action.applicationList = applicationList;
306     // give priorities to resolve actions
307     if (actionType == ResolveAction) {
308         m_privateActionList.append(action);
309     } else {
310         m_actionList.append(action);
311         m_numActionsTotal++;
312     }
313
314 #ifndef HAVE_NO_PACKAGEKIT
315     processQueue();
316 #endif
317 }
318
319 void ApplicationManager::resolveIfNeeded(ApplicationList appList)
320 {
321     QMutableListIterator<Application*> i(appList);
322     while (i.hasNext()) {
323         Application * app = i.next();
324         if (!app) {
325             qWarning() << "Error, application not found";
326             i.remove();
327         }
328         // it is safer to resolve always
329 #if 0
330         // we will resolve just the ones without package
331 #ifndef HAVE_NO_PACKAGEKIT
332         if (app->getPackage() != 0) {
333             i.remove();
334         }
335 #endif
336 #endif
337     }
338
339     resolve(appList);
340 }
341
342 #ifndef HAVE_NO_PACKAGEKIT
343 bool ApplicationManager::takeActionFromQueue()
344 {
345     Q_ASSERT(!m_currentTransaction);
346
347     if (m_privateActionList.count() > 0) {
348         // assuming all private actions are resolve and thus can be done offline
349         m_currentAction = m_privateActionList.takeAt(0);
350         Q_ASSERT(m_currentAction.actionType == ResolveAction);
351         m_isCurrentActionPrivate = true;
352         return true;
353     }
354     if (m_actionList.count() > 0) {
355         if  (GarageClientServices::instance()->isOnline()) {
356             m_currentAction = m_actionList.takeAt(0);
357             m_isCurrentActionPrivate = false;
358             return true;
359         } else {
360             int i;
361             for(i = 0;i < m_actionList.count();i++) {
362                 const Action & action = m_actionList.at(i);
363                 if (action.actionType == RemoveAction ||
364                     action.actionType == ResolveAction) {
365                     // when offline we just process the remove and resolve actions
366                     m_currentAction = m_actionList.takeAt(i);
367                     m_isCurrentActionPrivate = false;
368                     return true;
369                 }
370             }
371         }
372     }
373
374     return false;
375 }
376
377 void ApplicationManager::processQueue()
378 {
379     //gcsDebug();
380
381     PackageKit::Client * packageKitClient = PackageKit::Client::instance();
382     if (!packageKitClient) {
383         qWarning() << "ApplicationManager::processQueue" << "packageKit Client not available";
384         return;
385     }
386
387     dumpDaemon();
388
389     while (!m_currentTransaction && takeActionFromQueue()) {
390
391         gcsDebug() << "processing queue length=" << m_privateActionList.count() << m_actionList.count();
392
393         m_appsInProcess = m_currentAction.applicationList;
394         QList<QSharedPointer<PackageKit::Package> > packages;
395         QList<QString> packageNames;
396
397         gcsDebug() << "processing action=" << m_currentAction.actionType <<
398                 "appList=" << Utils::applicationListAsString(m_currentAction.applicationList);
399
400         if (m_currentAction.actionType == ResolveAction) {
401
402             // build list of packages names for resolving
403             ApplicationList::const_iterator i = m_currentAction.applicationList.constBegin();
404             while(i != m_currentAction.applicationList.constEnd()) {
405                 Application * application = (*i);
406                 if (application == 0)
407                     qWarning() << "Package not available for processing";
408                 else if (application->packageName().isEmpty())
409                     qWarning() << "Package not available for processing " << application;
410                 else {
411                     packageNames.append(application->packageName());
412                     application->setStatus(Application::ResolvingStatus);
413                 }
414                 i++;
415             }
416
417             if (packageNames.isEmpty()) {
418                 m_currentAction.actionType = NoAction;
419                 m_currentAction.applicationList.clear();
420                 m_appsInProcess.clear();
421                 packageNames.clear();
422                 packages.clear();
423                 //TODO emit error for the ones we don't process ...
424
425                 gcsDebug() << "Error: no package names to resolve";
426
427                 continue;
428             }
429
430         } else if (m_currentAction.actionType == InstallAction ||
431                    m_currentAction.actionType == RemoveAction ||
432                    m_currentAction.actionType == UpdateAction) {
433
434             // build list of packages for install, remove, update
435             ApplicationList::const_iterator i = m_currentAction.applicationList.constBegin();
436             while(i != m_currentAction.applicationList.constEnd()) {
437                 Application * application = (*i);
438                 if (application == 0)
439                     qWarning() << "Package not available for processing";
440                 else if (application->package().isNull())
441                     qWarning() << "Package not available for processing " << application->name();
442                 else {
443                     packages.append(application->package());
444                     application->setStatus( mapActionToRunningStatus(m_currentAction.actionType) );
445                 }
446                 i++;
447             }
448
449             if (packages.isEmpty()) {
450                 m_currentAction.actionType = NoAction;
451                 m_currentAction.applicationList.clear();
452                 m_appsInProcess.clear();
453                 packageNames.clear();
454                 packages.clear();
455                 //TODO emit error for the ones we don't process ...
456
457                 gcsDebug() << "Error: no packages for operation";
458
459                 continue;
460             }
461         }
462
463         sendProgressMessage(ActionStartedMessage);
464
465         /// Signaled when an application action is started
466         emit applicationActionStarted(m_currentAction.actionType,m_currentAction.applicationList,
467                                       m_isCurrentActionPrivate);
468
469         switch(m_currentAction.actionType) {
470         case InstallAction:
471             gcsDebug() << "installPackages count=" << packages.count();
472             m_currentTransaction = packageKitClient->installPackages(false, packages);
473             break;
474         case RemoveAction:
475             gcsDebug() << "removePackages count=" << packages.count();
476             // TODO yum does not support autoremove, check for zypp
477             //m_currentTransaction = packageKitClient->removePackages(packages, true, true);
478             m_currentTransaction = packageKitClient->removePackages(packages, true, false);
479             break;
480         case UpdateAction:
481             gcsDebug() << "updatePackages count=" << packages.count();
482             m_currentTransaction = packageKitClient->updatePackages(false, packages);
483             break;
484         case ResolveAction:
485             gcsDebug() << "resolve count=" << packageNames.count();
486             m_currentTransaction = packageKitClient->resolve(packageNames);
487             break;
488         case ApplicationManager::RefreshCacheAction:
489             gcsDebug() << "refreshCache";
490             m_currentTransaction = packageKitClient->refreshCache(true);
491             break;
492         case ApplicationManager::GetUpdatesAction:
493             gcsDebug() << "getUpdates";
494             m_currentTransaction = packageKitClient->getUpdates();
495             break;
496         case NoAction:
497             Q_ASSERT(false);
498             break;
499         }
500
501         if (!m_currentTransaction) {
502
503             gcsDebug() << "Error creating the transaction";
504
505             sendProgressMessage(ActionFailedMessage, tr("Transaction could not be created: ") +
506                                 tr(PKENUM_DAEMONERROR_STRING(PackageKit::Client::instance()->getLastError())) );
507
508             m_currentAction.actionType = NoAction;
509             m_currentAction.applicationList.clear();
510             m_appsInProcess.clear();
511             packageNames.clear();
512             packages.clear();
513
514             continue;
515         }
516
517         dumpDaemon();
518
519         connect(m_currentTransaction, SIGNAL(package(QSharedPointer<PackageKit::Package>)),
520                 SLOT(onPackageResolved(QSharedPointer<PackageKit::Package>)));
521         connect(m_currentTransaction, SIGNAL(changed()),
522                 SLOT(onTransactionChanged()));
523         connect(m_currentTransaction, SIGNAL(errorCode(PackageKit::Enum::Error, const QString&)),
524                 SLOT(onTransactionError(PackageKit::Enum::Error, const QString&)));
525         connect(m_currentTransaction, SIGNAL(finished(PackageKit::Enum::Exit,uint)),
526                 SLOT(onTransactionFinished(PackageKit::Enum::Exit,uint)));
527         connect(m_currentTransaction, SIGNAL(message(PackageKit::Enum::Message,QString)),
528                 SLOT(onMessage(PackageKit::Enum::Message,QString)));
529
530         connect(m_currentTransaction, SIGNAL(eulaRequired(PackageKit::Client::EulaInfo)),
531                 this, SLOT(onEulaRequired(PackageKit::Client::EulaInfo)));
532         connect(m_currentTransaction, SIGNAL(mediaChangeRequired(PackageKit::Enum::MediaType,QString,QString)),
533                 this, SLOT(onMediaChangeRequired(PackageKit::Enum::MediaType,QString,QString)));
534         connect(m_currentTransaction, SIGNAL(repoSignatureRequired(PackageKit::Client::SignatureInfo)),
535                 this, SLOT(onRepoSignatureRequired(PackageKit::Client::SignatureInfo)));
536         connect(m_currentTransaction, SIGNAL(requireRestart(PackageKit::Enum::Restart,QSharedPointer<PackageKit::Package>)),
537                 this, SLOT(onRequireRestart(PackageKit::Enum::Restart,QSharedPointer<PackageKit::Package>)));
538     }
539
540 /*
541     if (!m_currentTransaction && m_actionList.isEmpty()) {
542         m_numActionsTotal = 0;
543     }
544 */
545 }
546
547 void ApplicationManager::onEulaRequired(PackageKit::Client::EulaInfo eula)
548 {
549     QString shortStr;
550
551     if (eula.package.isNull()) {
552         shortStr = tr("EULA required id %1 vendor %2")
553                    .arg(eula.id)
554                    .arg(eula.vendorName);
555     } else {
556         shortStr = tr("EULA required id %1 package %2 vendor %3")
557                    .arg(eula.id)
558                    .arg(eula.package->name())
559                    .arg(eula.vendorName);
560     }
561
562     sendUserMessage(shortStr, eula.licenseAgreement);
563 }
564
565 void ApplicationManager::onMediaChangeRequired(PackageKit::Enum::MediaType type, const QString& id, const QString& text)
566 {
567     QString shortStr = tr("Media change required %1 id %2")
568                        .arg(tr(PKENUM_MEDIATYPE_STRING(type)))
569                        .arg(id);
570
571     sendUserMessage(shortStr, text);
572 }
573
574 void ApplicationManager::onRepoSignatureRequired(PackageKit::Client::SignatureInfo info)
575 {
576     QString shortStr = tr("Repo signature required for %1")
577                        .arg(info.package->name());
578
579     QString detailedStr = tr("repoId=%1 keyUrl=%2 keyUserId=%3 keyId=%4 keyFingerprint=%5 keyTimestamp=%6")
580                           .arg(info.repoId)
581                           .arg(info.keyUrl)
582                           .arg(info.keyUserid)
583                           .arg(info.keyId)
584                           .arg(info.keyFingerprint)
585                           .arg(info.keyTimestamp);
586
587     sendUserMessage(shortStr, detailedStr);
588 }
589
590 void ApplicationManager::onRequireRestart(PackageKit::Enum::Restart type, QSharedPointer<PackageKit::Package> p)
591 {
592     QString shortStr;
593     if (p.isNull()) {
594         shortStr = tr("Restart required %1")
595                            .arg(tr(PKENUM_RESTART_STRING(type)));
596     } else {
597         shortStr = tr("Restart required %1 for package %2")
598                            .arg(tr(PKENUM_RESTART_STRING(type)))
599                            .arg(p->name());
600     }
601
602     sendUserMessage(shortStr);
603 }
604
605 void ApplicationManager::onPackageResolved(QSharedPointer<PackageKit::Package> package)
606 {
607     if (package.isNull()) {
608         qWarning() << "ApplicationManager::onPackageResolved returned invalid package";
609         dumpDaemon();
610         return;
611     }
612
613     sendProgressMessage(ActionInProgressMessage, tr("Resolved %1").arg(package->id()) );
614
615     gcsDebug() << "called for " << package->name() << package->id() << package->info();
616     dumpDaemon();
617     dumpPackage(package);
618
619     Application * application = 0;
620     GarageClientServices * gcs = GarageClientServices::instance();
621     if (gcs && gcs->catalog()) {
622         application = gcs->catalog()->findApplicationByPackageName(package->name());
623     }
624
625     if (!application) {
626         qWarning() << "Catalog::onPackageResolve not found application with package name " << package->name();
627         return;
628     }
629
630     /*
631       We might get this signal for non-resolve transactions as well
632     */
633     if (m_currentAction.actionType == ResolveAction) {
634         m_appsInProcess.removeOne(application);
635     }
636
637     // check if it is an update
638     Application::Status status = Application::toStatus(
639             package->info(),
640             application->status());
641     if (application->package() != 0 &&
642         application->package()->name() ==  package->name() &&
643         application->package()->version() != package->version() &&
644         application->status() == Application::InstalledStatus &&
645         status == Application::NotInstalledStatus ) {
646         status = Application::UpdateAvailableStatus;
647         //application->setUpdatePackage(package);
648         application->setVersionToUpdate(package->version());
649         application->setPackageToUpdate(package);
650         // TODO for version 1.1 manage both package and uninstalled package
651     } else {
652         application->setInstalledVersion(package->version());
653     }
654
655     // set package
656     application->setPackage(package);
657
658     // we will not set the status when the same package is still in the queue waiting for other ops to execute
659     // to avoid spurious changes of state
660     if (actionQueuedForApplication(application, false) == NoAction) {
661         // package resolved succesfully
662         application->setStatus(status);
663     }
664 }
665
666 void ApplicationManager::onTransactionChanged()
667 {
668     gcsDebug();
669     dumpDaemon();
670
671     QString transStatus = getTransactionStatusMessage(m_currentTransaction->status());
672     sendProgressMessage(ActionInProgressMessage, transStatus);
673
674     emit progressUpdated(QString(), m_isCurrentActionPrivate);
675 }
676
677 void ApplicationManager::onTransactionError(PackageKit::Enum::Error error, const QString& errorStr)
678 {
679     gcsDebug() << "error=" << PKENUM_ERROR_STRING(error) << errorStr;
680     dumpDaemon();
681
682     // we keep the list for the signal sent later
683     ApplicationList appsInProcess = m_appsInProcess;
684
685     /*
686       We don't get the package names of the packages which have error.
687       We assume we get them all in string (it happens at least with resolve).
688     */
689     ApplicationList appsError = findApplicationsContainedInString(m_appsInProcess, errorStr);
690     if (appsError.isEmpty()) {
691         // if there are no apps in appsError, we will assume all had error
692         appsError = m_appsInProcess;
693     }
694
695     // sent transaction error to every app with errors and remove from apps in process
696     QListIterator<Application*> i(appsError);
697     while (i.hasNext()) {
698         Application * application = i.next();
699         if (application) {
700             application->onTransactionError(m_currentAction.actionType, errorStr);
701             m_appsInProcess.removeOne(application);
702         }
703     }
704
705     sendProgressMessage(ActionErrorMessage, errorStr + "(" + tr(PKENUM_ERROR_STRING(error)) + ")");
706
707     emit applicationActionError(m_currentAction.actionType, appsInProcess, errorStr, m_isCurrentActionPrivate);
708 }
709
710 void ApplicationManager::onTransactionFinished(PackageKit::Enum::Exit code, uint time)
711 {
712     gcsDebug() << "status=" << code << PKENUM_EXIT_STRING(code) << time;
713     dumpDaemon();
714
715     bool success = (code == PackageKit::Enum::ExitSuccess);
716
717     if (success) {
718         sendProgressMessage(ActionFinishedMessage);
719     } else {
720         sendProgressMessage(ActionFailedMessage, PKENUM_EXIT_STRING(code));
721     }
722
723     // resolve does not send neither error nor success failed if not possible to resolve ...
724     // so we force transaction error if we didn't get the package and success is true
725     // also make the whole transaction not successful
726     if (success && m_currentAction.actionType == ResolveAction) {
727         QListIterator<Application*> i(m_appsInProcess);
728         while (i.hasNext()) {
729             Application * application = i.next();
730             if (application && application->package().isNull()) {
731                 application->onTransactionError(m_currentAction.actionType, tr("Transaction finished without providing packages"));
732                 m_appsInProcess.removeOne(application);
733                 success = false;
734             }
735         }
736     }
737
738     // we keep the list for the resolve issued later
739     ApplicationList appsToResolve;
740     if (!success &&
741         m_currentAction.actionType == ResolveAction &&
742         !m_appsInProcess.isEmpty()) {
743         appsToResolve = m_appsInProcess;
744     }
745
746     // if operation was not resolve and failed, we will try to resolve
747     // it might be due to inconsistent cached application status
748     if (code == PackageKit::Enum::ExitFailed &&
749         m_currentAction.actionType != ResolveAction) {
750         appsToResolve = m_currentAction.applicationList;
751     }
752
753     // emit action finished for every single application
754     QListIterator<Application*> i( m_currentAction.applicationList );
755     while(i.hasNext()) {
756         Application * app = i.next();
757         app->onTransactionFinished(m_currentAction.actionType, success);
758     }
759
760     m_currentTransaction = 0;
761     emit applicationActionCompleted(m_currentAction.actionType, m_currentAction.applicationList, success, m_isCurrentActionPrivate);
762
763     // clean the current action and continue processing
764     m_currentAction.actionType = NoAction;
765     m_currentAction.applicationList.clear();
766     m_appsInProcess.clear();
767
768     /*
769       Special case with resolving. It stops working on error.
770       So we reissue the resolve packages action for the packages that were not resolved.
771       Also resolve -> if current operation was not resolve and failed,
772     */
773     if (!appsToResolve.isEmpty()) {
774         resolve(appsToResolve);
775     }
776
777     // check if something to process in the queue
778     processQueue();
779 }
780 #endif
781
782 Application * ApplicationManager::getApplicationByName(ApplicationList applicationList, QString str) const
783 {
784     // Get all packagenames
785     ApplicationList::const_iterator i;
786     for (i = applicationList.constBegin(); i != applicationList.constEnd(); i++) {
787         Application* application = *i;
788         if (application->name() == str) {
789             return application;
790         }
791     }
792
793     // application not found
794     return 0;
795 }
796
797 Application::Status mapActionToQueuedStatus(ApplicationManager::ActionType actionType)
798 {
799     switch(actionType) {
800     case ApplicationManager::InstallAction:
801         return Application::QueuedInstallStatus;
802         break;
803     case ApplicationManager::RemoveAction:
804         return Application::QueuedRemoveStatus;
805         break;
806     case ApplicationManager::UpdateAction:
807         return Application::QueuedUpdateStatus;
808         break;
809     case ApplicationManager::ResolveAction:
810         return Application::QueuedResolveStatus;
811         break;
812     case ApplicationManager::NoAction:
813     case ApplicationManager::RefreshCacheAction:
814     case ApplicationManager::GetUpdatesAction:
815         Q_ASSERT(false);
816         break;
817     }
818
819     return Application::ErrorStatus;
820 }
821
822 Application::Status mapActionToRunningStatus(ApplicationManager::ActionType actionType)
823 {
824     switch(actionType) {
825     case ApplicationManager::InstallAction:
826         return Application::InstallingStatus;
827         break;
828     case ApplicationManager::RemoveAction:
829         return Application::RemovingStatus;
830         break;
831     case ApplicationManager::UpdateAction:
832         return Application::UpdatingStatus;
833         break;
834     case ApplicationManager::ResolveAction:
835         return Application::ResolvingStatus;
836         break;
837     case ApplicationManager::NoAction:
838     case ApplicationManager::RefreshCacheAction:
839     case ApplicationManager::GetUpdatesAction:
840         Q_ASSERT(false);
841         break;
842     }
843
844     return Application::ErrorStatus;
845 }
846
847 Application::Status mapActionToFinishedStatus(ApplicationManager::ActionType actionType)
848 {
849     switch(actionType) {
850     case ApplicationManager::InstallAction:
851     case ApplicationManager::UpdateAction:
852         return Application::InstalledStatus;
853         break;
854     case ApplicationManager::RemoveAction:
855         return Application::NotInstalledStatus;
856         break;
857     case ApplicationManager::ResolveAction:
858         // it should be obtained from the resolved package
859         Q_ASSERT(false);
860         break;
861     case ApplicationManager::NoAction:
862     case ApplicationManager::RefreshCacheAction:
863     case ApplicationManager::GetUpdatesAction:
864         Q_ASSERT(false);
865         break;
866     }
867
868     return Application::ErrorStatus;
869 }
870
871 Application *ApplicationManager::findApplicationContainedInString(
872         ApplicationList applicationList,
873         QString string) const
874 {
875     if (string.isEmpty()) {
876         return 0;
877     }
878
879     ApplicationList resultingAppList = applicationList;
880     QMutableListIterator<Application*> i(resultingAppList);
881     while (i.hasNext()) {
882         Application* application = i.next();
883         if (string == application->packageName() ||
884             string.contains(" " + application->packageName() + " ") ||
885             string.startsWith(application->packageName() + " ") ||
886             string.endsWith(" " + application->packageName())) {
887             return application;
888         }
889     }
890
891     return 0;
892 }
893
894 ApplicationList ApplicationManager::findApplicationsContainedInString(
895         ApplicationList applicationList,
896         QString string) const
897 {
898     if (string.isEmpty()) {
899         applicationList.clear();
900         return applicationList;
901     }
902
903     ApplicationList resultingAppList = applicationList;
904     QMutableListIterator<Application*> i(resultingAppList);
905     while (i.hasNext()) {
906         Application* application = i.next();
907         if (string != application->packageName() &&
908             !string.contains(" " + application->packageName() + " ") &&
909             !string.startsWith(application->packageName() + " ") &&
910             !string.endsWith(" " + application->packageName())) {
911             i.remove();
912         }
913     }
914
915     return resultingAppList;
916 }
917
918 ApplicationList ApplicationManager::filterAppsToResolve(ApplicationList applicationList)
919 {
920     ApplicationList resultingAppList = applicationList;
921     QMutableListIterator<Application*> i(resultingAppList);
922     while (i.hasNext()) {
923         Application* application = i.next();
924         if (application->status() != Application::UnknownStatus) {
925             i.remove();
926         }
927     }
928
929     return resultingAppList;
930 }
931
932 QString ApplicationManager::actionTypeAsString(ActionType actionType)
933 {
934     switch(actionType) {
935     case ResolveAction:
936         return tr("Resolving");
937         break;
938     case InstallAction:
939         return tr("Installing");
940         break;
941     case RemoveAction:
942         return tr("Removing");
943         break;
944     case UpdateAction:
945         return tr("Updating");
946         break;
947     case RefreshCacheAction:
948         return tr("Refreshing Cache");
949         break;
950     case GetUpdatesAction:
951         return tr("Get Updates Action");
952         break;
953     case NoAction:
954         Q_ASSERT(false);
955         break;
956     }
957
958     return tr("Unknown");
959 }
960
961 int ApplicationManager::numActionsQueued() const
962 {
963     int numQueue = m_actionList.count();
964     return numQueue;
965 }
966
967 int ApplicationManager::numActionsTotal() const
968 {
969     //gcsDebug() << "total=" << m_numActionsTotal;
970
971     return m_numActionsTotal;
972 }
973
974 int ApplicationManager::numActionsDone() const
975 {
976     int numQueue = m_actionList.count();
977
978     if (m_currentTransaction) {
979         numQueue++;
980     }
981
982     int result = numActionsTotal() - numQueue;
983
984     //gcsDebug() << "done=" << result << "queue=" << numQueue << " m_currentTransaction" << m_currentTransaction;
985
986     return result;
987 }
988
989 bool ApplicationManager::isActionQueueEmpty() const
990 {
991     if (m_currentTransaction) {
992         return false;
993     }
994     return (m_actionList.count() + m_privateActionList.count()) <= 0;
995 }
996
997 #ifndef HAVE_NO_PACKAGEKIT
998 void ApplicationManager::onMessage(PackageKit::Enum::Message type, QString str)
999 {
1000     gcsDebug() << type << PKENUM_MESSAGE_STRING(type) << str;
1001
1002     emit progressUpdated(str, m_isCurrentActionPrivate);
1003 }
1004 #endif
1005
1006 void ApplicationManager::saveStatus()
1007 {
1008     gcsDebug();
1009
1010     QString dirStr = GarageSettings::configPath();
1011     QDir configDir(dirStr);
1012     configDir.mkpath(dirStr);
1013     QFile file(dirStr + "/appstatus.xml");
1014     file.open(QIODevice::ReadWrite | QIODevice::Truncate);  
1015     m_statusStorage->write(&file);
1016     file.close();
1017 }
1018
1019 void ApplicationManager::loadStatus()
1020 {
1021     gcsDebug();
1022     
1023     QString dirStr = GarageSettings::configPath();
1024     QDir configDir(dirStr);
1025     configDir.mkpath(dirStr);
1026     QFile file(dirStr + "/appstatus.xml");
1027     file.open(QIODevice::ReadOnly);
1028     m_statusStorage->read(&file);
1029     file.close();
1030 }
1031
1032 void ApplicationManager::registerApplications(ApplicationList appList)
1033 {
1034     gcsDebug();
1035
1036     m_statusStorage->registerApplications(appList);
1037 }
1038
1039 void ApplicationManager::resolveOldOrUnknownApps()
1040 {
1041     gcsDebug();
1042
1043     ApplicationList oldOrUnknownApps = m_statusStorage->oldOrUnknownApps();
1044     resolve(oldOrUnknownApps);
1045 }
1046
1047 void ApplicationManager::dumpDaemon()
1048 {
1049 #ifndef HAVE_NO_PACKAGEKIT
1050     PackageKit::Client * client = PackageKit::Client::instance();
1051     qDebug() << "=== Begin dump daemon " <<
1052             "backendName=" << client->backendName() <<
1053             "distro=" << client->distroId() <<
1054             "version=" << client->versionMajor() <<
1055             "." << client->versionMinor() <<
1056             "." << client->versionMicro();
1057     qDebug() << "\tnetworkState=" <<  PKENUM_NETWORK_STRING(client->networkState()) <<
1058             "isOnline=" << GarageClientServices::instance()->isOnline() <<
1059             "locked=" <<  client->locked();
1060     if (client->getLastError() != PackageKit::Client::NoError) {
1061         qDebug() << "\tgetLastError=" <<  PKENUM_DAEMONERROR_STRING(client->getLastError());
1062     }
1063
1064     QList<PackageKit::Transaction*> transactions = PackageKit::Client::instance()->getTransactions();
1065     QListIterator<PackageKit::Transaction*> i(transactions);
1066     int cnt = 0;
1067     while(i.hasNext()) {
1068         PackageKit::Transaction * transaction = i.next();
1069         if (transaction) {
1070             qDebug() << "\tTransaction " << cnt << " valid: " <<
1071                     "tid=" << transaction->tid() <<
1072                     "role=" << PKENUM_ROLE_STRING(transaction->role()) <<
1073                     "package=" << ((!transaction->lastPackage().isNull()) ? transaction->lastPackage()->id() : "None");
1074             //dumpTransaction(transaction);
1075         } else {
1076             qDebug() << "\tTransaction " << cnt << "invalid";
1077         }
1078         cnt++;
1079     }
1080
1081     qDebug() << "=== Queue private count=" << m_privateActionList.count();
1082     QListIterator<Action> j(m_privateActionList);
1083     while (j.hasNext()) {
1084         Action action = j.next();
1085         qDebug() << "Action " << actionTypeAsString(action.actionType) <<
1086                 Utils::applicationListAsString(action.applicationList);
1087     }
1088
1089     qDebug() << "=== Queue non-private count=" << m_actionList.count();
1090     j = m_actionList;
1091     while (j.hasNext()) {
1092         Action action = j.next();
1093         qDebug() << "Action " << actionTypeAsString(action.actionType) <<
1094                 Utils::applicationListAsString(action.applicationList);
1095     }
1096 #endif
1097 }
1098
1099 #ifndef HAVE_NO_PACKAGEKIT
1100 void ApplicationManager::dumpTransaction(PackageKit::Transaction * transaction)
1101 {
1102     QSharedPointer<PackageKit::Package> package = transaction->lastPackage();
1103     qDebug() << "=== Dump transaction " <<
1104             "tid=" << transaction->tid() <<
1105             "role=" << PKENUM_ROLE_STRING(transaction->role()) <<
1106             "package=" << ((!package.isNull()) ? package->id() : "None") <<
1107             "status=" << PKENUM_STATUS_STRING(transaction->status());
1108     if (transaction->error() != PackageKit::Client::NoError) {
1109         qDebug() << "\terror=" << PKENUM_DAEMONERROR_STRING(transaction->error());
1110     }
1111     qDebug() << "\tsucceeded=" << transaction->succeeded() <<
1112             "percentage=" << transaction->percentage() <<
1113             "allowCancel=" << transaction->allowCancel() <<
1114             "callerActive=" << transaction->callerActive();
1115     qDebug() << "=== End dump transaction ";
1116 }
1117
1118 void ApplicationManager::dumpPackage(QSharedPointer<PackageKit::Package> package)
1119 {
1120     qDebug() << "=== Dump package id=" << package->id() << "info=" << PKENUM_INFO_STRING( package->info() );
1121     qDebug() << "\tname=" << package->name() << "version=" << package->version() <<
1122             "arch=" << package->arch() << "data=" << package->data();
1123     if (!package->summary().isEmpty()) {
1124         qDebug() << "\tsummary=" << package->summary();
1125     }
1126     if (!package->iconPath().isEmpty()) {
1127         qDebug() << "\ticonPath=" << package->iconPath();
1128     }
1129     if (package->hasDetails()) {
1130         PackageKit::Package::Details * details;
1131         details = package->details();
1132         if (!details->license().isEmpty()) {
1133             qDebug() << "\tlicense=" << details->license();
1134         }
1135         qDebug() << "\tgroup=" << details->group();
1136         if (!details->description().isEmpty()) {
1137             qDebug() << "\tdescription=" << details->description();
1138         }
1139         if (!details->url().isEmpty()) {
1140             qDebug() << "\turl=" << details->url();
1141         }
1142         qDebug() << "\tsize" << details->size();
1143     }
1144 }
1145 #endif
1146
1147 void ApplicationManager::refreshCache()
1148 {
1149     queueAction(RefreshCacheAction);
1150 }
1151
1152 void ApplicationManager::getUpdates()
1153 {
1154     queueAction(GetUpdatesAction);
1155 }
1156
1157 void ApplicationManager::sendProgressMessage(MessageType messageType, QString detailedStr)
1158 {
1159     ApplicationManager::ActionType actionType = m_currentAction.actionType;
1160     ApplicationList apps = m_currentAction.applicationList;
1161     bool isActionPrivate = m_isCurrentActionPrivate;
1162
1163     QString appName;
1164     //QString appListNames;
1165     if (apps.size() > 0) {
1166         appName = apps.at(0)->name();
1167         //appListNames = Catalog::applicationListAsString(apps);
1168     }
1169
1170     QString actionStr = getActionMessage(messageType, actionType, appName);
1171
1172     /// send null string instead of repeated one
1173     if (m_lastDetailedStr == detailedStr) {
1174         detailedStr = "";
1175     } else {
1176         m_lastDetailedStr = detailedStr;
1177     }
1178
1179     /// send null string instead of repeated one
1180     if (m_lastActionStr == actionStr) {
1181         actionStr =  "";
1182     } else {
1183         m_lastActionStr = actionStr;
1184     }
1185
1186     emit progressMessage(messageType, actionType, apps, isActionPrivate, actionStr, detailedStr,
1187                          percentage());
1188 }
1189
1190 void ApplicationManager::sendUserMessage(QString shortStr, QString detailedStr)
1191 {
1192     emit progressMessage(UserMessage, NoAction, ApplicationList(), false, shortStr, detailedStr, -1);
1193 }
1194
1195 QString ApplicationManager::getActionMessage(
1196         ApplicationManager::MessageType messageType,
1197         ApplicationManager::ActionType actionType,
1198         QString appName)
1199 {
1200     QString msg;
1201
1202     switch(messageType) {
1203     case ActionStartedMessage:
1204         switch(actionType) {
1205         case ApplicationManager::InstallAction:
1206             msg = tr("Started %1 installation");
1207             break;
1208         case ApplicationManager::RemoveAction:
1209             msg = tr("Started %1 removal");
1210             break;
1211         case ApplicationManager::UpdateAction:
1212             msg = tr("Started %1 update");
1213             break;
1214         case ApplicationManager::ResolveAction:
1215             msg = tr("Started %1 resolve");
1216             break;
1217         case ApplicationManager::RefreshCacheAction:
1218             msg = tr("Started cache refresh");
1219             break;
1220         case ApplicationManager::GetUpdatesAction:
1221             msg = tr("Started getting updates");
1222             break;
1223         case ApplicationManager::NoAction:
1224             Q_ASSERT(false);
1225         }
1226         break;
1227     case ActionInProgressMessage:
1228         switch(actionType) {
1229         case ApplicationManager::InstallAction:
1230             msg = tr("Installing %1");
1231             break;
1232         case ApplicationManager::RemoveAction:
1233             msg = tr("Removing %1");
1234             break;
1235         case ApplicationManager::UpdateAction:
1236             msg = tr("Updating %1");
1237             break;
1238         case ApplicationManager::ResolveAction:
1239             msg = tr("Resolving %1");
1240             break;
1241         case ApplicationManager::RefreshCacheAction:
1242             msg = tr("Refreshing cache");
1243             break;
1244         case ApplicationManager::GetUpdatesAction:
1245             msg = tr("Getting updates");
1246             break;
1247         case ApplicationManager::NoAction:
1248             Q_ASSERT(false);
1249         }
1250         break;
1251     case ActionErrorMessage:
1252         switch(actionType) {
1253         case ApplicationManager::InstallAction:
1254             msg = tr("Error while installing %1");
1255             break;
1256         case ApplicationManager::RemoveAction:
1257             msg = tr("Error while removing %1");
1258             break;
1259         case ApplicationManager::UpdateAction:
1260             msg = tr("Error while updating %1");
1261             break;
1262         case ApplicationManager::ResolveAction:
1263             msg = tr("Error while resolving %1");
1264             break;
1265         case ApplicationManager::RefreshCacheAction:
1266             msg = tr("Error while refreshing cache");
1267             break;
1268         case ApplicationManager::GetUpdatesAction:
1269             msg = tr("Error while getting updates");
1270             break;
1271         case ApplicationManager::NoAction:
1272             Q_ASSERT(false);
1273             break;
1274         }
1275         break;
1276     case ActionFinishedMessage:
1277         switch(actionType) {
1278         case ApplicationManager::InstallAction:
1279             msg = tr("%1 installed successfully");
1280             break;
1281         case ApplicationManager::RemoveAction:
1282             msg = tr("%1 removed successfully");
1283             break;
1284         case ApplicationManager::UpdateAction:
1285             msg = tr("%1 updated successfully");
1286             break;
1287         case ApplicationManager::ResolveAction:
1288             msg = tr("%1 resolved successfully");
1289             break;
1290         case ApplicationManager::RefreshCacheAction:
1291             msg = tr("Refresh cache successful");
1292             break;
1293         case ApplicationManager::GetUpdatesAction:
1294             msg = tr("Get updates successful");
1295             break;
1296         case ApplicationManager::NoAction:
1297             Q_ASSERT(false);
1298             break;
1299         }
1300         break;
1301     case ActionFailedMessage:
1302         switch(actionType) {
1303         case ApplicationManager::InstallAction:
1304             msg = tr("%1 install failed");
1305             break;
1306         case ApplicationManager::RemoveAction:
1307             msg = tr("%1 remove failed");
1308             break;
1309         case ApplicationManager::UpdateAction:
1310             msg = tr("%1 update failed");
1311             break;
1312         case ApplicationManager::ResolveAction:
1313             msg = tr("%1 resolve failed");
1314             break;
1315         case ApplicationManager::RefreshCacheAction:
1316             msg = tr("Refresh cache failed");
1317             break;
1318         case ApplicationManager::GetUpdatesAction:
1319             msg = tr("Getting updates failed");
1320             break;
1321         case ApplicationManager::NoAction:
1322             Q_ASSERT(false);
1323             break;
1324         }
1325         break;
1326     case UserMessage:
1327         Q_ASSERT(false);
1328         break;
1329     }
1330
1331     if (msg.contains("%1")) {
1332         return msg.arg(appName);
1333     } else {
1334         return msg;
1335     }
1336 }
1337
1338 #ifndef HAVE_NO_PACKAGEKIT
1339 QString ApplicationManager::getTransactionStatusMessage(PackageKit::Enum::Status status)
1340 {
1341     QString statusStr;
1342
1343     switch(status) {
1344     case PackageKit::Enum::UnknownStatus:
1345         statusStr = tr("Unknown Status");
1346         break;
1347     case PackageKit::Enum::StatusWait:
1348         statusStr = tr("Waiting for other transaction(s)");
1349         break;
1350     case PackageKit::Enum::StatusSetup:
1351         statusStr = tr("Setting up transaction");
1352         break;
1353     case PackageKit::Enum::StatusRunning:
1354         statusStr = tr("Starting transaction");
1355         break;
1356     case PackageKit::Enum::StatusQuery:
1357         statusStr = tr("Querying backend");
1358         break;
1359     case PackageKit::Enum::StatusInfo:
1360         statusStr = tr("Getting info from server");
1361         break;
1362     case PackageKit::Enum::StatusRemove:
1363         statusStr = tr("Removing package(s)");
1364         break;
1365     case PackageKit::Enum::StatusRefreshCache:
1366         statusStr = tr("Refreshing internal cache");
1367         break;
1368     case PackageKit::Enum::StatusDownload:
1369         statusStr = tr("Downloading package(s)");
1370         break;
1371     case PackageKit::Enum::StatusInstall:
1372         statusStr = tr("Installing package(s)");
1373         break;
1374     case PackageKit::Enum::StatusUpdate:
1375         statusStr = tr("Updating package(s)");
1376         break;
1377     case PackageKit::Enum::StatusCleanup:
1378         statusStr = tr("Cleaning up old package(s) and config files");
1379         break;
1380     case PackageKit::Enum::StatusObsolete:
1381         statusStr = tr("Obsoleting old package(s)");
1382         break;
1383     case PackageKit::Enum::StatusDepResolve:
1384         statusStr = tr("Resolving package(s) dependencies");
1385         break;
1386     case PackageKit::Enum::StatusSigCheck:
1387         statusStr = tr("Checking signatures");
1388         break;
1389     case PackageKit::Enum::StatusRollback:
1390         statusStr = tr("Rolling back to previous state");
1391         break;
1392     case PackageKit::Enum::StatusTestCommit:
1393         statusStr = tr("Testing commit to database");
1394         break;
1395     case PackageKit::Enum::StatusCommit:
1396         statusStr = tr("Committing changes to databse");
1397         break;
1398     case PackageKit::Enum::StatusRequest:
1399         statusStr = tr("Requesting data from server");
1400         break;
1401     case PackageKit::Enum::StatusFinished:
1402         statusStr = tr("Transaction finished");
1403         break;
1404     case PackageKit::Enum::StatusCancel:
1405         statusStr = tr("Cancelling transaction");
1406         break;
1407     case PackageKit::Enum::StatusDownloadRepository:
1408         statusStr = tr("Downloading repository information");
1409         break;
1410     case PackageKit::Enum::StatusDownloadPackagelist:
1411         statusStr = tr("Downloading list of packages");
1412         break;
1413     case PackageKit::Enum::StatusDownloadFilelist:
1414         statusStr = tr("Downloading list of files");
1415         break;
1416     case PackageKit::Enum::StatusDownloadChangelog:
1417         statusStr = tr("Downloading list of changes");
1418         break;
1419     case PackageKit::Enum::StatusDownloadGroup:
1420         statusStr = tr("Downloading groups");
1421         break;
1422     case PackageKit::Enum::StatusDownloadUpdateinfo:
1423         statusStr = tr("Downloading update information");
1424         break;
1425     case PackageKit::Enum::StatusRepackaging:
1426         statusStr = tr("Repackaging files");
1427         break;
1428     case PackageKit::Enum::StatusLoadingCache:
1429         statusStr = tr("Loading cache");
1430         break;
1431     case PackageKit::Enum::StatusScanApplications:
1432         statusStr = tr("Scanning installed applications");
1433         break;
1434     case PackageKit::Enum::StatusGeneratePackageList:
1435         statusStr = tr("Generating list of installed packages");
1436         break;
1437     case PackageKit::Enum::StatusWaitingForLock:
1438         statusStr = tr("Waiting for the native installer to finish");
1439         break;
1440     case PackageKit::Enum::StatusWaitingForAuth:
1441         statusStr = tr("Waiting for the user to type the password");
1442         break;
1443     case PackageKit::Enum::StatusScanProcessList:
1444         statusStr = tr("Checking running applications");
1445         break;
1446     case PackageKit::Enum::StatusCheckExecutableFiles:
1447         statusStr = tr("Checkking executable files currently in use");
1448         break;
1449     case PackageKit::Enum::StatusCheckLibraries:
1450         statusStr = tr("Checking libraries currently in use");
1451         break;
1452     case PackageKit::Enum::StatusCopyFiles:
1453         statusStr = tr("Copying files");
1454         break;
1455     case PackageKit::Enum::LastStatus:
1456         Q_ASSERT(false);
1457     }
1458
1459     return statusStr;
1460 }
1461
1462 void ApplicationManager::onError(PackageKit::Client::DaemonError error)
1463 {
1464     sendProgressMessage(UserMessage,
1465                         tr("Packagekit daemon error %1").arg(tr(PKENUM_DAEMONERROR_STRING(error))));
1466 }
1467 #endif
1468
1469 void ApplicationManager::onOnlineStateChanged(bool isOnline)
1470 {
1471     gcsDebug() << "isOnline=" << isOnline;
1472     if (isOnline) {
1473 #ifndef HAVE_NO_PACKAGEKIT
1474         processQueue();
1475 #endif
1476     }
1477 }
1478