Krita Source Code Documentation
Loading...
Searching...
No Matches
KisKXMLGUIClientPrivate Class Reference

Public Member Functions

QDomElement findMatchingElement (const QDomElement &base, const QDomElement &additive)
 
bool isEmptyContainer (const QDomElement &base, KisKActionCollection *actionCollection) const
 
 KisKXMLGUIClientPrivate ()
 
bool mergeXML (QDomElement &base, QDomElement &additive, KisKActionCollection *actionCollection)
 
 ~KisKXMLGUIClientPrivate ()
 

Public Attributes

KisKActionCollectionm_actionCollection
 
QMap< QString, KisKXMLGUIClient::StateChangem_actionsStateMap
 
QDomDocument m_buildDocument
 
KisKXMLGUIBuilderm_builder
 
QList< KisKXMLGUIClient * > m_children
 
QString m_componentName
 
QDomDocument m_doc
 
QPointer< KisKXMLGUIFactorym_factory
 
QString m_localXMLFile
 
KisKXMLGUIClientm_parent
 
QStringList m_textTagNames
 
QString m_xmlFile
 

Detailed Description

Definition at line 33 of file kxmlguiclient.cpp.

Constructor & Destructor Documentation

◆ KisKXMLGUIClientPrivate()

KisKXMLGUIClientPrivate::KisKXMLGUIClientPrivate ( )
inline

Definition at line 36 of file kxmlguiclient.cpp.

37 : m_componentName(QCoreApplication::applicationName()),
39 m_parent(0L),
40 m_builder(0L)
41 {
42 m_textTagNames.append(QLatin1String("text"));
43 m_textTagNames.append(QLatin1String("Text"));
44 m_textTagNames.append(QLatin1String("title"));
45 }
KisKXMLGUIBuilder * m_builder
KisKActionCollection * m_actionCollection
KisKXMLGUIClient * m_parent

References m_textTagNames.

◆ ~KisKXMLGUIClientPrivate()

KisKXMLGUIClientPrivate::~KisKXMLGUIClientPrivate ( )
inline

Definition at line 46 of file kxmlguiclient.cpp.

47 {
48 }

Member Function Documentation

◆ findMatchingElement()

QDomElement KisKXMLGUIClientPrivate::findMatchingElement ( const QDomElement & base,
const QDomElement & additive )

Definition at line 604 of file kxmlguiclient.cpp.

605{
606 QDomNode n = additive.firstChild();
607 while (!n.isNull()) {
608 QDomElement e = n.toElement();
609 n = n.nextSibling(); // Advance now so that we can safely delete e -- TODO we don't, so simplify this
610 if (e.isNull()) {
611 continue;
612 }
613
614 const QString tag = e.tagName();
615 // skip all action and merge tags as we will never use them
616 if (equalstr(tag, QLatin1String("Action"))
617 || equalstr(tag, QLatin1String("MergeLocal"))) {
618 continue;
619 }
620
621 // now see if our tags are equivalent
622 if (equalstr(tag, base.tagName()) &&
623 e.attribute(QStringLiteral("name")) == base.attribute(QStringLiteral("name"))) {
624 return e;
625 }
626 }
627
628 // nope, return a (now) null element
629 return QDomElement();
630}
static bool equalstr(const QString &a, const QString &b)

References equalstr().

◆ isEmptyContainer()

bool KisKXMLGUIClientPrivate::isEmptyContainer ( const QDomElement & base,
KisKActionCollection * actionCollection ) const

Definition at line 551 of file kxmlguiclient.cpp.

552{
553 // now we check if we are empty (in which case we return "true", to
554 // indicate the caller that it can delete "us" (the base element
555 // argument of "this" call)
556 QDomNode n = base.firstChild();
557 while (!n.isNull()) {
558 const QDomElement e = n.toElement();
559 n = n.nextSibling(); // Advance now so that we can safely delete e
560 if (e.isNull()) {
561 continue;
562 }
563
564 const QString tag = e.tagName();
565
566 if (equalstr(tag, QLatin1String("Action"))) {
567 // if base contains an implemented action, then we must not get
568 // deleted (note that the actionCollection contains both,
569 // "global" and "local" actions)
570 if (actionCollection->action(e.attribute(QStringLiteral("name")))) {
571 return false;
572 }
573 } else if (equalstr(tag, QLatin1String("Separator"))) {
574 // if we have a separator which has *not* the weak attribute
575 // set, then it must be owned by the "local" tree in which case
576 // we must not get deleted either
577 const QString weakAttr = e.attribute(QStringLiteral("weakSeparator"));
578 if (weakAttr.isEmpty() || weakAttr.toInt() != 1) {
579 return false;
580 }
581 }
582
583 else if (equalstr(tag, QLatin1String("merge"))) {
584 continue;
585 }
586
587 // a text tag is NOT enough to spare this container
588 else if (equalstr(tag, QLatin1String("text"))) {
589 continue;
590 }
591
592 // what's left are non-empty containers! *don't* delete us in this
593 // case (at this position we can be *sure* that the container is
594 // *not* empty, as the recursive call for it was in the first loop
595 // which deleted the element in case the call returned "true"
596 else {
597 return false;
598 }
599 }
600
601 return true; // I'm empty, please delete me.
602}
QAction * action(int index) const

