Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package qpwgraph for openSUSE:Factory 
checked in at 2023-07-26 13:23:58
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/qpwgraph (Old)
 and      /work/SRC/openSUSE:Factory/.qpwgraph.new.15225 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "qpwgraph"

Wed Jul 26 13:23:58 2023 rev:18 rq:1100590 version:0.5.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/qpwgraph/qpwgraph.changes        2023-07-11 
15:57:41.369306161 +0200
+++ /work/SRC/openSUSE:Factory/.qpwgraph.new.15225/qpwgraph.changes     
2023-07-26 13:25:02.756398697 +0200
@@ -1,0 +2,19 @@
+Mon Jul 17 19:34:29 UTC 2023 - Alexei Sorokin <[email protected]>
+
+- Update to version 0.5.1:
+  * Fix segfault on initialisation that was affecting Qt5 builds.
+
+-------------------------------------------------------------------
+Sun Jul 16 15:15:29 UTC 2023 - Alexei Sorokin <[email protected]>
+
+- Update to version 0.5.0:
+  * Completely refactored the internal PipeWire node registry
+    logic, just to have unique node names, as seen fit to purpose
+    to solve an old undefined behaviour to positioning and Patchbay
+    persistence of multiple nodes with the very same and exact
+    name.
+  * Fix the main PipeWire registry thread-safety, into a two-level
+    critical section, hopefully preventing the race-conditions that
+    are the suspected cause to some rare crashes.
+
+-------------------------------------------------------------------

Old:
----
  qpwgraph-v0.4.5.tar.bz2

New:
----
  qpwgraph-v0.5.1.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ qpwgraph.spec ++++++
--- /var/tmp/diff_new_pack.uBX8Pu/_old  2023-07-26 13:25:03.284401884 +0200
+++ /var/tmp/diff_new_pack.uBX8Pu/_new  2023-07-26 13:25:03.284401884 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           qpwgraph
-Version:        0.4.5
+Version:        0.5.1
 Release:        0
 Summary:        PipeWire Graph Qt GUI Interface
 License:        GPL-2.0-or-later

++++++ qpwgraph-v0.4.5.tar.bz2 -> qpwgraph-v0.5.1.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpwgraph-v0.4.5/CMakeLists.txt 
new/qpwgraph-v0.5.1/CMakeLists.txt
--- old/qpwgraph-v0.4.5/CMakeLists.txt  2023-07-10 17:37:36.000000000 +0200
+++ new/qpwgraph-v0.5.1/CMakeLists.txt  2023-07-17 11:59:55.000000000 +0200
@@ -1,7 +1,7 @@
 cmake_minimum_required (VERSION 3.15)
 
 project(qpwgraph
-  VERSION 0.4.5
+  VERSION 0.5.1
   DESCRIPTION "A PipeWire Graph Qt GUI Interface"
   HOMEPAGE_URL "https://gitlab.freedesktop.org/rncbc/qpwgraph";
   LANGUAGES C CXX)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpwgraph-v0.4.5/ChangeLog 
new/qpwgraph-v0.5.1/ChangeLog
--- old/qpwgraph-v0.4.5/ChangeLog       2023-07-10 17:37:36.000000000 +0200
+++ new/qpwgraph-v0.5.1/ChangeLog       2023-07-17 11:59:55.000000000 +0200
@@ -2,6 +2,22 @@
 --------------------------------------------
 
 
+0.5.1  2023-07-17  A summer'23 hot-fix release.
+
+- Fixed segfault on initialization that was affecting Qt5 builds.
+
+
+0.5.0  2023-07-16  Yet another summer'23 release.
+
+- Completely refactored the internal PipeWire node registry logic,
+  just to have unique node names, as seen fit to purpose to solve
+  an old undefined behavior to positioning and Patchbay persistence
+  of multiple nodes with the very same and exact name.
+- Fixed the main PipeWire registry thread-safety, into a two-level
+  critical section, hopefully preventing the race-conditions that
+  are the suspected cause to some rare crashes.
+
+
 0.4.5  2023-07-10  A summer'23 release.
 
 - Split non-physical terminal device nodes for monitor and control
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpwgraph-v0.4.5/debian/changelog 
new/qpwgraph-v0.5.1/debian/changelog
--- old/qpwgraph-v0.4.5/debian/changelog        2023-07-10 17:37:36.000000000 
+0200
+++ new/qpwgraph-v0.5.1/debian/changelog        2023-07-17 11:59:55.000000000 
+0200
@@ -1,3 +1,15 @@
+qpwgraph (0.5.1-29.1) unstable; urgency=low
+
+  * A summer'23 hot-fix release.
+
+ -- Rui Nuno Capela <[email protected]>  Mon, 17 Jul 2023 12:00:00 +0100
+
+qpwgraph (0.5.0-28.1) unstable; urgency=low
+
+  * Yet another summer'23 release.
+
+ -- Rui Nuno Capela <[email protected]>  Sun, 16 Jul 2023 18:00:00 +0100
+
 qpwgraph (0.4.5-27.1) unstable; urgency=low
 
   * A summer'23 release.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpwgraph-v0.4.5/rpm/qpwgraph.spec 
new/qpwgraph-v0.5.1/rpm/qpwgraph.spec
--- old/qpwgraph-v0.4.5/rpm/qpwgraph.spec       2023-07-10 17:37:36.000000000 
+0200
+++ new/qpwgraph-v0.5.1/rpm/qpwgraph.spec       2023-07-17 11:59:55.000000000 
+0200
@@ -16,8 +16,8 @@
 #
 
 %define name   qpwgraph
-%define version        0.4.5
-%define release        27.1
+%define version        0.5.1
+%define release        29.1
 
 %define _prefix        /usr
 
@@ -141,6 +141,10 @@
 
 
 %changelog
+* Mon Jul 17 2023 Rui Nuno Capela <[email protected]> 0.5.1
+- A summer'23 hot-fix release.
+* Sun Jul 16 2023 Rui Nuno Capela <[email protected]> 0.5.0
+- Yet another summer'23 release.
 * Mon Jul 10 2023 Rui Nuno Capela <[email protected]> 0.4.5
 - A summer'23 release.
 * Sun Jun 18 2023 Rui Nuno Capela <[email protected]> 0.4.4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/qpwgraph-v0.4.5/src/appdata/org.rncbc.qpwgraph.metainfo.xml 
