Adding upstream version 0.3.1.
Signed-off-by: Alf Gaida <agaida@siduction.org>
This commit is contained in:
parent
7abe319414
commit
3deb287238
34
.github/ISSUE_TEMPLATE.md
vendored
34
.github/ISSUE_TEMPLATE.md
vendored
@ -1,34 +0,0 @@
|
||||
<!--- Provide a general summary of the issue in the Title above -->
|
||||
<!--- You could delete sections and/or questions irrelevant to your report --->
|
||||
|
||||
##### Expected Behavior
|
||||
<!--- If you're describing a bug, tell us what should happen -->
|
||||
<!--- If you're suggesting a change/improvement, tell us how it should work -->
|
||||
|
||||
##### Current Behavior
|
||||
<!--- If describing a bug, tell us what happens instead of the expected behavior -->
|
||||
<!--- If suggesting a change/improvement, explain the difference from current behavior -->
|
||||
|
||||
##### Possible Solution
|
||||
<!--- Not obligatory, but suggest a fix/reason for the bug, -->
|
||||
<!--- or ideas how to implement the addition or change -->
|
||||
|
||||
##### Steps to Reproduce (for bugs)
|
||||
<!--- Provide a link to a live example, or an unambiguous set of steps to -->
|
||||
<!--- reproduce this bug. Include code to reproduce, if relevant -->
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
4.
|
||||
|
||||
##### Context
|
||||
<!--- How has this issue affected you? What are you trying to accomplish? -->
|
||||
<!--- Providing context helps us come up with a solution that is most useful in the real world -->
|
||||
|
||||
##### System Information
|
||||
<!--- Include as many relevant details about the system you experienced the bug in -->
|
||||
* Distribution & Version:
|
||||
* Kernel:
|
||||
* Qt Version:
|
||||
* cmake Version:
|
||||
* Package version:
|
14
CHANGELOG
14
CHANGELOG
@ -1,7 +1,19 @@
|
||||
|
||||
libqtxdg-3.0.0 / 2017-09-22
|
||||
libqtxdg-3.1.0 / 2017-10-21
|
||||
===========================
|
||||
|
||||
* Bump version to 3.1.0
|
||||
* xdgdesktopfile: Add API for getting actions info
|
||||
* xdgdesktopfile: Add support for activating actions
|
||||
* xdgdesktopfile: Add getting actions
|
||||
* Check $XDG_CONFIG_HOME and $XDG_CONFIG_DIRS for mimeapps.list first.
|
||||
* Fix reading and writing mimeapps.list file.
|
||||
* Don't export github templates
|
||||
|
||||
3.0.0 / 2017-09-22
|
||||
==================
|
||||
|
||||
* Release 3.0.0: Update changelog
|
||||
* Backport support for Scale directory key according to Icon Theme spec
|
||||
* Bump Major to 3
|
||||
* test: Drop Q_FOREACH
|
||||
|
@ -26,7 +26,7 @@ else()
|
||||
endif()
|
||||
|
||||
set(QTXDG_MAJOR_VERSION 3)
|
||||
set(QTXDG_MINOR_VERSION 0)
|
||||
set(QTXDG_MINOR_VERSION 1)
|
||||
set(QTXDG_PATCH_VERSION 0)
|
||||
set(QTXDG_VERSION_STRING ${QTXDG_MAJOR_VERSION}.${QTXDG_MINOR_VERSION}.${QTXDG_PATCH_VERSION})
|
||||
|
||||
|
@ -66,6 +66,7 @@ static const QStringList nonDetachExecs = QStringList()
|
||||
static const QLatin1String onlyShowInKey("OnlyShowIn");
|
||||
static const QLatin1String notShowInKey("NotShowIn");
|
||||
static const QLatin1String categoriesKey("Categories");
|
||||
static const QLatin1String actionsKey("Actions");
|
||||
static const QLatin1String extendPrefixKey("X-");
|
||||
static const QLatin1String mimeTypeKey("MimeType");
|
||||
static const QLatin1String applicationsStr("applications");
|
||||
@ -274,14 +275,37 @@ QString &unEscapeExec(QString& str)
|
||||
return doUnEscape(str, repl);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
/*!
|
||||
* Helper class for getting the keys for "Additional applications actions"
|
||||
* ([Desktop Action %s] sections)
|
||||
*/
|
||||
class XdgDesktopAction : public XdgDesktopFile
|
||||
{
|
||||
public:
|
||||
XdgDesktopAction(const XdgDesktopFile & parent, const QString & action)
|
||||
: XdgDesktopFile(parent)
|
||||
, m_prefix(QString{QLatin1String("Desktop Action %1")}.arg(action))
|
||||
{}
|
||||
|
||||
protected:
|
||||
virtual QString prefix() const { return m_prefix; }
|
||||
|
||||
private:
|
||||
const QString m_prefix;
|
||||
};
|
||||
}
|
||||
|
||||
class XdgDesktopFileData: public QSharedData {
|
||||
public:
|
||||
XdgDesktopFileData();
|
||||
bool read(const QString &prefix);
|
||||
XdgDesktopFile::Type detectType(XdgDesktopFile *q) const;
|
||||
bool startApplicationDetached(const XdgDesktopFile *q, const QStringList& urls) const;
|
||||
bool startApplicationDetached(const XdgDesktopFile *q, const QString & action, const QStringList& urls) const;
|
||||
bool startLinkDetached(const XdgDesktopFile *q) const;
|
||||
bool startByDBus(const QStringList& urls) const;
|
||||
bool startByDBus(const QString & action, const QStringList& urls) const;
|
||||
QStringList getListValue(const XdgDesktopFile * q, const QString & key, bool tryExtendPrefix) const;
|
||||
|
||||
QString mFileName;
|
||||
bool mIsValid;
|
||||
@ -365,7 +389,7 @@ XdgDesktopFile::Type XdgDesktopFileData::detectType(XdgDesktopFile *q) const
|
||||
return XdgDesktopFile::UnknownType;
|
||||
}
|
||||
|
||||
bool XdgDesktopFileData::startApplicationDetached(const XdgDesktopFile *q, const QStringList& urls) const
|
||||
bool XdgDesktopFileData::startApplicationDetached(const XdgDesktopFile *q, const QString & action, const QStringList& urls) const
|
||||
{
|
||||
//DBusActivatable handling
|
||||
if (q->value(QLatin1String("DBusActivatable"), false).toBool()) {
|
||||
@ -390,10 +414,12 @@ bool XdgDesktopFileData::startApplicationDetached(const XdgDesktopFile *q, const
|
||||
* We consider that this violation is more acceptable than an failure
|
||||
* in launching an application.
|
||||
*/
|
||||
if (startByDBus(urls))
|
||||
if (startByDBus(action, urls))
|
||||
return true;
|
||||
}
|
||||
QStringList args = q->expandExecString(urls);
|
||||
QStringList args = action.isEmpty()
|
||||
? q->expandExecString(urls)
|
||||
: XdgDesktopAction{*q, action}.expandExecString(urls);
|
||||
|
||||
if (args.isEmpty())
|
||||
return false;
|
||||
@ -481,8 +507,7 @@ bool XdgDesktopFileData::startLinkDetached(const XdgDesktopFile *q) const
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Handle ActivateAction
|
||||
bool XdgDesktopFileData::startByDBus(const QStringList& urls) const
|
||||
bool XdgDesktopFileData::startByDBus(const QString & action, const QStringList& urls) const
|
||||
{
|
||||
QFileInfo f(mFileName);
|
||||
QString path(f.completeBaseName());
|
||||
@ -509,7 +534,13 @@ bool XdgDesktopFileData::startByDBus(const QStringList& urls) const
|
||||
<< ", but trying to continue...";
|
||||
}
|
||||
QDBusMessage reply;
|
||||
if (urls.isEmpty())
|
||||
if (!action.isEmpty())
|
||||
{
|
||||
QList<QVariant> v_urls;
|
||||
for (const auto & url : urls)
|
||||
v_urls.append(url);
|
||||
reply = app.call(QLatin1String("ActivateAction"), action, v_urls, platformData);
|
||||
} else if (urls.isEmpty())
|
||||
reply = app.call(QLatin1String("Activate"), platformData);
|
||||
else
|
||||
reply = app.call(QLatin1String("Open"), urls, platformData);
|
||||
@ -517,6 +548,19 @@ bool XdgDesktopFileData::startByDBus(const QStringList& urls) const
|
||||
return QDBusMessage::ErrorMessage != reply.type();
|
||||
}
|
||||
|
||||
QStringList XdgDesktopFileData::getListValue(const XdgDesktopFile * q, const QString & key, bool tryExtendPrefix) const
|
||||
{
|
||||
QString used_key = key;
|
||||
if (!q->contains(used_key) && tryExtendPrefix)
|
||||
{
|
||||
used_key = extendPrefixKey + key;
|
||||
if (!q->contains(used_key))
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
return q->value(key).toString().split(QLatin1Char(';'), QString::SkipEmptyParts);
|
||||
}
|
||||
|
||||
|
||||
XdgDesktopFile::XdgDesktopFile():
|
||||
d(new XdgDesktopFileData)
|
||||
@ -750,22 +794,13 @@ QVariant XdgDesktopFile::localizedValue(const QString& key, const QVariant& defa
|
||||
|
||||
QStringList XdgDesktopFile::categories() const
|
||||
{
|
||||
QString key;
|
||||
if (contains(categoriesKey))
|
||||
{
|
||||
key = categoriesKey;
|
||||
}
|
||||
else
|
||||
{
|
||||
key = extendPrefixKey + categoriesKey;
|
||||
if (!contains(key))
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
QStringList cats = value(key).toString().split(QLatin1Char(';'));
|
||||
return cats;
|
||||
return d->getListValue(this, categoriesKey, true);
|
||||
}
|
||||
|
||||
QStringList XdgDesktopFile::actions() const
|
||||
{
|
||||
return d->getListValue(this, actionsKey, false);
|
||||
}
|
||||
|
||||
void XdgDesktopFile::removeEntry(const QString& key)
|
||||
{
|
||||
@ -806,18 +841,41 @@ QIcon const XdgDesktopFile::icon(const QIcon& fallback) const
|
||||
}
|
||||
|
||||
|
||||
QIcon const XdgDesktopFile::actionIcon(const QString & action, const QIcon& fallback) const
|
||||
{
|
||||
return d->mType == ApplicationType
|
||||
? XdgDesktopAction{*this, action}.icon(icon(fallback))
|
||||
: fallback;
|
||||
}
|
||||
|
||||
|
||||
QString const XdgDesktopFile::iconName() const
|
||||
{
|
||||
return value(iconKey).toString();
|
||||
}
|
||||
|
||||
|
||||
QString const XdgDesktopFile::actionIconName(const QString & action) const
|
||||
{
|
||||
return d->mType == ApplicationType
|
||||
? XdgDesktopAction{*this, action}.iconName()
|
||||
: QString{};
|
||||
}
|
||||
|
||||
|
||||
QStringList XdgDesktopFile::mimeTypes() const
|
||||
{
|
||||
return value(mimeTypeKey).toString().split(QLatin1Char(';'), QString::SkipEmptyParts);
|
||||
}
|
||||
|
||||
|
||||
QString XdgDesktopFile::actionName(const QString & action) const
|
||||
{
|
||||
return d->mType == ApplicationType
|
||||
? XdgDesktopAction{*this, action}.name()
|
||||
: QString{};
|
||||
}
|
||||
|
||||
XdgDesktopFile::Type XdgDesktopFile::type() const
|
||||
{
|
||||
return d->mType;
|
||||
@ -839,7 +897,7 @@ bool XdgDesktopFile::startDetached(const QStringList& urls) const
|
||||
switch(d->mType)
|
||||
{
|
||||
case ApplicationType:
|
||||
return d->startApplicationDetached(this, urls);
|
||||
return d->startApplicationDetached(this, QString{}, urls);
|
||||
break;
|
||||
|
||||
case LinkType:
|
||||
@ -851,6 +909,11 @@ bool XdgDesktopFile::startDetached(const QStringList& urls) const
|
||||
}
|
||||
}
|
||||
|
||||
bool XdgDesktopFile::actionActivate(const QString & action, const QStringList& urls) const
|
||||
{
|
||||
return d->mType == ApplicationType ? d->startApplicationDetached(this, action, urls) : false;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
This is an overloaded function.
|
||||
@ -1396,7 +1459,7 @@ bool readDesktopFile(QIODevice & device, QSettings::SettingsMap & map)
|
||||
|
||||
if (value.contains(QLatin1Char(';')))
|
||||
{
|
||||
map.insert(key, value.split(QLatin1Char(';')));
|
||||
map.insert(key, value.split(QLatin1Char(';'), QString::SkipEmptyParts));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1418,7 +1481,10 @@ bool writeDesktopFile(QIODevice & device, const QSettings::SettingsMap & map)
|
||||
|
||||
for (auto it = map.constBegin(); it != map.constEnd(); ++it)
|
||||
{
|
||||
if (! it.value().canConvert<QString>())
|
||||
bool isString = it.value().canConvert<QString>();
|
||||
bool isStringList = (it.value().type() == QVariant::StringList);
|
||||
|
||||
if ((! isString) && (! isStringList))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -1444,7 +1510,21 @@ bool writeDesktopFile(QIODevice & device, const QSettings::SettingsMap & map)
|
||||
return false;
|
||||
}
|
||||
|
||||
stream << remainingKey << QLatin1Char('=') << it.value().toString() << QLatin1Char('\n');
|
||||
stream << remainingKey << QLatin1Char('=');
|
||||
|
||||
if (isString)
|
||||
{
|
||||
stream << it.value().toString() << QLatin1Char(';');
|
||||
}
|
||||
else /* if (isStringList) */
|
||||
{
|
||||
for (const QString &value: it.value().toStringList())
|
||||
{
|
||||
stream << value << QLatin1Char(';');
|
||||
}
|
||||
}
|
||||
|
||||
stream << QLatin1Char('\n');
|
||||
|
||||
}
|
||||
|
||||
@ -1612,13 +1692,22 @@ QList<XdgDesktopFile*> XdgDesktopFileCache::getApps(const QString& mimetype)
|
||||
|
||||
XdgDesktopFile* XdgDesktopFileCache::getDefaultApp(const QString& mimetype)
|
||||
{
|
||||
// First, we look in ~/.local/share/applications/mimeapps.list, /usr/local/share/applications/mimeapps.list and
|
||||
// /usr/share/applications/mimeapps.list (in that order) for a default.
|
||||
QStringList dataDirs = XdgDirs::dataDirs();
|
||||
dataDirs.prepend(XdgDirs::dataHome(false));
|
||||
for (const QString &dataDir : const_cast<const QStringList&>(dataDirs))
|
||||
// First, we look in following places for a default in specified order:
|
||||
// ~/.config/mimeapps.list
|
||||
// /etc/xdg/mimeapps.list
|
||||
// ~/.local/share/applications/mimeapps.list
|
||||
// /usr/local/share/applications/mimeapps.list
|
||||
// /usr/share/applications/mimeapps.list
|
||||
QStringList mimeDirsList;
|
||||
|
||||
mimeDirsList.append(XdgDirs::configHome(false));
|
||||
mimeDirsList.append(XdgDirs::configDirs());
|
||||
mimeDirsList.append(XdgDirs::dataHome(false) + QLatin1String("/applications"));
|
||||
mimeDirsList.append(XdgDirs::dataDirs(QLatin1String("/applications")));
|
||||
|
||||
for (const QString &mimeDir : const_cast<const QStringList&>(mimeDirsList))
|
||||
{
|
||||
QString defaultsListPath = dataDir + QLatin1String("/applications/mimeapps.list");
|
||||
QString defaultsListPath = mimeDir + QLatin1String("/mimeapps.list");
|
||||
if (QFileInfo::exists(defaultsListPath))
|
||||
{
|
||||
QSettings defaults(defaultsListPath, desktopFileSettingsFormat());
|
||||
|
@ -130,6 +130,9 @@ public:
|
||||
//! Returns the entry Categories. It supports X-Categories extensions.
|
||||
QStringList categories() const;
|
||||
|
||||
//! Returns list of values in entry Actions.
|
||||
QStringList actions() const;
|
||||
|
||||
//! Returns true if there exists a setting called key; returns false otherwise.
|
||||
bool contains(const QString& key) const;
|
||||
|
||||
@ -142,9 +145,13 @@ public:
|
||||
|
||||
//! Returns an icon specified in this file.
|
||||
QIcon const icon(const QIcon& fallback = QIcon()) const;
|
||||
//! Returns an icon for application action \param action.
|
||||
QIcon const actionIcon(const QString & action, const QIcon& fallback = QIcon()) const;
|
||||
|
||||
//! Returns an icon name specified in this file.
|
||||
QString const iconName() const;
|
||||
//! Returns an icon name for application action \param action.
|
||||
QString const actionIconName(const QString & action) const;
|
||||
|
||||
//! Returns an list of mimetypes specified in this file.
|
||||
/*! @return Returns a list of the "MimeType=" entries.
|
||||
@ -155,6 +162,8 @@ public:
|
||||
|
||||
//! This function is provided for convenience. It's equivalent to calling localizedValue("Name").toString().
|
||||
QString name() const { return localizedValue(QLatin1String("Name")).toString(); }
|
||||
//! Returns an (localized) name for application action \param action.
|
||||
QString actionName(const QString & action) const;
|
||||
|
||||
//! This function is provided for convenience. It's equivalent to calling localizedValue("Comment").toString().
|
||||
QString comment() const { return localizedValue(QLatin1String("Comment")).toString(); }
|
||||
@ -175,6 +184,19 @@ public:
|
||||
//! This function is provided for convenience. It's equivalent to calling startDetached(QStringList(url)).
|
||||
bool startDetached(const QString& url = QString()) const;
|
||||
|
||||
/*! For file with Application type. Activates action defined by the \param action. Action is activated
|
||||
* either with the [Desktop Action %s]/Exec or by the D-Bus if the [Desktop Entry]/DBusActivatable is set.
|
||||
* \note Starting is done the same way as \sa startDetached()
|
||||
*
|
||||
* \return true on success; otherwise returns false.
|
||||
* \param urls - A list of files or URLS. Each file is passed as a separate argument to the executable program.
|
||||
*
|
||||
* For file with Link type, do nothing.
|
||||
*
|
||||
* For file with Directory type, do nothing.
|
||||
*/
|
||||
bool actionActivate(const QString & action, const QStringList & urls) const;
|
||||
|
||||
/*! A Exec value consists of an executable program optionally followed by one or more arguments.
|
||||
This function expands this arguments and returns command line string parts.
|
||||
Note this method make sense only for Application type.
|
||||
|
Loading…
x
Reference in New Issue
Block a user