summaryrefslogtreecommitdiffstats
path: root/src/libs/installer/packagemanagercore.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/installer/packagemanagercore.cpp')
-rw-r--r--src/libs/installer/packagemanagercore.cpp944
1 files changed, 688 insertions, 256 deletions
diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp
index cb957f9aa..fc1ecff02 100644
--- a/src/libs/installer/packagemanagercore.cpp
+++ b/src/libs/installer/packagemanagercore.cpp
@@ -39,6 +39,7 @@
**
**************************************************************************/
#include "packagemanagercore.h"
+#include "packagemanagercore_p.h"
#include "adminauthorization.h"
#include "binaryformat.h"
@@ -47,12 +48,11 @@
#include "downloadarchivesjob.h"
#include "errors.h"
#include "fsengineclient.h"
+#include "globals.h"
#include "getrepositoriesmetainfojob.h"
#include "messageboxhandler.h"
-#include "packagemanagercore_p.h"
#include "packagemanagerproxyfactory.h"
#include "progresscoordinator.h"
-#include "qinstallerglobal.h"
#include "qprocesswrapper.h"
#include "qsettingswrapper.h"
#include "settings.h"
@@ -71,9 +71,6 @@
#include <QDesktopServices>
#include <QFileDialog>
-#include <QtScript/QScriptEngine>
-#include <QtScript/QScriptContext>
-
#include "kdsysinfo.h"
#include "kdupdaterupdateoperationfactory.h"
@@ -85,30 +82,267 @@
# include <QStandardPaths>
#endif
+/*!
+ \qmltype QInstaller
+ \inqmlmodule scripting
+
+ \brief Provides access to the installer from Qt Script.
+
+ Use the \c installer object in the global namespace to access functionality of the installer.
+
+ \section2 Wizard Pages
+
+ The installer has various pre-defined pages that can be used to for example insert pages
+ in a certain place:
+ \list
+ \li QInstaller.Introduction
+ \li QInstaller.TargetDirectory
+ \li QInstaller.ComponentSelection
+ \li QInstaller.LicenseCheck
+ \li QInstaller.StartMenuSelection
+ \li QInstaller.ReadyForInstallation
+ \li QInstaller.PerformInstallation
+ \li QInstaller.InstallationFinished
+ \li QInstaller.End
+ \endlist
+*/
+
+
+/*!
+ \qmlproperty enumeration QInstaller::status
+
+ Status of the installer.
+
+ Possible values are:
+ \list
+ \li QInstaller.Success (deprecated: QInstaller.InstallerSucceeded)
+ \li QInstaller.Failure (deprecated: QInstaller.InstallerFailed)
+ \li QInstaller.Running (deprecated: QInstaller.InstallerFailed)
+ \li QInstaller.Canceled (deprecated: QInstaller.CanceledByUser)
+ \li deprecated: QInstaller.InstallerUnfinished
+ \endlist
+*/
+
+/*!
+ \qmlsignal QInstaller::aboutCalculateComponentsToInstall()
+
+ Emitted before the ordered list of components to install is calculated.
+*/
+
+/*!
+ \qmlsignal QInstaller::componentAdded(Component component)
+
+ Emitted when a new root component has been added.
+
+ \sa rootComponentsAdded, updaterComponentsAdded
+*/
+
+/*!
+ \qmlsignal QInstaller::rootComponentsAdded(list<Component> components)
+
+ Emitted when a new list of root components has been added.
+
+ \sa componentAdded, updaterComponentsAdded
+*/
+
+/*!
+ \qmlsignal QInstaller::updaterComponentsAdded(list<Component> components)
+
+ Emitted when a new list of updater components has been added.
+ \sa componentAdded, rootComponentsAdded
+*/
+
+/*!
+ \qmlsignal QInstaller::componentsAboutToBeCleared()
+
+ Deprecated, and not emitted any more.
+*/
+
+/*!
+ \qmlsignal QInstaller::valueChanged(string key, string value)
+
+ Emitted whenever a value changes.
+
+ \sa setValue
+*/
+
+/*!
+ \qmlsignal QInstaller::statusChanged(Status status)
+
+ Emitted whenever the installer status changes.
+*/
+
+/*!
+ \qmlsignal QInstaller::currentPageChanged(int page)
+
+ Emitted whenever the current page changes.
+*/
+
+/*!
+ \qmlsignal QInstaller::finishButtonClicked()
+
+ Emitted when the user clicks the \uicontrol Finish button of the installer.
+*/
+
+/*!
+ \qmlsignal QInstaller::metaJobInfoMessage(string message)
+
+ Triggered with informative updates of the communication with a remote repository.
+ This is only useful for debugging purposes.
+*/
+
+/*!
+ \qmlsignal QInstaller::startAllComponentsReset()
+
+ Triggered when the list of components starts to get updated.
+
+ \sa finishAllComponentsReset
+*/
+
+/*!
+ \qmlsignal QInstaller::finishAllComponentsReset(list<Component> rootComponents)
+
+ Triggered when the list of new root components has been updated.
+
+ \sa startAllComponentsReset
+*/
+
+/*!
+ \qmlsignal QInstaller::startUpdaterComponentsReset()
+
+ Triggered when components start to get updated during a remote update.
+*/
+
+/*!
+ \qmlsignal QInstaller::finishUpdaterComponentsReset(list<Component> componentsWithUpdates)
+
+ Triggered when the list of available remote updates has been updated.
+*/
+
+/*!
+ \qmlsignal QInstaller::installationStarted()
+
+ Triggered when installation has started.
+
+ \sa installationFinished installationInterrupted
+*/
+
+/*!
+ \qmlsignal QInstaller::installationInterrupted()
+
+ Triggered when installation has been interrupted (cancelled).
+
+ \sa interrupt installationStarted installationFinished
+*/
+
+/*!
+ \qmlsignal QInstaller::installationFinished()
+
+ Triggered when installation has been finished.
+
+ \sa installationStarted installationInterrupted
+*/
+
+/*!
+ \qmlsignal QInstaller::updateFinished()
+
+ Triggered when an update has been finished.
+*/
+
+/*!
+ \qmlsignal QInstaller::uninstallationStarted()
+
+ Triggered when uninstallation has started.
+
+ \sa uninstallationFinished
+*/
+
+/*!
+ \qmlsignal QInstaller::uninstallationFinished()
+
+ Triggered when uninstallation has been finished.
+
+ \sa uninstallationStarted
+*/
+
+/*!
+ \qmlsignal QInstaller::titleMessageChanged(string title)
+
+ Emitted when the text of the installer status (on the PerformInstallation page) changes to
+ \a title.
+*/
+
+/*!
+ \qmlsignal QInstaller::wizardPageInsertionRequested(Widget widget, WizardPage page)
+
+ Emitted when a custom \a widget is about to be inserted into \a page by addWizardPage.
+*/
+
+/*!
+ \qmlsignal QInstaller::wizardPageRemovalRequested(Widget widget)
+
+ Emitted when a \a widget is removed by removeWizardPage.
+*/
+
+/*!
+ \qmlsignal QInstaller::wizardWidgetInsertionRequested(Widget widget, WizardPage page)
+
+ Emitted when a \a widget is inserted into \a page by addWizardPageItem.
+*/
+
+/*!
+ \qmlsignal QInstaller::wizardWidgetRemovalRequested(Widget widget)
+
+ Emitted when a \a widget is removed by removeWizardPageItem.
+*/
+
+/*!
+ \qmlsignal QInstaller::wizardPageVisibilityChangeRequested(bool visible, int page)
+
+ Emitted when the visibility of the page with id \a page changes to \a visible.
+
+ \sa setDefaultPageVisible
+*/
+
+/*!
+ \qmlsignal QInstaller::setValidatorForCustomPageRequested(Componentcomponent, string name,
+ string callbackName)
+
+ Triggered when setValidatorForCustomPage is called.
+*/
+
+/*!
+ \qmlsignal QInstaller::setAutomatedPageSwitchEnabled(bool request)
+
+ Triggered when the automatic switching from PerformInstallation to InstallationFinished page
+ is enabled (\a request = \c true) or disabled (\a request = \c false).
+
+ The automatic switching is disabled automatically when for example the user expands or unexpands
+ the \gui Details section of the PerformInstallation page.
+*/
+
+/*!
+ \qmlsignal QInstaller::coreNetworkSettingsChanged()
+
+ Emitted when the network settings are changed.
+*/
+
+/*!
+ \qmlmethod list<Component> QInstaller::components()
+
+ Returns the list of all components.
+*/
+
using namespace QInstaller;
-static QMutex sModelMutex;
+Q_GLOBAL_STATIC(QMutex, globalModelMutex);
static QFont *sVirtualComponentsFont = 0;
-static QMutex sVirtualComponentsFontMutex;
+Q_GLOBAL_STATIC(QMutex, globalVirtualComponentsFontMutex);
static bool sNoForceInstallation = false;
static bool sVirtualComponentsVisible = false;
static bool sCreateLocalRepositoryFromBinary = false;
-static QScriptValue checkArguments(QScriptContext *context, int amin, int amax)
-{
- if (context->argumentCount() < amin || context->argumentCount() > amax) {
- if (amin != amax) {
- return context->throwError(QObject::tr("Invalid arguments: %1 arguments given, %2 to "
- "%3 expected.").arg(QString::number(context->argumentCount()),
- QString::number(amin), QString::number(amax)));
- }
- return context->throwError(QObject::tr("Invalid arguments: %1 arguments given, %2 expected.")
- .arg(QString::number(context->argumentCount()), QString::number(amin)));
- }
- return QScriptValue();
-}
-
static bool componentMatches(const Component *component, const QString &name,
const QString &version = QString())
{
@@ -131,12 +365,12 @@ Component *PackageManagerCore::subComponentByName(const QInstaller::PackageManag
if (check != 0 && componentMatches(check, name, version))
return check;
- if (installer->runMode() == AllMode) {
+ if (!installer->isUpdater()) {
QList<Component*> rootComponents;
if (check == 0)
rootComponents = installer->rootComponents();
else
- rootComponents = check->childComponents(false, AllMode);
+ rootComponents = check->childComponents(Component::DirectChildrenOnly);
foreach (QInstaller::Component *component, rootComponents) {
Component *const result = subComponentByName(installer, name, version, component);
@@ -154,146 +388,6 @@ Component *PackageManagerCore::subComponentByName(const QInstaller::PackageManag
return 0;
}
-/*!
- Scriptable version of PackageManagerCore::componentByName(QString).
- \sa PackageManagerCore::componentByName
- */
-QScriptValue QInstaller::qInstallerComponentByName(QScriptContext *context, QScriptEngine *engine)
-{
- const QScriptValue check = checkArguments(context, 1, 1);
- if (check.isError())
- return check;
-
- // well... this is our "this" pointer
- PackageManagerCore *const core = dynamic_cast<PackageManagerCore*>(engine->globalObject()
- .property(QLatin1String("installer")).toQObject());
-
- const QString name = context->argument(0).toString();
- return engine->newQObject(core->componentByName(name));
-}
-
-QScriptValue QInstaller::qDesktopServicesOpenUrl(QScriptContext *context, QScriptEngine *engine)
-{
- Q_UNUSED(engine);
- const QScriptValue check = checkArguments(context, 1, 1);
- if (check.isError())
- return check;
- QString url = context->argument(0).toString();
- url.replace(QLatin1String("\\\\"), QLatin1String("/"));
- url.replace(QLatin1String("\\"), QLatin1String("/"));
- return QDesktopServices::openUrl(QUrl::fromUserInput(url));
-}
-
-QScriptValue QInstaller::qDesktopServicesDisplayName(QScriptContext *context, QScriptEngine *engine)
-{
- Q_UNUSED(engine);
- const QScriptValue check = checkArguments(context, 1, 1);
- if (check.isError())
- return check;
-
-#if QT_VERSION < 0x050000
- const QDesktopServices::StandardLocation location =
- static_cast< QDesktopServices::StandardLocation >(context->argument(0).toInt32());
- return QDesktopServices::displayName(location);
-#else
- const QStandardPaths::StandardLocation location =
- static_cast< QStandardPaths::StandardLocation >(context->argument(0).toInt32());
- return QStandardPaths::displayName(location);
-#endif
-}
-
-QScriptValue QInstaller::qDesktopServicesStorageLocation(QScriptContext *context, QScriptEngine *engine)
-{
- Q_UNUSED(engine);
- const QScriptValue check = checkArguments(context, 1, 1);
- if (check.isError())
- return check;
-
-#if QT_VERSION < 0x050000
- const QDesktopServices::StandardLocation location =
- static_cast< QDesktopServices::StandardLocation >(context->argument(0).toInt32());
- return QDesktopServices::storageLocation(location);
-#else
- const QStandardPaths::StandardLocation location =
- static_cast< QStandardPaths::StandardLocation >(context->argument(0).toInt32());
- return QStandardPaths::writableLocation(location);
-#endif
-}
-
-QScriptValue QInstaller::qFileDialogGetExistingDirectory( QScriptContext *context, QScriptEngine *engine )
-{
- Q_UNUSED(engine);
- const QScriptValue check = checkArguments(context, 0, 2);
- if (check.isError())
- return check;
- QString caption;
- QString dir;
- if (context->argumentCount() > 0)
- caption = context->argument(0).toString();
- if (context->argumentCount() > 1)
- dir = context->argument(1).toString();
- return QFileDialog::getExistingDirectory(0, caption, dir);
-}
-
-QString QInstaller::uncaughtExceptionString(QScriptEngine *scriptEngine, const QString &context)
-{
- QString error(QLatin1String("\n\n%1\n\nBacktrace:\n\t%2"));
- if (!context.isEmpty())
- error.prepend(context);
-
- return error.arg(scriptEngine->uncaughtException().toString(), scriptEngine->uncaughtExceptionBacktrace()
- .join(QLatin1String("\n\t")));
-}
-
-
-/*!
- \class QInstaller::PackageManagerCore
- PackageManagerCore forms the core of the installation, update, maintenance and un-installation system.
- */
-
-/*!
- \enum QInstaller::PackageManagerCore::WizardPage
- WizardPage is used to number the different pages known to the Installer GUI.
- */
-
-/*!
- \var QInstaller::PackageManagerCore::Introduction
- I ntroduction page.
- */
-
-/*!
- \var QInstaller::PackageManagerCore::LicenseCheck
- License check page
- */
-/*!
- \var QInstaller::PackageManagerCore::TargetDirectory
- Target directory selection page
- */
-/*!
- \var QInstaller::PackageManagerCore::ComponentSelection
- %Component selection page
- */
-/*!
- \var QInstaller::PackageManagerCore::StartMenuSelection
- Start menu directory selection page - Microsoft Windows only
- */
-/*!
- \var QInstaller::PackageManagerCore::ReadyForInstallation
- "Ready for Installation" page
- */
-/*!
- \var QInstaller::PackageManagerCore::PerformInstallation
- Page shown while performing the installation
- */
-/*!
- \var QInstaller::PackageManagerCore::InstallationFinished
- Page shown when the installation was finished
- */
-/*!
- \var QInstaller::PackageManagerCore::End
- Non-existing page - this value has to be used if you want to insert a page after \a InstallationFinished
- */
-
void PackageManagerCore::writeUninstaller()
{
if (d->m_needToWriteUninstaller) {
@@ -319,17 +413,37 @@ void PackageManagerCore::writeUninstaller()
}
}
+void PackageManagerCore::writeMaintenanceConfigFiles()
+{
+ d->writeMaintenanceConfigFiles();
+}
+
void PackageManagerCore::reset(const QHash<QString, QString> &params)
{
d->m_completeUninstall = false;
- d->m_forceRestart = false;
+ d->m_needsHardRestart = false;
d->m_status = PackageManagerCore::Unfinished;
d->m_installerBaseBinaryUnreplaced.clear();
d->initialize(params);
}
+void PackageManagerCore::setGuiObject(QObject *gui)
+{
+ if (gui == d->m_guiObject)
+ return;
+ d->m_guiObject = gui;
+ emit guiObjectChanged(gui);
+}
+
+QObject *PackageManagerCore::guiObject() const
+{
+ return d->m_guiObject;
+}
+
/*!
+ \qmlmethod void QInstaller::setCompleteUninstallation(bool complete)
+
Sets the uninstallation to be \a complete. If \a complete is false, only components deselected
by the user will be uninstalled. This option applies only on uninstallation.
*/
@@ -338,27 +452,60 @@ void PackageManagerCore::setCompleteUninstallation(bool complete)
d->m_completeUninstall = complete;
}
+/*!
+ \qmlmethod void QInstaller::cancelMetaInfoJob()
+
+ Cancels the retrieval of meta information from a remote repository.
+ */
void PackageManagerCore::cancelMetaInfoJob()
{
if (d->m_repoMetaInfoJob)
d->m_repoMetaInfoJob->cancel();
}
+/*!
+ \qmlmethod void QInstaller::componentsToInstallNeedsRecalculation()
+
+ Ensures that component dependencies are re-calculated.
+ */
void PackageManagerCore::componentsToInstallNeedsRecalculation()
{
d->m_componentsToInstallCalculated = false;
}
+/*!
+ \qmlmethod void QInstaller::autoAcceptMessageBoxes()
+
+ Automatically accept all user message boxes.
+
+ \sa autoRejectMessageBoxes, setMessageBoxAutomaticAnswer
+ */
void PackageManagerCore::autoAcceptMessageBoxes()
{
MessageBoxHandler::instance()->setDefaultAction(MessageBoxHandler::Accept);
}
+/*!
+ \qmlmethod void QInstaller::autoRejectMessageBoxes()
+
+ Automatically reject all user message boxes.
+
+ \sa autoAcceptMessageBoxes, setMessageBoxAutomaticAnswer
+ */
void PackageManagerCore::autoRejectMessageBoxes()
{
MessageBoxHandler::instance()->setDefaultAction(MessageBoxHandler::Reject);
}
+/*!
+ \qmlmethod void QInstaller::setMessageBoxAutomaticAnswer(string identifier, int button)
+
+ Automatically close the message box with ID \a identifier as if the user had pressed \a button.
+
+ This can be used for unattended (automatic) installations.
+
+ \sa QMessageBox, autoAcceptMessageBoxes, autoRejectMessageBoxes
+ */
void PackageManagerCore::setMessageBoxAutomaticAnswer(const QString &identifier, int button)
{
MessageBoxHandler::instance()->setAutomaticAnswer(identifier,
@@ -372,6 +519,13 @@ quint64 size(QInstaller::Component *component, const QString &value)
return component->value(value).toLongLong();
}
+/*!
+ \qmlmethod float QInstaller::requiredDiskSpace()
+
+ Returns the estimated amount of disk space in bytes required after installation.
+
+ \sa requiredTemporaryDiskSpace
+ */
quint64 PackageManagerCore::requiredDiskSpace() const
{
quint64 result = 0;
@@ -382,6 +536,13 @@ quint64 PackageManagerCore::requiredDiskSpace() const
return result;
}
+/*!
+ \qmlmethod float QInstaller::requiredTemporaryDiskSpace()
+
+ Returns the estimated required disk space during installation in bytes.
+
+ \sa requiredDiskSpace
+ */
quint64 PackageManagerCore::requiredTemporaryDiskSpace() const
{
quint64 result = 0;
@@ -448,11 +609,17 @@ int PackageManagerCore::downloadNeededArchives(double partProgressSize)
If a component marked as important was installed during update
process true is returned.
*/
-bool PackageManagerCore::needsRestart() const
+bool PackageManagerCore::needsHardRestart() const
+{
+ return d->m_needsHardRestart;
+}
+
+void PackageManagerCore::setNeedsHardRestart(bool needsHardRestart)
{
- return d->m_forceRestart;
+ d->m_needsHardRestart = needsHardRestart;
}
+
void PackageManagerCore::rollBackInstallation()
{
emit titleMessageChanged(tr("Cancelling the Installer"));
@@ -487,7 +654,7 @@ void PackageManagerCore::rollBackInstallation()
if (!componentName.isEmpty()) {
Component *component = componentByName(componentName);
if (!component)
- component = d->componentsToReplace(runMode()).value(componentName).second;
+ component = d->componentsToReplace().value(componentName).second;
if (component) {
component->setUninstalled();
packages.removePackage(component->name());
@@ -510,12 +677,26 @@ void PackageManagerCore::rollBackInstallation()
packages.writeToDisk();
}
+/*!
+ \qmlmethod boolean Installer::isFileExtensionRegistered(string extension)
+
+ Returns whether a file extension is already registered in the Windows registry. Returns \c false
+ on all other platforms.
+ */
bool PackageManagerCore::isFileExtensionRegistered(const QString &extension) const
{
QSettingsWrapper settings(QLatin1String("HKEY_CLASSES_ROOT"), QSettingsWrapper::NativeFormat);
return settings.value(QString::fromLatin1(".%1/Default").arg(extension)).isValid();
}
+/*!
+ \qmlmethod boolean QInstaller::fileExists(string filePath)
+
+ Returns \c true if the \a filePath exists; otherwise returns \c false.
+
+ \note If the file is a symlink that points to a non existing
+ file, \c false is returned.
+ */
bool PackageManagerCore::fileExists(const QString &filePath) const
{
return QFileInfo(filePath).exists();
@@ -530,6 +711,8 @@ bool PackageManagerCore::fileExists(const QString &filePath) const
PackageManagerCore::PackageManagerCore()
: d(new PackageManagerCorePrivate(this))
{
+ qRegisterMetaType<QInstaller::PackageManagerCore::Status>("QInstaller::PackageManagerCore::Status");
+ qRegisterMetaType<QInstaller::PackageManagerCore::WizardPage>("QInstaller::PackageManagerCore::WizardPage");
}
PackageManagerCore::PackageManagerCore(qint64 magicmaker, const OperationList &performedOperations)
@@ -550,12 +733,16 @@ PackageManagerCore::~PackageManagerCore()
QInstaller::VerboseWriter::instance()->setOutputStream(logFileName);
}
delete d;
+
+ QMutexLocker _(globalVirtualComponentsFontMutex());
+ delete sVirtualComponentsFont;
+ sVirtualComponentsFont = 0;
}
/* static */
QFont PackageManagerCore::virtualComponentsFont()
{
- QMutexLocker _(&sVirtualComponentsFontMutex);
+ QMutexLocker _(globalVirtualComponentsFontMutex());
if (!sVirtualComponentsFont)
sVirtualComponentsFont = new QFont;
return *sVirtualComponentsFont;
@@ -564,7 +751,7 @@ QFont PackageManagerCore::virtualComponentsFont()
/* static */
void PackageManagerCore::setVirtualComponentsFont(const QFont &font)
{
- QMutexLocker _(&sVirtualComponentsFontMutex);
+ QMutexLocker _(globalVirtualComponentsFontMutex());
if (sVirtualComponentsFont)
delete sVirtualComponentsFont;
sVirtualComponentsFont = new QFont(font);
@@ -606,11 +793,6 @@ void PackageManagerCore::setCreateLocalRepositoryFromBinary(bool create)
sCreateLocalRepositoryFromBinary = create;
}
-RunMode PackageManagerCore::runMode() const
-{
- return isUpdater() ? UpdaterMode : AllMode;
-}
-
bool PackageManagerCore::fetchLocalPackagesTree()
{
d->setStatus(Running);
@@ -650,9 +832,8 @@ bool PackageManagerCore::fetchLocalPackagesTree()
updateDisplayVersions(scDisplayVersion);
- emit finishAllComponentsReset();
+ emit finishAllComponentsReset(d->m_rootComponents);
d->setStatus(Success);
- emit setRootComponents(d->m_rootComponents);
return true;
}
@@ -705,8 +886,8 @@ bool PackageManagerCore::fetchRemotePackagesTree()
return false;
}
- if (!ProductKeyCheck::instance()->hasValidKey()) {
- d->setStatus(Failure, ProductKeyCheck::instance()->lastErrorString());
+ if (!ProductKeyCheck::instance(this)->hasValidKey()) {
+ d->setStatus(Failure, ProductKeyCheck::instance(this)->lastErrorString());
return false;
}
@@ -725,9 +906,39 @@ bool PackageManagerCore::fetchRemotePackagesTree()
return false;
bool success = false;
- if (runMode() == AllMode)
+ if (!isUpdater()) {
success = fetchAllPackages(packages, installedPackages);
- else {
+ if (success && !d->statusCanceledOrFailed() && isPackageManager()) {
+ foreach (Package *const update, packages) {
+ if (update->data(scEssential, scFalse).toString().toLower() == scTrue) {
+ const QString name = update->data(scName).toString();
+ if (!installedPackages.contains(name)) {
+ success = false;
+ break; // unusual, the maintenance tool should always be available
+ }
+
+ const LocalPackage localPackage = installedPackages.value(name);
+ const QString updateVersion = update->data(scRemoteVersion).toString();
+ if (KDUpdater::compareVersion(updateVersion, localPackage.version) <= 0)
+ break; // remote version equals or is less than the installed maintenance tool
+
+ const QDate updateDate = update->data(scReleaseDate).toDate();
+ if (localPackage.lastUpdateDate >= updateDate)
+ break; // remote release date equals or is less than the installed maintenance tool
+
+ success = false;
+ break; // we found a newer version of the maintenance tool
+ }
+ }
+
+ if (!success && !d->statusCanceledOrFailed()) {
+ updateDisplayVersions(scRemoteDisplayVersion);
+ d->setStatus(ForceUpdate, tr("There is an important update available, please run the "
+ "updater first."));
+ return false;
+ }
+ }
+ } else {
success = fetchUpdaterPackages(packages, installedPackages);
}
@@ -739,9 +950,16 @@ bool PackageManagerCore::fetchRemotePackagesTree()
}
/*!
+ \qmlmethod boolean QInstaller::addWizardPage(Component component, string name, int page)
+
Adds the widget with objectName() \a name registered by \a component as a new page
into the installer's GUI wizard. The widget is added before \a page.
- \a page has to be a value of \ref QInstaller::PackageManagerCore::WizardPage "WizardPage".
+
+ See \l{Wizard Pages} for the possible values of \a page.
+
+ Returns \c true if the operation succeeded.
+
+ \sa removeWizardPage, setDefaultPageVisible
*/
bool PackageManagerCore::addWizardPage(Component *component, const QString &name, int page)
{
@@ -753,8 +971,14 @@ bool PackageManagerCore::addWizardPage(Component *component, const QString &name
}
/*!
+ \qmlmethod boolean QInstaller::removeWizardPage(Component component, string name)
+
Removes the widget with objectName() \a name previously added to the installer's wizard
by \a component.
+
+ Returns \c true if the operation succeeded.
+
+ \sa addWizardPage, setDefaultPageVisible, wizardPageRemovalRequested
*/
bool PackageManagerCore::removeWizardPage(Component *component, const QString &name)
{
@@ -766,9 +990,15 @@ bool PackageManagerCore::removeWizardPage(Component *component, const QString &n
}
/*!
+ \qmlmethod boolean QInstaller::setDefaultPageVisible(int page, boolean visible)
+
Sets the visibility of the default page with id \a page to \a visible, i.e.
removes or adds it from/to the wizard. This works only for pages which have been
in the installer when it was started.
+
+ Returns \c true.
+
+ \sa addWizardPage, removeWizardPage
*/
bool PackageManagerCore::setDefaultPageVisible(int page, bool visible)
{
@@ -776,6 +1006,12 @@ bool PackageManagerCore::setDefaultPageVisible(int page, bool visible)
return true;
}
+/*!
+ \qmlmethod void QInstaller::setValidatorForCustomPage(Component component, string name,
+ string callbackName)
+
+ \sa setValidatorForCustomPageRequested
+ */
void PackageManagerCore::setValidatorForCustomPage(Component *component, const QString &name,
const QString &callbackName)
{
@@ -783,9 +1019,14 @@ void PackageManagerCore::setValidatorForCustomPage(Component *component, const Q
}
/*!
+ \qmlmethod boolean QInstaller::addWizardPageItem(Component component, string name, int page)
+
Adds the widget with objectName() \a name registered by \a component as an GUI element
into the installer's GUI wizard. The widget is added on \a page.
- \a page has to be a value of \ref QInstaller::PackageManagerCore::WizardPage "WizardPage".
+
+ See \l{Wizard Pages} for the possible values of \a page.
+
+ \sa removeWizardPageItem, wizardWidgetInsertionRequested
*/
bool PackageManagerCore::addWizardPageItem(Component *component, const QString &name, int page)
{
@@ -797,8 +1038,12 @@ bool PackageManagerCore::addWizardPageItem(Component *component, const QString &
}
/*!
+ \qmlmethod boolean QInstaller::removeWizardPageItem(Component component, string name)
+
Removes the widget with objectName() \a name previously added to the installer's wizard
by \a component.
+
+ \sa addWizardPageItem
*/
bool PackageManagerCore::removeWizardPageItem(Component *component, const QString &name)
{
@@ -809,6 +1054,13 @@ bool PackageManagerCore::removeWizardPageItem(Component *component, const QStrin
return false;
}
+/*!
+ \qmlmethod void QInstaller::addUserRepositories(stringlist repositories)
+
+ Registers additional \a repositories.
+
+ \sa setTemporaryRepositories
+ */
void PackageManagerCore::addUserRepositories(const QStringList &repositories)
{
QSet<Repository> repositorySet;
@@ -819,8 +1071,12 @@ void PackageManagerCore::addUserRepositories(const QStringList &repositories)
}
/*!
- Sets additional repository for this instance of the installer or updater.
+ \qmlmethod void QInstaller::setTemporaryRepositories(stringlist repositories, boolean replace)
+
+ Sets additional \a repositories for this instance of the installer or updater.
Will be removed after invoking it again.
+
+ \sa addUserRepositories
*/
void PackageManagerCore::setTemporaryRepositories(const QStringList &repositories, bool replace)
{
@@ -847,6 +1103,16 @@ void PackageManagerCore::setTestChecksum(bool test)
d->m_testChecksum = test;
}
+ScriptEngine *PackageManagerCore::componentScriptEngine() const
+{
+ return d->componentScriptEngine();
+}
+
+ScriptEngine *PackageManagerCore::controlScriptEngine() const
+{
+ return d->controlScriptEngine();
+}
+
/*!
Returns the number of components in the list for installer and package manager mode. Might return 0 in
case the engine has only been run in updater mode or no components have been fetched.
@@ -886,6 +1152,8 @@ void PackageManagerCore::appendRootComponent(Component *component)
}
/*!
+ \qmlmethod int QInstaller::updaterComponentCount()
+
Returns the number of components in the list for updater mode. Might return 0 in case the engine has only
been run in installer or package manager mode or no components have been fetched.
*/
@@ -934,13 +1202,15 @@ QList<Component*> PackageManagerCore::availableComponents() const
QList<Component*> result = d->m_rootComponents;
foreach (QInstaller::Component *component, d->m_rootComponents)
- result += component->childComponents(true, AllMode);
+ result += component->childComponents(Component::Descendants);
return result + d->m_rootDependencyReplacements;
}
/*!
+ \qmlmethod Component QInstaller::componentByName(string name)
+
Returns a component matching \a name. \a name can also contains a version requirement.
- E.g. "com.nokia.sdk.qt" returns any component with that name, "com.nokia.sdk.qt->=4.5" requires
+ E.g. "org.qt-project.sdk.qt" returns any component with that name, "org.qt-project.sdk.qt->=4.5" requires
the returned component to have at least version 4.5.
If no component matches the requirement, 0 is returned.
*/
@@ -968,21 +1238,23 @@ bool PackageManagerCore::calculateComponentsToInstall() const
if (!d->m_componentsToInstallCalculated) {
d->clearComponentsToInstall();
QList<Component*> components;
- if (runMode() == UpdaterMode) {
+ if (isUpdater()) {
foreach (Component *component, updaterComponents()) {
if (component->updateRequested())
components.append(component);
}
- } else if (runMode() == AllMode) {
+ } else if (!isUpdater()) {
// relevant means all components which are not replaced
QList<Component*> relevantComponents = rootComponents();
foreach (QInstaller::Component *component, rootComponents())
- relevantComponents += component->childComponents(true, AllMode);
+ relevantComponents += component->childComponents(Component::Descendants);
foreach (Component *component, relevantComponents) {
// ask for all components which will be installed to get all dependencies
- // even dependencies wich are changed without an increased version
- if (component->installationRequested() || (component->isInstalled() && !component->uninstallationRequested()))
- components.append(component);
+ // even dependencies which are changed without an increased version
+ if (component->installationRequested() || (component->isInstalled()
+ && !component->uninstallationRequested())) {
+ components.append(component);
+ }
}
}
@@ -1005,10 +1277,10 @@ QList<Component*> PackageManagerCore::orderedComponentsToInstall() const
*/
bool PackageManagerCore::calculateComponentsToUninstall() const
{
- if (runMode() == UpdaterMode)
+ if (isUpdater())
return true;
- // hack to avoid removeing needed dependencies
+ // hack to avoid removing needed dependencies
QSet<Component*> componentsToInstall = d->m_orderedComponentsToInstall.toSet();
QList<Component*> components;
@@ -1046,7 +1318,7 @@ QString PackageManagerCore::installReason(Component *component) const
}
/*!
- Returns a list of components that dependend on \a component. The list can be empty. Note: Auto
+ Returns a list of components that depend on \a component. The list can be empty. Note: Auto
installed dependencies are not resolved.
*/
QList<Component*> PackageManagerCore::dependees(const Component *_component) const
@@ -1090,21 +1362,25 @@ QList<Component*> PackageManagerCore::dependencies(const Component *component, Q
ComponentModel *PackageManagerCore::defaultComponentModel() const
{
- QMutexLocker _(&sModelMutex);
+ QMutexLocker _(globalModelMutex());
if (!d->m_defaultModel) {
d->m_defaultModel = componentModel(const_cast<PackageManagerCore*> (this),
QLatin1String("AllComponentsModel"));
}
+ connect(this, SIGNAL(finishAllComponentsReset(QList<QInstaller::Component*>)), d->m_defaultModel,
+ SLOT(setRootComponents(QList<QInstaller::Component*>)));
return d->m_defaultModel;
}
ComponentModel *PackageManagerCore::updaterComponentModel() const
{
- QMutexLocker _(&sModelMutex);
+ QMutexLocker _(globalModelMutex());
if (!d->m_updaterModel) {
d->m_updaterModel = componentModel(const_cast<PackageManagerCore*> (this),
QLatin1String("UpdaterComponentsModel"));
}
+ connect(this, SIGNAL(finishUpdaterComponentsReset(QList<QInstaller::Component*>)), d->m_updaterModel,
+ SLOT(setRootComponents(QList<QInstaller::Component*>)));
return d->m_updaterModel;
}
@@ -1114,7 +1390,11 @@ Settings &PackageManagerCore::settings() const
}
/*!
- This method tries to gain admin rights. On success, it returns true.
+ \qmlmethod boolean QInstaller::gainAdminRights()
+
+ Tries to gain admin rights. On success, it returns \c true.
+
+ \sa dropAdminRights
*/
bool PackageManagerCore::gainAdminRights()
{
@@ -1128,7 +1408,11 @@ bool PackageManagerCore::gainAdminRights()
}
/*!
- This method drops gained admin rights.
+ \qmlmethod void QInstaller::dropAdminRights()
+
+ Drops admin rights gained by gainAdminRights.
+
+ \sa gainAdminRights
*/
void PackageManagerCore::dropAdminRights()
{
@@ -1136,7 +1420,9 @@ void PackageManagerCore::dropAdminRights()
}
/*!
- Return true, if a process with \a name is running. On Windows, the comparison
+ \qmlmethod boolean QInstaller::isProcessRunning(string name)
+
+ Returns true, if a process with \a name is running. On Windows, the comparison
is case-insensitive.
*/
bool PackageManagerCore::isProcessRunning(const QString &name) const
@@ -1145,8 +1431,11 @@ bool PackageManagerCore::isProcessRunning(const QString &name) const
}
/*!
- Return true, if a process with \a absoluteFilePath could be killed or isn't running
- Note: this is implemented in a semi blocking way (to keep the main thread to paint the UI)
+ \qmlmethod boolean QInstaller::killProcess(string absoluteFilePath)
+
+ Returns true, if a process with \a absoluteFilePath could be killed or isn't running
+
+ \note This is implemented in a semi blocking way (to keep the main thread to paint the UI).
*/
bool PackageManagerCore::killProcess(const QString &absoluteFilePath) const
{
@@ -1180,11 +1469,30 @@ bool PackageManagerCore::killProcess(const QString &absoluteFilePath) const
}
+/*!
+ \qmlmethod void QInstaller::setDependsOnLocalInstallerBinary()
+
+ Makes sure the installer runs from a local drive. Otherwise the user will get an
+ appropriate error message.
+
+ \note This only works on Windows.
+
+ \sa localInstallerBinaryUsed
+*/
+
void PackageManagerCore::setDependsOnLocalInstallerBinary()
{
d->m_dependsOnLocalInstallerBinary = true;
}
+/*!
+ \qmlmethod boolean QInstaller::localInstallerBinaryUsed()
+
+ Returns \c false if the installer is run on Windows, and the installer has been started from
+ a remote file system drive. Otherwise returns \c true.
+
+ \sa setDependsOnLocalInstallerBinary
+*/
bool PackageManagerCore::localInstallerBinaryUsed()
{
#ifdef Q_OS_WIN
@@ -1194,14 +1502,20 @@ bool PackageManagerCore::localInstallerBinaryUsed()
}
/*!
- Executes a program.
+ \qmlmethod array QInstaller::execute(string program, stringlist arguments = undefined,
+ string stdin = "")
+
+ Starts the program \a program with the arguments \a arguments in a
+ new process and waits for it to finish.
+
+ \a stdin is sent as standard input to the application.
+
+ Returns an empty array if the program could not be executed, otherwise
+ the output of command as the first item, and the return code as the second.
- \param program The program that should be executed.
- \param arguments Optional list of arguments.
- \param stdIn Optional stdin the program reads.
- \return If the command could not be executed, an empty QList, otherwise the output of the
- command as first item, the return code as second item.
\note On Unix, the output is just the output to stdout, not to stderr.
+
+ \sa executeDetached
*/
QList<QVariant> PackageManagerCore::execute(const QString &program, const QStringList &arguments,
const QString &stdIn) const
@@ -1234,12 +1548,24 @@ QList<QVariant> PackageManagerCore::execute(const QString &program, const QStrin
}
/*!
- Executes a program.
+ \qmlmethod boolean QInstaller::executeDetached(string program, stringlist arguments = undefined,
+ string workingDirectory = "")
+
+ Starts the program \a program with the arguments \a arguments in a
+ new process, and detaches from it. Returns \c true on success;
+ otherwise returns \c false. If the installer exits, the
+ detached process will continue to live.
- \param program The program that should be executed.
- \param arguments Optional list of arguments.
- \param workingDirectory Optional working directory of the forked process.
- \return If the command could not be executed, an false will be returned
+ \note Arguments that contain spaces are not passed to the
+ process as separate arguments.
+
+ \b{Unix:} The started process will run in its own session and act
+ like a daemon.
+
+ \b{Windows:} Arguments that contain spaces are wrapped in quotes.
+ The started process will run as a regular standalone process.
+
+ The process will be started in the directory \a workingDirectory.
*/
bool PackageManagerCore::executeDetached(const QString &program, const QStringList &arguments,
@@ -1259,16 +1585,20 @@ bool PackageManagerCore::executeDetached(const QString &program, const QStringLi
/*!
- Returns an environment variable.
+ \qmlmethod string QInstaller::environmentVariable(string name)
+
+ Returns content of an environment variable \a name. An empty string is returned if the
+ environment variable is not set.
*/
QString PackageManagerCore::environmentVariable(const QString &name) const
{
+ if (name.isEmpty())
+ return QString();
+
#ifdef Q_OS_WIN
- const LPCWSTR n = (LPCWSTR) name.utf16();
- LPTSTR buff = (LPTSTR) malloc(4096 * sizeof(TCHAR));
- DWORD getenvret = GetEnvironmentVariable(n, buff, 4096);
- QString value = getenvret != 0 ? QString::fromUtf16((const unsigned short *) buff) : QString();
- free(buff);
+ static TCHAR buffer[32767];
+ DWORD size = GetEnvironmentVariable(LPCWSTR(name.utf16()), buffer, 32767);
+ QString value = QString::fromUtf16((const unsigned short *) buffer, size);
if (value.isEmpty()) {
static QLatin1String userEnvironmentRegistryPath("HKEY_CURRENT_USER\\Environment");
@@ -1281,14 +1611,14 @@ QString PackageManagerCore::environmentVariable(const QString &name) const
}
return value;
#else
- const char *pPath = name.isEmpty() ? 0 : getenv(name.toLatin1());
- return pPath ? QLatin1String(pPath) : QString();
+ return QString::fromUtf8(qgetenv(name.toLatin1()));
#endif
}
/*!
+ \qmlmethod boolean QInstaller::performOperation(string name, stringlist arguments)
+
Instantly performs an operation \a name with \a arguments.
- \sa Component::addOperation
*/
bool PackageManagerCore::performOperation(const QString &name, const QStringList &arguments)
{
@@ -1306,7 +1636,9 @@ bool PackageManagerCore::performOperation(const QString &name, const QStringList
}
/*!
- Returns true when \a version matches the \a requirement.
+ \qmlmethod boolean QInstaller::versionMatches(string version, string requirement)
+
+ Returns \c true when \a version matches the \a requirement.
\a requirement can be a fixed version number or it can be prefix by the comparators '>', '>=',
'<', '<=' and '='.
*/
@@ -1333,10 +1665,15 @@ bool PackageManagerCore::versionMatches(const QString &version, const QString &r
}
/*!
+ \qmlmethod string QInstaller::findLibrary(string name, stringlist paths = [])
+
Finds a library named \a name in \a paths.
If \a paths is empty, it gets filled with platform dependent default paths.
- The resulting path is stored in \a library.
+ The resulting path is returned.
+
This method can be used by scripts to check external dependencies.
+
+ \sa findPath
*/
QString PackageManagerCore::findLibrary(const QString &name, const QStringList &paths)
{
@@ -1362,9 +1699,14 @@ QString PackageManagerCore::findLibrary(const QString &name, const QStringList &
}
/*!
+ \qmlmethod string QInstaller::findPath(string name, stringlist paths = [])
+
Tries to find a file name \a name in one of \a paths.
- The resulting path is stored in \a path.
+ The resulting path is returned.
+
This method can be used by scripts to check external dependencies.
+
+ \sa findLibrary
*/
QString PackageManagerCore::findPath(const QString &name, const QStringList &paths)
{
@@ -1380,8 +1722,11 @@ QString PackageManagerCore::findPath(const QString &name, const QStringList &pat
}
/*!
+ \qmlmethod void QInstaller::setInstallerBaseBinary(string path)
+
Sets the "installerbase" binary to use when writing the package manager/uninstaller.
Set this if an update to installerbase is available.
+
If not set, the executable segment of the running un/installer will be used.
*/
void PackageManagerCore::setInstallerBaseBinary(const QString &path)
@@ -1390,8 +1735,12 @@ void PackageManagerCore::setInstallerBaseBinary(const QString &path)
}
/*!
+ \qmlmethod string QInstaller::value(string key, string defaultValue = "")
+
Returns the installer value for \a key. If \a key is not known to the system, \a defaultValue is
returned. Additionally, on Windows, \a key can be a registry key.
+
+ \sa setValue, containsValue, valueChanged
*/
QString PackageManagerCore::value(const QString &key, const QString &defaultValue) const
{
@@ -1399,7 +1748,11 @@ QString PackageManagerCore::value(const QString &key, const QString &defaultValu
}
/*!
+ \qmlmethod void QInstaller::setValue(string key, string value)
+
Sets the installer value for \a key to \a value.
+
+ \sa value, containsValue, valueChanged
*/
void PackageManagerCore::setValue(const QString &key, const QString &value)
{
@@ -1409,18 +1762,38 @@ void PackageManagerCore::setValue(const QString &key, const QString &value)
}
/*!
- Returns true, when the installer contains a value for \a key.
+ \qmlmethod boolean QInstaller::containsValue(string key)
+
+ Returns \c true if the installer contains a value for \a key.
+
+ \sa value, setValue, valueChanged
*/
bool PackageManagerCore::containsValue(const QString &key) const
{
return d->m_data.contains(key);
}
+/*!
+ \qmlmethod void QInstaller::setSharedFlag(string key, boolean value)
+
+ Sets a shared flag with name \a key to \a value. This is one option
+ to share information between scripts.
+
+ \sa sharedFlag
+*/
void PackageManagerCore::setSharedFlag(const QString &key, bool value)
{
d->m_sharedFlags.insert(key, value);
}
+/*!
+ \qmlmethod boolean QInstaller::sharedFlag(string key)
+
+ Returns shared flag with name \a key. This is one option
+ to share information between scripts.
+
+ \sa setSharedFlag
+*/
bool PackageManagerCore::sharedFlag(const QString &key) const
{
return d->m_sharedFlags.value(key, false);
@@ -1447,7 +1820,7 @@ QString PackageManagerCore::error() const
}
/*!
- Returns true if at least one complete installation/update was successful, even if the user cancelled the
+ Returns \c true if at least one complete installation/update was successful, even if the user cancelled the
newest installation process.
*/
bool PackageManagerCore::finishedWithSuccess() const
@@ -1455,12 +1828,24 @@ bool PackageManagerCore::finishedWithSuccess() const
return d->m_status == PackageManagerCore::Success || d->m_needToWriteUninstaller;
}
+/*!
+ \qmlmethod void QInstaller::interrupt()
+
+ Cancels an ongoing installation.
+
+ \sa installationInterrupted
+ */
void PackageManagerCore::interrupt()
{
setCanceled();
emit installationInterrupted();
}
+/*!
+ \qmlmethod void QInstaller::setCanceled()
+
+ Cancels the installation.
+ */
void PackageManagerCore::setCanceled()
{
cancelMetaInfoJob();
@@ -1506,7 +1891,11 @@ QString PackageManagerCore::installerBinaryPath() const
}
/*!
- Returns true when this is the installer running.
+ \qmlmethod boolean QInstaller::isInstaller()
+
+ Returns \c true if executed in an install step.
+
+ \sa isUninstaller, isUpdater, isPackageManager
*/
bool PackageManagerCore::isInstaller() const
{
@@ -1514,47 +1903,79 @@ bool PackageManagerCore::isInstaller() const
}
/*!
- Returns true if this is an offline-only installer.
+ \qmlmethod boolean QInstaller::isOfflineOnly()
+
+ Returns \c true if this is an offline-only installer.
*/
bool PackageManagerCore::isOfflineOnly() const
{
return d->isOfflineOnly();
}
+/*!
+ \qmlmethod void QInstaller::setUninstaller()
+
+ Forces an uninstaller context.
+
+ \sa isUninstaller, setUpdater, setPackageManager
+*/
void PackageManagerCore::setUninstaller()
{
d->m_magicBinaryMarker = QInstaller::MagicUninstallerMarker;
}
/*!
- Returns true when this is the uninstaller running.
+ \qmlmethod boolean QInstaller::isUninstaller()
+
+ Returns \c true if the script is executed in an uninstall context.
+
+ \sa setUninstaller, isInstaller, isUpdater, isPackageManager
*/
bool PackageManagerCore::isUninstaller() const
{
return d->isUninstaller();
}
+/*!
+ \qmlmethod void QInstaller::setUpdater()
+
+ Forces an updater context.
+
+ \sa isUpdater, setUninstaller, setPackageManager
+*/
void PackageManagerCore::setUpdater()
{
d->m_magicBinaryMarker = QInstaller::MagicUpdaterMarker;
}
/*!
- Returns true when this is neither an installer nor an uninstaller running.
- Must be an updater, then.
+ \qmlmethod boolean QInstaller::isUpdater()
+
+ Returns \c true if the script is executed in an updater context.
+
+ \sa setUpdater, isInstaller, isUninstaller, isPackageManager
*/
bool PackageManagerCore::isUpdater() const
{
return d->isUpdater();
}
+/*!
+ \qmlmethod void QInstaller::setPackageManager()
+
+ Forces a package manager context.
+*/
void PackageManagerCore::setPackageManager()
{
d->m_magicBinaryMarker = QInstaller::MagicPackageManagerMarker;
}
+
/*!
- Returns true when this is the package manager running.
+ \qmlmethod boolean QInstaller::isPackageManager()
+
+ Returns \c true if the script is executed in a package manager context.
+ \sa setPackageManager, isInstaller, isUninstaller, isUpdater
*/
bool PackageManagerCore::isPackageManager() const
{
@@ -1562,7 +1983,9 @@ bool PackageManagerCore::isPackageManager() const
}
/*!
- Runs the installer. Returns true on success, false otherwise.
+ \qmlmethod boolean QInstaller::runInstaller()
+
+ Runs the installer. Returns \c true on success, \c false otherwise.
*/
bool PackageManagerCore::runInstaller()
{
@@ -1570,7 +1993,9 @@ bool PackageManagerCore::runInstaller()
}
/*!
- Runs the uninstaller. Returns true on success, false otherwise.
+ \qmlmethod boolean QInstaller::runUninstaller()
+
+ Runs the uninstaller. Returns \c true on success, \c false otherwise.
*/
bool PackageManagerCore::runUninstaller()
{
@@ -1578,7 +2003,9 @@ bool PackageManagerCore::runUninstaller()
}
/*!
- Runs the package updater. Returns true on success, false otherwise.
+ \qmlmethod boolean QInstaller::runPackageUpdater()
+
+ Runs the package updater. Returns \c true on success, \c false otherwise.
*/
bool PackageManagerCore::runPackageUpdater()
{
@@ -1586,7 +2013,8 @@ bool PackageManagerCore::runPackageUpdater()
}
/*!
- \internal
+ \qmlmethod void QInstaller::languageChanged()
+
Calls languangeChanged on all components.
*/
void PackageManagerCore::languageChanged()
@@ -1646,7 +2074,7 @@ bool PackageManagerCore::updateComponentData(struct Data &data, Component *compo
// add downloadable archive from xml
const QStringList downloadableArchives = data.package->data(scDownloadableArchives).toString()
- .split(scCommaRegExp, QString::SkipEmptyParts);
+ .split(QInstaller::commaRegExp(), QString::SkipEmptyParts);
if (component->isFromOnlineRepository()) {
foreach (const QString downloadableArchive, downloadableArchives)
@@ -1654,7 +2082,7 @@ bool PackageManagerCore::updateComponentData(struct Data &data, Component *compo
}
const QStringList componentsToReplace = data.package->data(scReplaces).toString()
- .split(scCommaRegExp, QString::SkipEmptyParts);
+ .split(QInstaller::commaRegExp(), QString::SkipEmptyParts);
if (!componentsToReplace.isEmpty()) {
// Store the component (this is a component that replaces others) and all components that
@@ -1711,14 +2139,14 @@ void PackageManagerCore::storeReplacedComponents(QHash<QString, Component *> &co
qWarning() << componentName << "- Does not exist in the repositories anymore.";
continue;
}
- if (!component && !d->componentsToReplace(data.runMode).contains(componentName)) {
+ if (!component && !d->componentsToReplace().contains(componentName)) {
component = new Component(this);
component->setValue(scName, componentName);
} else {
component->loadComponentScript();
- d->replacementDependencyComponents(data.runMode).append(component);
+ d->replacementDependencyComponents().append(component);
}
- d->componentsToReplace(data.runMode).insert(componentName, qMakePair(it.key(), component));
+ d->componentsToReplace().insert(componentName, qMakePair(it.key(), component));
}
}
}
@@ -1731,7 +2159,6 @@ bool PackageManagerCore::fetchAllPackages(const PackagesList &remotes, const Loc
QHash<QString, QInstaller::Component*> components;
Data data;
- data.runMode = AllMode;
data.components = &components;
data.installedPackages = &locals;
@@ -1762,8 +2189,7 @@ bool PackageManagerCore::fetchAllPackages(const PackagesList &remotes, const Loc
if (!d->buildComponentTree(components, true))
return false;
- emit finishAllComponentsReset();
- emit setRootComponents(d->m_rootComponents);
+ emit finishAllComponentsReset(d->m_rootComponents);
return true;
}
@@ -1775,7 +2201,6 @@ bool PackageManagerCore::fetchUpdaterPackages(const PackagesList &remotes, const
QHash<QString, QInstaller::Component *> components;
Data data;
- data.runMode = UpdaterMode;
data.components = &components;
data.installedPackages = &locals;
@@ -1804,7 +2229,8 @@ bool PackageManagerCore::fetchUpdaterPackages(const PackagesList &remotes, const
bool isValidUpdate = locals.contains(name);
if (!isValidUpdate && !replaces.isEmpty()) {
- const QStringList possibleNames = replaces.split(scCommaRegExp, QString::SkipEmptyParts);
+ const QStringList possibleNames = replaces.split(QInstaller::commaRegExp(),
+ QString::SkipEmptyParts);
foreach (const QString &possibleName, possibleNames) {
if (locals.contains(possibleName)) {
isValidUpdate = true;
@@ -1813,7 +2239,9 @@ bool PackageManagerCore::fetchUpdaterPackages(const PackagesList &remotes, const
}
}
- if (!isValidUpdate)
+ // break if the update is not valid and if it's not the maintenance tool (we might get an update
+ // for the maintenance tool even if it's not currently installed - possible offline installation)
+ if (!isValidUpdate && (update->data(scEssential, scFalse).toString().toLower() == scFalse))
continue; // Update for not installed package found, skip it.
const LocalPackage &localPackage = locals.value(name);
@@ -1851,14 +2279,18 @@ bool PackageManagerCore::fetchUpdaterPackages(const PackagesList &remotes, const
try {
if (!components.isEmpty()) {
- // load the scripts and append all components w/o parent to the direct list
+ // append all components w/o parent to the direct list
+ foreach (QInstaller::Component *component, components) {
+ appendUpdaterComponent(component);
+ }
+
+ // after everything is set up, load the scripts
foreach (QInstaller::Component *component, components) {
if (d->statusCanceledOrFailed())
return false;
component->loadComponentScript();
component->setCheckState(Qt::Checked);
- appendUpdaterComponent(component);
}
// after everything is set up, check installed components
@@ -1900,7 +2332,7 @@ bool PackageManagerCore::fetchUpdaterPackages(const PackagesList &remotes, const
}
} catch (const Error &error) {
d->clearUpdaterComponentLists();
- emit finishUpdaterComponentsReset();
+ emit finishUpdaterComponentsReset(QList<QInstaller::Component*>());
d->setStatus(Failure, error.message());
// TODO: make sure we remove all message boxes inside the library at some point.
@@ -1909,8 +2341,7 @@ bool PackageManagerCore::fetchUpdaterPackages(const PackagesList &remotes, const
return false;
}
- emit finishUpdaterComponentsReset();
- emit setRootComponents(d->m_updaterComponents);
+ emit finishUpdaterComponentsReset(d->m_updaterComponents);
return true;
}
@@ -1963,7 +2394,7 @@ QString PackageManagerCore::findDisplayVersion(const QString &componentName,
ComponentModel *PackageManagerCore::componentModel(PackageManagerCore *core, const QString &objectName) const
{
- ComponentModel *model = new ComponentModel(4, core);
+ ComponentModel *model = new ComponentModel(5, core);
model->setObjectName(objectName);
model->setHeaderData(ComponentModelHelper::NameColumn, Qt::Horizontal,
@@ -1972,11 +2403,12 @@ ComponentModel *PackageManagerCore::componentModel(PackageManagerCore *core, con
ComponentModel::tr("Installed Version"));
model->setHeaderData(ComponentModelHelper::NewVersionColumn, Qt::Horizontal,
ComponentModel::tr("New Version"));
+ model->setHeaderData(ComponentModelHelper::ReleaseDateColumn, Qt::Horizontal,
+ ComponentModel::tr("Release Date"));
model->setHeaderData(ComponentModelHelper::UncompressedSizeColumn, Qt::Horizontal,
ComponentModel::tr("Size"));
- connect(this, SIGNAL(setRootComponents(QList<QInstaller::Component*>)), model,
- SLOT(setRootComponents(QList<QInstaller::Component*>)));
- connect(model, SIGNAL(defaultCheckStateChanged(bool)), this, SLOT(componentsToInstallNeedsRecalculation()));
+ connect(model, SIGNAL(checkStateChanged(QInstaller::ComponentModel::ModelState)), this,
+ SLOT(componentsToInstallNeedsRecalculation()));
return model;
}