new/qpwgraph-v0.5.1/src/appdata/org.rncbc.qpwgraph.metainfo.xml
--- old/qpwgraph-v0.4.5/src/appdata/org.rncbc.qpwgraph.metainfo.xml     
2023-07-10 17:37:36.000000000 +0200
+++ new/qpwgraph-v0.5.1/src/appdata/org.rncbc.qpwgraph.metainfo.xml     
2023-07-17 11:59:55.000000000 +0200
@@ -37,7 +37,7 @@
  <developer_name>rncbc aka. Rui Nuno Capela</developer_name>
  <update_contact>[email protected]</update_contact>
  <releases>
-  <release version="0.4.5" date="2023-07-10" urgency="low" />
+  <release version="0.5.1" date="2023-07-17" urgency="low" />
  </releases>
  <content_rating type="oars-1.0"/>
 </component>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpwgraph-v0.4.5/src/config.h.cmake 
new/qpwgraph-v0.5.1/src/config.h.cmake
--- old/qpwgraph-v0.4.5/src/config.h.cmake      2023-07-10 17:37:36.000000000 
+0200
+++ new/qpwgraph-v0.5.1/src/config.h.cmake      2023-07-17 11:59:55.000000000 
+0200
@@ -29,5 +29,6 @@
 /* Define if Wayland is supported */
 #cmakedefine CONFIG_WAYLAND @CONFIG_WAYLAND@
 
+
 #endif // __CONFIG_H
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpwgraph-v0.4.5/src/qpwgraph.cpp 
new/qpwgraph-v0.5.1/src/qpwgraph.cpp
--- old/qpwgraph-v0.4.5/src/qpwgraph.cpp        2023-07-10 17:37:36.000000000 
+0200
+++ new/qpwgraph-v0.5.1/src/qpwgraph.cpp        2023-07-17 11:59:55.000000000 
+0200
@@ -232,7 +232,7 @@
                        if (form && parse_args(QString(data).split(' ')))
                                form->apply_args(this);
                        // Just make it always shows up fine...
