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.
ktechlab/src/icndocument.h

282 lines
9.0 KiB

/***************************************************************************
* 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 TQValueList<TQGuardedPtr<Connector> > ConnectorList;
typedef TQValueList<TQGuardedPtr<Node> > NodeList;
typedef TQValueList<NodeGroup*> NodeGroupList;
typedef TQValueList<TQGuardedPtr<NodeGroup> > GuardedNodeGroupList;
/**
@author David Saxton
*/
class ICNDocument : public ItemDocument
{
Q_OBJECT
public:
ICNDocument( const TQString &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 TQString &id, const TQPoint &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 TQString &startNodeId, const TQString &endNodeId, TQPointList *pointList = 0L );
/**
* short for casting whatever itemWithID(id) returns
*/
CNItem* cnItemWithID( const TQString &id );
/**
* Returns a pointer to a node on the canvas with the given id,
* or NULL if no such node exists
*/
Node* nodeWithID( const TQString &id );
/**
* Returns a pointer to a Connector on the canvas with the given id,
* or NULL if no such Connector exists
*/
Connector* connectorWithID( const TQString &id );
/**
* Adds a TQCanvasItem to the delete list to be deleted,
* when flushDeleteList() is called
*/
virtual void appendDeleteList( TQCanvasItem *qcanvasItem );
/**
* Permantly deletes all items that have been added to the delete list with
* the appendDeleteList( TQCanvasItem *qcanvasItem ) function.
*/
virtual void flushDeleteList();
/**
* Reinherit this function to perform special checks on whether the two
* given TQCanvasItems (either nodes or connectors or both) can be
* connected together.
*/
virtual bool canConnect( TQCanvasItem *qcanvasItem1, TQCanvasItem *qcanvasItem2 ) const;
virtual void copy();
virtual void selectAll();
virtual bool registerItem( TQCanvasItem *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 TQPoint gridSnap( const TQPoint &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 TQString &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, TQPointList *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 TQPoint &pos2, TQPointList *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 TQPoint &pos1, const TQPoint &pos2, TQPointList *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 TQPoint &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 TQPoint &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:
TQCanvasItemList m_itemDeleteList; // List of canvas items to be deleted
};
/**
@author David Saxton
*/
class DirCursor
{
public:
static DirCursor* self();
~DirCursor();
static TQPixmap leftArrow()
{
return self()->m_leftArrow;
}
static TQPixmap rightArrow()
{
return self()->m_rightArrow;
}
static TQPixmap upArrow()
{
return self()->m_upArrow;
}
static TQPixmap downArrow()
{
return self()->m_downArrow;
}
protected:
DirCursor();
void initCursors();
static DirCursor *m_self;
TQPixmap m_leftArrow;
TQPixmap m_rightArrow;
TQPixmap m_upArrow;
TQPixmap m_downArrow;
};
#endif