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 32 of file kxmlguiclient.cpp.

Constructor & Destructor Documentation

◆ KisKXMLGUIClientPrivate()

KisKXMLGUIClientPrivate::KisKXMLGUIClientPrivate ( )
inline

Definition at line 35 of file kxmlguiclient.cpp.

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

References m_textTagNames.

◆ ~KisKXMLGUIClientPrivate()

KisKXMLGUIClientPrivate::~KisKXMLGUIClientPrivate ( )
inline

Definition at line 45 of file kxmlguiclient.cpp.

46 {
47 }

Member Function Documentation

◆ findMatchingElement()

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

Definition at line 611 of file kxmlguiclient.cpp.

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

References equalstr().

◆ isEmptyContainer()

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

Definition at line 558 of file kxmlguiclient.cpp.

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

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

◆ mergeXML()

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

Definition at line 379 of file kxmlguiclient.cpp.

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

Member Data Documentation

◆ m_actionCollection

KisKActionCollection* KisKXMLGUIClientPrivate::m_actionCollection

Definition at line 60 of file kxmlguiclient.cpp.

◆ m_actionsStateMap

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

Definition at line 72 of file kxmlguiclient.cpp.

◆ m_buildDocument

QDomDocument KisKXMLGUIClientPrivate::m_buildDocument

Definition at line 61 of file kxmlguiclient.cpp.

◆ m_builder

KisKXMLGUIBuilder* KisKXMLGUIClientPrivate::m_builder

Definition at line 66 of file kxmlguiclient.cpp.

◆ m_children

QList<KisKXMLGUIClient *> KisKXMLGUIClientPrivate::m_children

Definition at line 65 of file kxmlguiclient.cpp.

◆ m_componentName

QString KisKXMLGUIClientPrivate::m_componentName

Definition at line 57 of file kxmlguiclient.cpp.

◆ m_doc

QDomDocument KisKXMLGUIClientPrivate::m_doc

Definition at line 59 of file kxmlguiclient.cpp.

◆ m_factory

QPointer<KisKXMLGUIFactory> KisKXMLGUIClientPrivate::m_factory

Definition at line 62 of file kxmlguiclient.cpp.

◆ m_localXMLFile

QString KisKXMLGUIClientPrivate::m_localXMLFile

Definition at line 68 of file kxmlguiclient.cpp.

◆ m_parent

KisKXMLGUIClient* KisKXMLGUIClientPrivate::m_parent

Definition at line 63 of file kxmlguiclient.cpp.

◆ m_textTagNames

QStringList KisKXMLGUIClientPrivate::m_textTagNames

Definition at line 69 of file kxmlguiclient.cpp.

◆ m_xmlFile

QString KisKXMLGUIClientPrivate::m_xmlFile

Definition at line 67 of file kxmlguiclient.cpp.


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