-                       if (m_widget) {
+                       if (m_widget && !m_start_minimized) {
                                m_widget->hide();
                                m_widget->show();
                                m_widget->raise();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpwgraph-v0.4.5/src/qpwgraph_canvas.cpp 
new/qpwgraph-v0.5.1/src/qpwgraph_canvas.cpp
--- old/qpwgraph-v0.4.5/src/qpwgraph_canvas.cpp 2023-07-10 17:37:36.000000000 
+0200
+++ new/qpwgraph-v0.5.1/src/qpwgraph_canvas.cpp 2023-07-17 11:59:55.000000000 
+0200
@@ -305,9 +305,8 @@
                        emit removed(node);
                        node->removePorts();
                        removeNodeKeys(node);
-               }
-               if (node)
                        m_nodes.removeAll(node);
+               }
        }
        else
        if (item->type() == qpwgraph_port::Type) {
@@ -483,8 +482,8 @@
 
        foreach (qpwgraph_node *node, m_nodes) {
                if (node->nodeType() == node_type) {
-                       m_node_keys.remove(qpwgraph_node::NodeNameKey(node));
-                       m_node_ids.remove(qpwgraph_node::NodeIdKey(node));
+                       m_node_names.remove(qpwgraph_node::NodeNameKey(node), 
node);
+                       m_node_ids.remove(qpwgraph_node::NodeIdKey(node), node);
                        m_nodes.removeAll(node);
                        nodes.append(node);
                }
@@ -498,23 +497,22 @@
 qpwgraph_node *qpwgraph_canvas::findNode (
        uint id, qpwgraph_item::Mode mode, uint type ) const
 {
-       return static_cast<qpwgraph_node *> (
-               m_node_ids.value(qpwgraph_node::IdKey(id, mode, type), 
nullptr));
+       return m_node_ids.value(qpwgraph_item::IdKey(id, mode, type), nullptr);
 }
 
 
-// Whether it's in the middle of something...
-bool qpwgraph_canvas::isBusy (void) const
+qpwgraph_node *qpwgraph_canvas::findNode (
+       const QString& name, qpwgraph_item::Mode mode, uint type ) const
 {
-       return (m_state != DragNone || m_connect   != nullptr
-               ||  m_item  != nullptr  || m_edit_item != nullptr);
+       return m_node_names.value(qpwgraph_node::NodeNameKey(name, mode, type), 
nullptr);
 }
 
 
-QList<qpwgraph_node *> qpwgraph_canvas::findNodes (
-       const QString& name, qpwgraph_item::Mode mode, uint type ) const
+// Whether it's in the middle of something...
+bool qpwgraph_canvas::isBusy (void) const
 {
-       return m_node_keys.values(qpwgraph_node::NodeNameKey(name, mode, type));
+       return (m_state != DragNone || m_connect   != nullptr
+               ||  m_item  != nullptr  || m_edit_item != nullptr);
 }
 
 
@@ -1268,11 +1266,7 @@
        if (m_settings == nullptr || node == nullptr)
                return false;
 
-       // Assume node name-keys have been added before this...
-       //
-       const qpwgraph_node::NodeNameKey name_key(node);
-       const int n = m_node_keys.values(name_key).count();
-       const QString& node_key = nodeKey(node, n);
+       const QString& node_key = nodeKey(node);
 
        m_settings->beginGroup(NodeAliasesGroup);
        const QString& node_title
@@ -1301,17 +1295,10 @@
        if (m_settings == nullptr || node == nullptr)
                return false;
 
-       // Assume node name-keys are to be removed after this...
-       //
-       const qpwgraph_node::NodeNameKey name_key(node);
-       const int n = m_node_keys.values(name_key).count();
-       if (n < 1)
-               return false;
-
-       const QString& node_key = nodeKey(node, n);
+       const QString& node_key = nodeKey(node);
 
        m_settings->beginGroup(NodeAliasesGroup);
-       if (node->nodeName() != node->nodeTitle()) {
+       if (node->nodeNameLabel() != node->nodeTitle()) {
                m_settings->setValue('/' + node_key, node->nodeTitle());
        } else {
                m_settings->remove('/' + node_key);
@@ -1354,7 +1341,7 @@
        const QString& port_key = portKey(port);
 
        m_settings->beginGroup(PortAliasesGroup);
-       if (port->portName() != port->portTitle())
+       if (port->portNameLabel() != port->portTitle())
                m_settings->setValue('/' + port_key, port->portTitle());
        else
                m_settings->remove('/' + port_key);
@@ -1369,6 +1356,10 @@
        if (m_settings == nullptr)
                return false;
 
+#ifdef CONFIG_CLEANUP_NODE_NAMES
+       cleanupNodeNames(NodePosGroup);
+       cleanupNodeNames(NodeAliasesGroup);
+#endif
        m_settings->beginGroup(ColorsGroup);
        const QRegularExpression rx("^0x");
        QStringListIterator key(m_settings->childKeys());
@@ -1410,22 +1401,17 @@
                if (item->type() == qpwgraph_node::Type) {
                        qpwgraph_node *node = static_cast<qpwgraph_node *> 
(item);
                        if (node && !nodes.contains(node)) {
-                               int n = 0;
-                               const QList<qpwgraph_node *>& nodes2
-                                       = 
m_node_keys.values(qpwgraph_node::NodeNameKey(node));
-                               foreach (qpwgraph_node *node2, nodes2) {
-                                       const QString& node2_key = 
nodeKey(node2, ++n);
-                                       m_settings->beginGroup(NodePosGroup);
-                                       m_settings->setValue('/' + node2_key, 
node2->pos());
-                                       m_settings->endGroup();
-                                       
m_settings->beginGroup(NodeAliasesGroup);
-                                       if (node2->nodeName() != 
node2->nodeTitle())
-                                               m_settings->setValue('/' + 
node2_key, node2->nodeTitle());
-                                       else
-                                               m_settings->remove('/' + 
node2_key);
-                                       m_settings->endGroup();
-                                       nodes.append(node2);
-                               }
+                               const QString& node_key = nodeKey(node);
+                               m_settings->beginGroup(NodePosGroup);
+                               m_settings->setValue('/' + node_key, 
node->pos());
+                               m_settings->endGroup();
+                               m_settings->beginGroup(NodeAliasesGroup);
+                               if (node->nodeName() != node->nodeTitle())
+                                       m_settings->setValue('/' + node_key, 
node->nodeTitle());
+                               else
+                                       m_settings->remove('/' + node_key);
+                               m_settings->endGroup();
+                               nodes.append(node);
                        }
                }
                else
@@ -1465,13 +1451,9 @@
 
 
 // Graph node/port key helpers.
-QString qpwgraph_canvas::nodeKey ( qpwgraph_node *node, int n ) const
+QString qpwgraph_canvas::nodeKey ( qpwgraph_node *node ) const
 {
        QString node_key = node->nodeName();
-       if (n > 1) {
-               node_key += '-';
-               node_key += QString::number(n - 1);
-       }
 
        switch (node->nodeMode()) {
        case qpwgraph_item::Input:
@@ -1488,7 +1470,7 @@
 }
 
 
-QString qpwgraph_canvas::portKey ( qpwgraph_port *port, int n ) const
+QString qpwgraph_canvas::portKey ( qpwgraph_port *port ) const
 {
        QString port_key;
 
@@ -1499,10 +1481,6 @@
        port_key += node->nodeName();
        port_key += ':';
        port_key += port->portName();
-       if (n > 1) {
-               port_key += '-';
-               port_key += QString::number(n - 1);
-       }
 
        switch (port->portMode()) {
        case qpwgraph_item::Input:
@@ -1522,14 +1500,14 @@
 void qpwgraph_canvas::addNodeKeys ( qpwgraph_node *node )
 {
        m_node_ids.insert(qpwgraph_node::NodeIdKey(node), node);
-       m_node_keys.insert(qpwgraph_node::NodeNameKey(node), node);
+       m_node_names.insert(qpwgraph_node::NodeNameKey(node), node);
 }
 
 
 void qpwgraph_canvas::removeNodeKeys ( qpwgraph_node *node )
 {
-       m_node_keys.remove(qpwgraph_node::NodeNameKey(node));
-       m_node_ids.remove(qpwgraph_node::NodeIdKey(node));
+       m_node_names.remove(qpwgraph_node::NodeNameKey(node), node);
+       m_node_ids.remove(qpwgraph_node::NodeIdKey(node), node);
 }
 
 
@@ -1813,4 +1791,69 @@
 }
 
 
+#ifdef CONFIG_CLEANUP_NODE_NAMES
+
+void qpwgraph_canvas::cleanupNodeNames ( const char *group )
+{
+       bool cleanup = false;
+
+       m_settings->beginGroup("/CleanupNodeNames");
+       cleanup = m_settings->value(group).toBool();
+       if (!cleanup)
+               m_settings->setValue(group, true);
+       m_settings->endGroup();
+
+       if (cleanup)
+               return;
+
+       m_settings->beginGroup(group);
+       const QRegularExpression rx("\\-([0-9]+).*$");
+       QHash<QString, QVariant> keys;
+       QStringListIterator iter(m_settings->childKeys());
+       while (iter.hasNext()) {
+               const QString& key = iter.next();
+               const QVariant& value = m_settings->value(key);
+               QString key2 = key;
+               if (cleanupNodeName(key2)) {
+                       int n = 0;
+                       if (keys.find(key2) != keys.end()) {
+                               const QRegularExpressionMatch mx = 
rx.match(key2);
+                               if (mx.hasMatch()) {
+                                       n = mx.captured(1).toInt();
+                                       key2.remove(rx);
+                               }
+                               QString key3;
+                               do { key3 = key2 + '-' + QString::number(++n); }
+                               while (keys.find(key3) != keys.end());
+                               key2 = key3;
+                       }
+                       if (n == 0) {
+                               keys.insert(key2, value);
+                               m_settings->setValue(key2, value);
+                       }
+                       m_settings->remove(key);
+               } else {
+                       keys.insert(key, value);
+               }
+       }
+       m_settings->endGroup();
+}
+
+
+bool qpwgraph_canvas::cleanupNodeName ( QString& name )
+{
+       const QRegularExpression rx("^.+( \\[.+\\])[^ ]*$");
+       const QRegularExpressionMatch& mx = rx.match(name);
+       if (mx.hasMatch()) {
+               name.remove(mx.captured(1));
+               return true;
+       } else {
+               return false;
+       }
+}
+
+#endif//CONFIG_CLEANUP_NODE_NAMES
+
+
+
 // end of qpwgraph_canvas.cpp
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpwgraph-v0.4.5/src/qpwgraph_canvas.h 
new/qpwgraph-v0.5.1/src/qpwgraph_canvas.h
--- old/qpwgraph-v0.4.5/src/qpwgraph_canvas.h   2023-07-10 17:37:36.000000000 
+0200
+++ new/qpwgraph-v0.5.1/src/qpwgraph_canvas.h   2023-07-17 11:59:55.000000000 
+0200
@@ -49,6 +49,10 @@
 class qpwgraph_patchbay;
 
 
+// Define if cleanup of legacy node names is needed (v0.5.0)...
+#define CONFIG_CLEANUP_NODE_NAMES 1
+
+
 //----------------------------------------------------------------------------
 // qpwgraph_canvas -- Canvas graphics scene/view.
 
@@ -117,7 +121,7 @@
        // Special node finders.
        qpwgraph_node *findNode(
                uint id, qpwgraph_item::Mode mode, uint type = 0) const;
-       QList<qpwgraph_node *> findNodes(
+       qpwgraph_node *findNode(
                const QString& name, qpwgraph_item::Mode mode, uint type = 0) 
const;
 
        void releaseNode(qpwgraph_node *node);
@@ -164,6 +168,10 @@
        // Snap into position helper.
        QPointF snapPos(qreal x, qreal y) const;
 
+#ifdef CONFIG_CLEANUP_NODE_NAMES
+       static bool cleanupNodeName(QString& name);
+#endif
+
 signals:
 
        // Node factory notifications.
@@ -241,8 +249,8 @@
        void pinchGesture(QPinchGesture *pinch);
 
        // Graph node/port key helpers.
-       QString nodeKey(qpwgraph_node *node, int n = 0) const;
-       QString portKey(qpwgraph_port *port, int n = 0) const;
+       QString nodeKey(qpwgraph_node *node) const;
+       QString portKey(qpwgraph_port *port) const;
 
        void addNodeKeys(qpwgraph_node *node);
        void removeNodeKeys(qpwgraph_node *node);
@@ -267,6 +275,10 @@
        // Snap into position helper.
        void snapPos(QPointF& pos) const;
 
+#ifdef CONFIG_CLEANUP_NODE_NAMES
+       void cleanupNodeNames(const char *group);
+#endif
+
 private:
 
        // Mouse pointer dragging states.
@@ -283,9 +295,9 @@
        bool              m_zoomrange;
        bool              m_gesture;
 
-       qpwgraph_node::IdKeys   m_node_ids;
-       qpwgraph_node::NodeKeys m_node_keys;
-       QList<qpwgraph_node *>  m_nodes;
+       qpwgraph_node::NodeIds   m_node_ids;
+       qpwgraph_node::NodeNames m_node_names;
+       QList<qpwgraph_node *>   m_nodes;
 
        QUndoStack *m_commands;
        QSettings  *m_settings;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpwgraph-v0.4.5/src/qpwgraph_item.cpp 
new/qpwgraph-v0.5.1/src/qpwgraph_item.cpp
--- old/qpwgraph-v0.4.5/src/qpwgraph_item.cpp   2023-07-10 17:37:36.000000000 
+0200
+++ new/qpwgraph-v0.5.1/src/qpwgraph_item.cpp   2023-07-17 11:59:55.000000000 
+0200
@@ -1,7 +1,7 @@
 // qpwgraph_item.cpp
 //
 /****************************************************************************
-   Copyright (C) 2021-2022, rncbc aka Rui Nuno Capela. All rights reserved.
+   Copyright (C) 2021-2023, rncbc aka Rui Nuno Capela. All rights reserved.
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpwgraph-v0.4.5/src/qpwgraph_item.h 
new/qpwgraph-v0.5.1/src/qpwgraph_item.h
--- old/qpwgraph-v0.4.5/src/qpwgraph_item.h     2023-07-10 17:37:36.000000000 
+0200
+++ new/qpwgraph-v0.5.1/src/qpwgraph_item.h     2023-07-17 11:59:55.000000000 
+0200
@@ -1,7 +1,7 @@
 // qpwgraph_item.h
 //
 /****************************************************************************
-   Copyright (C) 2021-2022, rncbc aka Rui Nuno Capela. All rights reserved.
+   Copyright (C) 2021-2023, rncbc aka Rui Nuno Capela. All rights reserved.
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
@@ -133,6 +133,8 @@
                uint m_type;
        };
 
+       typedef QHash<IdKey, qpwgraph_item *> NameKeys;
+
        // Item-type hash (static)
        static uint itemType(const QByteArray& type_name);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpwgraph-v0.4.5/src/qpwgraph_node.cpp 
new/qpwgraph-v0.5.1/src/qpwgraph_node.cpp
--- old/qpwgraph-v0.4.5/src/qpwgraph_node.cpp   2023-07-10 17:37:36.000000000 
+0200
+++ new/qpwgraph-v0.5.1/src/qpwgraph_node.cpp   2023-07-17 11:59:55.000000000 
+0200
@@ -1,7 +1,7 @@
 // qpwgraph_node.cpp
 //
 /****************************************************************************
-   Copyright (C) 2021-2022, rncbc aka Rui Nuno Capela. All rights reserved.
+   Copyright (C) 2021-2023, rncbc aka Rui Nuno Capela. All rights reserved.
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
@@ -69,8 +69,7 @@
        QGraphicsPathItem::setFlag(QGraphicsItem::ItemIsMovable);
        QGraphicsPathItem::setFlag(QGraphicsItem::ItemIsSelectable);
 
-       QGraphicsPathItem::setToolTip(m_name);
-       setNodeTitle(m_name);
+       setNodeTitle(QString());
 
        const bool is_darkest = (base_value < 24);
        QColor shadow_color = (is_darkest ? Qt::white : Qt::black);
@@ -110,7 +109,7 @@
 {
        m_name = name;
 
-       QGraphicsPathItem::setToolTip(m_name);
+       QGraphicsPathItem::setToolTip(nodeNameLabel());
 }
 
 
@@ -158,11 +157,43 @@
 }
 
 
+void qpwgraph_node::setNodeLabel ( const QString& label )
+{
+       m_label = label;
+
+       setNodeTitle(QString()); // reset title.
+}
+
+
+const QString& qpwgraph_node::nodeLabel (void) const
+{
+       return m_label;
+}
+
+
+QString qpwgraph_node::nodeNameLabel (void) const
+{
+       QString label = m_name;
+
+       if (!m_label.isEmpty()) {
+               label += ' ';
+               label += '[';
+               label += m_label;
+               label += ']';
+       }
+
+       return label;
+}
+
+
 void qpwgraph_node::setNodeTitle ( const QString& title )
 {
+       const QString& name_label = nodeNameLabel();
+       QGraphicsPathItem::setToolTip(name_label);
+
        const QFont& font = m_text->font();
        m_text->setFont(QFont(font.family(), font.pointSize(), QFont::Bold));
-       m_title = (title.isEmpty() ? m_name : title);
+       m_title = (title.isEmpty() ? name_label : title);
 
        static const int MAX_TITLE_LENGTH = 29;
        static const QString ellipsis(3, '.');
@@ -175,9 +206,9 @@
 }
 
 
-QString qpwgraph_node::nodeTitle (void) const
+const QString& qpwgraph_node::nodeTitle (void) const
 {
-       return m_title; // m_text->toPlainText();
+       return m_title;
 }
 
 
@@ -189,7 +220,7 @@
 
        m_ports.append(port);
        m_port_ids.insert(qpwgraph_port::PortIdKey(port), port);
-       m_port_keys.insert(qpwgraph_port::PortNameKey(port), port);
+       m_port_names.insert(qpwgraph_port::PortNameKey(port), port);
 
        updatePath();
 
@@ -213,7 +244,7 @@
 
 void qpwgraph_node::removePort ( qpwgraph_port *port )
 {
-       m_port_keys.remove(qpwgraph_port::PortNameKey(port));
+       m_port_names.remove(qpwgraph_port::PortNameKey(port));
        m_port_ids.remove(qpwgraph_port::PortIdKey(port));
        m_ports.removeAll(port);
 
@@ -231,7 +262,7 @@
        //qDeleteAll(m_ports);
        m_ports.clear();
        m_port_ids.clear();
-       m_port_keys.clear();
+       m_port_names.clear();
 }
 
 
@@ -239,15 +270,14 @@
 qpwgraph_port *qpwgraph_node::findPort (
        uint id, qpwgraph_item::Mode mode, uint type )
 {
-       return static_cast<qpwgraph_port *> (
-               m_port_ids.value(qpwgraph_port::IdKey(id, mode, type), 
nullptr));
+       return m_port_ids.value(qpwgraph_port::PortIdKey(id, mode, type), 
nullptr);
 }
 
 
-QList<qpwgraph_port *> qpwgraph_node::findPorts (
+qpwgraph_port *qpwgraph_node::findPort (
        const QString& name, qpwgraph_item::Mode mode, uint type )
 {
-       return m_port_keys.values(qpwgraph_port::PortNameKey(name, mode, type));
+       return m_port_names.value(qpwgraph_port::PortNameKey(name, mode, type), 
nullptr);
 }
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpwgraph-v0.4.5/src/qpwgraph_node.h 
new/qpwgraph-v0.5.1/src/qpwgraph_node.h
--- old/qpwgraph-v0.4.5/src/qpwgraph_node.h     2023-07-10 17:37:36.000000000 
+0200
+++ new/qpwgraph-v0.5.1/src/qpwgraph_node.h     2023-07-17 11:59:55.000000000 
+0200
@@ -1,7 +1,7 @@
 // qpwgraph_node.h
 //
 /****************************************************************************
-   Copyright (C) 2021-2022, rncbc aka Rui Nuno Capela. All rights reserved.
+   Copyright (C) 2021-2023, rncbc aka Rui Nuno Capela. All rights reserved.
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
@@ -65,8 +65,12 @@
        void setNodeIcon(const QIcon& icon);
        const QIcon& nodeIcon() const;
 
+       void setNodeLabel(const QString& label);
+       const QString& nodeLabel() const;
+       QString nodeNameLabel() const;
+
        void setNodeTitle(const QString& title);
-       QString nodeTitle() const;
+       const QString& nodeTitle() const;
 
        // Port-list methods.
        qpwgraph_port *addPort(uint id, const QString& name, Mode mode, int 
type = 0);
@@ -79,7 +83,7 @@
 
        // Port finder (by id/name, mode and type)
        qpwgraph_port *findPort(uint id, Mode mode, uint type = 0);
-       QList<qpwgraph_port *> findPorts(const QString& name, Mode mode, uint 
type = 0);
+       qpwgraph_port *findPort(const QString& name, Mode mode, uint type = 0);
 
        // Port-list accessor.
        const QList<qpwgraph_port *>& ports() const;
@@ -99,6 +103,8 @@
                        : IdKey(node->nodeId(), node->nodeMode(), 
node->nodeType()) {}
        };
 
+       typedef QMultiHash<IdKey, qpwgraph_node *> NodeIds;
+
        // Node hash key (by name).
        class NodeNameKey : public NameKey
        {
@@ -110,7 +116,7 @@
                        : NameKey(node->nodeName(), node->nodeMode(), 
node->nodeType()) {}
        };
 
-       typedef QMultiHash<NodeNameKey, qpwgraph_node *> NodeKeys;
+       typedef QMultiHash<NodeNameKey, qpwgraph_node *> NodeNames;
 
        // Rectangular editor extents.
        QRectF editorRect() const;
@@ -131,15 +137,15 @@
        uint    m_type;
 
        QIcon   m_icon;
-
+       QString m_label;
        QString m_title;
 
        QGraphicsPixmapItem *m_pixmap;
        QGraphicsTextItem   *m_text;
 
-       qpwgraph_port::IdKeys   m_port_ids;
-       qpwgraph_port::PortKeys m_port_keys;
-       QList<qpwgraph_port *>  m_ports;
+       qpwgraph_port::PortIds   m_port_ids;
+       qpwgraph_port::PortNames m_port_names;
+       QList<qpwgraph_port *>   m_ports;
 };
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpwgraph-v0.4.5/src/qpwgraph_patchbay.cpp 
new/qpwgraph-v0.5.1/src/qpwgraph_patchbay.cpp
--- old/qpwgraph-v0.4.5/src/qpwgraph_patchbay.cpp       2023-07-10 
17:37:36.000000000 +0200
+++ new/qpwgraph-v0.5.1/src/qpwgraph_patchbay.cpp       2023-07-17 
11:59:55.000000000 +0200
@@ -121,6 +121,10 @@
                QDomElement eroot = nroot.toElement();
                if (eroot.isNull())
                        continue;
+       #ifdef CONFIG_CLEANUP_NODE_NAMES
+               const bool cleanup
+                       = (eroot.attribute("version") < "0.5.0");
+       #endif
                if (eroot.tagName() == "items") {
                        for (QDomNode nitem = eroot.firstChild();
                                !nitem.isNull();
@@ -148,6 +152,14 @@
                                                        port2 = 
eitem2.attribute("port");
                                                }
                                        }
+                               #ifdef CONFIG_CLEANUP_NODE_NAMES
+                                       if (cleanup) { // FIXME: Cleanup legacy 
node names...
+                                               if 
(qpwgraph_canvas::cleanupNodeName(node1))
+                                                       ++m_dirty;
+                                               if 
(qpwgraph_canvas::cleanupNodeName(node2))
+                                                       ++m_dirty;
+                                       }
+                               #endif
                                        if (node_type > 0 && port_type > 0
                                                && !node1.isEmpty() && 
!port1.isEmpty()
                                                && !node2.isEmpty() && 
!port2.isEmpty()) {
@@ -178,36 +190,6 @@
        doc.appendChild(eroot);
 
        QDomElement eitems = doc.createElement("items");
-#if 0//--direct snapshot!
-       QGraphicsScene *scene = m_canvas->scene();
-       if (scene) foreach (QGraphicsItem *item, scene->items()) {
-               if (item->type() == qpwgraph_connect::Type) {
-                       qpwgraph_connect *connect = 
static_cast<qpwgraph_connect *> (item);
-                       if (connect) {
-                               qpwgraph_port *port1 = connect->port1();
-                               qpwgraph_port *port2 = connect->port2();
-                               if (port1 && port2) {
-                                       qpwgraph_node *node1 = 
port1->portNode();
-                                       qpwgraph_node *node2 = 
port2->portNode();
-                                       if (node1 && node2) {
-                                               QDomElement eitem = 
doc.createElement("item");
-                                               eitem.setAttribute("node-type", 
textFromNodeType(node1->nodeType()));
-                                               eitem.setAttribute("port-type", 
textFromPortType(port1->portType()));
-                                               QDomElement eitem1 = 
doc.createElement("output");
-                                               eitem1.setAttribute("node", 
node1->nodeName());
-                                               eitem1.setAttribute("port", 
port1->portName());
-                                               eitem.appendChild(eitem1);
-                                               QDomElement eitem2 = 
doc.createElement("input");
-                                               eitem2.setAttribute("node", 
node2->nodeName());
-                                               eitem2.setAttribute("port", 
port2->portName());
-                                               eitem.appendChild(eitem2);
-                                               eitems.appendChild(eitem);
-                                       }
-                               }
-                       }
-               }
-       }
-#else
        Items::ConstIterator iter = m_items.constBegin();
        const Items::ConstIterator& iter_end = m_items.constEnd();
        for ( ; iter != iter_end; ++iter) {
@@ -225,7 +207,6 @@
                eitem.appendChild(eitem2);
                eitems.appendChild(eitem);
        }
-#endif
        eroot.appendChild(eitems);
 
        QFile file(filename);
@@ -261,75 +242,67 @@
        const Items::ConstIterator& iter_end = m_items.constEnd();
        for ( ; iter != iter_end; ++iter) {
                Item *item = iter.value();
-               QList<qpwgraph_node *> nodes1
-                       = m_canvas->findNodes(
+               qpwgraph_node *node1
+                       = m_canvas->findNode(
                                item->node1,
                                qpwgraph_item::Output,
                                item->node_type);
-               if (nodes1.isEmpty())
-                       nodes1 = m_canvas->findNodes(
+               if (node1 == nullptr)
+                       node1 = m_canvas->findNode(
                                item->node1,
                                qpwgraph_item::Duplex,
                                item->node_type);
-               if (nodes1.isEmpty())
+               if (node1 == nullptr)
+                       continue;
+               qpwgraph_port *port1
+                       = node1->findPort(
+                               item->port1,
+                               qpwgraph_item::Output,
+                               item->port_type);
+               if (port1 == nullptr)
+                       continue;
+               qpwgraph_node * node2
+                       = m_canvas->findNode(
+                               item->node2,
+                               qpwgraph_item::Input,
+                               item->node_type);
+               if (node2 == nullptr)
+                       node2 = m_canvas->findNode(
+                               item->node2,
+                               qpwgraph_item::Duplex,
+                               item->node_type);
+               if (node2 == nullptr)
+                       continue;
+               qpwgraph_port * port2
+                       = node2->findPort(
+                               item->port2,
+                               qpwgraph_item::Input,
+                               item->port_type);
+               if (port2 == nullptr)
                        continue;
-               foreach (qpwgraph_node *node1, nodes1) {
-                       QList<qpwgraph_port *> ports1
-                               = node1->findPorts(
-                                       item->port1,
-                                       qpwgraph_item::Output,
-                                       item->port_type);
-                       if (ports1.isEmpty())
-                               continue;
-                       foreach (qpwgraph_port *port1, ports1) {
-                               QList<qpwgraph_node *> nodes2
-                                       = m_canvas->findNodes(
-                                               item->node2,
-                                               qpwgraph_item::Input,
-                                               item->node_type);
-                               if (nodes2.isEmpty())
-                                       nodes2 = m_canvas->findNodes(
-                                               item->node2,
-                                               qpwgraph_item::Duplex,
-                                               item->node_type);
-                               if (nodes2.isEmpty())
+               if (m_exclusive) {
+                       foreach (qpwgraph_connect *connect, port1->connects()) {
+                               qpwgraph_port *port3 = connect->port2();
+                               if (port3 == nullptr)
                                        continue;
-                               foreach (qpwgraph_node *node2, nodes2) {
-                                       QList<qpwgraph_port *> ports2
-                                               = node2->findPorts(
-                                                       item->port2,
-                                                       qpwgraph_item::Input,
-                                                       item->port_type);
-                                       if (ports2.isEmpty())
+                               if (port3 != port2) {
+                                       qpwgraph_node *node3 = 
port3->portNode();
+                                       if (node3 == nullptr)
                                                continue;
-                                       foreach (qpwgraph_port *port2, ports2) {
-                                               if (m_exclusive) {
-                                                       foreach 
(qpwgraph_connect *connect, port1->connects()) {
-                                                               qpwgraph_port 
*port3 = connect->port2();
-                                                               if (port3 == 
nullptr)
-                                                                       
continue;
-                                                               if (port3 != 
port2) {
-                                                                       
qpwgraph_node *node3 = port3->portNode();
-                                                                       if 
(node3 == nullptr)
-                                                                               
continue;
-                                                                       const 
Item item2(
-                                                                               
node1->nodeType(),
-                                                                               
port1->portType(),
-                                                                               
node1->nodeName(),
-                                                                               
port1->portName(),
-                                                                               
node3->nodeName(),
-                                                                               
port3->portName());
-                                                                       if 
(m_items.constFind(item2) == iter_end)
-                                                                               
connects.insert(item2, connect);
-                                                               }
-                                                       }
-                                               }
-                                               if (!port1->findConnect(port2))
-                                                       
m_canvas->emitConnected(port1, port2);
-                                       }
+                                       const Item item2(
+                                               node1->nodeType(),
+                                               port1->portType(),
+                                               node1->nodeName(),
+                                               port1->portName(),
+                                               node3->nodeName(),
+                                               port3->portName());
+                                       if (m_items.constFind(item2) == 
iter_end)
+                                               connects.insert(item2, connect);
                                }
                        }
                }
+               if (!port1->findConnect(port2))
+                       m_canvas->emitConnected(port1, port2);
        }
 
        QHash<Item, qpwgraph_connect *>::ConstIterator iter2 = 
connects.constBegin();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpwgraph-v0.4.5/src/qpwgraph_pipewire.cpp 
new/qpwgraph-v0.5.1/src/qpwgraph_pipewire.cpp
--- old/qpwgraph-v0.4.5/src/qpwgraph_pipewire.cpp       2023-07-10 
17:37:36.000000000 +0200
+++ new/qpwgraph-v0.5.1/src/qpwgraph_pipewire.cpp       2023-07-17 
11:59:55.000000000 +0200
@@ -27,7 +27,7 @@
 #include <pipewire/pipewire.h>
 
 #include <QMutexLocker>
-
+#include <QMultiHash>
 #include <QTimer>
 
 
@@ -103,6 +103,30 @@
                Midi  = 4
        };
 
+       struct NameKey
+       {
+               NameKey (Node *node)
+                       : node_name(node->node_name),
+                               node_mode(node->node_mode),
+                               node_type(node->node_type) {}
+
+               NameKey (const NameKey& key)
+                       : node_name(key.node_name),
+                               node_mode(key.node_mode),
+                               node_type(key.node_type) {}
+
+               bool operator== (const NameKey& key) const
+               {
+                       return node_type == key.node_type
+                               && node_mode == key.node_mode
+                               && node_name == key.node_name;
+               }
+
+               QString node_name;
+               qpwgraph_item::Mode node_mode;
+               uint node_type;
+       };
+
        QString node_name;
        qpwgraph_item::Mode node_mode;
        NodeType node_type;
@@ -111,6 +135,7 @@
        QString media_name;
        bool node_changed;
        bool node_ready;
+       uint name_num;
 };
 
 struct qpwgraph_pipewire::Port : public qpwgraph_pipewire::Object
@@ -157,8 +182,17 @@
        int last_seq;
        int last_res;
        bool error;
+
+       typedef QMultiHash<Node::NameKey, uint> NodeNames;
+
+       NodeNames *node_names;
 };
 
+inline uint qHash ( const qpwgraph_pipewire::Node::NameKey& key )
+{
+       return qHash(key.node_name) ^ qHash(uint(key.node_mode)) ^ 
qHash(key.node_type);
+}
+
 
 // sync-methods...
 static
@@ -626,9 +660,6 @@
 //----------------------------------------------------------------------------
 // qpwgraph_pipewire -- PipeWire graph driver
 
-QMutex qpwgraph_pipewire::g_mutex;
-
-
 // Constructor.
 qpwgraph_pipewire::qpwgraph_pipewire ( qpwgraph_canvas *canvas )
        : qpwgraph_sect(canvas), m_data(nullptr)
@@ -650,7 +681,7 @@
 // Client methods.
 bool qpwgraph_pipewire::open (void)
 {
-       QMutexLocker locker(&g_mutex);
+       QMutexLocker locker1(&m_mutex1);
 
        pw_init(nullptr, nullptr);
 
@@ -659,6 +690,8 @@
        spa_list_init(&m_data->pending);
        m_data->pending_seq = 0;
 
+       m_data->node_names = new Data::NodeNames;
+
        m_data->loop = pw_thread_loop_new("qpwgraph_thread_loop", nullptr);
        if (m_data->loop == nullptr) {
                qDebug("pw_thread_loop_new: Can't create thread loop.");
@@ -715,7 +748,7 @@
        if (m_data == nullptr)
                return;
 
-       QMutexLocker locker(&g_mutex);
+       QMutexLocker locker1(&m_mutex1);
 
        clearObjects();
 
@@ -738,6 +771,9 @@
        if (m_data->loop)
                pw_thread_loop_destroy(m_data->loop);
 
+       if (m_data->node_names)
+               delete m_data->node_names;
+
        delete m_data;
        m_data = nullptr;
 
@@ -780,7 +816,7 @@
        if (node1 == nullptr || node2 == nullptr)
                return;
 
-       QMutexLocker locker(&g_mutex);
+       QMutexLocker locker1(&m_mutex1);
 
        pw_thread_loop_lock(m_data->loop);
 
@@ -939,6 +975,10 @@
        if (add_new && *node == nullptr) {
                QString node_name = n->node_name;
                if ((p->port_flags & Port::Physical) == Port::None) {
+                       if (n->name_num > 0) {
+                               node_name += '-';
+                               node_name += QString::number(n->name_num);
+                       }
                        if (p->port_flags & Port::Monitor) {
                                node_name += ' ';
                                node_name += "[Monitor]";
@@ -947,15 +987,10 @@
                                node_name += ' ';
                                node_name += "[Control]";
                        }
-                       if (!n->media_name.isEmpty()) {
-                               node_name += ' ';
-                               node_name += '[';
-                               node_name += n->media_name;
-                               node_name += ']';
-                       }
                }
                *node = new qpwgraph_node(node_id, node_name, node_mode, 
node_type);
                (*node)->setNodeIcon(n->node_icon);
+               (*node)->setNodeLabel(n->media_name);
                n->node_changed = false;
                qpwgraph_sect::addItem(*node);
        }
@@ -979,7 +1014,8 @@
 #ifdef CONFIG_DEBUG
        qDebug("qpwgraph_pipewire::updateItems()");
 #endif
-       QMutexLocker locker(&g_mutex);
+       QMutexLocker locker1(&m_mutex1);
+       QMutexLocker locker2(&m_mutex2);
 
        // 0. Check for core errors...
        //
@@ -1059,7 +1095,7 @@
 #ifdef CONFIG_DEBUG
        qDebug("qpwgraph_pipewire::clearItems()");
 #endif
-       QMutexLocker locker(&g_mutex);
+       QMutexLocker locker1(&m_mutex1);
 
        // Clean-up all items...
        //
@@ -1154,25 +1190,17 @@
 
 void qpwgraph_pipewire::removeObjectEx ( uint id )
 {
-       const bool locked
-               = g_mutex.tryLock();
+       QMutexLocker locker2(&m_mutex2);
 
        removeObject(id);
-
-       if (locked)
-               g_mutex.unlock();
 }
 
 
 void qpwgraph_pipewire::addObjectEx ( uint id, Object *object )
 {
-       const bool locked
-               = g_mutex.tryLock();
+       QMutexLocker locker2(&m_mutex2);
 
        addObject(id, object);
-
-       if (locked)
-               g_mutex.unlock();
 }
 
 
@@ -1198,6 +1226,19 @@
        node->node_icon = qpwgraph_icon(":/images/itemPipewire.png");
        node->node_changed = false;
        node->node_ready = false;
+       node->name_num = 0;
+
+       Data::NodeNames *node_names = nullptr;
+       if (m_data)
+               node_names = m_data->node_names;
+       if (node_names) {
+               const Node::NameKey name_key(node);
+               Data::NodeNames::Iterator name_iter
+                       = node_names->find(name_key, node->name_num);
+               while (name_iter != node_names->end())
+                       name_iter = node_names->find(name_key, 
++(node->name_num));
+               node_names->insert(name_key, node->name_num);
+       }
 
        addObjectEx(node_id, node);
 
@@ -1207,6 +1248,12 @@
 
 void qpwgraph_pipewire::destroyNode ( Node *node )
 {
+       Data::NodeNames *node_names = nullptr;
+       if (m_data)
+               node_names = m_data->node_names;
+       if (node_names)
+               node_names->remove(Node::NameKey(node), node->name_num);
+
        foreach (const Port *port, node->node_ports)
                removeObject(port->id);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpwgraph-v0.4.5/src/qpwgraph_pipewire.h 
new/qpwgraph-v0.5.1/src/qpwgraph_pipewire.h
--- old/qpwgraph-v0.4.5/src/qpwgraph_pipewire.h 2023-07-10 17:37:36.000000000 
+0200
+++ new/qpwgraph-v0.5.1/src/qpwgraph_pipewire.h 2023-07-17 11:59:55.000000000 
+0200
@@ -148,7 +148,8 @@
        QList<Object *> m_objects;
 
        // Callback sanity mutex.
-       static QMutex g_mutex;
+       QMutex m_mutex1;
+       QMutex m_mutex2;
 };
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpwgraph-v0.4.5/src/qpwgraph_port.cpp 
new/qpwgraph-v0.5.1/src/qpwgraph_port.cpp
--- old/qpwgraph-v0.4.5/src/qpwgraph_port.cpp   2023-07-10 17:37:36.000000000 
+0200
+++ new/qpwgraph-v0.5.1/src/qpwgraph_port.cpp   2023-07-17 11:59:55.000000000 
+0200
@@ -59,9 +59,7 @@
 
        QGraphicsPathItem::setAcceptHoverEvents(true);
 
-       QGraphicsPathItem::setToolTip(m_name);
-
-       setPortTitle(m_name);
+       setPortTitle(QString());
 }
 
 
@@ -93,7 +91,7 @@
 {
        m_name = name;
 
-       QGraphicsPathItem::setToolTip(m_name);
+       QGraphicsPathItem::setToolTip(portNameLabel());
 }
 
 
@@ -139,8 +137,39 @@
 }
 
 
+void qpwgraph_port::setPortLabel ( const QString& label )
+{
+       m_label = label;
+
+       setPortTitle(QString()); // reset title.
+}
+
+
+const QString& qpwgraph_port::portLabel (void) const
+{
+       return m_label;
+}
+
+
+QString qpwgraph_port::portNameLabel (void) const
+{
+       QString label = m_name;
+
+       if (!m_label.isEmpty()) {
+               label += ' ';
+               label += '[';
+               label += m_label;
+               label += ']';
+       }
+
+       return label;
+}
+
+
 void qpwgraph_port::setPortTitle ( const QString& title )
 {
+       QGraphicsPathItem::setToolTip(portNameLabel());
+
        m_title = (title.isEmpty() ? m_name : title);
 
        static const int MAX_TITLE_LENGTH = 29;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/qpwgraph-v0.4.5/src/qpwgraph_port.h 
new/qpwgraph-v0.5.1/src/qpwgraph_port.h
--- old/qpwgraph-v0.4.5/src/qpwgraph_port.h     2023-07-10 17:37:36.000000000 
+0200
+++ new/qpwgraph-v0.5.1/src/qpwgraph_port.h     2023-07-17 11:59:55.000000000 
+0200
@@ -69,6 +69,10 @@
        void setPortType(uint type);
        uint portType() const;
 
+       void setPortLabel(const QString& label);
+       const QString& portLabel() const;
+       QString portNameLabel() const;
+
        void setPortTitle(const QString& title);
        const QString& portTitle() const;
 
@@ -101,10 +105,14 @@
        {
        public:
                // Constructor.
+               PortIdKey (uint id, Mode mode, uint type = 0)
+                       : IdKey(id, mode, type) {}
                PortIdKey(qpwgraph_port *port)
                        : IdKey(port->portId(), port->portMode(), 
port->portType()) {}
        };
 
+       typedef QHash<PortIdKey, qpwgraph_port *> PortIds;
+
        // Port hash/map key (by name).
        class PortNameKey : public NameKey
        {
@@ -116,7 +124,7 @@
                        : NameKey(port->portName(), port->portMode(), 
port->portType()) {}
        };
 
-       typedef QMultiHash<PortNameKey, qpwgraph_port *> PortKeys;
+       typedef QHash<PortNameKey, qpwgraph_port *> PortNames;
 
        // Port sorting type.
        enum SortType { PortName = 0, PortTitle, PortIndex };
@@ -165,6 +173,7 @@
        Mode    m_mode;
        uint    m_type;
 
+       QString m_label;
        QString m_title;
        int     m_index;
 

Reply via email to