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/itemdocument.h

452 lines
12 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 ITEMDOCUMENT_H
#define ITEMDOCUMENT_H
#include <document.h>
#include <tqcanvas.h>
#include <tqptrstack.h>
#include <tqvaluevector.h>
class Canvas;
class CanvasTip;
class Connector;
class CMManager;
class ECNode;
class Item;
class ItemDocumentData;
class ItemGroup;
class KTechlab;
class Operation;
class KActionMenu;
class TQCanvasItem;
typedef TQPtrStack<ItemDocumentData> IDDStack;
typedef TQGuardedPtr<Item> GuardedItem;
typedef TQMap< int, GuardedItem > IntItemMap;
typedef TQValueList<GuardedItem> ItemList;
typedef TQValueList<TQPoint> TQPointList;
/**
@author David Saxton
*/
class ItemDocument : public Document
{
Q_OBJECT
TQ_OBJECT
public:
ItemDocument( const TQString &caption, KTechlab *ktechlab, const char *name = 0 );
~ItemDocument();
class Z
{
public:
enum
{
Select = 10000000,
Connector = 20000000,
Item = 30000000,
RaisedItem = 40000000,
ResizeHandle = 50000000,
Tip = 60000000,
ConnectorCreateLine = 70000000,
// How much "Z" separates items stacked on each other
DeltaItem = 10000
};
};
class RTTI
{
public:
enum
{
None = 1000,
CNItem = 1001,
Node = 1002,
Connector = 1003,
Pin = 1004,
Widget = 1005,
MechanicsItem = 1006,
ResizeHandle = 1007,
DrawPart = 1008,
ConnectorLine = 1009
};
};
/**
* Some things (such as the canvas getting resized, connectors being
* tqinvalidated, need to be done after editing operations have finished,
* etc, and they also need to be done in the order given in the
* enumeration below.
*/
class ItemDocumentEvent
{
public: enum type
{
ResizeCanvasToItems = 1 << 0,
UpdateNodeGroups = 1 << 1,
RerouteInvalidatedConnectors = 1 << 2,
UpdateZOrdering = 1 << 3,
};
};
virtual void fileSave();
virtual void fileSaveAs();
virtual void print();
virtual bool openURL( const KURL &url );
/**
* Attempt to register the item, returning true iff successful
*/
virtual bool registerItem( TQCanvasItem *qcanvasItem );
/**
* 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 ) = 0;
/**
* @returns A pointer to the canvas
*/
Canvas *canvas() const { return m_canvas; }
/**
* Attemtps to register a unique id for the canvas view of an item on the
* canvas. If the id does not already exist, will return true; otherwise
* the function will return false.
*/
bool registerUID( const TQString & uid );
/**
* Generates a unique id based on a possibly unique component name.
*/
TQString generateUID( TQString name );
/**
* Unlists the given id as one that is used.
* @see registerUID
*/
void unregisterUID( const TQString & uid );
/**
* @return Whether or not the item is valid; i.e. is appropriate to the
* document being edited, and does not have other special restrictions
* on it (such as only allowing one instance of the Start part in
* FlowCode).
*/
virtual bool isValidItem( Item *item ) = 0;
/**
* @return Whether or not the item is valid; i.e. is appropriate to the
* document being edited, and does not have other special restrictions
* on it (such as only allowing one instance of the Start part in
* FlowCode).
*/
virtual bool isValidItem( const TQString &itemId ) = 0;
/**
* Increases the "height" of the given list of items by "one".
*/
void raiseZ( const ItemList & itemList );
/**
* Decreases the "height" of the given list of items by "one".
*/
void lowerZ( const ItemList & itemList );
/**
* @return ItemGroup that is used as the select list for this document.
*/
virtual ItemGroup *selectList() const = 0;
/**
* Deselects any currently selected items
*/
void unselectAll();
/**
* Select a list of TQCanvasItem's
*/
void select( const TQCanvasItemList & list );
/**
* Select a TQCanvasItem
*/
void select( TQCanvasItem * item );
/**
* Unselects the item
*/
void unselect( TQCanvasItem *qcanvasItem );
/**
* Deletes anything waiting to be deleted.
*/
virtual void flushDeleteList() = 0;
/**
* Returns a rubber-band rectangle that contains all of the items on the
* canvas, padded out by a small border.
*/
TQRect canvasBoundingRect() const;
/**
* Returns a pointer to a Item on the canvas with the given id,
* or NULL if no such Item exists.
*/
Item* itemWithID( const TQString & );
/**
* Returns true if the the user can perform an undo action
* (i.e. the undo stack is not empty)
*/
virtual bool isUndoAvailable() const;
/**
* Returns true if the the user can perform an redo action
* (i.e. the redo stack is not empty)
*/
virtual bool isRedoAvailable() const;
/**
* Returns the top item at point (x, y), or NULL if there is no item there
*/
TQCanvasItem* itemAtTop( const TQPoint &pos ) const;
/**
* Called when the canvas is clicked on with the right mouse button.
* Popups up a menu for editing operations
*/
virtual void canvasRightClick( const TQPoint &pos, TQCanvasItem* item );
/**
* List of items in the ItemDocument
*/
ItemList itemList() const { return m_itemList; }
/**
* Set the given TQCanvasItem (which will attempt to be casted to known
* items to be deleted.
*/
virtual void appendDeleteList( TQCanvasItem * ) = 0;
/**
* Save the current state of the document to the undo/redo history.
* @param actionTicket if this is non-negative, and the last state save
* also had the same actionTicket, then the next state save will
* overwrite the previous state save.
* @see getActionTicket
*/
void requestStateSave( int actionTicket = -1 );
/**
* Returns a unique id, for use in requestStateSave
*/
int getActionTicket() const { return m_nextActionTicket++; }
/**
* Clears the undo / redo history
*/
void clearHistory();
/**
* Requests an event to be done after other stuff (editing, etc) is finished.
*/
void requestEvent( ItemDocumentEvent::type type );
/**
* Called from Canvas (when TQCanvas::advance is called).
*/
virtual void update();
public slots:
virtual void undo();
virtual void redo();
virtual void cut();
virtual void paste();
/**
* Selects everything in the view.
*/
virtual void selectAll() = 0;
/**
* Increases the "height" of the selected items.
*/
void raiseZ();
/**
* Decreases the "height" of the selected items.
*/
void lowerZ();
/**
* Brings up a file dialog requesting the location of the file to export
* to, and then exports an image of the canvas.
*/
void exportToImage();
/**
* Deletes whatever is selected.
*/
virtual void deleteSelection() {};
/**
* Called when the user presses Escape (or similar)
*/
void cancelCurrentOperation();
/**
* Sets the y-positions of the selected items to the average of the
* initial y-positions.
*/
void alignHorizontally();
/**
* Sets the x-positions of the selected items to the average of the
* initial x-positions.
*/
void alignVertically();
/**
* Averages out the horizontal spacing between the selected items.
*/
void distributeHorizontally();
/**
* Averages out the vertical spacing between the selected items.
*/
void distributeVertically();
/**
* Adds an items not in the Z ordering to the ordering, and removes any
* items from the Z ordering if they have tqparents. Then, calls all items
* found in the ordering to tell them their Z position.
*/
void slotUpdateZOrdering();
/**
* Call this with ItemDocument::DrawAction to start drawing the given thing
*/
void slotSetDrawAction( int da );
/**
* Sets the editing mode to repeatedly creating a CNItem
* with the given id. Usually called when the user double-clicks on
* the component box.
*/
void slotSetRepeatedItemId( const TQString &id );
/**
* Unsets the editing mode from repeatedly creating a CNItem
*/
void slotUnsetRepeatedItemId();
/**
* Called when the user changes the configuration.
* This, for example, will tell the CNItems on the canvas to update
* their configuration.
*/
virtual void slotUpdateConfiguration();
/**
* Enables / disables / selects various actions depending on
* what is selected or not.
*/
virtual void slotInitItemActions( Item *item = 0 );
/**
* Process queued events (see ItemDocument::ItemDocumentEvent).
*/
void processItemDocumentEvents();
signals:
/**
* Emitted when a Item is selected
*/
void itemSelected( Item *item );
/**
* Emitted when a Item is unselected
*/
void itemUnselected( Item *item = 0 );
protected:
/**
* Called from registerItem when a new item is added.
*/
virtual void itemAdded( Item * item );
virtual void handleNewView( View *view );
/**
* Set to true to remove buttons and grid and so on from the canvas, set false to put them back
*/
void setSVGExport( bool svgExport );
void writeFile();
/**
* Reinherit this if you want to add any options to the right-click context
*/
virtual void fillContextMenu( const TQPoint & pos );
/**
* Reads the background settings (grid-colour, underlying colour) from the Config settings,
* and generates the background pixmap from those settings
*/
void updateBackground();
/**
* Sets the canvas size to both (a) containing all items present on the
* canvas, and (b) no smaller than the smallest view of the canvas. This
* function should only be called by processItemDocumentEvents - a resize
* request must be made with requestEvent.
*/
void resizeCanvasToItems();
Canvas *m_canvas;
KTechlab *p_ktechlab;
TQStringList m_idList;
static int m_nextActionTicket;
uint m_nextIdNum;
bool m_bIsLoading;
TQSize m_oldCanvasSize;
CMManager *m_cmManager;
ItemList m_itemDeleteList;
ItemList m_itemList;
IDDStack m_undoStack;
IDDStack m_redoStack;
ItemDocumentData * m_currentState;
int m_currentActionTicket;
ItemDocumentData * m_savedState; // Pointer to the document data that holds the state when it saved
TQString m_fileExtensionInfo; // For displaying in the save file dialog
CanvasTip * m_canvasTip;
IntItemMap m_zOrder;
KActionMenu * m_pAlignmentAction;
TQTimer * m_pEventTimer;
unsigned m_queuedEvents; // OR'ed together list of ItemDocumentEvent::type
friend class ICNView;
friend class ItemView;
};
/**
@author David Saxton
*/
class Canvas : public TQCanvas
{
Q_OBJECT
TQ_OBJECT
public:
Canvas( ItemDocument *itemDocument, const char * name = 0 );
/**
* Sets a message to be displayed on the canvas for a brief period of
* time. If this is called with an empty message, then any existing
* message will be removed.
*/
void setMessage( const TQString & message );
virtual void update();
public slots:
void slotSetAllChanged() { setAllChanged(); }
protected:
virtual void drawBackground ( TQPainter & painter, const TQRect & clip );
virtual void drawForeground ( TQPainter & painter, const TQRect & clip );
ItemDocument *p_itemDocument;
TQString m_message;
TQTimer * m_pMessageTimeout;
};
/**
@author David Saxton
*/
class CanvasTip : public TQCanvasText
{
public:
CanvasTip( ItemDocument *itemDocument, TQCanvas *qcanvas );
virtual ~CanvasTip();
void displayVI( ECNode *node, const TQPoint &pos );
void displayVI( Connector *connector, const TQPoint &pos );
protected:
virtual void draw( TQPainter &p );
bool updateVI();
void display( const TQPoint &pos );
TQString displayText( unsigned num ) const;
TQValueVector<double> m_v;
TQValueVector<double> m_i;
ItemDocument *p_itemDocument;
};
#endif