summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkh1 <karsten.heimrich@nokia.com>2012-08-21 16:29:45 +0200
committerKarsten Heimrich <karsten.heimrich@nokia.com>2012-08-21 16:30:37 +0200
commit6d7dbad2de546f2a0a39e21bcfe7afc0fc55ac91 (patch)
treea9383bb1d1d668c69786290abaf81d3ea662be94
parentb22a0e8e6d1b3114fc37acad7e96b6b3564a8e19 (diff)
Create a new folder for S40.
Share as much files as possible, also add a basic version for the new component selection page. It does compile, still no guarantee to function in any way. Change-Id: Ib10303041876d7ae7b7bb4a741989c131997a3b2 Reviewed-by: Karsten Heimrich <karsten.heimrich@nokia.com>
-rw-r--r--src/s40/componentviewpage.cpp407
-rw-r--r--src/s40/componentviewpage.h124
-rw-r--r--src/s40/installerbasecommons.cpp549
-rw-r--r--src/s40/installerbasecommons.h147
-rw-r--r--src/s40/s40.pro105
-rw-r--r--src/src.pro2
6 files changed, 1333 insertions, 1 deletions
diff --git a/src/s40/componentviewpage.cpp b/src/s40/componentviewpage.cpp
new file mode 100644
index 000000000..74dc576b6
--- /dev/null
+++ b/src/s40/componentviewpage.cpp
@@ -0,0 +1,407 @@
+/**************************************************************************
+**
+** This file is part of Installer Framework
+**
+** Copyright (c) 2010-2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+#include "componentviewpage.h"
+
+#include <component.h>
+#include <componentmodel.h>
+#include <messageboxhandler.h>
+#include <packagemanagercore.h>
+#include <settings.h>
+
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtCore/QTimer>
+
+#include <QtGui/QLabel>
+#include <QtGui/QPushButton>
+#include <QtGui/QTreeView>
+#include <QtGui/QHeaderView>
+#include <QtGui/QProgressBar>
+#include <QtGui/QRadioButton>
+#include <QtGui/QStackedWidget>
+#include <QtGui/QVBoxLayout>
+
+using namespace QInstaller;
+
+// -- ComponentViewPage
+
+ComponentViewPage::ComponentViewPage(QInstaller::PackageManagerCore *core)
+ : QInstaller::PackageManagerPage(core)
+ , m_updatesFetched(false)
+ , m_allPackagesFetched(false)
+ , m_core(core)
+ , m_treeView(new QTreeView(this))
+ , m_allModel(m_core->defaultComponentModel())
+ , m_updaterModel(m_core->updaterComponentModel())
+ , m_currentModel(m_allModel)
+{
+
+ setPixmap(QWizard::LogoPixmap, logoPixmap());
+ setPixmap(QWizard::WatermarkPixmap, QPixmap());
+ setObjectName(QLatin1String("ComponentViewPage"));
+ setTitle(titleForPage(QLatin1String("ComponentViewPage"), tr("Select Components")));
+
+
+
+ m_treeView->setObjectName(QLatin1String("ComponentsTreeView"));
+
+ connect(m_allModel, SIGNAL(defaultCheckStateChanged(bool)), this, SLOT(setModified(bool)));
+ connect(m_updaterModel, SIGNAL(defaultCheckStateChanged(bool)), this, SLOT(setModified(bool)));
+
+ m_descriptionLabel = new QLabel(this);
+ m_descriptionLabel->setWordWrap(true);
+ m_descriptionLabel->setObjectName(QLatin1String("ComponentDescriptionLabel"));
+
+ m_sizeLabel = new QLabel(this);
+ m_sizeLabel->setWordWrap(true);
+ m_sizeLabel->setObjectName(QLatin1String("ComponentSizeLabel"));
+
+ m_checkDefault = new QPushButton;
+ connect(m_checkDefault, SIGNAL(clicked()), this, SLOT(selectDefault()));
+ connect(m_allModel, SIGNAL(defaultCheckStateChanged(bool)), m_checkDefault, SLOT(setEnabled(bool)));
+ const QVariantHash hash = elementsForPage(QLatin1String("ComponentViewPage"));
+ if (m_core->isInstaller()) {
+ m_checkDefault->setObjectName(QLatin1String("SelectDefaultComponentsButton"));
+ m_checkDefault->setShortcut(QKeySequence(ComponentViewPage::tr("Alt+A", "select default components")));
+ m_checkDefault->setText(hash.value(QLatin1String("SelectDefaultComponentsButton"), ComponentViewPage::tr("Def&ault"))
+ .toString());
+ } else {
+ m_checkDefault->setEnabled(false);
+ m_checkDefault->setObjectName(QLatin1String("ResetComponentsButton"));
+ m_checkDefault->setShortcut(QKeySequence(ComponentViewPage::tr("Alt+R", "reset to already installed components")));
+ m_checkDefault->setText(hash.value(QLatin1String("ResetComponentsButton"), ComponentViewPage::tr("&Reset")).toString());
+ }
+
+ m_checkAll = new QPushButton;
+ connect(m_checkAll, SIGNAL(clicked()), this, SLOT(selectAll()));
+ m_checkAll->setObjectName(QLatin1String("SelectAllComponentsButton"));
+ m_checkAll->setShortcut(QKeySequence(ComponentViewPage::tr("Alt+S", "select all components")));
+ m_checkAll->setText(hash.value(QLatin1String("SelectAllComponentsButton"), ComponentViewPage::tr("&Select All")).toString());
+
+ m_uncheckAll = new QPushButton;
+ connect(m_uncheckAll, SIGNAL(clicked()), this, SLOT(deselectAll()));
+ m_uncheckAll->setObjectName(QLatin1String("DeselectAllComponentsButton"));
+ m_uncheckAll->setShortcut(QKeySequence(ComponentViewPage::tr("Alt+D", "deselect all components")));
+ m_uncheckAll->setText(hash.value(QLatin1String("DeselectAllComponentsButton"), ComponentViewPage::tr("&Deselect All"))
+ .toString());
+
+ m_progressBar = new QProgressBar(this);
+ m_progressBar->setRange(0, 0);
+
+ m_errorLabel = new QLabel(this);
+ m_errorLabel->setWordWrap(true);
+
+ gui()->showSettingsButton(true);
+
+ connect(core, SIGNAL(metaJobInfoMessage(QString)), this, SLOT(setMessage(QString)));
+ connect(core, SIGNAL(coreNetworkSettingsChanged()), this, SLOT(onCoreNetworkSettingsChanged()));
+}
+
+void ComponentViewPage::currentChanged(const QModelIndex &current)
+{
+ // if there is not selection or the current selected node didn't change, return
+ if (!current.isValid() || current != m_treeView->selectionModel()->currentIndex())
+ return;
+
+ m_descriptionLabel->setText(m_currentModel->data(m_currentModel->index(current.row(),
+ ComponentModelHelper::NameColumn, current.parent()), Qt::ToolTipRole).toString());
+
+ m_sizeLabel->clear();
+ if (!m_core->isUninstaller()) {
+ Component *component = m_currentModel->componentFromIndex(current);
+ if (component && component->updateUncompressedSize() > 0) {
+ const QVariantHash hash = elementsForPage(QLatin1String("ComponentViewPage"));
+ m_sizeLabel->setText(hash.value(QLatin1String("ComponentSizeLabel"),
+ ComponentViewPage::tr("This component will occupy approximately %1 on your hard disk drive.")).toString()
+ .arg(m_currentModel->data(m_currentModel->index(current.row(),
+ ComponentModelHelper::UncompressedSizeColumn, current.parent())).toString()));
+ }
+ }
+}
+
+ComponentViewPage::~ComponentViewPage()
+{
+}
+
+
+// TODO: all *select* function ignore the fact that components can be selected inside the tree view as
+// well, which will result in e.g. a disabled button state as long as "ALL" components not
+// unchecked again.
+void ComponentViewPage::selectAll()
+{
+ m_currentModel->selectAll();
+
+ m_checkAll->setEnabled(false);
+ m_uncheckAll->setEnabled(true);
+}
+
+void ComponentViewPage::deselectAll()
+{
+ m_currentModel->deselectAll();
+
+ m_checkAll->setEnabled(true);
+ m_uncheckAll->setEnabled(false);
+}
+
+void ComponentViewPage::selectDefault()
+{
+ m_currentModel->selectDefault();
+
+ m_checkAll->setEnabled(true);
+ m_uncheckAll->setEnabled(true);
+}
+
+/*!
+ Selects the component with /a id in the component tree.
+*/
+void ComponentViewPage::selectComponent(const QString &id)
+{
+ const QModelIndex &idx = m_currentModel->indexFromComponentName(id);
+ if (idx.isValid())
+ m_currentModel->setData(idx, Qt::Checked, Qt::CheckStateRole);
+}
+
+/*!
+ Deselects the component with /a id in the component tree.
+*/
+void ComponentViewPage::deselectComponent(const QString &id)
+{
+ const QModelIndex &idx = m_currentModel->indexFromComponentName(id);
+ if (idx.isValid())
+ m_currentModel->setData(idx, Qt::Unchecked, Qt::CheckStateRole);
+}
+
+
+void ComponentViewPage::updateTreeView()
+{
+ m_checkDefault->setVisible(m_core->isInstaller() || m_core->isPackageManager());
+ if (m_treeView->selectionModel()) {
+ disconnect(m_treeView->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)),
+ this, SLOT(currentChanged(QModelIndex)));
+ disconnect(m_currentModel, SIGNAL(checkStateChanged(QModelIndex)), this,
+ SLOT(currentChanged(QModelIndex)));
+ }
+
+ m_currentModel = m_core->isUpdater() ? m_updaterModel : m_allModel;
+ m_treeView->setModel(m_currentModel);
+ m_treeView->setExpanded(m_currentModel->index(0, 0), true);
+
+ if (m_core->isInstaller()) {
+ m_treeView->setHeaderHidden(true);
+ for (int i = 1; i < m_currentModel->columnCount(); ++i)
+ m_treeView->hideColumn(i);
+ } else {
+ m_treeView->header()->setStretchLastSection(true);
+ for (int i = 0; i < m_currentModel->columnCount(); ++i)
+ m_treeView->resizeColumnToContents(i);
+ }
+
+ bool hasChildren = false;
+ const int rowCount = m_currentModel->rowCount();
+ for (int row = 0; row < rowCount && !hasChildren; ++row)
+ hasChildren = m_currentModel->hasChildren(m_currentModel->index(row, 0));
+ m_treeView->setRootIsDecorated(hasChildren);
+
+ connect(m_treeView->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)),
+ this, SLOT(currentChanged(QModelIndex)));
+ connect(m_currentModel, SIGNAL(checkStateChanged(QModelIndex)), this,
+ SLOT(currentChanged(QModelIndex)));
+
+ m_treeView->setCurrentIndex(m_currentModel->index(0, 0));
+}
+
+
+bool ComponentViewPage::validatePage()
+{
+ PackageManagerCore *core = packageManagerCore();
+
+ setComplete(false);
+ gui()->setSettingsButtonEnabled(false);
+
+ const bool maintanence = core->isUpdater() || core->isPackageManager();
+ if (maintanence) {
+ showAll();
+ } else {
+ showMetaInfoUdate();
+ }
+
+ // fetch updater packages
+ if (core->isUpdater()) {
+ if (!m_updatesFetched) {
+ m_updatesFetched = core->fetchRemotePackagesTree();
+ if (!m_updatesFetched)
+ setErrorMessage(core->error());
+ }
+
+ callControlScript(QLatin1String("UpdaterSelectedCallback"));
+
+ if (m_updatesFetched) {
+ if (core->updaterComponents().count() <= 0)
+ setErrorMessage(QLatin1String("<b>") + tr("No updates available.") + QLatin1String("</b>"));
+ else
+ setComplete(true);
+ }
+ }
+
+ // fetch common packages
+ if (core->isInstaller() || core->isPackageManager()) {
+ bool localPackagesTreeFetched = false;
+ if (!m_allPackagesFetched) {
+ // first try to fetch the server side packages tree
+ m_allPackagesFetched = core->fetchRemotePackagesTree();
+ if (!m_allPackagesFetched) {
+ QString error = core->error();
+ if (core->isPackageManager()) {
+ // if that fails and we're in maintenance mode, try to fetch local installed tree
+ localPackagesTreeFetched = core->fetchLocalPackagesTree();
+ if (localPackagesTreeFetched) {
+ // if that succeeded, adjust error message
+ error = QLatin1String("<font color=\"red\">") + error + tr(" Only local package "
+ "management available.") + QLatin1String("</font>");
+ }
+ }
+ setErrorMessage(error);
+ }
+ }
+
+ callControlScript(QLatin1String("PackageManagerSelectedCallback"));
+
+ if (m_allPackagesFetched | localPackagesTreeFetched)
+ setComplete(true);
+ }
+
+ if (maintanence) {
+ showMaintenanceTools();
+ } else {
+ hideAll();
+ }
+ gui()->setSettingsButtonEnabled(true);
+
+ return isComplete();
+}
+
+void ComponentViewPage::showAll()
+{
+ showWidgets(true);
+}
+
+void ComponentViewPage::hideAll()
+{
+ showWidgets(false);
+}
+
+void ComponentViewPage::showMetaInfoUdate()
+{
+ showWidgets(false);
+ m_label->setVisible(true);
+ m_progressBar->setVisible(true);
+}
+
+void ComponentViewPage::showMaintenanceTools()
+{
+ showWidgets(true);
+ m_label->setVisible(false);
+ m_progressBar->setVisible(false);
+}
+
+// -- public slots
+
+void ComponentViewPage::setMessage(const QString &msg)
+{
+ m_label->setText(msg);
+}
+
+void ComponentViewPage::setErrorMessage(const QString &error)
+{
+ QPalette palette;
+ const PackageManagerCore::Status s = packageManagerCore()->status();
+ if (s == PackageManagerCore::Failure || s == PackageManagerCore::Failure) {
+ palette.setColor(QPalette::WindowText, Qt::red);
+ } else {
+ palette.setColor(QPalette::WindowText, palette.color(QPalette::WindowText));
+ }
+
+ m_errorLabel->setText(error);
+ m_errorLabel->setPalette(palette);
+}
+
+void ComponentViewPage::callControlScript(const QString &callback)
+{
+ // Initialize the gui. Needs to be done after check repositories as only then the ui can handle
+ // hide of pages depending on the components.
+ gui()->init();
+ gui()->callControlScriptMethod(callback);
+}
+
+void ComponentViewPage::onCoreNetworkSettingsChanged()
+{
+ // force a repaint of the ui as after the settings dialog has been closed and the wizard has been
+ // restarted, the "Next" button looks still disabled. TODO: figure out why this happens at all!
+ gui()->repaint();
+
+ m_updatesFetched = false;
+ m_allPackagesFetched = false;
+}
+
+// -- private
+
+void ComponentViewPage::entering()
+{
+ setComplete(true);
+ showWidgets(false);
+ setMessage(QString());
+ setErrorMessage(QString());
+ setButtonText(QWizard::CancelButton, tr("Quit"));
+
+ PackageManagerCore *core = packageManagerCore();
+ if (core->isUninstaller() ||core->isUpdater() || core->isPackageManager()) {
+ showMaintenanceTools();
+ }
+}
+
+void ComponentViewPage::setModified(bool modified)
+{
+ setComplete(modified);
+}
+
+void ComponentViewPage::leaving()
+{
+ // TODO: force repaint on next page, keeps unpainted after fetch
+ QTimer::singleShot(100, gui()->page(nextId()), SLOT(repaint()));
+ setButtonText(QWizard::CancelButton, gui()->defaultButtonText(QWizard::CancelButton));
+}
+
+void ComponentViewPage::showWidgets(bool show)
+{
+ m_label->setVisible(show);
+ m_progressBar->setVisible(show);
+}
diff --git a/src/s40/componentviewpage.h b/src/s40/componentviewpage.h
new file mode 100644
index 000000000..5d4db7553
--- /dev/null
+++ b/src/s40/componentviewpage.h
@@ -0,0 +1,124 @@
+/**************************************************************************
+**
+** This file is part of Installer Framework
+**
+** Copyright (c) 2010-2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#ifndef COMPONENTVIEWPAGE_H
+#define COMPONENTVIEWPAGE_H
+
+#include <packagemanagergui.h>
+
+QT_BEGIN_NAMESPACE
+class QLabel;
+class QString;
+class QProgressBar;
+class QModelIndex;
+class QTreeView;
+QT_END_NAMESPACE
+
+
+namespace QInstaller {
+ class ComponentModel;
+
+class ComponentViewPage : public QInstaller::PackageManagerPage
+{
+ Q_OBJECT
+
+public:
+ explicit ComponentViewPage(QInstaller::PackageManagerCore *core);
+ ~ComponentViewPage();
+
+ bool validatePage();
+
+ void showAll();
+ void hideAll();
+ void showMetaInfoUdate();
+ void showMaintenanceTools();
+ void updateTreeView();
+
+public slots:
+ void onCoreNetworkSettingsChanged();
+ void setMessage(const QString &msg);
+ void setErrorMessage(const QString &error);
+
+
+public slots:
+ void currentChanged(const QModelIndex &current);
+
+ void selectAll();
+ void deselectAll();
+ void selectDefault();
+ void selectComponent(const QString &id);
+ void deselectComponent(const QString &id);
+
+signals:
+ void packageManagerCoreTypeChanged();
+
+
+ bool isComplete() const;
+
+
+protected:
+ void entering();
+
+private Q_SLOTS:
+ void setModified(bool modified);
+
+private:
+ void leaving();
+
+ void showWidgets(bool show);
+ void callControlScript(const QString &callback);
+
+private:
+ bool m_updatesFetched;
+ bool m_updatesCompleted;
+ bool m_allPackagesFetched;
+
+ QLabel *m_label;
+ QLabel *m_errorLabel;
+ QProgressBar *m_progressBar;
+
+
+ PackageManagerCore *m_core;
+ QTreeView *m_treeView;
+ ComponentModel *m_allModel;
+ ComponentModel *m_updaterModel;
+ ComponentModel *m_currentModel;
+ QLabel *m_sizeLabel;
+ QLabel *m_descriptionLabel;
+ QPushButton *m_checkAll;
+ QPushButton *m_uncheckAll;
+ QPushButton *m_checkDefault;
+
+};
+} //namespace QInstaller
+
+#endif // COMPONENTVIEWPAGE_H
diff --git a/src/s40/installerbasecommons.cpp b/src/s40/installerbasecommons.cpp
new file mode 100644
index 000000000..1a3a08b36
--- /dev/null
+++ b/src/s40/installerbasecommons.cpp
@@ -0,0 +1,549 @@
+/**************************************************************************
+**
+** This file is part of Installer Framework
+**
+** Copyright (c) 2010-2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+#include "installerbasecommons.h"
+
+#include <component.h>
+#include <messageboxhandler.h>
+#include <packagemanagercore.h>
+#include <settings.h>
+
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtCore/QTimer>
+
+#include <QtGui/QLabel>
+#include <QtGui/QProgressBar>
+#include <QtGui/QRadioButton>
+#include <QtGui/QStackedWidget>
+#include <QtGui/QVBoxLayout>
+
+using namespace QInstaller;
+
+
+// -- IntroductionPageImpl
+
+IntroductionPageImpl::IntroductionPageImpl(QInstaller::PackageManagerCore *core)
+ : QInstaller::IntroductionPage(core)
+ , m_updatesFetched(false)
+ , m_allPackagesFetched(false)
+{
+ QWidget *widget = new QWidget(this);
+ QVBoxLayout *layout = new QVBoxLayout(widget);
+
+ m_packageManager = new QRadioButton(tr("Package manager"), this);
+ layout->addWidget(m_packageManager);
+ m_packageManager->setChecked(core->isPackageManager());
+ connect(m_packageManager, SIGNAL(toggled(bool)), this, SLOT(setPackageManager(bool)));
+
+ m_updateComponents = new QRadioButton(tr("Update components"), this);
+ layout->addWidget(m_updateComponents);
+ m_updateComponents->setChecked(core->isUpdater());
+ connect(m_updateComponents, SIGNAL(toggled(bool)), this, SLOT(setUpdater(bool)));
+
+ m_removeAllComponents = new QRadioButton(tr("Remove all components"), this);
+ layout->addWidget(m_removeAllComponents);
+ m_removeAllComponents->setChecked(core->isUninstaller());
+ connect(m_removeAllComponents, SIGNAL(toggled(bool)), this, SLOT(setUninstaller(bool)));
+ connect(m_removeAllComponents, SIGNAL(toggled(bool)), core, SLOT(setCompleteUninstallation(bool)));
+
+ layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Expanding));
+
+ m_label = new QLabel(this);
+ m_label->setWordWrap(true);
+ m_label->setText(tr("Retrieving information from remote installation sources..."));
+ layout->addWidget(m_label);
+
+ m_progressBar = new QProgressBar(this);
+ m_progressBar->setRange(0, 0);
+ layout->addWidget(m_progressBar);
+
+ layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Expanding));
+
+ m_errorLabel = new QLabel(this);
+ m_errorLabel->setWordWrap(true);
+ layout->addWidget(m_errorLabel);
+
+ widget->setLayout(layout);
+ setWidget(widget);
+
+ core->setCompleteUninstallation(core->isUninstaller());
+
+ connect(core, SIGNAL(metaJobInfoMessage(QString)), this, SLOT(setMessage(QString)));
+ connect(core, SIGNAL(coreNetworkSettingsChanged()), this, SLOT(onCoreNetworkSettingsChanged()));
+}
+
+int IntroductionPageImpl::nextId() const
+{
+ if (packageManagerCore()->isUninstaller())
+ return PackageManagerCore::ReadyForInstallation;
+
+ if (packageManagerCore()->isUpdater() || packageManagerCore()->isPackageManager())
+ return PackageManagerCore::ComponentSelection;
+
+ return QInstaller::IntroductionPage::nextId();
+}
+
+bool IntroductionPageImpl::validatePage()
+{
+ PackageManagerCore *core = packageManagerCore();
+ if (core->isUninstaller())
+ return true;
+
+ setComplete(false);
+ gui()->setSettingsButtonEnabled(false);
+
+ const bool maintanence = core->isUpdater() || core->isPackageManager();
+ if (maintanence) {
+ showAll();
+ setMaintenanceToolsEnabled(false);
+ } else {
+ showMetaInfoUdate();
+ }
+
+ // fetch updater packages
+ if (core->isUpdater()) {
+ if (!m_updatesFetched) {
+ m_updatesFetched = core->fetchRemotePackagesTree();
+ if (!m_updatesFetched)
+ setErrorMessage(core->error());
+ }
+
+ callControlScript(QLatin1String("UpdaterSelectedCallback"));
+
+ if (m_updatesFetched) {
+ if (core->updaterComponents().count() <= 0)
+ setErrorMessage(QLatin1String("<b>") + tr("No updates available.") + QLatin1String("</b>"));
+ else
+ setComplete(true);
+ }
+ }
+
+ // fetch common packages
+ if (core->isInstaller() || core->isPackageManager()) {
+ bool localPackagesTreeFetched = false;
+ if (!m_allPackagesFetched) {
+ // first try to fetch the server side packages tree
+ m_allPackagesFetched = core->fetchRemotePackagesTree();
+ if (!m_allPackagesFetched) {
+ QString error = core->error();
+ if (core->isPackageManager()) {
+ // if that fails and we're in maintenance mode, try to fetch local installed tree
+ localPackagesTreeFetched = core->fetchLocalPackagesTree();
+ if (localPackagesTreeFetched) {
+ // if that succeeded, adjust error message
+ error = QLatin1String("<font color=\"red\">") + error + tr(" Only local package "
+ "management available.") + QLatin1String("</font>");
+ }
+ }
+ setErrorMessage(error);
+ }
+ }
+
+ callControlScript(QLatin1String("PackageManagerSelectedCallback"));
+
+ if (m_allPackagesFetched | localPackagesTreeFetched)
+ setComplete(true);
+ }
+
+ if (maintanence) {
+ showMaintenanceTools();
+ setMaintenanceToolsEnabled(true);
+ } else {
+ hideAll();
+ }
+ gui()->setSettingsButtonEnabled(true);
+
+ return isComplete();
+}
+
+void IntroductionPageImpl::showAll()
+{
+ showWidgets(true);
+}
+
+void IntroductionPageImpl::hideAll()
+{
+ showWidgets(false);
+}
+
+void IntroductionPageImpl::showMetaInfoUdate()
+{
+ showWidgets(false);
+ m_label->setVisible(true);
+ m_progressBar->setVisible(true);
+}
+
+void IntroductionPageImpl::showMaintenanceTools()
+{
+ showWidgets(true);
+ m_label->setVisible(false);
+ m_progressBar->setVisible(false);
+}
+
+void IntroductionPageImpl::setMaintenanceToolsEnabled(bool enable)
+{
+ m_packageManager->setEnabled(enable);
+ m_updateComponents->setEnabled(enable);
+ m_removeAllComponents->setEnabled(enable);
+}
+
+// -- public slots
+
+void IntroductionPageImpl::setMessage(const QString &msg)
+{
+ m_label->setText(msg);
+}
+
+void IntroductionPageImpl::setErrorMessage(const QString &error)
+{
+ QPalette palette;
+ const PackageManagerCore::Status s = packageManagerCore()->status();
+ if (s == PackageManagerCore::Failure || s == PackageManagerCore::Failure) {
+ palette.setColor(QPalette::WindowText, Qt::red);
+ } else {
+ palette.setColor(QPalette::WindowText, palette.color(QPalette::WindowText));
+ }
+
+ m_errorLabel->setText(error);
+ m_errorLabel->setPalette(palette);
+}
+
+void IntroductionPageImpl::callControlScript(const QString &callback)
+{
+ // Initialize the gui. Needs to be done after check repositories as only then the ui can handle
+ // hide of pages depending on the components.
+ gui()->init();
+ gui()->callControlScriptMethod(callback);
+}
+
+// -- private slots
+
+void IntroductionPageImpl::setUpdater(bool value)
+{
+ if (value) {
+ entering();
+ gui()->showSettingsButton(true);
+ packageManagerCore()->setUpdater();
+ emit packageManagerCoreTypeChanged();
+ }
+}
+
+void IntroductionPageImpl::setUninstaller(bool value)
+{
+ if (value) {
+ entering();
+ gui()->showSettingsButton(false);
+ packageManagerCore()->setUninstaller();
+ emit packageManagerCoreTypeChanged();
+ }
+}
+
+void IntroductionPageImpl::setPackageManager(bool value)
+{
+ if (value) {
+ entering();
+ gui()->showSettingsButton(true);
+ packageManagerCore()->setPackageManager();
+ emit packageManagerCoreTypeChanged();
+ }
+}
+
+void IntroductionPageImpl::onCoreNetworkSettingsChanged()
+{
+ // force a repaint of the ui as after the settings dialog has been closed and the wizard has been
+ // restarted, the "Next" button looks still disabled. TODO: figure out why this happens at all!
+ gui()->repaint();
+
+ m_updatesFetched = false;
+ m_allPackagesFetched = false;
+}
+
+// -- private
+
+void IntroductionPageImpl::entering()
+{
+ setComplete(true);
+ showWidgets(false);
+ setMessage(QString());
+ setErrorMessage(QString());
+ setButtonText(QWizard::CancelButton, tr("Quit"));
+
+ PackageManagerCore *core = packageManagerCore();
+ if (core->isUninstaller() ||core->isUpdater() || core->isPackageManager()) {
+ showMaintenanceTools();
+ setMaintenanceToolsEnabled(true);
+ }
+}
+
+void IntroductionPageImpl::leaving()
+{
+ // TODO: force repaint on next page, keeps unpainted after fetch
+ QTimer::singleShot(100, gui()->page(nextId()), SLOT(repaint()));
+ setButtonText(QWizard::CancelButton, gui()->defaultButtonText(QWizard::CancelButton));
+}
+
+void IntroductionPageImpl::showWidgets(bool show)
+{
+ m_label->setVisible(show);
+ m_progressBar->setVisible(show);
+ m_packageManager->setVisible(show);
+ m_updateComponents->setVisible(show);
+ m_removeAllComponents->setVisible(show);
+}
+
+
+// -- TargetDirectoryPageImpl
+
+/*!
+ A custom target directory selection based due to the no-space restriction...
+*/
+TargetDirectoryPageImpl::TargetDirectoryPageImpl(PackageManagerCore *core)
+ : TargetDirectoryPage(core)
+{
+ QPalette palette;
+ palette.setColor(QPalette::WindowText, Qt::red);
+
+ m_warningLabel = new QLabel(this);
+ m_warningLabel->setPalette(palette);
+
+ insertWidget(m_warningLabel, QLatin1String("MessageLabel"), 2);
+}
+
+QString TargetDirectoryPageImpl::targetDirWarning() const
+{
+ if (targetDir().isEmpty()) {
+ return TargetDirectoryPageImpl::tr("The installation path cannot be empty, please specify a valid "
+ "folder.");
+ }
+
+ if (QDir(targetDir()).isRelative()) {
+ return TargetDirectoryPageImpl::tr("The installation path cannot be relative, please specify an "
+ "absolute path.");
+ }
+
+ QString dir = targetDir();
+#ifdef Q_OS_WIN
+ // remove e.g. "c:"
+ dir = dir.mid(2);
+#endif
+ // check if there are not allowed characters in the target path
+ if (dir.contains(QRegExp(QLatin1String("[!@#$%^&*: ,;]")))) {
+ return TargetDirectoryPageImpl::tr("The installation path must not contain !@#$%^&*:,; or spaces, "
+ "please specify a valid folder.");
+ }
+
+ return QString();
+}
+
+bool TargetDirectoryPageImpl::isComplete() const
+{
+ m_warningLabel->setText(targetDirWarning());
+ return m_warningLabel->text().isEmpty();
+}
+
+bool TargetDirectoryPageImpl::askQuestion(const QString &identifier, const QString &message)
+{
+ QMessageBox::StandardButton bt =
+ MessageBoxHandler::warning(MessageBoxHandler::currentBestSuitParent(), identifier,
+ TargetDirectoryPageImpl::tr("Warning"), message, QMessageBox::Yes | QMessageBox::No);
+ QTimer::singleShot(100, wizard()->page(nextId()), SLOT(repaint()));
+
+ return bt == QMessageBox::Yes;
+}
+
+bool TargetDirectoryPageImpl::failWithError(const QString &identifier, const QString &message)
+{
+ MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(), identifier,
+ TargetDirectoryPageImpl::tr("Error"), message);
+ QTimer::singleShot(100, wizard()->page(nextId()), SLOT(repaint()));
+
+ return false;
+}
+
+bool TargetDirectoryPageImpl::validatePage()
+{
+ if (!isVisible())
+ return true;
+
+ const QString remove = packageManagerCore()->value(QLatin1String("RemoveTargetDir"));
+ if (!QVariant(remove).toBool())
+ return true;
+
+ const QString targetDir = this->targetDir();
+ if (!packageManagerCore()->settings().allowNonAsciiCharacters()) {
+ for (int i = 0; i < targetDir.length(); ++i) {
+ if (targetDir.at(i).unicode() & 0xff80) {
+ return failWithError(QLatin1String("NonAsciiTarget"), tr("The path or installation directory "
+ "contains non ASCII characters. This is currently not supported! Please choose a different "
+ "path or installation directory."));
+ }
+ }
+ }
+
+ const QDir dir(targetDir);
+ // the directory exists and is empty...
+ if (dir.exists() && dir.entryList(QDir::AllEntries | QDir::NoDotAndDotDot).isEmpty())
+ return true;
+
+ const QFileInfo fi(targetDir);
+ if (fi.isDir()) {
+ if (dir == QDir::root() || dir == QDir::home()) {
+ return failWithError(QLatin1String("ForbiddenTargetDirectory"), tr("As the install directory "
+ "is completely deleted installing in %1 is forbidden.").arg(QDir::rootPath()));
+ }
+
+ QString fileName = packageManagerCore()->settings().uninstallerName();
+#if defined(Q_OS_MAC)
+ if (QFileInfo(QCoreApplication::applicationDirPath() + QLatin1String("/../..")).isBundle())
+ fileName += QLatin1String(".app/Contents/MacOS/") + fileName;
+#elif defined(Q_OS_WIN)
+ fileName += QLatin1String(".exe");
+#endif
+
+ QFileInfo fi2(targetDir + QDir::separator() + fileName);
+ if (fi2.exists()) {
+ return askQuestion(QLatin1String("OverwriteTargetDirectory"),
+ TargetDirectoryPageImpl::tr("The folder you selected exists already and contains an "
+ "installation.\nDo you want to overwrite it?"));
+ }
+
+ return askQuestion(QLatin1String("OverwriteTargetDirectory"),
+ tr("You have selected an existing, non-empty folder for installation.\nNote that it will be "
+ "completely wiped on uninstallation of this application.\nIt is not advisable to install into "
+ "this folder as installation might fail.\nDo you want to continue?"));
+ } else if (fi.isFile() || fi.isSymLink()) {
+ return failWithError(QLatin1String("WrongTargetDirectory"), tr("You have selected an existing file "
+ "or symlink, please choose a different target for installation."));
+ }
+ return true;
+}
+
+
+// -- InstallerGui
+
+InstallerGui::InstallerGui(PackageManagerCore *core)
+ : PackageManagerGui(core, 0)
+{
+ setPage(PackageManagerCore::Introduction, new IntroductionPageImpl(core));
+ setPage(PackageManagerCore::TargetDirectory, new TargetDirectoryPageImpl(core));
+ setPage(PackageManagerCore::ComponentSelection, new ComponentSelectionPage(core));
+ setPage(PackageManagerCore::LicenseCheck, new LicenseAgreementPage(core));
+#ifdef Q_OS_WIN
+ setPage(PackageManagerCore::StartMenuSelection, new StartMenuDirectoryPage(core));
+#endif
+ setPage(PackageManagerCore::ReadyForInstallation, new ReadyForInstallationPage(core));
+ setPage(PackageManagerCore::PerformInstallation, new PerformInstallationPage(core));
+ setPage(PackageManagerCore::InstallationFinished, new FinishedPage(core));
+
+ bool ok = false;
+ const int startPage = core->value(QLatin1String("GuiStartPage")).toInt(&ok);
+ if (ok)
+ setStartId(startPage);
+}
+
+void InstallerGui::init()
+{
+}
+
+int InstallerGui::nextId() const
+{
+ const int next = QWizard::nextId();
+ if (next == PackageManagerCore::LicenseCheck) {
+ PackageManagerCore *const core = packageManagerCore();
+ const int nextNextId = pageIds().value(pageIds().indexOf(next)+ 1, -1);
+ if (!core->isInstaller())
+ return nextNextId;
+
+ core->calculateComponentsToInstall();
+ foreach (Component* component, core->orderedComponentsToInstall()) {
+ if (!component->licenses().isEmpty())
+ return next;
+ }
+ return nextNextId;
+ }
+ return next;
+}
+
+
+// -- MaintenanceGui
+
+MaintenanceGui::MaintenanceGui(PackageManagerCore *core)
+ : PackageManagerGui(core, 0)
+{
+ IntroductionPageImpl *intro = new IntroductionPageImpl(core);
+ connect(intro, SIGNAL(packageManagerCoreTypeChanged()), this, SLOT(updateRestartPage()));
+
+ setPage(PackageManagerCore::Introduction, intro);
+ setPage(PackageManagerCore::ComponentSelection, new ComponentSelectionPage(core));
+ setPage(PackageManagerCore::LicenseCheck, new LicenseAgreementPage(core));
+ setPage(PackageManagerCore::ReadyForInstallation, new ReadyForInstallationPage(core));
+ setPage(PackageManagerCore::PerformInstallation, new PerformInstallationPage(core));
+ setPage(PackageManagerCore::InstallationFinished, new FinishedPage(core));
+
+ RestartPage *p = new RestartPage(core);
+ connect(p, SIGNAL(restart()), this, SIGNAL(gotRestarted()));
+ setPage(PackageManagerCore::InstallationFinished + 1, p);
+
+ if (core->isUninstaller())
+ wizardPageVisibilityChangeRequested(false, PackageManagerCore::InstallationFinished + 1);
+}
+
+void MaintenanceGui::init()
+{
+}
+
+int MaintenanceGui::nextId() const
+{
+ const int next = QWizard::nextId();
+ if (next == PackageManagerCore::LicenseCheck) {
+ PackageManagerCore *const core = packageManagerCore();
+ const int nextNextId = pageIds().value(pageIds().indexOf(next)+ 1, -1);
+ if (!core->isPackageManager() && !core->isUpdater())
+ return nextNextId;
+
+ core->calculateComponentsToInstall();
+ foreach (Component* component, core->orderedComponentsToInstall()) {
+ if (component->isInstalled())
+ continue;
+ if (!component->licenses().isEmpty())
+ return next;
+ }
+ return nextNextId;
+ }
+ return next;
+}
+
+void MaintenanceGui::updateRestartPage()
+{
+ wizardPageVisibilityChangeRequested((packageManagerCore()->isUninstaller() ? false : true),
+ PackageManagerCore::InstallationFinished + 1);
+}
diff --git a/src/s40/installerbasecommons.h b/src/s40/installerbasecommons.h
new file mode 100644
index 000000000..f0f0c3d95
--- /dev/null
+++ b/src/s40/installerbasecommons.h
@@ -0,0 +1,147 @@
+/**************************************************************************
+**
+** This file is part of Installer Framework
+**
+** Copyright (c) 2010-2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#ifndef INSTALLERBASECOMMONS_H
+#define INSTALLERBASECOMMONS_H
+
+#include <packagemanagergui.h>
+
+QT_BEGIN_NAMESPACE
+class QLabel;
+class QString;
+class QProgressBar;
+QT_END_NAMESPACE
+
+
+// -- IntroductionPageImpl
+
+class IntroductionPageImpl : public QInstaller::IntroductionPage
+{
+ Q_OBJECT
+
+public:
+ explicit IntroductionPageImpl(QInstaller::PackageManagerCore *core);
+
+ int nextId() const;
+ bool validatePage();
+
+ void showAll();
+ void hideAll();
+ void showMetaInfoUdate();
+ void showMaintenanceTools();
+ void setMaintenanceToolsEnabled(bool enable);
+
+public Q_SLOTS:
+ void onCoreNetworkSettingsChanged();
+ void setMessage(const QString &msg);
+ void setErrorMessage(const QString &error);
+
+Q_SIGNALS:
+ void packageManagerCoreTypeChanged();
+
+private Q_SLOTS:
+ void setUpdater(bool value);
+ void setUninstaller(bool value);
+ void setPackageManager(bool value);
+
+private:
+ void entering();
+ void leaving();
+
+ void showWidgets(bool show);
+ void callControlScript(const QString &callback);
+
+private:
+ bool m_updatesFetched;
+ bool m_updatesCompleted;
+ bool m_allPackagesFetched;
+
+ QLabel *m_label;
+ QLabel *m_errorLabel;
+ QProgressBar *m_progressBar;
+ QRadioButton *m_packageManager;
+ QRadioButton *m_updateComponents;
+ QRadioButton *m_removeAllComponents;
+};
+
+
+// --TargetDirectoryPageImpl
+
+class TargetDirectoryPageImpl : public QInstaller::TargetDirectoryPage
+{
+ Q_OBJECT
+
+public:
+ explicit TargetDirectoryPageImpl(QInstaller::PackageManagerCore *core);
+
+ QString targetDirWarning() const;
+ bool isComplete() const;
+ bool askQuestion(const QString &identifier, const QString &message);
+ bool failWithError(const QString &identifier, const QString &message);
+ bool validatePage();
+
+private:
+ QLabel *m_warningLabel;
+};
+
+
+// -- InstallerGui
+
+class InstallerGui : public QInstaller::PackageManagerGui
+{
+ Q_OBJECT
+
+public:
+ explicit InstallerGui(QInstaller::PackageManagerCore *core);
+
+ virtual void init();
+ virtual int nextId() const;
+};
+
+
+// -- MaintenanceGui
+
+class MaintenanceGui : public QInstaller::PackageManagerGui
+{
+ Q_OBJECT
+
+public:
+ explicit MaintenanceGui(QInstaller::PackageManagerCore *core);
+
+ virtual void init();
+ virtual int nextId() const;
+
+private Q_SLOTS:
+ void updateRestartPage();
+};
+
+#endif // INSTALLERBASECOMMONS_H
diff --git a/src/s40/s40.pro b/src/s40/s40.pro
new file mode 100644
index 000000000..0f85fbc7f
--- /dev/null
+++ b/src/s40/s40.pro
@@ -0,0 +1,105 @@
+TEMPLATE = app
+DEPENDPATH += . .. ../sdk
+INCLUDEPATH += . .. ../sdk
+TARGET = installerbase
+
+include(../../installerfw.pri)
+
+QT += network script
+
+CONFIG -= app_bundle
+DESTDIR = $$IFW_APP_PATH
+
+if (exists($$LRELEASE)) {
+ QT_LANGUAGES = qt_de
+ IB_LANGUAGES = de_de en_us
+ defineReplace(prependAll) {
+ for(a,$$1):result += $$2$${a}$$3
+ return($$result)
+ }
+
+ defineTest(testFiles) {
+ for(file, $$1) {
+ !exists($$file):return(false)
+ }
+ return(true)
+ }
+
+ SUCCESS = false
+ IB_TRANSLATIONS = $$prependAll(IB_LANGUAGES, $$PWD/translations/,.ts)
+ QT_TRANSLATIONS = $$prependAll(QT_LANGUAGES, $$[QT_INSTALL_TRANSLATIONS]/,.ts)
+
+ if (!testFiles(QT_TRANSLATIONS)) {
+ QT_COMPILED_TRANSLATIONS = $$prependAll(QT_LANGUAGES, $$[QT_INSTALL_TRANSLATIONS]/,.qm)
+ if (testFiles(QT_COMPILED_TRANSLATIONS)) {
+ SUCCESS = true
+ copyqm.input = QT_COMPILED_TRANSLATIONS
+ copyqm.output = $$PWD/translations/${QMAKE_FILE_BASE}.qm
+ unix:copyqm.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
+ win32:copyqm.commands = $$QMAKE_COPY \"${QMAKE_FILE_IN}\" \"${QMAKE_FILE_OUT}\"
+ copyqm.name = COPY ${QMAKE_FILE_IN}
+ copyqm.CONFIG += no_link target_predeps
+ QMAKE_EXTRA_COMPILERS += copyqm
+ }
+ } else {
+ SUCCESS = true
+ IB_TRANSLATIONS += $$QT_TRANSLATIONS
+ }
+
+ if (contains(SUCCESS, true)) {
+ updateqm.input = IB_TRANSLATIONS
+ updateqm.output = $$PWD/translations/${QMAKE_FILE_BASE}.qm
+ updateqm.commands = $$LRELEASE ${QMAKE_FILE_IN} -qm ${QMAKE_FILE_OUT}
+ updateqm.name = LRELEASE ${QMAKE_FILE_IN}
+ updateqm.CONFIG += no_link target_predeps
+ QMAKE_EXTRA_COMPILERS += updateqm
+
+ if (exists($$RCC)) {
+ RESOURCE_IB_TRANSLATIONS = $$prependAll(IB_LANGUAGES, $$PWD/translations/,.qm)
+ RESOURCE_QT_TRANSLATIONS = $$prependAll(QT_LANGUAGES, $$PWD/translations/,.qm)
+ RESOURCE = $$PWD/installerbase.qrc
+ runrcc.input = RESOURCE
+ runrcc.output = $$PWD/qrc_installerbase.cpp
+ runrcc.commands = $$RCC -name ${QMAKE_FILE_BASE} ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
+ runrcc.name = RCC ${QMAKE_FILE_IN}
+ runrcc.CONFIG += no_link explicit_dependencies
+ runrcc.depends = $$RESOURCE_IB_TRANSLATIONS $$RESOURCE_QT_TRANSLATIONS
+ runrcc.variable_out = SOURCES
+ QMAKE_EXTRA_COMPILERS += runrcc
+ }
+ }
+}
+
+# the following stuff get's shared with the original installer base
+
+HEADERS_SHARED = ../sdk/installerbase_p.h \
+ ../sdk/tabcontroller.h \
+ ../sdk/settingsdialog.h \
+
+SOURCE_SHARED = ../sdk/installerbase.cpp \
+ ../sdk/installerbase_p.cpp \
+ ../sdk/tabcontroller.cpp \
+ ../sdk/settingsdialog.cpp
+
+FORMS += ../sdk/settingsdialog.ui
+
+# things specifically for s40
+
+HEADERS += $$HEADERS_SHARED \
+ installerbasecommons.h \
+ componentviewpage.h
+
+SOURCES = $$SOURCE_SHARED \
+ installerbasecommons.cpp \
+ componentviewpage.cpp
+
+win32:RC_FILE = ../sdk/installerbase.rc
+win32-msvc2005 {
+ CONFIG += embed_manifest_exe #msvc2008 is doing this automatically
+}
+
+embed_manifest_exe:win32-msvc2005 {
+ # The default configuration embed_manifest_exe overrides the manifest file
+ # already embedded via RC_FILE. Vs2008 already have the necessary manifest entry
+ QMAKE_POST_LINK += $$quote(mt.exe -updateresource:$$IFW_APP_PATH/$${TARGET}.exe -manifest \"$${IFW_SOURCE_TREE}\\src\\s40\\$${TARGET}.exe.manifest\")
+}
diff --git a/src/src.pro b/src/src.pro
index 92ee0cf9b..828b364f9 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -1,4 +1,4 @@
CONFIG += ordered
TEMPLATE = subdirs
-SUBDIRS += libs sdk
+SUBDIRS += libs s40
TRANSLATIONS += sdk/translations/de_de.ts sdk/translations/en_us.ts