File indexing completed on 2024-10-13 05:05:16

0001 /***************************************************************************
0002  *   Copyright (C) 2004-2006 by David Saxton                               *
0003  *   david@bluehaze.org                                                    *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  ***************************************************************************/
0010 
0011 #ifndef ITEM_H
0012 #define ITEM_H
0013 
0014 #include "itemdocument.h"
0015 #include "variant.h"
0016 
0017 //#include <canvas.h> // 2018.10.16 - not needed
0018 #include "canvasitems.h"
0019 #include <QPointer>
0020 
0021 class Document;
0022 class EventInfo;
0023 class Item;
0024 class ItemData;
0025 class ItemDocument;
0026 class ItemView;
0027 class DoubleSpinBox;
0028 class Document;
0029 class Variant;
0030 class QBitArray;
0031 class QTimer;
0032 
0033 typedef Variant Property;
0034 
0035 typedef Item *(*createItemPtr)(ItemDocument *itemDocument, bool newItem, const char *id);
0036 typedef QPointer<Item> GuardedItem;
0037 typedef QMap<QString, Variant *> VariantDataMap;
0038 typedef QList<GuardedItem> ItemList;
0039 
0040 /**
0041 @author David Saxton
0042 @author Daniel Clarke
0043 */
0044 class Item : /* public QObject, */ public KtlQCanvasPolygon
0045 {
0046     Q_OBJECT
0047 public:
0048     Item(ItemDocument *itemDocument, bool newItem, const QString &id);
0049     ~Item() override;
0050 
0051     /**
0052      * @return Pointer to the VariantMap used for internal data storage
0053      */
0054     VariantDataMap *variantMap()
0055     {
0056         return &m_variantData;
0057     }
0058 
0059     double dataDouble(const QString &id) const;
0060     int dataInt(const QString &id) const;
0061     bool dataBool(const QString &id) const;
0062     QString dataString(const QString &id) const;
0063     QColor dataColor(const QString &id) const;
0064 
0065     virtual Property *createProperty(const QString &id, Variant::Type::Value type);
0066     Property *property(const QString &id) const;
0067     bool hasProperty(const QString &id) const;
0068 
0069     /**
0070      * Whether or not we can resize the item
0071      */
0072     virtual bool canResize() const
0073     {
0074         return false;
0075     }
0076     /**
0077      * Returns whether the CNItem allows itself to be moved on the canvas.
0078      * Most do, but some (such as the PicItem) don't allow this
0079      */
0080     virtual bool isMovable() const
0081     {
0082         return true;
0083     }
0084     /**
0085      * Returns whether or not what the item is displaying has (possibly) changed
0086      * since this function was last called. If your item doesn't move, yet still
0087      * continously changes what is being displayed (such as a seven segment
0088      * display or a lamp), then set m_bDynamicContent to be true in the
0089      * constructor or reinherit this to return true when the contents of the
0090      * item have changed since this function was last called.
0091      */
0092     virtual bool contentChanged() const
0093     {
0094         return m_bDynamicContent;
0095     }
0096     /**
0097      * Returns a identifier for the CNItem, which is unique on the ICNDocument
0098      */
0099     QString id() const
0100     {
0101         return m_id;
0102     }
0103     QString type() const
0104     {
0105         return m_type;
0106     }
0107     /**
0108      * @return the font used for drawing items. This is taken to be the
0109      * standard desktop font, limited to a size of 12 pixels.
0110      */
0111     QFont font() const;
0112     /**
0113      * Called from ItemLibrary after this class and subclasses have finished
0114      * constructing themselves.
0115      */
0116     virtual void finishedCreation();
0117     /**
0118      * Sets the selected flag of the item to yes. selected or unselected will be
0119      * emitted as appropriate
0120      */
0121     void setSelected(bool yes) override;
0122     /**
0123      * Convenience function for setting the item bounding area as changed on the
0124      * canvas
0125      */
0126     void setChanged();
0127     /**
0128      * Sets this item as a child of the given item. Calls reparented with the
0129      * old and the new parent.
0130      */
0131     void setParentItem(Item *parentItem);
0132     /**
0133      * The parent item for this item, or nullptr if none
0134      */
0135     Item *parentItem() const
0136     {
0137         return p_parentItem;
0138     }
0139     ItemDocument *itemDocument() const
0140     {
0141         return p_itemDocument;
0142     }
0143     /**
0144      * Returns the number of items away from the top item this is
0145      * (parent-wise). Returns 0 if has no parent.
0146      */
0147     int level() const;
0148     /**
0149      * If true, then adds ItemDocument::Z::(RaisedItem-Item) to the z value of
0150      * the item.
0151      */
0152     void setRaised(bool isRaised);
0153     /**
0154      * @Returns whether raised or not
0155      */
0156     bool isRaised() const
0157     {
0158         return m_bIsRaised;
0159     }
0160     /**
0161      * Sets this item to the given baseZ level, and calls this function for the
0162      * children with baseZ incremented by one. Reinherit this function to set
0163      * the Z of attached stuff (such as nodes).
0164      */
0165     virtual void updateZ(int baseZ);
0166     /**
0167      * Returns the item's position in the overall z-stack of items.
0168      */
0169     int baseZ() const
0170     {
0171         return m_baseZ;
0172     }
0173     /**
0174      * Adds a child. Calls the virtual function childAdded.
0175      */
0176     void addChild(Item *child);
0177     /**
0178      * Returns the list of children.
0179      * @param includeGrandChildren if includeGrandChildren is true then this list will also contain
0180      * the children's children, and so on recursively, instead of just the
0181      * immediate children.
0182      */
0183     ItemList children(bool includeGrandChildren = false) const;
0184     /**
0185      * Returns whether we have the given child as either a direct child, or as
0186      * either a direct or indirect child
0187      */
0188     bool contains(Item *item, bool direct = false) const;
0189     /**
0190      * Calls prePresize with the bounds, and if that returns true, sets
0191      * m_sizeRect to the given rect, and then calls postResize. The center of
0192      * \p sizeRect is taken as the point of rotation.
0193      * @param forceItemPoints if true, will set the item points to a rectangle
0194      * @of the given size. Pass true if you have already set the size, and want
0195      * to update the appearance and bounding of the item.
0196      */
0197     void setSize(QRect sizeRect, bool forceItemPoints = false);
0198     /**
0199      * Convenience function.
0200      * @see setSize( QRect sizeRect, bool forceItemPoints );
0201      */
0202     void setSize(int x, int y, int w, int h, bool forceItemPoints = false)
0203     {
0204         setSize(QRect(x, y, w, h), forceItemPoints);
0205     }
0206     /**
0207      * @returns the m_sizeRect rectangble that contains the item points
0208      */
0209     QRect sizeRect() const
0210     {
0211         return m_sizeRect;
0212     }
0213     /**
0214      * Reinherit this function if you want to determine what the minimum size is
0215      * that this item can be resized to.
0216      */
0217     virtual QSize minimumSize() const
0218     {
0219         return QSize(0, 0);
0220     }
0221     int offsetX() const
0222     {
0223         return m_sizeRect.x();
0224     }
0225     int offsetY() const
0226     {
0227         return m_sizeRect.y();
0228     }
0229     int width() const
0230     {
0231         return m_sizeRect.width();
0232     }
0233     int height() const
0234     {
0235         return m_sizeRect.height();
0236     }
0237     virtual bool mousePressEvent(const EventInfo &eventInfo);
0238     virtual bool mouseReleaseEvent(const EventInfo &eventInfo);
0239     virtual bool mouseDoubleClickEvent(const EventInfo &eventInfo);
0240     virtual bool mouseMoveEvent(const EventInfo &eventInfo);
0241     virtual bool wheelEvent(const EventInfo &eventInfo);
0242     virtual void enterEvent(QEvent *);
0243     virtual void leaveEvent(QEvent *);
0244     /**
0245      * Returns the name of the CNItem, e.g. "Resistor"
0246      */
0247     QString name() const
0248     {
0249         return m_name;
0250     }
0251     /**
0252      * Modifies the exponent of the number so that it appears readable:
0253      * eg 10000->10, 174822->175, 0.6->600, etc
0254      */
0255     static int getNumberPre(double num);
0256     /**
0257      * Returns the SI exponent of the number as a letter:
0258      * eg 10000 returns 'k', 0.6 returns 'm', etc
0259      */
0260     static QString getNumberMag(double num);
0261     /**
0262      * Returns the multiplier required to get the num up to human readable form:
0263      * eg 10000 returns 0.001, etc
0264      */
0265     static double getMultiplier(double num);
0266     /**
0267      * Returns the multiplier required to get the num from human readable form
0268      * to its actual value based on the SI exponent:
0269      * eg 'm' returns 0.001, etc
0270      */
0271     static double getMultiplier(const QString &mag);
0272 
0273     virtual ItemData itemData() const;
0274     virtual void restoreFromItemData(const ItemData &itemData);
0275 
0276 public slots:
0277     virtual void removeItem();
0278     /**
0279      * Moves item - use this instead of moveBy() so that associated Nodes also get moved
0280      */
0281     void moveBy(double dx, double dy) override;
0282     /**
0283      * Removes a child. Calls the virtual function childRemoved
0284      */
0285     void removeChild(Item *child);
0286 
0287 signals:
0288     /**
0289      * Emitted when the CNItem is removed. Normally, this signal is caught by associated
0290      * nodes, who will remove themselves as well.
0291      */
0292     void removed(Item *item);
0293     /**
0294      * Emitted when the item is selected or unselected.
0295      */
0296     void selectionChanged();
0297     /**
0298      * Emitted when the item is resized (after calling postResize)
0299      */
0300     void resized();
0301     /**
0302      * Emitted when the item is moved (by dx, dy).
0303      */
0304     void movedBy(double dx, double dy);
0305 
0306 protected slots:
0307     virtual void propertyChangedInitial();
0308     virtual void dataChanged() {};
0309 
0310 protected:
0311     /**
0312      * Reinherit this function if you want to do anything with children. Called
0313      * after the parent is changed, with the old parent and the new parent.
0314      */
0315     virtual void reparented(Item * /*oldParent*/, Item * /*newParent*/) {};
0316     /**
0317      * Reinherit this function if you want to do anything with children. Called
0318      * after a child has been added.
0319      */
0320     virtual void childAdded(Item *) {};
0321     /**
0322      * Reinherit this function if you want to do anything with children. Called
0323      * after a child has been removed.
0324      */
0325     virtual void childRemoved(Item *) {};
0326     /**
0327      * Set the rough bounding points for this item. Calls itemPointsChanged
0328      * after setting the points
0329      */
0330     void setItemPoints(const QPolygon &pa, bool setSizeFromPoints = true);
0331     /**
0332      * Reinherit this function if you want to apply any sort of transformation
0333      * to the item points
0334      */
0335     virtual void itemPointsChanged();
0336     virtual bool preResize(QRect sizeRect)
0337     {
0338         Q_UNUSED(sizeRect);
0339         return true;
0340     }
0341     virtual void postResize() {};
0342 
0343     QString m_id;
0344     QString m_name; ///< Name (e.g. "Resistor")
0345     QString m_type;
0346     GuardedItem p_parentItem; // If attached to a parent item
0347     ItemList m_children;
0348     QPointer<ItemDocument> p_itemDocument;
0349     QPolygon m_itemPoints;           // The unorientated and unsized item points
0350     QTimer *m_pPropertyChangedTimer; ///< Single show timer for one a property changes
0351 
0352     friend class ItemLibrary;
0353 
0354     int m_baseZ;
0355     bool m_bIsRaised;
0356     bool m_bDoneCreation;
0357     bool b_deleted;
0358     bool m_bDynamicContent;
0359     QRect m_sizeRect;
0360     VariantDataMap m_variantData;
0361 };
0362 
0363 #endif