diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationwidget.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationwidget.cpp index 87a6446132e4ce2bcea617303274205d29257c33..1866ab599dac7316d86095aaccf7dfbd8bc748ee 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationwidget.cpp +++ b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationwidget.cpp @@ -52,6 +52,8 @@ #include <utils/qtcassert.h> #include <QtCore/QTimer> +#include <QtGui/QFileDialog> +#include <QtGui/QImageReader> #include <QtGui/QMessageBox> namespace Qt4ProjectManager { @@ -78,6 +80,7 @@ void MaemoPackageCreationWidget::initGui() = m_step->buildConfiguration()->target()->project(); updateDebianFileList(project); updateVersionInfo(project); + updatePackageManagerIcon(project); connect(m_step, SIGNAL(packageFilePathChanged()), this, SIGNAL(updateSummary())); versionInfoChanged(); @@ -87,6 +90,9 @@ void MaemoPackageCreationWidget::initGui() connect(MaemoTemplatesManager::instance(), SIGNAL(changeLogChanged(const ProjectExplorer::Project*)), this, SLOT(updateVersionInfo(const ProjectExplorer::Project*))); + connect(MaemoTemplatesManager::instance(), + SIGNAL(controlChanged(const ProjectExplorer::Project*)), this, + SLOT(updatePackageManagerIcon(const ProjectExplorer::Project*))); } void MaemoPackageCreationWidget::updateDebianFileList(const ProjectExplorer::Project *project) @@ -121,6 +127,37 @@ void MaemoPackageCreationWidget::updateVersionInfo(const ProjectExplorer::Projec m_ui->patch->setValue(list.value(2, QLatin1String("0")).toInt()); } +void MaemoPackageCreationWidget::updatePackageManagerIcon(const ProjectExplorer::Project *project) +{ + if (project != m_step->buildConfiguration()->target()->project()) + return; + + QString error; + const QIcon &icon + = MaemoTemplatesManager::instance()->packageManagerIcon(project, &error); + if (!error.isEmpty()) + QMessageBox::critical(this, tr("Could not read icon"), error); + else + m_ui->packageManagerIconButton->setIcon(icon); +} + +void MaemoPackageCreationWidget::setPackageManagerIcon() +{ + QString imageFilter = tr("Images") + QLatin1String("( "); + const QList<QByteArray> &imageTypes = QImageReader::supportedImageFormats(); + foreach (const QByteArray &imageType, imageTypes) + imageFilter += "*." + QString::fromAscii(imageType) + QLatin1Char(' '); + imageFilter += QLatin1Char(')'); + const QString iconFileName = QFileDialog::getOpenFileName(this, + tr("Choose image"), QString(), imageFilter); + if (!iconFileName.isEmpty()) { + QString error; + if (!MaemoTemplatesManager::instance()->setPackageManagerIcon(m_step-> + buildConfiguration()->target()->project(), iconFileName, &error)) + QMessageBox::critical(this, tr("Could not set new icon"), error); + } +} + QString MaemoPackageCreationWidget::summaryText() const { return tr("<b>Create Package:</b> ") + QDir::toNativeSeparators(m_step->packageFilePath()); diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationwidget.h b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationwidget.h index cbdd3db260f545de1a26ddfaa30e96835502b571..c77be47917917361a83cc7bb6aa9eb38d4da347c 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationwidget.h +++ b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationwidget.h @@ -70,6 +70,8 @@ private slots: void initGui(); void updateDebianFileList(const ProjectExplorer::Project *project); void updateVersionInfo(const ProjectExplorer::Project *project); + void updatePackageManagerIcon(const ProjectExplorer::Project *project); + void setPackageManagerIcon(); private: MaemoPackageCreationStep * const m_step; diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationwidget.ui b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationwidget.ui index 0fe29d8e8c7b0b74020f74128f5aba635e6b8916..f4a16ed39bc6495b13180e4e427841f5aead0c2f 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationwidget.ui +++ b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationwidget.ui @@ -6,8 +6,8 @@ <rect> <x>0</x> <y>0</y> - <width>453</width> - <height>116</height> + <width>471</width> + <height>162</height> </rect> </property> <property name="sizePolicy"> @@ -42,9 +42,6 @@ </item> <item> <layout class="QFormLayout" name="formLayout"> - <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> - </property> <item row="0" column="0"> <widget class="QLabel" name="label"> <property name="sizePolicy"> @@ -193,6 +190,37 @@ </item> </layout> </item> + <item row="2" column="0"> + <widget class="QLabel" name="packageManagerIconLabel"> + <property name="text"> + <string><b>Package Manager Icon:</b></string> + </property> + </widget> + </item> + <item row="2" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <widget class="QToolButton" name="packageManagerIconButton"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> </layout> </item> </layout> @@ -279,6 +307,22 @@ </hint> </hints> </connection> + <connection> + <sender>packageManagerIconButton</sender> + <signal>clicked()</signal> + <receiver>MaemoPackageCreationWidget</receiver> + <slot>setPackageManagerIcon()</slot> + <hints> + <hint type="sourcelabel"> + <x>196</x> + <y>136</y> + </hint> + <hint type="destinationlabel"> + <x>2</x> + <y>143</y> + </hint> + </hints> + </connection> </connections> <slots> <slot>addFile()</slot> @@ -286,5 +330,6 @@ <slot>handleSkipButtonToggled(bool)</slot> <slot>versionInfoChanged()</slot> <slot>editDebianFile()</slot> + <slot>setPackageManagerIcon()</slot> </slots> </ui> diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemorunconfigurationwidget.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemorunconfigurationwidget.cpp index b9ce46e288b9d14303dcfb779731976a9dbf2b77..c3f4acdd1d1690dcd121e407a49bcbf19539afc0 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemorunconfigurationwidget.cpp +++ b/src/plugins/qt4projectmanager/qt-maemo/maemorunconfigurationwidget.cpp @@ -109,8 +109,7 @@ void MaemoRunConfigurationWidget::addGenericWidgets(QVBoxLayout *mainLayout) m_localExecutableLabel = new QLabel(m_runConfiguration->localExecutableFilePath()); formLayout->addRow(tr("Executable on host:"), m_localExecutableLabel); - m_remoteExecutableLabel - = new QLabel(m_runConfiguration->remoteExecutableFilePath()); + m_remoteExecutableLabel = new QLabel; formLayout->addRow(tr("Executable on device:"), m_remoteExecutableLabel); m_argsLineEdit = new QLineEdit(m_runConfiguration->arguments().join(" ")); formLayout->addRow(tr("Arguments:"), m_argsLineEdit); diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemotemplatesmanager.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemotemplatesmanager.cpp index 410b62d4e02878259bd7ac4a72cd49932ed3734f..939a75fda2f2f44d89ebd992a575884fd301c012 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemotemplatesmanager.cpp +++ b/src/plugins/qt4projectmanager/qt-maemo/maemotemplatesmanager.cpp @@ -41,18 +41,25 @@ #include <qt4projectmanager/qt4projectmanagerconstants.h> #include <qt4projectmanager/qt4target.h> +#include <QtCore/QBuffer> #include <QtCore/QDir> -#include <QtCore/QFile> #include <QtCore/QFileSystemWatcher> #include <QtCore/QList> +#include <QtGui/QPixmap> #include <QtCore/QProcess> #include <QtGui/QMessageBox> +#include <cctype> + using namespace ProjectExplorer; namespace Qt4ProjectManager { namespace Internal { +namespace { +const QByteArray IconFieldName("XB-Maemo-Icon-26:"); +} // anonymous namespace + const QLatin1String MaemoTemplatesManager::PackagingDirName("packaging"); MaemoTemplatesManager *MaemoTemplatesManager::m_instance = 0; @@ -92,16 +99,16 @@ void MaemoTemplatesManager::handleActiveProjectChanged(ProjectExplorer::Project foreach (Target * const target, targets) createTemplatesIfNecessary(target); m_fsWatcher = new QFileSystemWatcher(this); - const QString &debianPath = debianDirPath(m_activeProject); - const QString changeLogPath = debianPath + QLatin1String("/changelog"); - m_fsWatcher->addPath(debianPath); - m_fsWatcher->addPath(changeLogPath); + m_fsWatcher->addPath(debianDirPath(m_activeProject)); + m_fsWatcher->addPath(changeLogFilePath(m_activeProject)); + m_fsWatcher->addPath(controlFilePath(m_activeProject)); connect(m_fsWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(handleDebianDirContentsChanged())); connect(m_fsWatcher, SIGNAL(fileChanged(QString)), this, - SLOT(handleChangeLogChanged())); + SLOT(handleDebianFileChanged(QString))); handleDebianDirContentsChanged(); - handleChangeLogChanged(); + handleDebianFileChanged(changeLogFilePath(m_activeProject)); + handleDebianFileChanged(controlFilePath(m_activeProject)); } } @@ -201,30 +208,21 @@ void MaemoTemplatesManager::createTemplatesIfNecessary(ProjectExplorer::Target * QString MaemoTemplatesManager::version(const Project *project, QString *error) const { - const QString changeLogFilePath - = debianDirPath(project) + QLatin1String("/changelog"); - const QString nativePath = QDir::toNativeSeparators(changeLogFilePath); - QFile changeLog(changeLogFilePath); - if (!changeLog.exists()) { - *error = tr("File '%1' does not exist").arg(nativePath); + QSharedPointer<QFile> changeLog + = openFile(changeLogFilePath(project), QIODevice::ReadOnly, error); + if (!changeLog) return QString(); - } - if (!changeLog.open(QIODevice::ReadOnly)) { - *error = tr("Cannot open Debian changelog file '%1': %2") - .arg(nativePath, changeLog.errorString()); - return QString(); - } - const QByteArray &firstLine = changeLog.readLine(); + const QByteArray &firstLine = changeLog->readLine(); const int openParenPos = firstLine.indexOf('('); if (openParenPos == -1) { *error = tr("Debian changelog file '%1' has unexpected format.") - .arg(nativePath); + .arg(QDir::toNativeSeparators(changeLog->fileName())); return QString(); } const int closeParenPos = firstLine.indexOf(')', openParenPos); if (closeParenPos == -1) { *error = tr("Debian changelog file '%1' has unexpected format.") - .arg(nativePath); + .arg(QDir::toNativeSeparators(changeLog->fileName())); return QString(); } return QString::fromUtf8(firstLine.mid(openParenPos + 1, @@ -234,29 +232,118 @@ QString MaemoTemplatesManager::version(const Project *project, bool MaemoTemplatesManager::setVersion(const Project *project, const QString &version, QString *error) const { - const QString changeLogFilePath - = debianDirPath(project) + QLatin1String("/changelog"); - const QString nativePath = QDir::toNativeSeparators(changeLogFilePath); - QFile changeLog(changeLogFilePath); - if (!changeLog.exists()) { - *error = tr("File '%1' does not exist").arg(nativePath); - return false; - } - if (!changeLog.open(QIODevice::ReadWrite)) { - *error = tr("Cannot open Debian changelog file '%1': %2") - .arg(nativePath , changeLog.errorString()); + QSharedPointer<QFile> changeLog + = openFile(changeLogFilePath(project), QIODevice::ReadWrite, error); + if (!changeLog) return false; - } - QString content = QString::fromUtf8(changeLog.readAll()); + QString content = QString::fromUtf8(changeLog->readAll()); content.replace(QRegExp(QLatin1String("\\([a-zA-Z0-9_\\.]+\\)")), QLatin1Char('(') + version + QLatin1Char(')')); - changeLog.resize(0); - changeLog.write(content.toUtf8()); - changeLog.close(); - if (changeLog.error() != QFile::NoError) { + changeLog->resize(0); + changeLog->write(content.toUtf8()); + changeLog->close(); + if (changeLog->error() != QFile::NoError) { *error = tr("Error writing Debian changelog file '%1': %2") - .arg(nativePath , changeLog.errorString()); + .arg(QDir::toNativeSeparators(changeLog->fileName()), + changeLog->errorString()); + return false; + } + return true; +} + +QIcon MaemoTemplatesManager::packageManagerIcon(const Project *project, + QString *error) const +{ + QSharedPointer<QFile> controlFile + = openFile(controlFilePath(project), QIODevice::ReadOnly, error); + if (!controlFile) + return QIcon(); + + bool iconFieldFound = false; + QByteArray currentLine; + while (!iconFieldFound && !controlFile->atEnd()) { + currentLine = controlFile->readLine(); + iconFieldFound = currentLine.startsWith(IconFieldName); + } + if (!iconFieldFound) + return QIcon(); + + int pos = IconFieldName.length(); + currentLine = currentLine.trimmed(); + QByteArray base64Icon; + do { + while (pos < currentLine.length()) + base64Icon += currentLine.at(pos++); + do + currentLine = controlFile->readLine(); + while (currentLine.startsWith('#')); + if (currentLine.isEmpty() || !isspace(currentLine.at(0))) + break; + currentLine = currentLine.trimmed(); + if (currentLine.isEmpty()) + break; + pos = 0; + } while (true); + QPixmap pixmap; + if (!pixmap.loadFromData(QByteArray::fromBase64(base64Icon))) { + *error = tr("Invalid icon data in Debian control file."); + return QIcon(); + } + return QIcon(pixmap); +} + +bool MaemoTemplatesManager::setPackageManagerIcon(const Project *project, + const QString &iconFilePath, QString *error) const +{ + const QSharedPointer<QFile> controlFile + = openFile(controlFilePath(project), QIODevice::ReadWrite, error); + if (!controlFile) + return false; + const QPixmap pixmap(iconFilePath); + if (pixmap.isNull()) { + *error = tr("Could not read image file '%1'.").arg(iconFilePath); + return false; + } + + QByteArray iconAsBase64; + QBuffer buffer(&iconAsBase64); + buffer.open(QIODevice::WriteOnly); + if (!pixmap.scaled(48, 48).save(&buffer, + QFileInfo(iconFilePath).suffix().toAscii())) { + *error = tr("Could not export image file '%1'.").arg(iconFilePath); + return false; + } + buffer.close(); + iconAsBase64 = iconAsBase64.toBase64(); + QByteArray contents = controlFile->readAll(); + const int iconFieldPos = contents.startsWith(IconFieldName) + ? 0 : contents.indexOf('\n' + IconFieldName); + if (iconFieldPos == -1) { + if (!contents.endsWith('\n')) + contents += '\n'; + contents.append(IconFieldName).append(' ').append(iconAsBase64) + .append('\n'); + } else { + const int oldIconStartPos + = (iconFieldPos != 0) + iconFieldPos + IconFieldName.length(); + int nextEolPos = contents.indexOf('\n', oldIconStartPos); + while (nextEolPos != -1 && nextEolPos != contents.length() - 1 + && contents.at(nextEolPos + 1) != '\n' + && (contents.at(nextEolPos + 1) == '#' + || std::isspace(contents.at(nextEolPos + 1)))) + nextEolPos = contents.indexOf('\n', nextEolPos + 1); + if (nextEolPos == -1) + nextEolPos = contents.length(); + contents.replace(oldIconStartPos, nextEolPos - oldIconStartPos, + ' ' + iconAsBase64); + } + controlFile->resize(0); + controlFile->write(contents); + if (controlFile->error() != QFile::NoError) { + *error = tr("Error writing file '%1': %2") + .arg(QDir::toNativeSeparators(controlFile->fileName()), + controlFile->errorString()); return false; } return true; @@ -274,14 +361,27 @@ QString MaemoTemplatesManager::debianDirPath(const Project *project) const + PackagingDirName + QLatin1String("/debian"); } +QString MaemoTemplatesManager::changeLogFilePath(const Project *project) const +{ + return debianDirPath(project) + QLatin1String("/changelog"); +} + +QString MaemoTemplatesManager::controlFilePath(const Project *project) const +{ + return debianDirPath(project) + QLatin1String("/control"); +} + void MaemoTemplatesManager::raiseError(const QString &reason) { QMessageBox::critical(0, tr("Error creating Maemo templates"), reason); } -void MaemoTemplatesManager::handleChangeLogChanged() +void MaemoTemplatesManager::handleDebianFileChanged(const QString &filePath) { - emit changeLogChanged(m_activeProject); + if (filePath == changeLogFilePath(m_activeProject)) + emit changeLogChanged(m_activeProject); + else if (filePath == controlFilePath(m_activeProject)) + emit controlChanged(m_activeProject); } void MaemoTemplatesManager::handleDebianDirContentsChanged() @@ -289,5 +389,19 @@ void MaemoTemplatesManager::handleDebianDirContentsChanged() emit debianDirContentsChanged(m_activeProject); } +QSharedPointer<QFile> MaemoTemplatesManager::openFile(const QString &filePath, + QIODevice::OpenMode mode, QString *error) const +{ + const QString nativePath = QDir::toNativeSeparators(filePath); + QSharedPointer<QFile> file(new QFile(filePath)); + if (!file->exists()) { + *error = tr("File '%1' does not exist").arg(nativePath); + } else if (!file->open(mode)) { + *error = tr("Cannot open file '%1': %2") + .arg(nativePath, file->errorString()); + } + return file; +} + } // namespace Internal } // namespace Qt4ProjectManager diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemotemplatesmanager.h b/src/plugins/qt4projectmanager/qt-maemo/maemotemplatesmanager.h index ffc356c9378bbae7888188fcedc7f0becc1d4a21..76cfda36d79800253f9dde79c9601f1dd2dd2f67 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemotemplatesmanager.h +++ b/src/plugins/qt4projectmanager/qt-maemo/maemotemplatesmanager.h @@ -30,7 +30,10 @@ #ifndef MAEMOTEMPLATESCREATOR_H #define MAEMOTEMPLATESCREATOR_H +#include <QtCore/QFile> #include <QtCore/QObject> +#include <QtCore/QSharedPointer> +#include <QtGui/QIcon> QT_FORWARD_DECLARE_CLASS(QFileSystemWatcher); @@ -57,21 +60,32 @@ public: QString debianDirPath(const ProjectExplorer::Project *project) const; QStringList debianFiles(const ProjectExplorer::Project *project) const; + QIcon packageManagerIcon(const ProjectExplorer::Project *project, + QString *error) const; + bool setPackageManagerIcon(const ProjectExplorer::Project *project, + const QString &iconFilePath, QString *error) const; + static const QLatin1String PackagingDirName; signals: void debianDirContentsChanged(const ProjectExplorer::Project *project); void changeLogChanged(const ProjectExplorer::Project *project); + void controlChanged(const ProjectExplorer::Project *project); private slots: void handleActiveProjectChanged(ProjectExplorer::Project *project); void createTemplatesIfNecessary(ProjectExplorer::Target *target); void handleDebianDirContentsChanged(); - void handleChangeLogChanged(); + void handleDebianFileChanged(const QString &filePath); private: explicit MaemoTemplatesManager(QObject *parent); void raiseError(const QString &reason); + QString changeLogFilePath(const ProjectExplorer::Project *project) const; + QString controlFilePath(const ProjectExplorer::Project *project) const; + + QSharedPointer<QFile> openFile(const QString &filePath, + QIODevice::OpenMode mode, QString *error) const; static MaemoTemplatesManager *m_instance; ProjectExplorer::Project *m_activeProject;