/*************************************************************************** * 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 #include #include #include class Canvas; class CanvasTip; class Connector; class CMManager; class ECNode; class Item; class ItemDocumentData; class ItemGroup; class KTechlab; class Operation; class TDEActionMenu; class TQCanvasItem; typedef TQPtrStack IDDStack; typedef TQGuardedPtr GuardedItem; typedef TQMap< int, GuardedItem > IntItemMap; typedef TQValueList ItemList; typedef TQValueList TQPointList; /** @author David Saxton */ class ItemDocument : public Document { Q_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 * invalidated, 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 parents. 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; TDEActionMenu * 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 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 m_v; TQValueVector m_i; ItemDocument *p_itemDocument; }; #endif