References KisKActionCollection::action(), and equalstr().

◆ mergeXML()

bool KisKXMLGUIClientPrivate::mergeXML ( QDomElement & base,
QDomElement & additive,
KisKActionCollection * actionCollection )

Definition at line 372 of file kxmlguiclient.cpp.

373{
374 const QLatin1String tagAction("Action");
375 const QLatin1String tagMerge("Merge");
376 const QLatin1String tagSeparator("Separator");
377 const QLatin1String tagMergeLocal("MergeLocal");
378 const QLatin1String tagText("text");
379 const QLatin1String attrAppend("append");
380 const QString attrName(QStringLiteral("name"));
381 const QString attrWeakSeparator(QStringLiteral("weakSeparator"));
382 const QString attrAlreadyVisited(QStringLiteral("alreadyVisited"));
383 const QString attrNoMerge(QStringLiteral("noMerge"));
384 const QLatin1String attrOne("1");
385
386 // there is a possibility that we don't want to merge in the
387 // additive.. rather, we might want to *replace* the base with the
388 // additive. this can be for any container.. either at a file wide
389 // level or a simple container level. we look for the 'noMerge'
390 // tag, in any event and just replace the old with the new
391 if (additive.attribute(attrNoMerge) == attrOne) { // ### use toInt() instead? (Simon)
392 base.parentNode().replaceChild(additive, base);
393 return true;
394 } else {
395 // Merge attributes
396 {
397 const QDomNamedNodeMap attribs = additive.attributes();
398 const uint attribcount = attribs.count();
399
400 for (uint i = 0; i < attribcount; ++i) {
401 const QDomNode node = attribs.item(i);
402 base.setAttribute(node.nodeName(), node.nodeValue());
403 }
404 }
405
406 // iterate over all elements in the container (of the global DOM tree)
407 QDomNode n = base.firstChild();
408 while (!n.isNull()) {
409 QDomElement e = n.toElement();
410 n = n.nextSibling(); // Advance now so that we can safely delete e
411 if (e.isNull()) {
412 continue;
413 }
414
415 const QString tag = e.tagName();
416
417 // if there's an action tag in the global tree and the action is
418 // not implemented, then we remove the element
419 if (equalstr(tag, tagAction)) {
420 const QString name = e.attribute(attrName);
421 if (!actionCollection->action(name)) {
422 // remove this child as we aren't using it
423 base.removeChild(e);
424 continue;
425 }
426 }
427
428 // if there's a separator defined in the global tree, then add an
429 // attribute, specifying that this is a "weak" separator
430 else if (equalstr(tag, tagSeparator)) {
431 e.setAttribute(attrWeakSeparator, (uint)1);
432
433 // okay, hack time. if the last item was a weak separator OR
434 // this is the first item in a container, then we nuke the
435 // current one
436 QDomElement prev = e.previousSibling().toElement();
437 if (prev.isNull() ||
438 (equalstr(prev.tagName(), tagSeparator) && !prev.attribute(attrWeakSeparator).isNull()) ||
439 (equalstr(prev.tagName(), tagText))) {
440 // the previous element was a weak separator or didn't exist
441 base.removeChild(e);
442 continue;
443 }
444 }
445
446 // the MergeLocal tag lets us specify where non-standard elements
447 // of the local tree shall be merged in. After inserting the
448 // elements we delete this element
449 else if (equalstr(tag, tagMergeLocal)) {
450 QDomNode it = additive.firstChild();
451 while (!it.isNull()) {
452 QDomElement newChild = it.toElement();
453 it = it.nextSibling();
454 if (newChild.isNull()) {
455 continue;
456 }
457
458 if (equalstr(newChild.tagName(), tagText)) {
459 continue;
460 }
461
462 if (newChild.attribute(attrAlreadyVisited) == attrOne) {
463 continue;
464 }
465
466 QString itAppend(newChild.attribute(attrAppend));
467 QString elemName(e.attribute(attrName));
468
469 if ((itAppend.isNull() && elemName.isEmpty()) ||
470 (itAppend == elemName)) {
471 // first, see if this new element matches a standard one in
472 // the global file. if it does, then we skip it as it will
473 // be merged in, later
474 QDomElement matchingElement = findMatchingElement(newChild, base);
475 if (matchingElement.isNull() || equalstr(newChild.tagName(), tagSeparator)) {
476 base.insertBefore(newChild, e);
477 }
478 }
479 }
480
481 base.removeChild(e);
482 continue;
483 }
484
485 else if (equalstr(tag, tagText)) {
486 continue;
487 } else if (equalstr(tag, tagMerge)) {
488 continue;
489 }
490
491 // in this last case we check for a separator tag and, if not, we
492 // can be sure that it is a container --> proceed with child nodes
493 // recursively and delete the just proceeded container item in
494 // case it is empty (if the recursive call returns true)
495 else {
496 QDomElement matchingElement = findMatchingElement(e, additive);
497 if (!matchingElement.isNull()) {
498 matchingElement.setAttribute(attrAlreadyVisited, (uint)1);
499
500 if (mergeXML(e, matchingElement, actionCollection)) {
501 base.removeChild(e);
502 additive.removeChild(matchingElement); // make sure we don't append it below
503 continue;
504 }
505
506 continue;
507 } else {
508 // this is an important case here! We reach this point if the
509 // "local" tree does not contain a container definition for
510 // this container. However we have to call mergeXML recursively
511 // and make it check if there are actions implemented for this
512 // container. *If* none, then we can remove this container now
513 QDomElement dummy;
514 if (mergeXML(e, dummy, actionCollection)) {
515 base.removeChild(e);
516 }
517 continue;
518 }
519 }
520 }
521
522 //here we append all child elements which were not inserted
523 //previously via the LocalMerge tag
524 n = additive.firstChild();
525 while (!n.isNull()) {
526 QDomElement e = n.toElement();
527 n = n.nextSibling(); // Advance now so that we can safely delete e
528 if (e.isNull()) {
529 continue;
530 }
531
532 QDomElement matchingElement = findMatchingElement(e, base);
533
534 if (matchingElement.isNull()) {
535 base.appendChild(e);
536 }
537 }
538
539 // do one quick check to make sure that the last element was not
540 // a weak separator
541 QDomElement last = base.lastChild().toElement();
542 if (equalstr(last.tagName(), tagSeparator) &&
543 (!last.attribute(attrWeakSeparator).isNull())) {
544 base.removeChild(last);
545 }
546 }
547
548 return isEmptyContainer(base, actionCollection);
549}
unsigned int uint
bool isEmptyContainer(const QDomElement &base, KisKActionCollection *actionCollection) const
bool mergeXML(QDomElement &base, QDomElement &additive, KisKActionCollection *actionCollection)
QDomElement findMatchingElement(const QDomElement &base, const QDomElement &additive)
const char * name(StandardAction id)

