10#include "config-xmlgui.h"
20#include <QDomDocument>
22#include <QCoreApplication>
28#include <QStandardPaths>
31#include <ksharedconfig.h>
32#include <kconfiggroup.h>
79 void configureAction(QAction *action,
const QDomNamedNodeMap &attributes,
111 QString componentName = _componentName.isEmpty() ? QCoreApplication::applicationName() : _componentName;
114 if (!QDir::isRelativePath(filename)) {
118 xml_file = QStandardPaths::locate(QStandardPaths::AppDataLocation, QStringLiteral(
"kxmlgui5/") + componentName + QLatin1Char(
'/') + filename);
119 if (!QFile::exists(xml_file)) {
121 xml_file = QStringLiteral(
":/kxmlgui5/") + componentName + QLatin1Char(
'/') + filename;
125 if (!QFile::exists(xml_file)) {
127 xml_file = QStandardPaths::locate(QStandardPaths::AppDataLocation, componentName + QLatin1Char(
'/') + filename);
131 if (!QFile::exists(xml_file)) {
135 xml_file = QStandardPaths::locate(QStandardPaths::AppDataLocation, filename);
140 qWarning() <<
"kxmlguifactory: KisKXMLGUI file found at deprecated location" << xml_file <<
"-- please use ${KisKXMLGUI_INSTALL_DIR} to install these files instead.";
144 QFile file(xml_file);
145 if (xml_file.isEmpty() || !file.open(QIODevice::ReadOnly)) {
146 qCritical() <<
"No such XML file" << filename;
150 QByteArray buffer(file.readAll());
151 return QString::fromUtf8(buffer.constData(), buffer.size());
155 const QString &filename,
const QString &_componentName)
157 QString componentName = _componentName.isEmpty() ? QCoreApplication::applicationName() : _componentName;
158 QString xml_file(filename);
160 if (QDir::isRelativePath(xml_file))
161 xml_file = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) +
162 QStringLiteral(
"/kxmlgui5/") + componentName + QLatin1Char(
'/') + filename;
164 QFileInfo fileInfo(xml_file);
165 QDir().mkpath(fileInfo.absolutePath());
166 QFile file(xml_file);
167 if (xml_file.isEmpty() || !file.open(QIODevice::WriteOnly)) {
168 qCritical() <<
"Could not write to" << filename;
174 QTextStream ts(&file);
225 if (client->
factory() ==
this) {
257 if (doc.documentElement().isNull()) {
261 QDomElement docElement = doc.documentElement();
296 d->BuildState::reset();
329 const QLatin1String tagActionProp(
"ActionProperties");
330 QDomElement e = doc.documentElement().firstChildElement();
331 for (; !e.isNull(); e = e.nextSiblingElement()) {
332 if (QString::compare(e.tagName(), tagActionProp, Qt::CaseInsensitive) == 0) {
336 return QDomElement();
348 if (!actionPropElement.isNull()) {
358 Q_FOREACH (QAction *action, actions) {
360 if (!action || action->property(
"_k_DefaultShortcut").isValid()) {
371 if ((!activeShortcut.isEmpty()) && defaultShortcut.isEmpty()) {
372 action->setProperty(
"_k_DefaultShortcut", QVariant::fromValue(activeShortcut));
374 action->setProperty(
"_k_DefaultShortcut", QVariant::fromValue(defaultShortcut));
389 if (!client || client->
factory() !=
this) {
423 if (doc.documentElement().isNull()) {
424 doc = client->
domDocument().cloneNode(
true).toDocument();
431 d->BuildState::reset();
481 if (containerName.isEmpty()) {
520static inline bool equals(
const QString &str1,
const char *str2)
522 return str1.compare(QLatin1String(str2), Qt::CaseInsensitive) == 0;
524static inline bool equals(
const QString &str1,
const QString &str2)
526 return str1.compare(str2, Qt::CaseInsensitive) == 0;
530 const QString &tagName)
560 d->BuildState::reset();
573 d->BuildState::reset();
580 for (QDomElement e = actionPropElement.firstChildElement();
581 !e.isNull(); e = e.nextSiblingElement()) {
582 if (!
equals(e.tagName(),
"action")) {
598 for (
int i = 0; i < attributes.length(); i++) {
599 QDomAttr attr = attributes.item(i).toAttr();
611 QString
attrName = attribute.name();
614 attrName = QStringLiteral(
"shortcut");
627 QVariant propertyValue;
629 QVariant::Type propertyType = action->property(
attrName.toLatin1().constData()).type();
630 bool isShortcut = (propertyType == QVariant::KeySequence);
632 if (propertyType == QVariant::Int) {
633 propertyValue = QVariant(attribute.value().toInt());
634 }
else if (propertyType == QVariant::UInt) {
635 propertyValue = QVariant(attribute.value().toUInt());
636 }
else if (isShortcut) {
639 action->setShortcuts(QKeySequence::listFromString(attribute.value()));
641 action->setProperty(
"defaultShortcuts",
642 QVariant::fromValue(QKeySequence::listFromString(attribute.value())));
645 propertyValue = QVariant(attribute.value());
647 if (!isShortcut && !action->setProperty(
attrName.toLatin1().constData(), propertyValue)) {
648 qWarning() <<
"Error: Unknown action property " <<
attrName <<
" will be ignored!";
660 elem = doc.createElement(QStringLiteral(
"ActionProperties"));
661 doc.documentElement().appendChild(elem);
668 const QLatin1String attrName(
"name");
669 for (QDomNode it = elem.firstChild(); !it.isNull(); it = it.nextSibling()) {
670 QDomElement e = it.toElement();
671 if (e.attribute(attrName) == sName) {
677 QDomElement act_elem = elem.ownerDocument().createElement(QStringLiteral(
"Action"));
678 act_elem.setAttribute(attrName, sName);
679 elem.appendChild(act_elem);
682 return QDomElement();
QList< QAction * > actions() const
virtual void finalizeGUI(KisKXMLGUIClient *client)
virtual QStringList customTags() const
virtual QStringList containerTags() const
void setFactory(KisKXMLGUIFactory *factory)
void beginXMLPlug(QWidget *)
QDomDocument xmlguiBuildDocument() const
void setXMLGUIBuildDocument(const QDomDocument &doc)
KisKXMLGUIBuilder * clientBuilder() const
virtual QDomDocument domDocument() const
QAction * action(const char *name) const
void prepareXMLUnplug(QWidget *)
KisKXMLGUIFactory * factory() const
QList< KisKXMLGUIClient * > childClients()
virtual KisKActionCollection * actionCollection() const
QWidget * findRecursive(KisKXMLGUI::ContainerNode *node, bool tag)
void applyActionProperties(const QDomElement &element, ShortcutOption shortcutOption=KisKXMLGUIFactoryPrivate::SetActiveShortcut)
void configureAction(QAction *action, const QDomNamedNodeMap &attributes, ShortcutOption shortcutOption=KisKXMLGUIFactoryPrivate::SetActiveShortcut)
~KisKXMLGUIFactoryPrivate()
void saveDefaultActionProperties(const QList< QAction * > &actions)
void refreshActionProperties(KisKXMLGUIClient *client, const QList< QAction * > &actions, const QDomDocument &doc)
KisKXMLGUIFactoryPrivate()
QList< KisKXMLGUIClient * > m_clients
BuildStateStack m_stateStack
ContainerNode * m_rootNode
QString m_defaultMergingName
friend class KisKXMLGUI::BuildHelper
~KisKXMLGUIFactory() override
static QDomElement actionPropertiesElement(QDomDocument &doc)
static bool saveConfigFile(const QDomDocument &doc, const QString &filename, const QString &componentName=QString())
static QString readConfigFile(const QString &filename, const QString &componentName=QString())
void resetContainer(const QString &containerName, bool useTagName=false)
void clientRemoved(KisKXMLGUIClient *client)
void removeClient(KisKXMLGUIClient *client)
void addClient(KisKXMLGUIClient *client)
void clientAdded(KisKXMLGUIClient *client)
KisKXMLGUIFactoryPrivate *const d
static QDomElement findActionByName(QDomElement &elem, const QString &sName, bool create)
void plugActionList(KisKXMLGUIClient *client, const QString &name, const QList< QAction * > &actionList)
void unplugActionList(KisKXMLGUIClient *client, const QString &name)
QWidget * container(const QString &containerName, KisKXMLGUIClient *client, bool useTagName=false)
KisKXMLGUIFactory(KisKXMLGUIBuilder *builder, QObject *parent=0)
void forgetClient(KisKXMLGUIClient *client)
Internal, called by KisKXMLGUIClient destructor.
QList< QWidget * > containers(const QString &tagName)
QList< KisKXMLGUIClient * > clients() const
Q_DECLARE_METATYPE(KisPaintopLodLimitations)
static QDomElement findActionPropertiesElement(const QDomDocument &doc)
static bool equals(const QString &str1, const char *str2)
QIcon loadIcon(const QString &name)
void setUtf8OnStream(QTextStream &stream)
QStringList clientBuilderContainerTags
QStringList builderCustomTags
QStringList builderContainerTags
QStringList clientBuilderCustomTags
KisKXMLGUIBuilder * builder
KisKXMLGUIClient * guiClient
KisKXMLGUIBuilder * clientBuilder
void unplugActionList(BuildState &state)
KisKXMLGUIClient * client
void plugActionList(BuildState &state)
ContainerNode * findContainer(const QString &_name, bool tag)
QList< ContainerNode * > children
bool destruct(QDomElement element, BuildState &state)