File indexing completed on 2024-05-19 13:33:09

0001 /***************************************************************************
0002  *   Copyright (C) 2003-2004 by David Saxton                               *
0003  *   david@bluehaze.org                                                    *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  ***************************************************************************/
0010 
0011 #ifndef NODEGROUP_H
0012 #define NODEGROUP_H
0013 
0014 #include <QBitArray>
0015 #include <QList>
0016 #include <QObject>
0017 #include <QPointer>
0018 
0019 #include "cnitem.h"
0020 
0021 class ICNDocument;
0022 class Connector;
0023 class ConRouter;
0024 class Node;
0025 class NodeGroup;
0026 
0027 class QTimer;
0028 
0029 typedef QList<int> IntList;
0030 typedef QList<NodeGroup *> NodeGroupList;
0031 typedef QList<QPointer<Node>> NodeList;
0032 
0033 /**
0034 Controls a group of nodes who are not attached to any CNItems (poor things!)
0035 along with their associated connectors.
0036 @author David Saxton
0037 */
0038 class NodeGroup : public QObject
0039 {
0040     Q_OBJECT
0041 public:
0042     NodeGroup(ICNDocument *icnDocument);
0043     ~NodeGroup() override;
0044     /**
0045      * Adds a node to the group (this checks to make sure that the node is not
0046      * a child node). If checkSurrouding is true, then surrounding nodes will be
0047      * checked to see if they are valid for inclusion - and if so, include them.
0048      */
0049     void addNode(Node *node, bool checkSurrouding);
0050     /**
0051      * Returns the list of internal nodes
0052      */
0053     NodeList internalNodeList() const
0054     {
0055         return m_nodeList;
0056     }
0057     /**
0058      * Returns the list of external nodes
0059      */
0060     NodeList externalNodeList() const
0061     {
0062         return m_extNodeList;
0063     }
0064     /**
0065      * Returns the list of connectors
0066      */
0067     ConnectorList connectorList() const
0068     {
0069         return m_conList;
0070     }
0071     /**
0072      * Translates the routes by the given amount
0073      */
0074     void translate(int dx, int dy);
0075     void init();
0076     /**
0077      * @returns true if node is an internal node to this group
0078      */
0079     bool contains(Node *node) const
0080     {
0081         return m_nodeList.contains(node);
0082     }
0083     /**
0084      * Reroute the NodeGroup. This function should only ever be called by
0085      * ICNDocument::rerouteInvalidatedConnectors(), as it is important that
0086      * there is only ever one entity controlling the routing of connectors.
0087      */
0088     void updateRoutes();
0089     /**
0090      * Sets the visibility of all nodes in the group.
0091      */
0092     void setVisible(bool visible);
0093 
0094 public slots:
0095     /**
0096      * Called when an internal or external node is deleted
0097      */
0098     void nodeRemoved(Node *node);
0099     /**
0100      * Called when a connector is removed
0101      */
0102     void connectorRemoved(Connector *connector);
0103 
0104 protected:
0105     void clearConList();
0106     /**
0107      * Finds the common connector between two nodes
0108      */
0109     Connector *findCommonConnector(Node *n1, Node *n2);
0110     /**
0111      * Find the best pair of nodes in the given list to route between. These
0112      * will be nodes that give a ncie path (e.g. if they're aligned horizontally
0113      * or vertically), or otherwise the closest such pair. The two nodes will be
0114      * returned in n1 and n2.
0115      */
0116     void findBestPair(NodeList *list, Node **n1, Node **n2);
0117     /**
0118      * Finds the nodes along the route with the given start and end nodes (which
0119      * will be unique). The end nodes are not included in the returned list.
0120      */
0121     NodeList findRoute(Node *startNode, Node *endNode);
0122 
0123     ConnectorList m_conList;
0124     NodeList m_nodeList;
0125     NodeList m_extNodeList;
0126     ICNDocument *p_icnDocument;
0127     QBitArray b_routedMap; // Routes between different nodes
0128     bool b_visible;
0129 
0130 private:
0131     IntList findRoute(IntList used, int currentNode, int endNode, bool *success = nullptr);
0132     void resetRoutedMap();
0133     /**
0134      * Looks at b_routedMap as well as the connectors coming out of nodes, and
0135      * removes the nodes from the given list that have all of their connectors
0136      * routed.
0137      */
0138     void removeRoutedNodes(NodeList *nodes, Node *n1, Node *n2);
0139     void addExtNode(Node *node);
0140     /**
0141      * Looks at b_mappedRoute to see if there is a completely unrouted set of
0142      * connectors between the two given nodes;
0143      */
0144     bool canRoute(Node *n1, Node *n2);
0145     void getReachable(IntList *reachable, int node);
0146     /**
0147      * Either: position of node in m_nodeList,
0148      * or: (position of node in m_extNodeList) + m_nodeList.size()
0149      * or: -1
0150      */
0151     int getNodePos(Node *n);
0152     /**
0153      * Essentially the inverse of getNodePos
0154      */
0155     Node *getNodePtr(int n);
0156 };
0157 
0158 #endif