References KisKActionCollection::action(), equalstr(), findMatchingElement(), isEmptyContainer(), and mergeXML().

Member Data Documentation

◆ m_actionCollection

KisKActionCollection* KisKXMLGUIClientPrivate::m_actionCollection

Definition at line 61 of file kxmlguiclient.cpp.

◆ m_actionsStateMap

QMap<QString, KisKXMLGUIClient::StateChange> KisKXMLGUIClientPrivate::m_actionsStateMap

Definition at line 73 of file kxmlguiclient.cpp.

◆ m_buildDocument

QDomDocument KisKXMLGUIClientPrivate::m_buildDocument

Definition at line 62 of file kxmlguiclient.cpp.

◆ m_builder

KisKXMLGUIBuilder* KisKXMLGUIClientPrivate::m_builder

Definition at line 67 of file kxmlguiclient.cpp.

◆ m_children

QList<KisKXMLGUIClient *> KisKXMLGUIClientPrivate::m_children

Definition at line 66 of file kxmlguiclient.cpp.

◆ m_componentName

QString KisKXMLGUIClientPrivate::m_componentName

Definition at line 58 of file kxmlguiclient.cpp.

◆ m_doc

QDomDocument KisKXMLGUIClientPrivate::m_doc

Definition at line 60 of file kxmlguiclient.cpp.

◆ m_factory

QPointer<KisKXMLGUIFactory> KisKXMLGUIClientPrivate::m_factory

Definition at line 63 of file kxmlguiclient.cpp.

◆ m_localXMLFile

QString KisKXMLGUIClientPrivate::m_localXMLFile

Definition at line 69 of file kxmlguiclient.cpp.

◆ m_parent

KisKXMLGUIClient* KisKXMLGUIClientPrivate::m_parent

Definition at line 64 of file kxmlguiclient.cpp.

◆ m_textTagNames

QStringList KisKXMLGUIClientPrivate::m_textTagNames

Definition at line 70 of file kxmlguiclient.cpp.

◆ m_xmlFile

QString KisKXMLGUIClientPrivate::m_xmlFile

Definition at line 68 of file kxmlguiclient.cpp.


The documentation for this class was generated from the following file: