Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package qpwgraph for openSUSE:Factory checked in at 2022-09-25 15:35:37 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/qpwgraph (Old) and /work/SRC/openSUSE:Factory/.qpwgraph.new.2275 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "qpwgraph" Sun Sep 25 15:35:37 2022 rev:11 rq:1005793 version:0.3.6 Changes: -------- --- /work/SRC/openSUSE:Factory/qpwgraph/qpwgraph.changes 2022-09-16 13:32:48.417359061 +0200 +++ /work/SRC/openSUSE:Factory/.qpwgraph.new.2275/qpwgraph.changes 2022-09-25 15:36:04.159733664 +0200 @@ -1,0 +2,6 @@ +Sat Sep 24 17:16:51 UTC 2022 - Alexei Sorokin <sor.ale...@meowr.ru> + +- Update to version 0.3.6: + * View / Repel Overlapping Nodes option added. + +------------------------------------------------------------------- Old: ---- qpwgraph-v0.3.5.tar.bz2 New: ---- qpwgraph-v0.3.6.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ qpwgraph.spec ++++++ --- /var/tmp/diff_new_pack.g4pUrn/_old 2022-09-25 15:36:04.583734685 +0200 +++ /var/tmp/diff_new_pack.g4pUrn/_new 2022-09-25 15:36:04.587734695 +0200 @@ -17,7 +17,7 @@ Name: qpwgraph -Version: 0.3.5 +Version: 0.3.6 Release: 0 Summary: PipeWire Graph Qt GUI Interface License: GPL-2.0-or-later ++++++ qpwgraph-v0.3.5.tar.bz2 -> qpwgraph-v0.3.6.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qpwgraph-v0.3.5/CMakeLists.txt new/qpwgraph-v0.3.6/CMakeLists.txt --- old/qpwgraph-v0.3.5/CMakeLists.txt 2022-08-20 14:16:49.000000000 +0200 +++ new/qpwgraph-v0.3.6/CMakeLists.txt 2022-09-24 13:09:34.000000000 +0200 @@ -1,7 +1,7 @@ cmake_minimum_required (VERSION 3.15) project(qpwgraph - VERSION 0.3.5 + VERSION 0.3.6 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.3.5/ChangeLog new/qpwgraph-v0.3.6/ChangeLog --- old/qpwgraph-v0.3.5/ChangeLog 2022-08-20 14:16:49.000000000 +0200 +++ new/qpwgraph-v0.3.6/ChangeLog 2022-09-24 13:09:34.000000000 +0200 @@ -2,6 +2,11 @@ -------------------------------------------- +0.3.6 2022-09-24 An early-autumn'22 release. + +- View / Repel Overlapping Nodes option added. + + 0.3.5 2022-08-20 A thirteenth beta release. - Patchbay/Scan menu command removed as redundand. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qpwgraph-v0.3.5/src/appdata/org.rncbc.qpwgraph.metainfo.xml new/qpwgraph-v0.3.6/src/appdata/org.rncbc.qpwgraph.metainfo.xml --- old/qpwgraph-v0.3.5/src/appdata/org.rncbc.qpwgraph.metainfo.xml 2022-08-20 14:16:49.000000000 +0200 +++ new/qpwgraph-v0.3.6/src/appdata/org.rncbc.qpwgraph.metainfo.xml 2022-09-24 13:09:34.000000000 +0200 @@ -37,7 +37,7 @@ <developer_name>rncbc aka. Rui Nuno Capela</developer_name> <update_contact>rn...@rncbc.org</update_contact> <releases> - <release version="0.3.5" date="2022-08-20" urgency="low" /> + <release version="0.3.6" date="2022-09-24" urgency="low" /> </releases> <content_rating type="oars-1.0"/> </component> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qpwgraph-v0.3.5/src/qpwgraph_canvas.cpp new/qpwgraph-v0.3.6/src/qpwgraph_canvas.cpp --- old/qpwgraph-v0.3.5/src/qpwgraph_canvas.cpp 2022-08-20 14:16:49.000000000 +0200 +++ new/qpwgraph-v0.3.6/src/qpwgraph_canvas.cpp 2022-09-24 13:09:34.000000000 +0200 @@ -67,8 +67,8 @@ m_zoom(1.0), m_zoomrange(false), m_commands(nullptr), m_settings(nullptr), m_patchbay(nullptr), m_patchbay_edit(false), m_patchbay_autopin(true), - m_selected_nodes(0), m_edit_item(nullptr), - m_editor(nullptr), m_edited(0) + m_selected_nodes(0), m_repel_overlapping_nodes(false), + m_edit_item(nullptr), m_editor(nullptr), m_edited(0) { m_scene = new QGraphicsScene(); @@ -269,7 +269,9 @@ m_nodes.append(node); m_node_ids.insert(qpwgraph_node::NodeIdKey(node), node); m_node_keys.insert(qpwgraph_node::NodeNameKey(node), node); - if (!restoreNode(node)) + if (restoreNode(node)) + emit updated(node); + else emit added(node); } } @@ -1573,4 +1575,95 @@ } +// Repel overlapping nodes... +void qpwgraph_canvas::setRepelOverlappingNodes ( bool on ) +{ + m_repel_overlapping_nodes = on; +} + + +bool qpwgraph_canvas::isRepelOverlappingNodes (void) const +{ + return m_repel_overlapping_nodes; +} + + +void qpwgraph_canvas::repelOverlappingNodes ( qpwgraph_node *node, + qpwgraph_move_command *move_command, const QPointF& delta ) +{ + const qreal MIN_NODE_GAP = 8.0f; + + node->setMarked(true); + + QRectF rect1 = node->sceneBoundingRect(); + rect1.adjust( + -2.0 * MIN_NODE_GAP, -MIN_NODE_GAP, + +2.0 * MIN_NODE_GAP, +MIN_NODE_GAP); + + foreach (qpwgraph_node *node2, m_nodes) { + if (node2->isMarked()) + continue; + const QPointF& pos1 + = node2->pos(); + QPointF pos2 = pos1; + const QRectF& rect2 + = node2->sceneBoundingRect(); + const QRectF& recti + = rect2.intersected(rect1); + if (!recti.isNull()) { + const QPointF delta2 + = (delta.isNull() ? rect2.center() - rect1.center() : delta); + if (recti.width() < (1.5 * recti.height())) { + qreal dx = recti.width(); + if ((delta2.x() < 0.0 && recti.width() >= rect1.width()) || + (delta2.x() > 0.0 && recti.width() >= rect2.width())) { + dx += qAbs(rect2.right() - rect1.right()); + } + else + if ((delta2.x() > 0.0 && recti.width() >= rect1.width()) || + (delta2.x() < 0.0 && recti.width() >= rect2.width())) { + dx += qAbs(rect2.left() - rect1.left()); + } + if (delta2.x() < 0.0) + pos2.setX(pos1.x() - dx); + else + pos2.setX(pos1.x() + dx); + } else { + qreal dy = recti.height(); + if ((delta2.y() < 0.0 && recti.height() >= rect1.height()) || + (delta2.y() > 0.0 && recti.height() >= rect2.height())) { + dy += qAbs(rect2.bottom() - rect1.bottom()); + } + else + if ((delta2.y() > 0.0 && recti.height() >= rect1.height()) || + (delta2.y() < 0.0 && recti.height() >= rect2.height())) { + dy += qAbs(rect2.top() - rect1.top()); + } + if (delta2.y() < 0.0) + pos2.setY(pos1.y() - dy); + else + pos2.setY(pos1.y() + dy); + } + // Repel this node... + node2->setPos(pos2); + // Add this node for undo/redo... + if (move_command) + move_command->addItem(node2, pos1, pos2); + // Repel this node neighbors, if any... + repelOverlappingNodes(node2, move_command, delta2); + } + } + + node->setMarked(false); +} + + +void qpwgraph_canvas::repelOverlappingNodesAll ( + qpwgraph_move_command *move_command ) +{ + foreach (qpwgraph_node *node, m_nodes) + repelOverlappingNodes(node, move_command); +} + + // end of qpwgraph_canvas.cpp diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qpwgraph-v0.3.5/src/qpwgraph_canvas.h new/qpwgraph-v0.3.6/src/qpwgraph_canvas.h --- old/qpwgraph-v0.3.5/src/qpwgraph_canvas.h 2022-08-20 14:16:49.000000000 +0200 +++ new/qpwgraph-v0.3.6/src/qpwgraph_canvas.h 2022-09-24 13:09:34.000000000 +0200 @@ -123,6 +123,7 @@ // Port (dis)connections dispatcher. void emitConnectPorts( qpwgraph_port *port1, qpwgraph_port *port2, bool is_connect); + // Port (dis)connections notifiers. void emitConnected(qpwgraph_port *port1, qpwgraph_port *port2); void emitDisconnected(qpwgraph_port *port1, qpwgraph_port *port2); @@ -134,6 +135,15 @@ bool restoreState(); bool saveState() const; + // Repel overlapping nodes... + void setRepelOverlappingNodes(bool on); + bool isRepelOverlappingNodes() const; + void repelOverlappingNodes(qpwgraph_node *node, + qpwgraph_move_command *move_command = nullptr, + const QPointF& delta = QPointF()); + void repelOverlappingNodesAll( + qpwgraph_move_command *move_command = nullptr); + // Graph colors management. void setPortTypeColor(uint port_type, const QColor& color); const QColor& portTypeColor(uint port_type); @@ -150,6 +160,7 @@ // Node factory notifications. void added(qpwgraph_node *node); + void updated(qpwgraph_node *node); void removed(qpwgraph_node *node); // Port (dis)connection notifications. @@ -257,6 +268,8 @@ QList<QGraphicsItem *> m_selected; int m_selected_nodes; + bool m_repel_overlapping_nodes; + // Graph port colors. QHash<uint, QColor> m_port_colors; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qpwgraph-v0.3.5/src/qpwgraph_command.cpp new/qpwgraph-v0.3.6/src/qpwgraph_command.cpp --- old/qpwgraph-v0.3.5/src/qpwgraph_command.cpp 2022-08-20 14:16:49.000000000 +0200 +++ new/qpwgraph-v0.3.6/src/qpwgraph_command.cpp 2022-09-24 13:09:34.000000000 +0200 @@ -123,17 +123,26 @@ // Constructor. qpwgraph_move_command::qpwgraph_move_command ( qpwgraph_canvas *canvas, const QList<qpwgraph_node *>& nodes, const QPointF& pos1, const QPointF& pos2, - qpwgraph_command *parent ) : qpwgraph_command(canvas, parent), - m_pos1(pos1), m_pos2(pos2), m_nexec(0) + qpwgraph_command *parent ) : qpwgraph_command(canvas, parent), m_nexec(0) { qpwgraph_command::setText(QObject::tr("Move")); + const QPointF delta = (pos1 - pos2); + foreach (qpwgraph_node *node, nodes) { Item *item = new Item; item->node_id = node->nodeId(); item->node_mode = node->nodeMode(); item->node_type = node->nodeType(); - m_items.append(item); + const QPointF& pos = node->pos(); + item->node_pos1 = pos + delta; + item->node_pos2 = pos; + m_items.insert(node, item); + } + + if (canvas && canvas->isRepelOverlappingNodes()) { + foreach (qpwgraph_node *node, nodes) + canvas->repelOverlappingNodes(node, this); } } @@ -146,6 +155,27 @@ } +// Add/replace (an already moved) node position for undo/redo... +void qpwgraph_move_command::addItem ( + qpwgraph_node *node, const QPointF& pos1, const QPointF& pos2 ) +{ + Item *item = m_items.value(node, nullptr); + if (item) { + // item->node_pos1 = pos1; + item->node_pos2 = pos2;//node->pos(); + } else { + item = new Item; + item->node_id = node->nodeId(); + item->node_mode = node->nodeMode(); + item->node_type = node->nodeType(); + item->node_pos1 = pos1; + item->node_pos2 = pos2;//node->pos(); + m_items.insert(node, item); + } +} + + + // Command executive method. bool qpwgraph_move_command::execute ( bool /* is_undo */ ) { @@ -154,19 +184,21 @@ return false; if (++m_nexec > 1) { - const QPointF delta = (m_pos2 - m_pos1); - foreach (Item *item, m_items) { - qpwgraph_node *node = canvas->findNode( - item->node_id, item->node_mode, item->node_type); - if (node) - node->setPos(node->pos() + delta); + foreach (qpwgraph_node *key, m_items.keys()) { + Item *item = m_items.value(key, nullptr); + if (item) { + qpwgraph_node *node = canvas->findNode( + item->node_id, item->node_mode, item->node_type); + if (node) { + const QPointF pos1 = item->node_pos1; + node->setPos(pos1); + item->node_pos1 = item->node_pos2; + item->node_pos2 = pos1; + } + } } } - QPointF pos2 = m_pos2; - m_pos2 = m_pos1; - m_pos1 = pos2; - return true; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qpwgraph-v0.3.5/src/qpwgraph_command.h new/qpwgraph-v0.3.6/src/qpwgraph_command.h --- old/qpwgraph-v0.3.5/src/qpwgraph_command.h 2022-08-20 14:16:49.000000000 +0200 +++ new/qpwgraph-v0.3.6/src/qpwgraph_command.h 2022-09-24 13:09:34.000000000 +0200 @@ -152,6 +152,9 @@ // Destructor. ~qpwgraph_move_command(); + // Add/replace (an already moved) node position for undo/redo... + void addItem(qpwgraph_node *node, const QPointF& pos1, const QPointF& pos2); + protected: // Command item descriptor @@ -160,6 +163,8 @@ uint node_id; qpwgraph_item::Mode node_mode; uint node_type; + QPointF node_pos1; + QPointF node_pos2; }; // Command executive method. @@ -168,10 +173,7 @@ private: // Command arguments. - QList<Item *> m_items; - - QPointF m_pos1; - QPointF m_pos2; + QHash<qpwgraph_node *, Item *> m_items; int m_nexec; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qpwgraph-v0.3.5/src/qpwgraph_config.cpp new/qpwgraph-v0.3.6/src/qpwgraph_config.cpp --- old/qpwgraph-v0.3.5/src/qpwgraph_config.cpp 2022-08-20 14:16:49.000000000 +0200 +++ new/qpwgraph-v0.3.6/src/qpwgraph_config.cpp 2022-09-24 13:09:34.000000000 +0200 @@ -41,6 +41,7 @@ static const char *ViewZoomRangeKey = "/ZoomRange"; static const char *ViewSortTypeKey = "/SortType"; static const char *ViewSortOrderKey = "/SortOrder"; +static const char *ViewRepelOverlappingNodesKey = "/RepelOverlappingNodes"; static const char *PatchbayGroup = "/Patchbay"; static const char *PatchbayDirKey = "/Dir"; @@ -182,6 +183,18 @@ } +void qpwgraph_config::setRepelOverlappingNodes ( bool repelnodes ) +{ + m_repelnodes = repelnodes; +} + + +bool qpwgraph_config::isRepelOverlappingNodes (void) const +{ + return m_repelnodes; +} + + void qpwgraph_config::setPatchbayToolbar ( bool toolbar ) { m_patchbay_toolbar = toolbar; @@ -318,6 +331,7 @@ m_zoomrange = m_settings->value(ViewZoomRangeKey, false).toBool(); m_sorttype = m_settings->value(ViewSortTypeKey, 0).toInt(); m_sortorder = m_settings->value(ViewSortOrderKey, 0).toInt(); + m_repelnodes = m_settings->value(ViewRepelOverlappingNodesKey, false).toBool(); m_settings->endGroup(); m_settings->beginGroup(GeometryGroup); @@ -373,6 +387,7 @@ m_settings->setValue(ViewZoomRangeKey, m_zoomrange); m_settings->setValue(ViewSortTypeKey, m_sorttype); m_settings->setValue(ViewSortOrderKey, m_sortorder); + m_settings->setValue(ViewRepelOverlappingNodesKey, m_repelnodes); m_settings->endGroup(); m_settings->beginGroup(GeometryGroup); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qpwgraph-v0.3.5/src/qpwgraph_config.h new/qpwgraph-v0.3.6/src/qpwgraph_config.h --- old/qpwgraph-v0.3.5/src/qpwgraph_config.h 2022-08-20 14:16:49.000000000 +0200 +++ new/qpwgraph-v0.3.6/src/qpwgraph_config.h 2022-09-24 13:09:34.000000000 +0200 @@ -71,6 +71,9 @@ void setSortOrder(int sortorder); int sortOrder() const; + void setRepelOverlappingNodes(bool repelnodes); + bool isRepelOverlappingNodes() const; + void setPatchbayToolbar(bool toolbar); bool isPatchbayToolbar() const; @@ -86,7 +89,7 @@ void setPatchbayExclusive(bool exclusive); bool isPatchbayExclusive() const; - void setPatchbayAutoPin(bool exclusive); + void setPatchbayAutoPin(bool autopin); bool isPatchbayAutoPin() const; void patchbayRecentFiles(const QString& path); @@ -113,6 +116,8 @@ int m_sorttype; int m_sortorder; + bool m_repelnodes; + bool m_patchbay_toolbar; QString m_patchbay_dir; QString m_patchbay_path; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qpwgraph-v0.3.5/src/qpwgraph_form.cpp new/qpwgraph-v0.3.6/src/qpwgraph_form.cpp --- old/qpwgraph-v0.3.5/src/qpwgraph_form.cpp 2022-08-20 14:16:49.000000000 +0200 +++ new/qpwgraph-v0.3.6/src/qpwgraph_form.cpp 2022-09-24 13:09:34.000000000 +0200 @@ -114,6 +114,8 @@ m_ins = m_mids = m_outs = 0; + m_repel_overlapping_nodes = 0; + m_patchbay_names = new QComboBox(m_ui.patchbayToolbar); m_patchbay_names->setEditable(false); m_patchbay_names->setMinimumWidth(120); @@ -207,6 +209,9 @@ SIGNAL(added(qpwgraph_node *)), SLOT(added(qpwgraph_node *))); QObject::connect(m_ui.graphCanvas, + SIGNAL(updated(qpwgraph_node *)), + SLOT(updated(qpwgraph_node *))); + QObject::connect(m_ui.graphCanvas, SIGNAL(removed(qpwgraph_node *)), SLOT(removed(qpwgraph_node *))); @@ -344,6 +349,10 @@ SIGNAL(triggered(bool)), SLOT(viewZoomRange(bool))); + QObject::connect(m_ui.viewRepelOverlappingNodesAction, + SIGNAL(triggered(bool)), + SLOT(viewRepelOverlappingNodes(bool))); + m_ui.viewColorsPipewireAudioAction->setData(qpwgraph_pipewire::audioPortType()); m_ui.viewColorsPipewireMidiAction->setData(qpwgraph_pipewire::midiPortType()); m_ui.viewColorsPipewireVideoAction->setData(qpwgraph_pipewire::videoPortType()); @@ -710,6 +719,9 @@ pipewire_changed(); alsamidi_changed(); + if (m_ui.graphCanvas->isRepelOverlappingNodes()) + ++m_repel_overlapping_nodes; // fake nodes added! + refresh(); } @@ -784,6 +796,13 @@ } +void qpwgraph_form::viewRepelOverlappingNodes ( bool on ) +{ + m_ui.graphCanvas->setRepelOverlappingNodes(on); + if (on) ++m_repel_overlapping_nodes; +} + + void qpwgraph_form::helpSystemTray ( bool on ) { #ifdef CONFIG_SYSTEM_TRAY @@ -913,7 +932,14 @@ node->setPos(x, y); - stabilize(); + updated(node); +} + + +void qpwgraph_form::updated ( qpwgraph_node */*node*/ ) +{ + if (m_ui.graphCanvas->isRepelOverlappingNodes()) + ++m_repel_overlapping_nodes; } @@ -1031,6 +1057,12 @@ patchbay->scan(); stabilize(); } + else + if (m_repel_overlapping_nodes > 0) { + m_repel_overlapping_nodes = 0; + m_ui.graphCanvas->repelOverlappingNodesAll(); + stabilize(); + } QTimer::singleShot(300, this, SLOT(refresh())); } @@ -1470,6 +1502,7 @@ m_ui.viewTextBesideIconsAction->setChecked(m_config->isTextBesideIcons()); m_ui.viewZoomRangeAction->setChecked(m_config->isZoomRange()); + m_ui.viewRepelOverlappingNodesAction->setChecked(m_config->isRepelOverlappingNodes()); const qpwgraph_port::SortType sort_type = qpwgraph_port::SortType(m_config->sortType()); @@ -1507,6 +1540,7 @@ viewTextBesideIcons(m_config->isTextBesideIcons()); viewZoomRange(m_config->isZoomRange()); + viewRepelOverlappingNodes(m_config->isRepelOverlappingNodes()); m_ui.graphCanvas->restoreState(); @@ -1532,6 +1566,7 @@ m_config->setZoomRange(m_ui.viewZoomRangeAction->isChecked()); m_config->setSortType(int(qpwgraph_port::sortType())); m_config->setSortOrder(int(qpwgraph_port::sortOrder())); + m_config->setRepelOverlappingNodes(m_ui.viewRepelOverlappingNodesAction->isChecked()); m_config->setStatusbar(m_ui.StatusBar->isVisible()); m_config->setToolbar(m_ui.graphToolbar->isVisible()); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qpwgraph-v0.3.5/src/qpwgraph_form.h new/qpwgraph-v0.3.6/src/qpwgraph_form.h --- old/qpwgraph-v0.3.5/src/qpwgraph_form.h 2022-08-20 14:16:49.000000000 +0200 +++ new/qpwgraph-v0.3.6/src/qpwgraph_form.h 2022-09-24 13:09:34.000000000 +0200 @@ -71,6 +71,7 @@ // Node life-cycle slots void added(qpwgraph_node *node); + void updated(qpwgraph_node *node); void removed(qpwgraph_node *node); // Port (dis)connection slots. @@ -128,6 +129,8 @@ void viewColorsAction(); void viewColorsReset(); + void viewRepelOverlappingNodes(bool on); + void helpSystemTray(bool on); void helpAbout(); @@ -205,6 +208,8 @@ int m_ins, m_mids, m_outs; + int m_repel_overlapping_nodes; + QSlider *m_zoom_slider; QSpinBox *m_zoom_spinbox; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qpwgraph-v0.3.5/src/qpwgraph_form.ui new/qpwgraph-v0.3.6/src/qpwgraph_form.ui --- old/qpwgraph-v0.3.5/src/qpwgraph_form.ui 2022-08-20 14:16:49.000000000 +0200 +++ new/qpwgraph-v0.3.6/src/qpwgraph_form.ui 2022-09-24 13:09:34.000000000 +0200 @@ -160,6 +160,8 @@ <addaction name="viewZoomMenu"/> <addaction name="viewZoomRangeAction"/> <addaction name="separator"/> + <addaction name="viewRepelOverlappingNodesAction"/> + <addaction name="separator"/> <addaction name="viewRefreshAction"/> </widget> <widget class="QMenu" name="helpMenu"> @@ -982,6 +984,26 @@ </property> <property name="shortcut"> <string/> + </property> + </action> + <action name="viewRepelOverlappingNodesAction"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="text"> + <string>Repel &Overlapping Nodes</string> + </property> + <property name="iconText"> + <string>Repel nodes</string> + </property> + <property name="toolTip"> + <string>Repel overlapping nodes</string> + </property> + <property name="statusTip"> + <string>Repel overlapping nodes</string> + </property> + <property name="shortcut"> + <string/> </property> </action> <action name="helpSystemTrayAction">