You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
281 lines
8.9 KiB
281 lines
8.9 KiB
15 years ago
|
/***************************************************************************
|
||
|
* Copyright (C) 2005 by David Saxton *
|
||
|
* david@bluehaze.org *
|
||
|
* *
|
||
|
* This program is free software; you can redistribute it and/or modify *
|
||
|
* it under the terms of the GNU General Public License as published by *
|
||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||
|
* (at your option) any later version. *
|
||
|
***************************************************************************/
|
||
|
|
||
|
#ifndef ICNDOCUMENT_H
|
||
|
#define ICNDOCUMENT_H
|
||
|
|
||
|
#include "itemdocument.h"
|
||
|
|
||
|
|
||
|
class Cells;
|
||
|
class CNItem;
|
||
|
class CNItemGroup;
|
||
|
class Connector;
|
||
|
class ECNode;
|
||
|
class FlowContainer;
|
||
|
class Node;
|
||
|
class NodeGroup;
|
||
|
|
||
|
typedef QValueList<QGuardedPtr<Connector> > ConnectorList;
|
||
|
typedef QValueList<QGuardedPtr<Node> > NodeList;
|
||
|
typedef QValueList<NodeGroup*> NodeGroupList;
|
||
|
typedef QValueList<QGuardedPtr<NodeGroup> > GuardedNodeGroupList;
|
||
|
|
||
|
/**
|
||
|
@author David Saxton
|
||
|
*/
|
||
|
class ICNDocument : public ItemDocument
|
||
|
{
|
||
|
Q_OBJECT
|
||
|
public:
|
||
|
ICNDocument( const QString &caption, KTechlab *ktechlab, const char *name );
|
||
|
virtual ~ICNDocument();
|
||
|
|
||
|
enum hit_score
|
||
|
{
|
||
|
hs_none = 0,
|
||
|
hs_connector = 4,
|
||
|
hs_item = 1000
|
||
|
};
|
||
|
|
||
|
virtual View *createView( ViewContainer *viewContainer, uint viewAreaId, const char *name = 0l );
|
||
|
|
||
|
/**
|
||
|
* Will attempt to create an item with the given id at position p. Some item
|
||
|
* (such as PIC/START) have restrictions, and can only have one instance of
|
||
|
* themselves on the canvas, and adds the operation to the undo list
|
||
|
*/
|
||
|
virtual Item* addItem( const QString &id, const QPoint &p, bool newItem );
|
||
|
/**
|
||
|
* Creates a connector between two nodes, and returns a pointer to it
|
||
|
* and adds the operation to the undo list
|
||
|
*/
|
||
|
Connector* createConnector( const QString &startNodeId, const QString &endNodeId, QPointList *pointList = 0L );
|
||
|
/**
|
||
|
* short for casting whatever itemWithID(id) returns
|
||
|
*/
|
||
|
CNItem* cnItemWithID( const QString &id );
|
||
|
/**
|
||
|
* Returns a pointer to a node on the canvas with the given id,
|
||
|
* or NULL if no such node exists
|
||
|
*/
|
||
|
Node* nodeWithID( const QString &id );
|
||
|
/**
|
||
|
* Returns a pointer to a Connector on the canvas with the given id,
|
||
|
* or NULL if no such Connector exists
|
||
|
*/
|
||
|
Connector* connectorWithID( const QString &id );
|
||
|
/**
|
||
|
* Adds a QCanvasItem to the delete list to be deleted,
|
||
|
* when flushDeleteList() is called
|
||
|
*/
|
||
|
virtual void appendDeleteList( QCanvasItem *qcanvasItem );
|
||
|
/**
|
||
|
* Permantly deletes all items that have been added to the delete list with
|
||
|
* the appendDeleteList( QCanvasItem *qcanvasItem ) function.
|
||
|
*/
|
||
|
virtual void flushDeleteList();
|
||
|
/**
|
||
|
* Reinherit this function to perform special checks on whether the two
|
||
|
* given QCanvasItems (either nodes or connectors or both) can be
|
||
|
* connected together.
|
||
|
*/
|
||
|
virtual bool canConnect( QCanvasItem *qcanvasItem1, QCanvasItem *qcanvasItem2 ) const;
|
||
|
virtual void copy();
|
||
|
virtual void selectAll();
|
||
|
|
||
|
|
||
|
virtual bool registerItem( QCanvasItem *qcanvasItem );
|
||
|
/**
|
||
|
* Returns a pointer to the 2-dimension array of ICNDocument cells.
|
||
|
*/
|
||
|
Cells *cells() const { return m_cells; }
|
||
|
/**
|
||
|
* Returns true if the cell-reference given by x and y is valid (i.e.
|
||
|
* greater than 0, but within the m_cells boundary)
|
||
|
*/
|
||
|
inline bool isValidCellReference( const uint x, const uint y ) const
|
||
|
{
|
||
|
return ( x<m_cellsX && y<m_cellsY );
|
||
|
}
|
||
|
/**
|
||
|
* Adds score to the cells at the given cell referece
|
||
|
*/
|
||
|
void addCPenalty( int x, int y, int score );
|
||
|
/**
|
||
|
* If there are two connectors joined to a node, then they can be merged
|
||
|
* into one connector. The node will not be removed.
|
||
|
* @param node The node between the two connectors
|
||
|
* @param noCreate If true, no new connectors will be created
|
||
|
* @returns true if it was successful in merging the connectors
|
||
|
*/
|
||
|
bool joinConnectors( Node *node );
|
||
|
static int gridSnap( int pos ); /// Returns 'pos' when snapped to grid
|
||
|
static QPoint gridSnap( const QPoint &pos );
|
||
|
/**
|
||
|
* Returns true if the CNItem is valid - e.g. will return true for a
|
||
|
* component in a circuit, but not in a pic program
|
||
|
*/
|
||
|
virtual bool isValidItem( Item *item ) = 0;
|
||
|
virtual bool isValidItem( const QString &itemId ) = 0;
|
||
|
ConnectorList getCommonConnectors( const ItemList &list );
|
||
|
NodeList getCommonNodes( const ItemList &list );
|
||
|
const NodeList & nodeList() const { return m_nodeList; }
|
||
|
const ConnectorList & connectorList() const { return m_connectorList; }
|
||
|
const GuardedNodeGroupList & nodeGroupList() const { return m_nodeGroupList; }
|
||
|
virtual ItemGroup *selectList() const;
|
||
|
/**
|
||
|
* Creates a connector from node1 to node2. If pointList is non-null, then the
|
||
|
* connector will be assigned those points
|
||
|
*/
|
||
|
Connector * createConnector( Node *node1, Node *node2, QPointList *pointList = 0L );
|
||
|
/**
|
||
|
* Splits Connector con into two connectors at point pos2, and creates a connector from the node
|
||
|
* to the intersection of the two new connectors. If pointList is non-null, then the new connector
|
||
|
* from the node will be assigned those points
|
||
|
*/
|
||
|
Connector * createConnector( Node *node, Connector *con, const QPoint &pos2, QPointList *pointList = 0L );
|
||
|
/**
|
||
|
* Splits con1 and con2 into two new connectors each at points pos1 and pos2, and creates a new connector
|
||
|
* between the two points of intersection given by pos1 and pos2. If pointList is non-null, then the new
|
||
|
* connector between the two points will be assigned those points
|
||
|
*/
|
||
|
Connector * createConnector( Connector *con1, Connector *con2, const QPoint &pos1, const QPoint &pos2, QPointList *pointList = 0L );
|
||
|
/**
|
||
|
* Returns the flowcontainer at the given position at the highest level that
|
||
|
* is not in the current select list, or 0l if there isn't one
|
||
|
*/
|
||
|
FlowContainer *flowContainer( const QPoint &pos );
|
||
|
/**
|
||
|
* Sets the drag (e.g. horizontal arrow) cursor for resizing a CNItem, depending on the corner clicked on
|
||
|
*/
|
||
|
void setItemResizeCursor( int cornerType );
|
||
|
|
||
|
void getTranslatable( const ItemList & itemList, ConnectorList * fixedConnectors = 0l, ConnectorList * translatableConnectors = 0l, NodeGroupList * translatableNodeGroups = 0l );
|
||
|
/**
|
||
|
* Reroutes invalidated directors. You shouldn't call this function
|
||
|
* directly - instead use ItemDocument::requestEvent.
|
||
|
*/
|
||
|
void rerouteInvalidatedConnectors();
|
||
|
/**
|
||
|
* Assigns the orphan nodes into NodeGroups. You shouldn't call this
|
||
|
* function directly - instead use ItemDocument::requestEvent.
|
||
|
*/
|
||
|
void slotAssignNodeGroups();
|
||
|
|
||
|
public slots:
|
||
|
/**
|
||
|
* Deletes all items in the selected item list, along with associated
|
||
|
* connectors, etc, and adds the operation to the undo list
|
||
|
*/
|
||
|
virtual void deleteSelection();
|
||
|
/**
|
||
|
* This function looks at all the connectors and the nodes, determines
|
||
|
* which ones need rerouting, and then reroutes them
|
||
|
*/
|
||
|
void requestRerouteInvalidatedConnectors();
|
||
|
/**
|
||
|
* Remaps the 2-dimension array of ICNDocument cells, and the various
|
||
|
* hitscores / etc associated with them. This is used for connector
|
||
|
* routing, and should be called after e.g. items have been moved
|
||
|
*/
|
||
|
void createCellMap();
|
||
|
/**
|
||
|
* Call this to request NodeGroup reassignment.
|
||
|
*/
|
||
|
void slotRequestAssignNG();
|
||
|
|
||
|
signals:
|
||
|
/**
|
||
|
* Emitted when a Connector is added
|
||
|
*/
|
||
|
void connectorAdded( Connector *connector );
|
||
|
/**
|
||
|
* Emitted when a Node is added
|
||
|
*/
|
||
|
void nodeAdded( Node *node );
|
||
|
|
||
|
protected:
|
||
|
/**
|
||
|
* Adds all connector points from the items (used in connector routing).
|
||
|
* This only needs to be called when connector(s) need routing.
|
||
|
*/
|
||
|
void addAllItemConnectorPoints();
|
||
|
virtual void fillContextMenu( const QPoint &pos );
|
||
|
/**
|
||
|
* Creates a new NodeGroup to control the node, if there does not already
|
||
|
* exist a NodeGroup containing the given node. The associated nodes will
|
||
|
* also be added to the NodeGroup.
|
||
|
* @returns a pointer to the NodeGroup if one was created, or a pointer to the existing one containing that node
|
||
|
*/
|
||
|
NodeGroup* createNodeGroup( Node *node );
|
||
|
/**
|
||
|
* Finds (and deletes if found) the NodeGroup containing the given node.
|
||
|
* @returns true if the NodeGroup was found and deleted
|
||
|
*/
|
||
|
bool deleteNodeGroup( Node *node );
|
||
|
|
||
|
friend class CanvasEditor;
|
||
|
|
||
|
Cells *m_cells;
|
||
|
uint m_cellsX, m_cellsY;
|
||
|
NodeList m_nodeList;
|
||
|
ConnectorList m_connectorList;
|
||
|
CNItemGroup *m_selectList; // Selected objects
|
||
|
GuardedNodeGroupList m_nodeGroupList;
|
||
|
|
||
|
private:
|
||
|
QCanvasItemList m_itemDeleteList; // List of canvas items to be deleted
|
||
|
};
|
||
|
|
||
|
|
||
|
/**
|
||
|
@author David Saxton
|
||
|
*/
|
||
|
class DirCursor
|
||
|
{
|
||
|
public:
|
||
|
static DirCursor* self();
|
||
|
~DirCursor();
|
||
|
|
||
|
static QPixmap leftArrow()
|
||
|
{
|
||
|
return self()->m_leftArrow;
|
||
|
}
|
||
|
|
||
|
static QPixmap rightArrow()
|
||
|
{
|
||
|
return self()->m_rightArrow;
|
||
|
}
|
||
|
|
||
|
static QPixmap upArrow()
|
||
|
{
|
||
|
return self()->m_upArrow;
|
||
|
}
|
||
|
|
||
|
static QPixmap downArrow()
|
||
|
{
|
||
|
return self()->m_downArrow;
|
||
|
}
|
||
|
|
||
|
protected:
|
||
|
DirCursor();
|
||
|
void initCursors();
|
||
|
|
||
|
static DirCursor *m_self;
|
||
|
QPixmap m_leftArrow;
|
||
|
QPixmap m_rightArrow;
|
||
|
QPixmap m_upArrow;
|
||
|
QPixmap m_downArrow;
|
||
|
};
|
||
|
|
||
|
|
||
|
#endif
|