1 /*
2  * LibrePCB - Professional EDA for everyone!
3  * Copyright (C) 2013 LibrePCB Developers, see AUTHORS.md for contributors.
4  * https://librepcb.org/
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef LIBREPCB_LIBRARY_COMPONENTSYMBOLVARIANTITEM_H
21 #define LIBREPCB_LIBRARY_COMPONENTSYMBOLVARIANTITEM_H
22 
23 /*******************************************************************************
24  *  Includes
25  ******************************************************************************/
26 #include "componentpinsignalmap.h"
27 #include "componentsymbolvariantitemsuffix.h"
28 
29 #include <librepcb/common/fileio/cmd/cmdlistelementinsert.h>
30 #include <librepcb/common/fileio/cmd/cmdlistelementremove.h>
31 #include <librepcb/common/fileio/cmd/cmdlistelementsswap.h>
32 #include <librepcb/common/fileio/serializableobjectlist.h>
33 #include <librepcb/common/units/all_length_units.h>
34 #include <librepcb/common/uuid.h>
35 
36 #include <QtCore>
37 
38 /*******************************************************************************
39  *  Namespace / Forward Declarations
40  ******************************************************************************/
41 namespace librepcb {
42 namespace library {
43 
44 /*******************************************************************************
45  *  Class ComponentSymbolVariantItem
46  ******************************************************************************/
47 
48 /**
49  * @brief The ComponentSymbolVariantItem class represents one symbol of a
50  * component symbol variant
51  *
52  * Following information is considered as the "interface" of a symbol variant
53  * item and must therefore never be changed:
54  *  - UUID
55  *  - Symbol UUID
56  *  - Pin-signal-mapping
57  */
58 class ComponentSymbolVariantItem final : public SerializableObject {
59   Q_DECLARE_TR_FUNCTIONS(ComponentSymbolVariantItem)
60 
61 public:
62   // Signals
63   enum class Event {
64     UuidChanged,
65     SymbolUuidChanged,
66     SymbolPositionChanged,
67     SymbolRotationChanged,
68     IsRequiredChanged,
69     SuffixChanged,
70     PinSignalMapEdited,
71   };
72   Signal<ComponentSymbolVariantItem, Event> onEdited;
73   typedef Slot<ComponentSymbolVariantItem, Event> OnEditedSlot;
74 
75   // Constructors / Destructor
76   ComponentSymbolVariantItem() = delete;
77   ComponentSymbolVariantItem(const ComponentSymbolVariantItem& other) noexcept;
78   ComponentSymbolVariantItem(
79       const Uuid& uuid, const Uuid& symbolUuid, const Point& symbolPos,
80       const Angle& symbolRotation, bool isRequired,
81       const ComponentSymbolVariantItemSuffix& suffix) noexcept;
82   ComponentSymbolVariantItem(const SExpression& node,
83                              const Version& fileFormat);
84   ~ComponentSymbolVariantItem() noexcept;
85 
86   // Getters: Attributes
getUuid()87   const Uuid& getUuid() const noexcept { return mUuid; }
getSymbolUuid()88   const Uuid& getSymbolUuid() const noexcept { return mSymbolUuid; }
getSymbolPosition()89   const Point& getSymbolPosition() const noexcept { return mSymbolPos; }
getSymbolRotation()90   const Angle& getSymbolRotation() const noexcept { return mSymbolRot; }
isRequired()91   bool isRequired() const noexcept { return mIsRequired; }
getSuffix()92   const ComponentSymbolVariantItemSuffix& getSuffix() const noexcept {
93     return mSuffix;
94   }
95 
96   // Setters: Attributes
97   bool setSymbolUuid(const Uuid& uuid) noexcept;
98   bool setSymbolPosition(const Point& pos) noexcept;
99   bool setSymbolRotation(const Angle& rot) noexcept;
100   bool setIsRequired(bool required) noexcept;
101   bool setSuffix(const ComponentSymbolVariantItemSuffix& suffix) noexcept;
102 
103   // Pin-Signal-Map Methods
getPinSignalMap()104   ComponentPinSignalMap& getPinSignalMap() noexcept { return mPinSignalMap; }
getPinSignalMap()105   const ComponentPinSignalMap& getPinSignalMap() const noexcept {
106     return mPinSignalMap;
107   }
108 
109   /// @copydoc librepcb::SerializableObject::serialize()
110   void serialize(SExpression& root) const override;
111 
112   // Operator Overloadings
113   bool operator==(const ComponentSymbolVariantItem& rhs) const noexcept;
114   bool operator!=(const ComponentSymbolVariantItem& rhs) const noexcept {
115     return !(*this == rhs);
116   }
117   ComponentSymbolVariantItem& operator=(
118       const ComponentSymbolVariantItem& rhs) noexcept;
119 
120 private:  // Methods
121   void pinSignalMapEdited(
122       const ComponentPinSignalMap& map, int index,
123       const std::shared_ptr<const ComponentPinSignalMapItem>& item,
124       ComponentPinSignalMap::Event event) noexcept;
125 
126 private:  // Data
127   Uuid mUuid;
128   Uuid mSymbolUuid;
129   Point mSymbolPos;
130   Angle mSymbolRot;
131   bool mIsRequired;
132   ComponentSymbolVariantItemSuffix mSuffix;
133   ComponentPinSignalMap mPinSignalMap;
134 
135   // Slots
136   ComponentPinSignalMap::OnEditedSlot mOnPinSignalMapEditedSlot;
137 };
138 
139 /*******************************************************************************
140  *  Class ComponentSymbolVariantItemList
141  ******************************************************************************/
142 
143 struct ComponentSymbolVariantItemListNameProvider {
144   static constexpr const char* tagname = "gate";
145 };
146 using ComponentSymbolVariantItemList =
147     SerializableObjectList<ComponentSymbolVariantItem,
148                            ComponentSymbolVariantItemListNameProvider,
149                            ComponentSymbolVariantItem::Event>;
150 using CmdComponentSymbolVariantItemInsert =
151     CmdListElementInsert<ComponentSymbolVariantItem,
152                          ComponentSymbolVariantItemListNameProvider,
153                          ComponentSymbolVariantItem::Event>;
154 using CmdComponentSymbolVariantItemRemove =
155     CmdListElementRemove<ComponentSymbolVariantItem,
156                          ComponentSymbolVariantItemListNameProvider,
157                          ComponentSymbolVariantItem::Event>;
158 using CmdComponentSymbolVariantItemsSwap =
159     CmdListElementsSwap<ComponentSymbolVariantItem,
160                         ComponentSymbolVariantItemListNameProvider,
161                         ComponentSymbolVariantItem::Event>;
162 
163 /*******************************************************************************
164  *  Class ComponentSymbolVariantItemListHelpers
165  ******************************************************************************/
166 
167 class ComponentSymbolVariantItemListHelpers {
168 public:
169   ComponentSymbolVariantItemListHelpers() = delete;  // disable instantiation
170 
getAllSymbolUuids(const ComponentSymbolVariantItemList & list)171   static QSet<Uuid> getAllSymbolUuids(
172       const ComponentSymbolVariantItemList& list) noexcept {
173     QSet<Uuid> set;
174     for (const auto& item : list) {
175       set.insert(item.getSymbolUuid());
176     }
177     return set;
178   }
179 };
180 
181 /*******************************************************************************
182  *  End of File
183  ******************************************************************************/
184 
185 }  // namespace library
186 }  // namespace librepcb
187 
188 #endif  // LIBREPCB_LIBRARY_COMPONENTSYMBOLVARIANTITEM_H
189