Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Tobias Hunger
qt-creator
Commits
f96efa07
Commit
f96efa07
authored
Jun 16, 2010
by
ck
Browse files
Maemo: Use project file's INSTALLS variable for packaging.
parent
72bd632c
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/plugins/qt4projectmanager/qt-maemo/maemopackagecontents.cpp
View file @
f96efa07
...
...
@@ -32,22 +32,31 @@
#include
"maemopackagecreationstep.h"
#include
"maemotoolchain.h"
#include
<qt4projectmanager/profilereader.h>
#include
<qt4projectmanager/qt4buildconfiguration.h>
#include
<qt4projectmanager/qt4project.h>
#include
<qt4projectmanager/qt4target.h>
#include
<QtCore/QDir>
#include
<profile.h>
#include
<prowriter.h>
#include
<QtCore/QCryptographicHash>
#include
<QtCore/QFile>
#include
<QtCore/QFileInfo>
namespace
{
const
char
*
const
MODIFIED_KEY
=
"Qt4ProjectManager.BuildStep.MaemoPackage.Modified"
;
const
char
*
const
REMOTE_EXE_DIR_KEY
=
"Qt4ProjectManager.BuildStep.MaemoPackage.RemoteExeDir"
;
const
char
*
const
LOCAL_FILES_KEY
=
"Qt4ProjectManager.BuildStep.MaemoPackage.LocalFiles"
;
const
char
*
const
REMOTE_DIRS_KEY
=
"Qt4ProjectManager.BuildStep.MaemoPackage.RemoteDirs"
;
QString
pathVar
(
const
QString
&
var
)
{
return
var
+
QLatin1String
(
".path"
);
}
QString
filesVar
(
const
QString
&
var
)
{
return
var
+
QLatin1String
(
".files"
);
}
const
QLatin1String
InstallsVar
(
"INSTALLS"
);
const
QLatin1String
TargetVar
(
"target"
);
}
namespace
Qt4ProjectManager
{
...
...
@@ -56,43 +65,161 @@ namespace Internal {
MaemoPackageContents
::
MaemoPackageContents
(
MaemoPackageCreationStep
*
packageStep
)
:
QAbstractTableModel
(
packageStep
),
m_packageStep
(
packageStep
),
m_modified
(
true
)
m_proFileOption
(
new
ProFileOption
),
m_proFileReader
(
new
ProFileReader
(
m_proFileOption
.
data
())),
m_modified
(
false
),
m_proFile
(
0
)
{
}
MaemoPackageContents
::~
MaemoPackageContents
()
{}
bool
MaemoPackageContents
::
init
()
{
return
m_proFile
?
true
:
buildModel
();
}
bool
MaemoPackageContents
::
buildModel
()
const
{
m_deployables
.
clear
();
const
Qt4ProFileNode
*
const
proFileNode
=
m_packageStep
->
qt4BuildConfiguration
()
->
qt4Target
()
->
qt4Project
()
->
rootProjectNode
();
if
(
m_proFileName
.
isEmpty
())
{
m_proFileName
=
proFileNode
->
path
();
m_proDir
=
QFileInfo
(
m_proFileName
).
dir
();
}
resetProFileContents
();
if
(
!
m_proFile
)
return
false
;
const
QStringList
elemList
=
m_proFileReader
->
values
(
InstallsVar
,
m_proFile
);
bool
targetFound
=
false
;
foreach
(
const
QString
&
elem
,
elemList
)
{
const
QStringList
paths
=
m_proFileReader
->
values
(
pathVar
(
elem
),
m_proFile
);
if
(
paths
.
count
()
!=
1
)
{
qWarning
(
"Error: Variable %s has %d values."
,
qPrintable
(
pathVar
(
elem
)),
paths
.
count
());
continue
;
}
const
QStringList
files
=
m_proFileReader
->
values
(
filesVar
(
elem
),
m_proFile
);
if
(
files
.
isEmpty
()
&&
elem
!=
TargetVar
)
{
qWarning
(
"Error: Variable %s has no RHS."
,
qPrintable
(
filesVar
(
elem
)));
continue
;
}
if
(
elem
==
TargetVar
)
{
m_deployables
.
prepend
(
Deployable
(
m_packageStep
->
localExecutableFilePath
(),
paths
.
first
()));
targetFound
=
true
;
}
else
{
foreach
(
const
QString
&
file
,
files
)
m_deployables
<<
Deployable
(
cleanPath
(
file
),
paths
.
first
());
}
}
if
(
!
targetFound
)
{
const
QString
remoteDir
=
proFileNode
->
projectType
()
==
LibraryTemplate
?
QLatin1String
(
"/usr/local/lib"
)
:
QLatin1String
(
"/usr/local/bin"
);
m_deployables
.
prepend
(
Deployable
(
m_packageStep
->
localExecutableFilePath
(),
remoteDir
));
QString
errorString
;
if
(
!
readProFileContents
(
&
errorString
))
{
qWarning
(
"Error reading .pro file: %s"
,
qPrintable
(
errorString
));
return
false
;
}
addValueToProFile
(
pathVar
(
TargetVar
),
remoteDir
);
addValueToProFile
(
InstallsVar
,
TargetVar
);
if
(
!
writeProFileContents
(
&
errorString
))
{
qWarning
(
"Error writing .pro file: %s"
,
qPrintable
(
errorString
));
return
false
;
}
}
m_modified
=
true
;
return
true
;
}
MaemoPackageContents
::
Deployable
MaemoPackageContents
::
deployableAt
(
int
row
)
const
{
Q_ASSERT
(
row
>=
0
&&
row
<
rowCount
());
return
row
==
0
?
Deployable
(
m_packageStep
->
localExecutableFilePath
(),
remoteExecutableDir
())
:
m_deployables
.
at
(
row
-
1
);
return
m_deployables
.
at
(
row
);
}
bool
MaemoPackageContents
::
addDeployable
(
const
Deployable
&
deployable
)
bool
MaemoPackageContents
::
addDeployable
(
const
Deployable
&
deployable
,
QString
*
error
)
{
if
(
m_deployables
.
contains
(
deployable
)
||
deployableAt
(
0
)
==
deployable
)
return
false
;
if
(
!
readProFileContents
(
error
))
return
false
;
QCryptographicHash
elemHash
(
QCryptographicHash
::
Md5
);
elemHash
.
addData
(
deployable
.
localFilePath
.
toUtf8
());
const
QString
elemName
=
QString
::
fromAscii
(
elemHash
.
result
().
toHex
());
addFileToProFile
(
filesVar
(
elemName
),
deployable
.
localFilePath
);
addValueToProFile
(
pathVar
(
elemName
),
deployable
.
remoteDir
);
addValueToProFile
(
InstallsVar
,
elemName
);
if
(
!
writeProFileContents
(
error
))
return
false
;
beginInsertRows
(
QModelIndex
(),
rowCount
(),
rowCount
());
m_deployables
<<
deployable
;
endInsertRows
();
m_modified
=
true
;
return
true
;
}
void
MaemoPackageContents
::
removeDeployableAt
(
int
row
)
bool
MaemoPackageContents
::
removeDeployableAt
(
int
row
,
QString
*
error
)
{
Q_ASSERT
(
row
>
0
&&
row
<
rowCount
());
const
Deployable
&
deployable
=
deployableAt
(
row
);
const
QString
elemToRemove
=
findInstallsElem
(
deployable
);
if
(
elemToRemove
.
isEmpty
())
{
*
error
=
tr
(
"Inconsistent model: Deployable not found in .pro file."
);
return
false
;
}
if
(
!
readProFileContents
(
error
))
return
false
;
const
QString
filesVarName
=
filesVar
(
elemToRemove
);
const
bool
isOnlyElem
=
m_proFileReader
->
values
(
filesVarName
,
m_proFile
).
count
()
==
1
;
bool
success
=
removeFileFromProFile
(
filesVarName
,
deployable
.
localFilePath
);
if
(
success
&&
isOnlyElem
)
{
success
=
removeValueFromProFile
(
pathVar
(
elemToRemove
),
deployable
.
remoteDir
);
if
(
success
)
success
=
removeValueFromProFile
(
InstallsVar
,
elemToRemove
);
}
if
(
!
success
)
{
*
error
=
tr
(
"Could not remove deployable from .pro file."
);
return
false
;
}
if
(
!
writeProFileContents
(
error
))
return
false
;
beginRemoveRows
(
QModelIndex
(),
row
,
row
);
m_deployables
.
removeAt
(
row
-
1
);
endRemoveRows
();
m_modified
=
true
;
return
true
;
}
int
MaemoPackageContents
::
rowCount
(
const
QModelIndex
&
parent
)
const
{
return
parent
.
isValid
()
?
0
:
m_deployables
.
count
()
+
1
;
if
(
!
m_proFile
)
buildModel
();
return
parent
.
isValid
()
?
0
:
m_deployables
.
count
();
}
int
MaemoPackageContents
::
columnCount
(
const
QModelIndex
&
parent
)
const
...
...
@@ -128,12 +255,33 @@ bool MaemoPackageContents::setData(const QModelIndex &index,
||
role
!=
Qt
::
EditRole
)
return
false
;
const
QString
&
remoteDir
=
value
.
toString
();
if
(
index
.
row
()
==
0
)
m_remoteExecutableDir
=
remoteDir
;
else
m_deployables
[
index
.
row
()
-
1
].
remoteDir
=
remoteDir
;
m_modified
=
true
;
QString
error
;
if
(
!
readProFileContents
(
&
error
))
{
qWarning
(
qPrintable
(
error
));
return
false
;
}
Deployable
&
deployable
=
m_deployables
[
index
.
row
()];
const
QString
elemToChange
=
findInstallsElem
(
deployable
);
if
(
elemToChange
.
isEmpty
())
{
qWarning
(
"Error: Inconsistent model. "
"INSTALLS element not found in .pro file"
);
return
false
;
}
const
QString
pathElem
=
pathVar
(
elemToChange
);
if
(
!
removeValueFromProFile
(
pathElem
,
deployable
.
remoteDir
))
{
qWarning
(
"Error: Could not change remote path in .pro file."
);
return
false
;
}
const
QString
&
newRemoteDir
=
value
.
toString
();
addValueToProFile
(
pathElem
,
newRemoteDir
);
if
(
!
writeProFileContents
(
&
error
))
{
qWarning
(
qPrintable
(
error
));
return
false
;
}
deployable
.
remoteDir
=
newRemoteDir
;
emit
dataChanged
(
index
,
index
);
return
true
;
}
...
...
@@ -146,57 +294,146 @@ QVariant MaemoPackageContents::headerData(int section,
return
section
==
0
?
tr
(
"Local File Path"
)
:
tr
(
"Remote Directory"
);
}
QVariantMap
MaemoPackageContents
::
toMap
()
const
QString
MaemoPackageContents
::
remoteExecutableFilePath
()
const
{
if
(
!
m_proFile
)
buildModel
();
return
deployableAt
(
0
).
remoteDir
+
'/'
+
m_packageStep
->
executableFileName
();
}
bool
MaemoPackageContents
::
readProFileContents
(
QString
*
error
)
const
{
if
(
!
m_proFileLines
.
isEmpty
())
return
true
;
QFile
proFileOnDisk
(
m_proFileName
);
if
(
!
proFileOnDisk
.
open
(
QIODevice
::
ReadOnly
))
{
*
error
=
tr
(
"Project file '%1' could not be opened for reading."
)
.
arg
(
m_proFileName
);
return
false
;
}
const
QString
proFileContents
=
QString
::
fromLatin1
(
proFileOnDisk
.
readAll
());
if
(
proFileOnDisk
.
error
()
!=
QFile
::
NoError
)
{
*
error
=
tr
(
"Project file '%1' could not be read."
)
.
arg
(
m_proFileName
);
return
false
;
}
m_proFileLines
=
proFileContents
.
split
(
'\n'
);
return
true
;
}
bool
MaemoPackageContents
::
writeProFileContents
(
QString
*
error
)
const
{
QVariantMap
map
;
map
.
insert
(
MODIFIED_KEY
,
m_modified
);
map
.
insert
(
REMOTE_EXE_DIR_KEY
,
m_remoteExecutableDir
);
QFile
proFileOnDisk
(
m_proFileName
);
if
(
!
proFileOnDisk
.
open
(
QIODevice
::
WriteOnly
))
{
*
error
=
tr
(
"Project file '%1' could not be opened for writing."
)
.
arg
(
m_proFileName
);
resetProFileContents
();
return
false
;
}
QDir
dir
;
QStringList
localFiles
;
QStringList
remoteDirs
;
foreach
(
const
Deployable
&
p
,
m_deployables
)
{
localFiles
<<
dir
.
fromNativeSeparators
(
p
.
localFilePath
);
remoteDirs
<<
p
.
remoteDir
;
// TODO: Disconnect and reconnect FS watcher here.
proFileOnDisk
.
write
(
m_proFileLines
.
join
(
"
\n
"
).
toLatin1
());
proFileOnDisk
.
close
();
if
(
proFileOnDisk
.
error
()
!=
QFile
::
NoError
)
{
*
error
=
tr
(
"Project file '%1' could not be written."
)
.
arg
(
m_proFileName
);
resetProFileContents
();
return
false
;
}
map
.
insert
(
LOCAL_FILES_KEY
,
localFiles
);
map
.
insert
(
REMOTE_DIRS_KEY
,
remoteDirs
);
return
map
;
m_modified
=
true
;
return
true
;
}
void
MaemoPackageContents
::
fromMap
(
const
QVariantMap
&
map
)
QString
MaemoPackageContents
::
cleanPath
(
const
QString
&
relFileName
)
const
{
m_modified
=
map
.
value
(
MODIFIED_KEY
).
toBool
();
m_remoteExecutableDir
=
map
.
value
(
REMOTE_EXE_DIR_KEY
).
toString
();
const
QStringList
localFiles
=
map
.
value
(
LOCAL_FILES_KEY
).
toStringList
();
const
QStringList
remoteDirs
=
map
.
value
(
REMOTE_DIRS_KEY
).
toStringList
();
if
(
localFiles
.
count
()
!=
remoteDirs
.
count
())
qWarning
(
"%s: serialized data inconsistent"
,
Q_FUNC_INFO
);
// I'd rather use QDir::cleanPath(), but that doesn't work well
// enough for redundant ".." dirs.
return
QFileInfo
(
m_proFile
->
directoryName
()
+
'/'
+
relFileName
).
canonicalFilePath
();
}
QDir
dir
;
const
int
count
=
qMin
(
localFiles
.
count
(),
remoteDirs
.
count
());
for
(
int
i
=
0
;
i
<
count
;
++
i
)
{
m_deployables
<<
Deployable
(
dir
.
toNativeSeparators
(
localFiles
.
at
(
i
)),
remoteDirs
.
at
(
i
));
QString
MaemoPackageContents
::
findInstallsElem
(
const
Deployable
&
deployable
)
const
{
const
QStringList
elems
=
m_proFileReader
->
values
(
InstallsVar
,
m_proFile
);
foreach
(
const
QString
&
elem
,
elems
)
{
const
QStringList
elemPaths
=
m_proFileReader
->
values
(
pathVar
(
elem
),
m_proFile
);
if
(
elemPaths
.
count
()
!=
1
||
elemPaths
.
first
()
!=
deployable
.
remoteDir
)
continue
;
if
(
elem
==
TargetVar
)
return
elem
;
const
QStringList
elemFiles
=
m_proFileReader
->
values
(
filesVar
(
elem
),
m_proFile
);
foreach
(
const
QString
&
file
,
elemFiles
)
{
if
(
cleanPath
(
file
)
==
deployable
.
localFilePath
)
return
elem
;
}
}
return
QString
();
}
QString
MaemoPackageContents
::
remoteExecutableDir
()
const
void
MaemoPackageContents
::
addFileToProFile
(
const
QString
&
var
,
const
QString
&
absFilePath
)
{
if
(
m_remoteExecutableDir
.
isEmpty
())
{
const
Qt4ProjectType
projectType
=
m_packageStep
->
qt4BuildConfiguration
()
->
qt4Target
()
->
qt4Project
()
->
rootProjectNode
()
->
projectType
();
m_remoteExecutableDir
=
projectType
==
LibraryTemplate
?
QLatin1String
(
"/usr/local/lib"
)
:
QLatin1String
(
"/usr/local/bin"
);
ProWriter
::
addFiles
(
m_proFile
,
&
m_proFileLines
,
m_proDir
,
QStringList
(
absFilePath
),
var
);
parseProFile
(
ParseFromLines
);
}
void
MaemoPackageContents
::
addValueToProFile
(
const
QString
&
var
,
const
QString
&
value
)
const
{
ProWriter
::
addVarValues
(
m_proFile
,
&
m_proFileLines
,
m_proDir
,
QStringList
(
value
),
var
);
parseProFile
(
ParseFromLines
);
}
bool
MaemoPackageContents
::
removeFileFromProFile
(
const
QString
&
var
,
const
QString
&
absFilePath
)
{
const
bool
success
=
ProWriter
::
removeFiles
(
m_proFile
,
&
m_proFileLines
,
m_proDir
,
QStringList
(
absFilePath
),
QStringList
(
var
)).
isEmpty
();
if
(
success
)
parseProFile
(
ParseFromLines
);
else
resetProFileContents
();
return
success
;
}
bool
MaemoPackageContents
::
removeValueFromProFile
(
const
QString
&
var
,
const
QString
&
value
)
{
const
bool
success
=
ProWriter
::
removeVarValues
(
m_proFile
,
&
m_proFileLines
,
m_proDir
,
QStringList
(
value
),
QStringList
(
var
)).
isEmpty
();
if
(
success
)
parseProFile
(
ParseFromLines
);
else
resetProFileContents
();
return
success
;
}
void
MaemoPackageContents
::
parseProFile
(
ParseType
type
)
const
{
if
(
type
==
ParseFromLines
)
{
m_proFile
=
m_proFileReader
->
parsedProFile
(
m_proFileName
,
m_proFileLines
.
join
(
"
\n
"
));
}
else
{
m_proFile
=
m_proFileReader
->
readProFile
(
m_proFileName
)
?
m_proFileReader
->
proFileFor
(
m_proFileName
)
:
0
;
}
return
m_remoteExecutableDir
;
}
QString
MaemoPackageContents
::
re
moteExecutableFilePath
()
const
void
MaemoPackageContents
::
re
setProFileContents
()
const
{
return
remoteExecutableDir
()
+
'/'
+
m_packageStep
->
executableFileName
();
m_proFileLines
.
clear
();
parseProFile
(
ParseFromFile
);
if
(
!
m_proFile
)
qWarning
(
"Fatal: Could not parse .pro file '%s'."
,
qPrintable
(
m_proFileName
));
}
}
// namespace Qt4ProjectManager
...
...
src/plugins/qt4projectmanager/qt-maemo/maemopackagecontents.h
View file @
f96efa07
...
...
@@ -31,14 +31,21 @@
#define MAEMOPACKAGECONTENTS_H
#include
<QtCore/QAbstractTableModel>
#include
<QtCore/QDir>
#include
<QtCore/QList>
#include
<QtCore/QScopedPointer>
#include
<QtCore/QString>
#include
<QtCore/QVariantMap>
#include
<QtCore/QStringList>
QT_BEGIN_NAMESPACE
class
ProFile
;
class
ProFileOption
;
QT_END_NAMESPACE
namespace
Qt4ProjectManager
{
namespace
Internal
{
class
MaemoPackageCreationStep
;
class
ProFileReader
;
class
MaemoPackageContents
:
public
QAbstractTableModel
{
...
...
@@ -60,15 +67,15 @@ public:
};
MaemoPackageContents
(
MaemoPackageCreationStep
*
packageStep
);
~
MaemoPackageContents
();
virtual
int
rowCount
(
const
QModelIndex
&
parent
=
QModelIndex
())
const
;
bool
init
()
;
QVariantMap
toMap
()
const
;
void
fromMap
(
const
QVariantMap
&
map
);
virtual
int
rowCount
(
const
QModelIndex
&
parent
=
QModelIndex
())
const
;
Deployable
deployableAt
(
int
row
)
const
;
bool
addDeployable
(
const
Deployable
&
deployable
);
void
removeDeployableAt
(
int
row
);
bool
addDeployable
(
const
Deployable
&
deployable
,
QString
*
error
);
bool
removeDeployableAt
(
int
row
,
QString
*
error
);
bool
isModified
()
const
{
return
m_modified
;
}
void
setUnModified
()
{
m_modified
=
false
;
}
QString
remoteExecutableFilePath
()
const
;
...
...
@@ -83,13 +90,31 @@ private:
virtual
bool
setData
(
const
QModelIndex
&
index
,
const
QVariant
&
value
,
int
role
=
Qt
::
EditRole
);
QString
remoteExecutableDir
()
const
;
bool
buildModel
()
const
;
void
resetProFileContents
()
const
;
bool
readProFileContents
(
QString
*
error
)
const
;
bool
writeProFileContents
(
QString
*
error
)
const
;
QString
cleanPath
(
const
QString
&
relFileName
)
const
;
QString
findInstallsElem
(
const
Deployable
&
deployable
)
const
;
void
addFileToProFile
(
const
QString
&
var
,
const
QString
&
absFilePath
);
void
addValueToProFile
(
const
QString
&
var
,
const
QString
&
value
)
const
;
bool
removeFileFromProFile
(
const
QString
&
var
,
const
QString
&
absFilePath
);
bool
removeValueFromProFile
(
const
QString
&
var
,
const
QString
&
value
);
enum
ParseType
{
ParseFromFile
,
ParseFromLines
};
void
parseProFile
(
ParseType
type
)
const
;
private:
const
MaemoPackageCreationStep
*
const
m_packageStep
;
QList
<
Deployable
>
m_deployables
;
bool
m_modified
;
mutable
QString
m_remoteExecutableDir
;
QScopedPointer
<
ProFileOption
>
m_proFileOption
;
QScopedPointer
<
ProFileReader
>
m_proFileReader
;
mutable
QList
<
Deployable
>
m_deployables
;
mutable
bool
m_modified
;
mutable
ProFile
*
m_proFile
;
mutable
QStringList
m_proFileLines
;
// TODO: FS watcher
mutable
QString
m_proFileName
;
mutable
QDir
m_proDir
;
};
}
// namespace Qt4ProjectManager
...
...
src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationstep.cpp
View file @
f96efa07
...
...
@@ -95,12 +95,11 @@ QVariantMap MaemoPackageCreationStep::toMap() const
{
QVariantMap
map
(
ProjectExplorer
::
BuildStep
::
toMap
());
map
.
insert
(
PackagingEnabledKey
,
m_packagingEnabled
);
return
map
.
unite
(
m_packageContents
->
toMap
())
;
return
map
;
}
bool
MaemoPackageCreationStep
::
fromMap
(
const
QVariantMap
&
map
)
{
m_packageContents
->
fromMap
(
map
);
m_packagingEnabled
=
map
.
value
(
PackagingEnabledKey
,
true
).
toBool
();
return
ProjectExplorer
::
BuildStep
::
fromMap
(
map
);
}
...
...
src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationwidget.cpp
View file @
f96efa07
...
...
@@ -109,9 +109,9 @@ void MaemoPackageCreationWidget::addFile()
deployable
(
QDir
::
toNativeSeparators
(
QFileInfo
(
localFile
).
absoluteFilePath
()),
"/"
);
MaemoPackageContents
*
const
contents
=
m_step
->
packageContents
();
if
(
!
contents
->
addDeployable
(
deployable
))
{
QMessageBox
::
information
(
this
,
tr
(
"File already in package"
),
tr
(
"You have already added this
file
.
"
));
QString
errorString
;
if
(
!
contents
->
addDeployable
(
deployable
,
&
errorString
))
{
QMessageBox
::
information
(
this
,
tr
(
"Error adding
file"
)
,
errorString
);
}
else
{
const
QModelIndex
newIndex
=
contents
->
index
(
contents
->
rowCount
()
-
1
,
1
);
...
...
@@ -128,8 +128,13 @@ void MaemoPackageCreationWidget::removeFile()
if
(
selectedRows
.
isEmpty
())
return
;
const
int
row
=
selectedRows
.
first
().
row
();
if
(
row
!=
0
)
m_step
->
packageContents
()
->
removeDeployableAt
(
row
);
if
(
row
!=
0
)
{
QString
errorString
;
if
(
!
m_step
->
packageContents
()
->
removeDeployableAt
(
row
,
&
errorString
))
{
QMessageBox
::
information
(
this
,
tr
(
"Error removing file"
),
errorString
);
}
}
}
void
MaemoPackageCreationWidget
::
enableOrDisableRemoveButton
()
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment