File indexing completed on 2024-12-08 11:06:53
0001 /*************************************************************************** 0002 * Copyright (C) 2003-2005 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 FLOWPART_H 0012 #define FLOWPART_H 0013 0014 #include "cnitem.h" 0015 0016 class ICNDocument; 0017 class Node; 0018 class FlowCode; 0019 class FlowCodeDocument; 0020 class FlowPart; 0021 class FPNode; 0022 class QPixmap; 0023 class QSize; 0024 0025 typedef QList<FlowPart *> FlowPartList; 0026 0027 /** 0028 All flow parts (eg 'CallSub', 'Read from Port' ,etc) should inherit from this class. 0029 It provides basic functionality for creating commonly used nodes, as well as a virtual function 0030 that you should reinherit for generating the assembly code. 0031 @short Base class for all FlowParts 0032 @author David Saxton 0033 */ 0034 class FlowPart : public CNItem 0035 { 0036 Q_OBJECT 0037 public: 0038 enum FlowSymbol { 0039 ps_process, // Process - Plain rectangular box 0040 ps_call, // Call - Rectangular box with double vertical lines at either end 0041 ps_io, // I/O - Slanter rectangular box 0042 ps_round, // Start/End - Rounded rectangular box 0043 ps_decision, // Decision - Diamond shape 0044 ps_other // Custom shape, which is ignored by FlowPart 0045 }; 0046 FlowPart(ICNDocument *icnDocument, bool newItem, const QString &id); 0047 ~FlowPart() override; 0048 0049 virtual void generateMicrobe(FlowCode * /*code*/) = 0; 0050 /** 0051 * Set a preset "orientation" of this item - 0 through 7 0052 */ 0053 void setOrientation(uint orientation); 0054 uint orientation() const 0055 { 0056 return m_orientation; 0057 } 0058 /** 0059 * The allowed orientations, as bit positions of 0 through 7 0060 */ 0061 uint allowedOrientations() const; 0062 ItemData itemData() const override; 0063 void restoreFromItemData(const ItemData &itemData) override; 0064 /** 0065 * Sets the caption displayed in the flowpart, resizes the item as necessary 0066 */ 0067 virtual void setCaption(const QString &caption); 0068 /** 0069 * Traces the FlowCode document route from the nodes with the given internal 0070 * ids, and returns the FlowPart to which: 0071 * @li all the routes from the given nodes are eventually connected to downwards 0072 * @li their exists one (possibly internally branched) route for each node to that part 0073 * @param ids The list of internal ids of the nodes for the paths to begin from - if empty, 0074 * all nodes internal nodes are used 0075 * @param previousParts A list of parts in the calling tree. This avoids infinite recursion. 0076 * @returns The first FlowPart satisfying these conditions, or nullptr if no such part exists 0077 */ 0078 FlowPart *endPart(QStringList ids, FlowPartList *previousParts = nullptr); 0079 /** 0080 * Handles the addition of a if-else statement to the given FlowCode. This will 0081 * order the code as necessary, adding the branches in the appropriate places 0082 * @param code The FlowCode where the if-else will be added 0083 * @param case1Statement The statement (e.g. "PORTA.0 is high") used for the first case 0084 * @param case2Statement The logically opposite statement (e.g. "PORTA.0 is low") (note 0085 that only one of the two statements will be used. 0086 * @param case1 The internal node id for case1 0087 * @param case2 The internal node id for case2 0088 */ 0089 void handleIfElse(FlowCode *code, const QString &case1Statement, const QString &case2Statement, const QString &case1, const QString &case2); 0090 /** 0091 * Returns a pointer to the FlowPart that is connected to the node with the 0092 * given internal id, or nullptr if no such node / no connected part 0093 */ 0094 FlowPart *outputPart(const QString &internalNodeId); 0095 /** 0096 * Returns the FlowParts connected to the given node 0097 * @see outputPart 0098 */ 0099 FlowPartList inputParts(const QString &id); 0100 /** 0101 * Returns a list of parts that are connected to *all* input parts 0102 */ 0103 FlowPartList inputParts(); 0104 /** 0105 * Returns a list of parts that are connected to *all* output parts. Note that if 0106 * the same FlowPart is connected to more than one output, that flowpart will appear 0107 * in the FlowPartList the number of times it is connected. 0108 */ 0109 FlowPartList outputParts(); 0110 /** 0111 * Draw the picture of the flowpart in the given orientation onto the pixmap 0112 */ 0113 void orientationPixmap(uint orientation, QPixmap &pm) const; 0114 Variant *createProperty(const QString &id, Variant::Type::Value type) override; 0115 0116 public slots: 0117 /** 0118 * Called when variable name data for MicroSettings changes, and so our 0119 * data needs updating 0120 */ 0121 void updateVarNames(); 0122 /** 0123 * Called when a variable name has changed (from an entry box) 0124 */ 0125 void varNameChanged(QVariant newValue, QVariant oldValue); 0126 /** 0127 * Called when some of the FlowPart-specific variables (e.g. Pin or 0128 * SevenSegment) requiring updating, such as when the PIC type changes 0129 * or the list of Pin Maps changes. 0130 */ 0131 void slotUpdateFlowPartVariables(); 0132 0133 protected: 0134 void updateAttachedPositioning() override; 0135 /** 0136 * Removes the node ids that shouldn't be used for finding the end part 0137 */ 0138 virtual void filterEndPartIDs(QStringList *ids) 0139 { 0140 Q_UNUSED(ids); 0141 } 0142 /** 0143 * Normally just passes the paint request onto CNItem::drawShape, 0144 * although in the case of some FlowSymbols (e.g. decision), it will handle 0145 * the drawing itself 0146 */ 0147 void drawShape(QPainter &p) override; 0148 0149 /** 0150 * Returns the goto instruction that will goto the FlowPart that is connected 0151 * to the node with the given internal id. 0152 * For example, gotoCode("stdOutput") might return "goto delay__13" 0153 */ 0154 QString gotoCode(const QString &internalNodeId); 0155 /** 0156 * Creates a FPNode with an internal id of "stdinput". 0157 * The node is positioned half-way along the top of the FlowPart, 0158 * as determined by width(), height(), x() and y() 0159 */ 0160 void createStdInput(); 0161 /** 0162 * Creates a FPNode with an internal id of "stdoutput". 0163 * The node is positioned half-way along the bottom of the FlowPart, 0164 * as determined by width(), height(), x() and y() 0165 */ 0166 void createStdOutput(); 0167 /** 0168 * Creates a FPNode with an internal id of "altoutput". 0169 * The node is positioned half-way along the right of the FlowPart, 0170 * as determined by width(), height(), x() and y() 0171 */ 0172 void createAltOutput(); 0173 /** 0174 * Initialises a symbol, by calling setItemPoints with the shape 0175 */ 0176 void initSymbol(FlowPart::FlowSymbol symbol, int width = 48); 0177 0178 void initProcessSymbol() 0179 { 0180 initSymbol(FlowPart::ps_process); 0181 } 0182 void initCallSymbol() 0183 { 0184 initSymbol(FlowPart::ps_call); 0185 } 0186 void initIOSymbol() 0187 { 0188 initSymbol(FlowPart::ps_io); 0189 } 0190 void initRoundedRectSymbol() 0191 { 0192 initSymbol(FlowPart::ps_round); 0193 } 0194 void initDecisionSymbol() 0195 { 0196 initSymbol(FlowPart::ps_decision); 0197 } 0198 0199 QString m_caption; 0200 uint m_orientation; 0201 FPNode *m_stdInput; 0202 FPNode *m_stdOutput; 0203 FPNode *m_altOutput; 0204 QPointer<FlowCodeDocument> m_pFlowCodeDocument; 0205 0206 void postResize() override; 0207 void updateNodePositions(); 0208 0209 private: 0210 FlowSymbol m_flowSymbol; 0211 }; 0212 typedef QList<FlowPart *> FlowPartList; 0213 0214 #endif