Commit 9d712dee authored by ck's avatar ck
Browse files

Maemo: Let user choose package manager icon.

Reviewed-by: kh1
parent e8666322
......@@ -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());
......
......@@ -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;
......
......@@ -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>&lt;b&gt;Package Manager Icon:&lt;/b&gt;</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>
......@@ -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);
......
......@@ -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
......@@ -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;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment