You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
libqtxdg-packaging/xdgmenurules.cpp

235 lines
6.8 KiB

/* BEGIN_COMMON_COPYRIGHT_HEADER
* (c)LGPL2+
*
* Razor - a lightweight, Qt based, desktop toolset
* http://razor-qt.org
*
* Copyright: 2010-2011 Razor team
* Authors:
* Alexander Sokoloff <sokoloff.a@gmail.com>
*
* This program or library is free software; you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
*
* END_COMMON_COPYRIGHT_HEADER */
#include "xdgmenurules.h"
#include "xmlhelper.h"
#include <QDebug>
#include <QStringList>
/**
* See: http://standards.freedesktop.org/desktop-entry-spec
*/
XdgMenuRule::XdgMenuRule(const QDomElement& element, QObject* parent) :
QObject(parent)
{
Q_UNUSED(element)
}
XdgMenuRule::~XdgMenuRule()
{
}
/************************************************
The <Or> element contains a list of matching rules. If any of the matching rules
inside the <Or> element match a desktop entry, then the entire <Or> rule matches
the desktop entry.
************************************************/
XdgMenuRuleOr::XdgMenuRuleOr(const QDomElement& element, QObject* parent) :
XdgMenuRule(element, parent)
{
//qDebug() << "Create OR rule";
DomElementIterator iter(element, QString());
while(iter.hasNext())
{
QDomElement e = iter.next();
if (e.tagName() == "Or")
mChilds.append(new XdgMenuRuleOr(e, this));
else if (e.tagName() == "And")
mChilds.append(new XdgMenuRuleAnd(e, this));
else if (e.tagName() == "Not")
mChilds.append(new XdgMenuRuleNot(e, this));
else if (e.tagName() == "Filename")
mChilds.append(new XdgMenuRuleFileName(e, this));
else if (e.tagName() == "Category")
mChilds.append(new XdgMenuRuleCategory(e, this));
else if (e.tagName() == "All")
mChilds.append(new XdgMenuRuleAll(e, this));
else
qWarning() << "Unknown rule" << e.tagName();
}
}
bool XdgMenuRuleOr::check(const QString& desktopFileId, const XdgDesktopFile& desktopFile)
{
for (QLinkedList<XdgMenuRule*>::Iterator i=mChilds.begin(); i!=mChilds.end(); ++i)
if ((*i)->check(desktopFileId, desktopFile)) return true;
return false;
}
/************************************************
The <And> element contains a list of matching rules. If each of the matching rules
inside the <And> element match a desktop entry, then the entire <And> rule matches
the desktop entry.
************************************************/
XdgMenuRuleAnd::XdgMenuRuleAnd(const QDomElement& element, QObject *parent) :
XdgMenuRuleOr(element, parent)
{
// qDebug() << "Create AND rule";
}
bool XdgMenuRuleAnd::check(const QString& desktopFileId, const XdgDesktopFile& desktopFile)
{
for (QLinkedList<XdgMenuRule*>::Iterator i=mChilds.begin(); i!=mChilds.end(); ++i)
if (!(*i)->check(desktopFileId, desktopFile)) return false;
return mChilds.count();
}
/************************************************
The <Not> element contains a list of matching rules. If any of the matching rules
inside the <Not> element matches a desktop entry, then the entire <Not> rule does
not match the desktop entry. That is, matching rules below <Not> have a logical OR
relationship.
************************************************/
XdgMenuRuleNot::XdgMenuRuleNot(const QDomElement& element, QObject *parent) :
XdgMenuRuleOr(element, parent)
{
// qDebug() << "Create NOT rule";
}
bool XdgMenuRuleNot::check(const QString& desktopFileId, const XdgDesktopFile& desktopFile)
{
return ! XdgMenuRuleOr::check(desktopFileId, desktopFile);
}
/************************************************
The <Filename> element is the most basic matching rule. It matches a desktop entry
if the desktop entry has the given desktop-file id. See Desktop-File Id.
************************************************/
XdgMenuRuleFileName::XdgMenuRuleFileName(const QDomElement& element, QObject *parent) :
XdgMenuRule(element, parent)
{
//qDebug() << "Create FILENAME rule";
mId = element.text();
}
bool XdgMenuRuleFileName::check(const QString& desktopFileId, const XdgDesktopFile& desktopFile)
{
Q_UNUSED(desktopFile)
//qDebug() << "XdgMenuRuleFileName:" << desktopFileId << mId;
return desktopFileId == mId;
}
/************************************************
The <Category> element is another basic matching predicate. It matches a desktop entry
if the desktop entry has the given category in its Categories field.
************************************************/
XdgMenuRuleCategory::XdgMenuRuleCategory(const QDomElement& element, QObject *parent) :
XdgMenuRule(element, parent)
{
mCategory = element.text();
}
bool XdgMenuRuleCategory::check(const QString& desktopFileId, const XdgDesktopFile& desktopFile)
{
Q_UNUSED(desktopFileId)
QStringList cats = desktopFile.categories();
return cats.contains(mCategory);
}
/************************************************
The <All> element is a matching rule that matches all desktop entries.
************************************************/
XdgMenuRuleAll::XdgMenuRuleAll(const QDomElement& element, QObject *parent) :
XdgMenuRule(element, parent)
{
}
bool XdgMenuRuleAll::check(const QString& desktopFileId, const XdgDesktopFile& desktopFile)
{
Q_UNUSED(desktopFileId)
Q_UNUSED(desktopFile)
return true;
}
XdgMenuRules::XdgMenuRules(QObject* parent) :
QObject(parent)
{
}
XdgMenuRules::~XdgMenuRules()
{
}
void XdgMenuRules::addInclude(const QDomElement& element)
{
mIncludeRules.append(new XdgMenuRuleOr(element, this));
}
void XdgMenuRules::addExclude(const QDomElement& element)
{
mExcludeRules.append(new XdgMenuRuleOr(element, this));
}
bool XdgMenuRules::checkInclude(const QString& desktopFileId, const XdgDesktopFile& desktopFile)
{
for (QLinkedList<XdgMenuRule*>::Iterator i=mIncludeRules.begin(); i!=mIncludeRules.end(); ++i)
if ((*i)->check(desktopFileId, desktopFile)) return true;
return false;
}
bool XdgMenuRules::checkExclude(const QString& desktopFileId, const XdgDesktopFile& desktopFile)
{
for (QLinkedList<XdgMenuRule*>::Iterator i=mExcludeRules.begin(); i!=mExcludeRules.end(); ++i)
if ((*i)->check(desktopFileId, desktopFile)) return true;
return false;
}