12#include "config-xmlgui.h"
16#include <QDialogButtonBox>
17#include <QDomDocument>
24#include <QApplication>
29#include <QStandardPaths>
34#include <klistwidgetsearchline.h>
35#include <klocalizedstring.h>
36#include <kmessagebox.h>
37#include <kseparator.h>
49static const char separatorstring[] = QT_TRANSLATE_NOOP(
"KEditToolBar",
"--- separator ---");
51#define SEPARATORSTRING i18n(separatorstring)
67 for (QDomElement elem = start; !elem.isNull(); elem = elem.nextSiblingElement()) {
68 if (elem.tagName() == QStringLiteral(
"ToolBar")) {
69 if (elem.attribute(QStringLiteral(
"noEdit")) != QLatin1String(
"true")) {
73 if (elem.tagName() != QStringLiteral(
"MenuBar")) {
102 qDebug() <<
"XmlData" <<
this <<
"xmlFile:" <<
m_xmlFile;
103 foreach (
const QDomElement &element,
m_barList) {
110 qDebug() <<
" no action collection.";
174 const QLatin1String attrName(
"name");
177 QByteArray txt(it.namedItem(QStringLiteral(
"text")).toElement().text().toUtf8());
179 txt = it.namedItem(QStringLiteral(
"text")).toElement().text().toUtf8();
182 name = it.attribute(attrName);
184 QByteArray domain = it.namedItem(QStringLiteral(
"text")).toElement().attribute(QStringLiteral(
"translationDomain")).toUtf8();
185 if (domain.isEmpty()) {
186 domain = it.ownerDocument().documentElement().attribute(QStringLiteral(
"translationDomain")).toUtf8();
187 if (domain.isEmpty()) {
188 domain = KLocalizedString::applicationDomain();
191 name = i18nd(domain.constData(), txt.constData());
198 QString doc_name(
m_document.documentElement().attribute(attrName));
199 name += QStringLiteral(
" <") + doc_name + QLatin1Char(
'>');
207 ToolBarItem(QListWidget *parent,
const QString &tag = QString(),
const QString &name = QString(),
const QString &
statusText = QString())
208 : QListWidgetItem(parent),
216 setFlags((flags() | Qt::ItemIsDragEnabled) & ~Qt::ItemIsDropEnabled);
262 return listWidget()->row(
const_cast<ToolBarItem *
>(
this));
287 QString internalName;
305 : QListWidget(parent),
308 setDragDropMode(QAbstractItemView::DragDrop);
311#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
317 if (items.isEmpty()) {
320 QMimeData *mimedata =
new QMimeData();
324 QDataStream stream(&data, QIODevice::WriteOnly);
330 mimedata->setData(QStringLiteral(
"application/x-kde-action-list"), data);
331 mimedata->setData(QStringLiteral(
"application/x-kde-source-treewidget"), m_activeList ?
"active" :
"inactive");
339 const QByteArray data =
mimeData->data(QStringLiteral(
"application/x-kde-action-list"));
340 if (data.isEmpty()) {
343 QDataStream stream(data);
344 const bool sourceIsActiveList =
mimeData->data(QStringLiteral(
"application/x-kde-source-treewidget")) ==
"active";
347 Q_EMIT
dropped(
this, index, item, sourceIsActiveList);
353 return static_cast<ToolBarItem *
>(QListWidget::currentItem());
359 setWindowTitle(i18n(
"Change Text"));
362 QVBoxLayout *layout =
new QVBoxLayout(
this);
364 QGridLayout *grid =
new QGridLayout;
365 grid->setContentsMargins(0, 0, 0, 0);
369 QLabel *label =
new QLabel(i18n(
"Icon te&xt:"),
this);
371 grid->addWidget(label, 0, 0);
374 m_cbHidden =
new QCheckBox(i18n(
"&Hide text when toolbar shows text alongside icons"),
this);
377 layout->addLayout(grid);
380 m_buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
388 setFixedHeight(sizeHint().height());
414 m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!text.trimmed().isEmpty());
438 const int iconSize = widget->style()->pixelMetric(QStyle::PM_SmallIconSize);
465 void initOldStyle(
const QString &file,
bool global,
const QString &defaultToolbar);
470 QString
xmlFile(
const QString &xml_file)
const
472 return xml_file.isEmpty() ?
m_componentName + QStringLiteral(
"ui.xmlgui") : xml_file;
481 QString xml_file =
xmlFile(_xml_file);
484 if (!QDir::isRelativePath(xml_file)) {
500 QDomElement elem = n.toElement();
501 if ((elem.attribute(QStringLiteral(
"name")) == item->
internalName()) &&
507 return QDomElement();
603 d->m_factory = factory;
613 q->setWindowTitle(i18n(
"Configure Toolbars"));
621 m_buttonBox->setStandardButtons(QDialogButtonBox::RestoreDefaults
622 | QDialogButtonBox::Ok
623 | QDialogButtonBox::Apply
624 | QDialogButtonBox::Cancel);
625 KGuiItem::assign(
m_buttonBox->button(QDialogButtonBox::Ok), KStandardGuiItem::ok());
626 KGuiItem::assign(
m_buttonBox->button(QDialogButtonBox::Apply), KStandardGuiItem::apply());
627 KGuiItem::assign(
m_buttonBox->button(QDialogButtonBox::Cancel), KStandardGuiItem::cancel());
628 KGuiItem::assign(
m_buttonBox->button(QDialogButtonBox::RestoreDefaults), KStandardGuiItem::defaults());
630 q->connect(
m_buttonBox, SIGNAL(rejected()), SLOT(reject()));
637 q->setMinimumSize(
q->sizeHint());
650 s_defaultToolBarName()->clear();
655 if (toolBarName.isEmpty()) {
664 m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(b);
670 m_buttonBox->button(QDialogButtonBox::Apply)->setEnabled(b);
675 if (KMessageBox::warningContinueCancel(
q, i18n(
"Do you really want to reset all toolbars of this application to their default? The changes will be applied immediately."), i18n(
"Reset Toolbars"), KGuiItem(i18n(
"Reset"))) != KMessageBox::Continue) {
686 if (file.isEmpty()) {
691 if (QFile::exists(file))
692 if (!QFile::remove(file)) {
693 qWarning() <<
"Could not delete" << file;
703 int slash =
m_file.lastIndexOf(QLatin1Char(
'/')) + 1;
707 const QString xml_file = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) +
708 QStringLiteral(
"/kxmlgui5/") + QCoreApplication::instance()->applicationName() + QLatin1Char(
'/') +
m_file;
710 if (QFile::exists(xml_file))
711 if (!QFile::remove(xml_file)) {
712 qWarning() <<
"Could not delete " << xml_file;
720 m_widget->setGeometry(oldWidget->geometry());
738 case QDialogButtonBox::Ok:
741 case QDialogButtonBox::Apply:
744 case QDialogButtonBox::RestoreDefaults:
761 if (
m_buttonBox->button(QDialogButtonBox::Apply)->isEnabled()) {
779 *s_defaultToolBarName() = QString::fromLatin1(toolbarName);
814 const QString &defaultToolBar)
816 qDebug() <<
"initOldStyle";
829 const QString localXML =
loadXMLFile(resourceFile);
835 domDoc.setContent(localXML);
855 const QString &defaultToolBar)
857 qDebug() <<
"initFromFactory";
870 if (client->
xmlFile().isEmpty()) {
900 action->setShortcutContext(Qt::WidgetWithChildrenShortcut);
910 if (!((*it).m_isModified)) {
920 QDomNodeList menuNodes = (*it).domDocument().elementsByTagName(QStringLiteral(
"Menu"));
921 for (
int i = 0; i < menuNodes.length(); ++i) {
922 QDomNode menuNode = menuNodes.item(i);
923 QDomElement menuElement = menuNode.toElement();
924 if (menuElement.isNull()) {
927 menuElement.setAttribute(QStringLiteral(
"noMerge"), QLatin1String(
"1"));
954 if (!clients.count()) {
958 QListIterator<KisKXMLGUIClient *> clientIterator = clients;
959 clientIterator.toBack();
960 while (clientIterator.hasPrevious()) {
972 QString file(client->
xmlFile());
973 if (!file.isEmpty()) {
978 if (client == firstClient) {
983 client->
setXMLFile(file, client == firstClient );
1015 QLabel *inactive_label =
new QLabel(i18n(
"A&vailable actions:"),
m_widget);
1024 QObject::connect(
m_inactiveList, SIGNAL(itemDoubleClicked(QListWidgetItem*)),
1032 QObject::connect(scroller, &QScroller::stateChanged,
m_widget, [&](QScroller::State state) {
1039 inactiveListSearchLine->setPlaceholderText(i18nc(
"Filter as in showing only matching items",
"Filter"));
1042 QLabel *active_label =
new QLabel(i18n(
"Curr&ent actions:"),
m_widget);
1050 QObject::connect(
m_activeList, SIGNAL(itemSelectionChanged()),
1052 QObject::connect(
m_activeList, SIGNAL(itemDoubleClicked(QListWidgetItem*)),
1059 QObject::connect(scroller, &QScroller::stateChanged,
m_widget, [&](QScroller::State state) {
1074 KListWidgetSearchLine *activeListSearchLine =
new KListWidgetSearchLine(
m_widget,
m_activeList);
1075 activeListSearchLine->setPlaceholderText(i18n(
"Filter"));
1105 QVBoxLayout *top_layout =
new QVBoxLayout(
m_widget);
1106 top_layout->setContentsMargins(0, 0, 0, 0);
1108 QVBoxLayout *name_layout =
new QVBoxLayout();
1109 QHBoxLayout *list_layout =
new QHBoxLayout();
1111 QVBoxLayout *inactive_layout =
new QVBoxLayout();
1112 QVBoxLayout *active_layout =
new QVBoxLayout();
1114 QGridLayout *button_layout =
new QGridLayout();
1121 button_layout->setSpacing(0);
1122 button_layout->setRowStretch(0, 10);
1127 button_layout->setRowStretch(4, 10);
1129 inactive_layout->addWidget(inactive_label);
1130 inactive_layout->addWidget(inactiveListSearchLine);
1133 active_layout->addWidget(active_label);
1134 active_layout->addWidget(activeListSearchLine);
1138 list_layout->addLayout(inactive_layout);
1139 list_layout->addLayout(button_layout);
1140 list_layout->addLayout(active_layout);
1142 top_layout->addLayout(name_layout);
1144 top_layout->addLayout(list_layout, 10);
1146 top_layout->addWidget(
new KSeparator(
m_widget));
1151 const QLatin1String attrName(
"name");
1155 int defaultToolBarId = -1;
1159 for (; xit !=
m_xmlFiles.constEnd(); ++xit) {
1168 ToolBarList::const_iterator it = (*xit).barList().begin();
1169 for (; it != (*xit).barList().constEnd(); ++it) {
1170 const QString text = (*xit).toolBarText(*it);
1172 const QString name = (*it).attribute(attrName);
1173 if (defaultToolBarId == -1 && name == defaultToolBar) {
1174 defaultToolBarId = count;
1179 const bool showCombo = (count > 1);
1183 if (defaultToolBarId == -1) {
1184 defaultToolBarId = 0;
1193 const QLatin1String tagSeparator(
"Separator");
1194 const QLatin1String tagMerge(
"Merge");
1195 const QLatin1String tagActionList(
"ActionList");
1196 const QLatin1String tagAction(
"Action");
1197 const QLatin1String attrName(
"name");
1200 QString sep_name(QStringLiteral(
"separator_%1"));
1214 QSet<QString> active_list;
1217 KLocalizedString nameFilter = ki18nc(
"@item:intable Action name in toolbar editor",
"%1");
1220 QDomNode n = elem.firstChild();
1221 for (; !n.isNull(); n = n.nextSibling()) {
1222 QDomElement it = n.toElement();
1226 if (it.tagName() == tagSeparator) {
1234 if (it.tagName() == tagMerge) {
1236 QString name = it.attribute(attrName);
1238 if (name.isEmpty()) {
1239 act->setText(i18n(
"<Merge>"));
1241 act->setText(i18n(
"<Merge %1>", name));
1246 if (it.tagName() == tagActionList) {
1247 ToolBarItem *act =
new ToolBarItem(
m_activeList, tagActionList, it.attribute(attrName), i18n(
"This is a dynamic list of actions. You can move it, but if you remove it you will not be able to re-add it."));
1248 act->setText(i18n(
"ActionList: %1", it.attribute(attrName)));
1255 foreach (QAction *action, actionCollection->
actions()) {
1257 if (it.attribute(attrName) == action->objectName()) {
1260 act->setText(nameFilter.subs(KLocalizedString::removeAcceleratorMarker(action->iconText())).toString());
1261 act->setIcon(!action->icon().isNull() ? action->icon() :
m_emptyIcon);
1264 active_list.insert(action->objectName());
1271 foreach (QAction *action, actionCollection->
actions()) {
1273 if (active_list.contains(action->objectName())) {
1278 act->setText(nameFilter.subs(KLocalizedString::removeAcceleratorMarker(action->text())).toString());
1279 act->setIcon(!action->icon().isNull() ? action->icon() :
m_emptyIcon);
1301 int toolbarNumber = 0;
1312 ToolBarList::Iterator it = (*xit).barList().begin();
1313 for (; it != (*xit).barList().end(); ++it) {
1316 if (toolbarNumber == index) {
1347 m_helpArea->setText(i18nc(
"@label Action tooltip in toolbar editor, below the action list",
"%1", statusText));
1366 m_downAction->setEnabled(toolitem->
index() != toolitem->listWidget()->count() - 1);
1369 m_helpArea->setText(i18nc(
"@label Action tooltip in toolbar editor, below the action list",
"%1", statusText));
1393 for (
int i = 0; i < activeItemCount; i++) {
1415 QDomElement new_item;
1423 new_item.setAttribute(QStringLiteral(
"name"), item->
internalName());
1431 Q_ASSERT(!elem.isNull());
1460 if (!elem.isNull()) {
1477 int row = item->listWidget()->row(item) - 1;
1524 int newRow = item->listWidget()->row(item) + 1;
1545 dialog.setWindowTitle(i18n(
"Choose Icon"));
1546 dialog.resize(480, 500);
1548 QVBoxLayout *layout =
new QVBoxLayout(&dialog);
1551 QLineEdit *filterEdit =
new QLineEdit(&dialog);
1552 filterEdit->setPlaceholderText(i18n(
"Filter icons..."));
1553 layout->addWidget(filterEdit);
1556 QListWidget *list =
new QListWidget(&dialog);
1557 list->setViewMode(QListView::ListMode);
1558 list->setIconSize(QSize(22, 22));
1559 list->setResizeMode(QListWidget::Adjust);
1560 list->setSelectionMode(QAbstractItemView::SingleSelection);
1563 QObject::connect(scroller, &QScroller::stateChanged,
m_widget, [&](QScroller::State state) {
1569 for (
const QString &iconName : loadedIcons) {
1570 QListWidgetItem *item =
new QListWidgetItem(
1575 item->setData(Qt::UserRole, iconName);
1577 layout->addWidget(list);
1580 QDialogButtonBox *backButton =
new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, &dialog);
1581 layout->addWidget(backButton);
1583 QObject::connect(backButton, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
1584 QObject::connect(backButton, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
1587 QObject::connect(filterEdit, &QLineEdit::textChanged, &dialog, [&list](
const QString &text) {
1588 for (
int i = 0; i < list->count(); ++i) {
1589 QListWidgetItem *item = list->item(i);
1590 bool match = item->text().contains(text, Qt::CaseInsensitive);
1591 item->setHidden(!match);
1596 QString currentIconName = elem.attribute(QStringLiteral(
"icon"));
1597 for (
int i = 0; i < list->count(); ++i) {
1598 if (list->item(i)->data(Qt::UserRole).toString() == currentIconName) {
1599 list->setCurrentItem(list->item(i));
1605 if (dialog.exec() == QDialog::Accepted && list->currentItem()) {
1606 QString chosenIconName = list->currentItem()->data(Qt::UserRole).toString();
1613 QDomElement root = doc.documentElement();
1614 QDomElement overridesElem = root.namedItem(QStringLiteral(
"ActionIconOverrides")).toElement();
1615 if (overridesElem.isNull()) {
1616 overridesElem = doc.createElement(QStringLiteral(
"ActionIconOverrides"));
1617 root.appendChild(overridesElem);
1622 QDomElement overrideAction;
1623 for (QDomNode child = overridesElem.firstChild(); !child.isNull(); child = child.nextSibling()) {
1624 QDomElement childElement = child.toElement();
1625 if (childElement.attribute(QStringLiteral(
"name")) == actionName) {
1626 overrideAction = childElement;
1630 if (overrideAction.isNull()) {
1631 overrideAction = doc.createElement(QStringLiteral(
"Action"));
1632 overrideAction.setAttribute(QStringLiteral(
"name"), actionName);
1633 overridesElem.appendChild(overrideAction);
1637 overrideAction.setAttribute(QStringLiteral(
"icon"), chosenIconName);
1660 (*xit).m_isModified =
true;
1667 (*xit).m_isModified =
true;
1668 const QLatin1String attrName(
"name");
1669 ToolBarList::Iterator it = (*xit).barList().begin();
1670 for (; it != (*xit).barList().end(); ++it) {
1671 QString name((*it).attribute(attrName));
1672 QString tag((*it).tagName());
1673 if ((tag != elem.tagName()) || (name != elem.attribute(attrName))) {
1677 QDomElement toolbar = (*xit).domDocument().documentElement().toElement();
1678 toolbar.replaceChild(elem, (*it));
1683 QDomElement toolbar = (*xit).domDocument().documentElement().toElement();
1684 Q_ASSERT(!toolbar.isNull());
1685 toolbar.appendChild(elem);
1697 if (sourceIsActiveList) {
1719 if (!event->spontaneous()) {
1723 d->m_widget->load(d->m_factory, d->m_defaultToolBar);
1726 d->m_widget->load(d->m_file, d->m_global, d->m_defaultToolBar);
1731 QDialog::showEvent(event);
1739 QDialog::hideEvent(event);
1742#include "moc_kedittoolbar.cpp"
1743#include "moc_kedittoolbar_p.cpp"
Q_GLOBAL_STATIC(KisStoragePluginRegistry, s_instance)
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
int iconSize(qreal width, qreal height)
IconTextEditDialog(QWidget *parent=0)
void setIconText(const QString &text)
QDialogButtonBox * m_buttonBox
void setTextAlongsideIconHidden(bool hidden)
void slotTextChanged(const QString &text)
bool textAlongsideIconHidden() const
QString toolBarText(const QDomElement &it) const
KisKActionCollection * actionCollection() const
XmlData(XmlType xmlType, const QString &xmlFile, KisKActionCollection *collection)
void setDomDocument(const QDomDocument &domDoc)
const ToolBarList & barList() const
KisKActionCollection * m_actionCollection
QDomDocument & domDocument()
const QDomDocument & domDocument() const
A container for a set of QAction objects.
QList< QAction * > actions() const
void addAssociatedWidget(QWidget *widget)
void setXMLGUIBuildDocument(const QDomDocument &doc)
void setDOMDocument(const QDomDocument &document, bool merge=false)
virtual QString xmlFile() const
virtual QDomDocument domDocument() const
void loadStandardsXmlFile()
virtual QString localXMLFile() const
KisKXMLGUIFactory * factory() const
void setXMLFile(const QString &file, bool merge=false, bool setXMLDoc=true)
friend class KDEPrivate::KisKEditToolBarWidget
void setXML(const QString &document, bool merge=false)
virtual KisKActionCollection * actionCollection() const
static bool saveConfigFile(const QDomDocument &doc, const QString &filename, const QString &componentName=QString())
static QString readConfigFile(const QString &filename, const QString &componentName=QString())
void removeClient(KisKXMLGUIClient *client)
void addClient(KisKXMLGUIClient *client)
QList< KisKXMLGUIClient * > clients() const
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
typedef void(QOPENGLF_APIENTRYP PFNGLINVALIDATEBUFFERDATAPROC)(GLuint buffer)
QString button(const QWheelEvent &ev)
static ToolBarList findToolBars(const QDomElement &start)
static QDataStream & operator>>(QDataStream &s, ToolBarItem &item)
static QDataStream & operator<<(QDataStream &s, const ToolBarItem &item)
QIcon loadIcon(const QString &name)
QStringList allUniqueLoadedIconNames()