1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
|
/***************************************************************************
* 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
|