1 /*******************************************************************
2
3 Part of the Fritzing project - http://fritzing.org
4 Copyright (c) 2007-2014 Fachhochschule Potsdam - http://fh-potsdam.de
5
6 Fritzing 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 Fritzing 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 Fritzing. If not, see <http://www.gnu.org/licenses/>.
18
19 ********************************************************************
20
21 $Revision: 6954 $:
22 $Author: irascibl@gmail.com $:
23 $Date: 2013-04-05 10:22:00 +0200 (Fr, 05. Apr 2013) $
24
25 ********************************************************************/
26
27 #include "connector.h"
28 #include "connectorshared.h"
29 #include "connectoritem.h"
30 #include "../debugdialog.h"
31 #include "../model/modelpart.h"
32 #include "bus.h"
33 #include "../fsvgrenderer.h"
34 #include "ercdata.h"
35
36 QHash <Connector::ConnectorType, QString > Connector::Names;
37 static const QList<SvgIdLayer *> EmptySvgIdLayerList;
38
QuickHash(ViewLayer::ViewID viewID,ViewLayer::ViewLayerID viewLayerID)39 static inline int QuickHash(ViewLayer::ViewID viewID, ViewLayer::ViewLayerID viewLayerID) {
40 return (1000 * viewID) + viewLayerID;
41 }
42
Connector(ConnectorShared * connectorShared,ModelPart * modelPart)43 Connector::Connector( ConnectorShared * connectorShared, ModelPart * modelPart)
44 {
45 m_modelPart = modelPart;
46 m_connectorShared = connectorShared;
47 m_bus = NULL;
48 }
49
~Connector()50 Connector::~Connector() {
51 //DebugDialog::debug(QString("deleting connector %1 %2").arg((long) this, 0, 16).arg(connectorSharedID()));
52 foreach (ConnectorItem * connectorItem, m_connectorItems.values()) {
53 connectorItem->clearConnector();
54 }
55 }
56
initNames()57 void Connector::initNames() {
58 if (Names.count() == 0) {
59 Names.insert(Connector::Male, "male");
60 Names.insert(Connector::Female, "female");
61 Names.insert(Connector::Wire, "wire");
62 Names.insert(Connector::Pad, "pad");
63 }
64
65 }
66
connectorTypeFromName(const QString & name)67 Connector::ConnectorType Connector::connectorTypeFromName(const QString & name) {
68 QHashIterator<ConnectorType, QString> i(Names);
69 while (i.hasNext()) {
70 i.next();
71 if (name.compare(i.value(), Qt::CaseInsensitive ) == 0) {
72 return i.key();
73 }
74 }
75
76 return Connector::Unknown;
77 }
78
connectorNameFromType(ConnectorType type)79 const QString & Connector::connectorNameFromType(ConnectorType type) {
80 return Names[type];
81 }
82
connectorType() const83 Connector::ConnectorType Connector::connectorType() const {
84 if (m_connectorShared != NULL) {
85 return m_connectorShared->connectorType();
86 }
87
88 return Connector::Unknown;
89 }
90
connectorShared()91 ConnectorShared * Connector::connectorShared() {
92 return m_connectorShared;
93 }
94
addViewItem(ConnectorItem * item)95 void Connector::addViewItem(ConnectorItem * item) {
96 //item->debugInfo(QString("add view item c:%1 ci:%2 b:%3").arg((long) this, 0, 16).arg((long) item, 0, 16).arg((long) m_bus.data(), 0, 16));
97 m_connectorItems.insert(QuickHash(item->attachedToViewID(), item->attachedToViewLayerID()), item);
98 }
99
removeViewItem(ConnectorItem * item)100 void Connector::removeViewItem(ConnectorItem * item) {
101 //DebugDialog::debug(QString("remove view item c:%1 ci:%2 b:%3").arg((long) this, 0, 16).arg((long) item, 0, 16).arg((long) m_bus.data(), 0, 16));
102 m_connectorItems.remove(QuickHash(item->attachedToViewID(), item->attachedToViewLayerID()));
103 }
104
connectTo(Connector * connector)105 void Connector::connectTo(Connector * connector) {
106
107 if (this->modelPart() == NULL) {
108 DebugDialog::debug("connecting bus connector 1");
109 }
110 else if (connector->modelPart() == NULL) {
111 DebugDialog::debug("connecting bus connector 2");
112 }
113
114 if (!m_toConnectors.contains(connector)) {
115 m_toConnectors.append(connector);
116 }
117 if (!connector->m_toConnectors.contains(this)) {
118 connector->m_toConnectors.append(this);
119 }
120 }
121
disconnectFrom(Connector * connector)122 void Connector::disconnectFrom(Connector * connector) {
123 m_toConnectors.removeOne(connector);
124 connector->m_toConnectors.removeOne(this);
125 }
126
saveAsPart(QXmlStreamWriter & writer)127 void Connector::saveAsPart(QXmlStreamWriter & writer) {
128 writer.writeStartElement("connector");
129 writer.writeAttribute("id", connectorShared()->id());
130 writer.writeAttribute("type", connectorShared()->connectorTypeString());
131 writer.writeAttribute("name", connectorShared()->sharedName());
132 writer.writeTextElement("description", connectorShared()->description());
133 writer.writeTextElement("replacedby", connectorShared()->replacedby());
134 writer.writeStartElement("views");
135 QMultiHash<ViewLayer::ViewID,SvgIdLayer *> pins = m_connectorShared->pins();
136 foreach (ViewLayer::ViewID currView, pins.uniqueKeys()) {
137 writer.writeStartElement(ViewLayer::viewIDXmlName(currView));
138 foreach (SvgIdLayer * svgIdLayer, pins.values(currView)) {
139 writer.writeStartElement("p");
140 writeLayerAttr(writer, svgIdLayer->m_svgViewLayerID);
141 writeSvgIdAttr(writer, currView, svgIdLayer->m_svgId);
142 writeTerminalIdAttr(writer, currView, svgIdLayer->m_terminalId);
143 writer.writeEndElement();
144 }
145 writer.writeEndElement();
146 }
147 writer.writeEndElement();
148 writer.writeEndElement();
149 }
150
writeLayerAttr(QXmlStreamWriter & writer,ViewLayer::ViewLayerID viewLayerID)151 void Connector::writeLayerAttr(QXmlStreamWriter &writer, ViewLayer::ViewLayerID viewLayerID) {
152 writer.writeAttribute("layer",ViewLayer::viewLayerXmlNameFromID(viewLayerID));
153 }
154
writeSvgIdAttr(QXmlStreamWriter & writer,ViewLayer::ViewID view,QString connId)155 void Connector::writeSvgIdAttr(QXmlStreamWriter &writer, ViewLayer::ViewID view, QString connId) {
156 Q_UNUSED(view);
157 writer.writeAttribute("svgId",connId);
158 }
159
writeTerminalIdAttr(QXmlStreamWriter & writer,ViewLayer::ViewID view,QString terminalId)160 void Connector::writeTerminalIdAttr(QXmlStreamWriter &writer, ViewLayer::ViewID view, QString terminalId) {
161 if((view == ViewLayer::BreadboardView || view == ViewLayer::SchematicView)
162 &&
163 (!terminalId.isNull() && !terminalId.isEmpty()) ) {
164 writer.writeAttribute("terminalId",terminalId);
165 } else {
166 return;
167 }
168 }
169
toConnectors()170 const QList<Connector *> & Connector::toConnectors() {
171 return m_toConnectors;
172 }
173
connectorItemByViewLayerID(ViewLayer::ViewID viewID,ViewLayer::ViewLayerID viewLayerID)174 ConnectorItem * Connector::connectorItemByViewLayerID(ViewLayer::ViewID viewID, ViewLayer::ViewLayerID viewLayerID) {
175 return m_connectorItems.value(QuickHash(viewID, viewLayerID), NULL);
176 }
177
connectorItem(ViewLayer::ViewID viewID)178 ConnectorItem * Connector::connectorItem(ViewLayer::ViewID viewID) {
179 foreach (ConnectorItem * connectorItem, m_connectorItems.values()) {
180 if (connectorItem->attachedToViewID() == viewID) return connectorItem;
181 }
182
183 return NULL;
184 }
185
connectionIsAllowed(Connector * that)186 bool Connector::connectionIsAllowed(Connector* that)
187 {
188 Connector::ConnectorType thisConnectorType = connectorType();
189 Connector::ConnectorType thatConnectorType = that->connectorType();
190 if (thisConnectorType == Connector::Unknown) return false;
191 if (thatConnectorType == Connector::Unknown) return false; // unknowns are celebate
192
193 if (thisConnectorType == Connector::Wire) return true;
194 if (thatConnectorType == Connector::Wire) return true; // wires are bisexual
195
196 return (thisConnectorType != thatConnectorType); // otherwise heterosexual
197 }
198
connectorSharedID() const199 const QString & Connector::connectorSharedID() const {
200 if (m_connectorShared == NULL) return ___emptyString___;
201
202 return m_connectorShared->id();
203 }
204
connectorSharedName() const205 const QString & Connector::connectorSharedName() const {
206 if (m_connectorShared == NULL) return ___emptyString___;
207
208 if (!m_connectorLocalName.isEmpty()) {
209 return m_connectorLocalName;
210 }
211
212 return m_connectorShared->sharedName();
213 }
214
connectorSharedDescription() const215 const QString & Connector::connectorSharedDescription() const {
216 if (m_connectorShared == NULL) return ___emptyString___;
217
218 return m_connectorShared->description();
219 }
220
connectorSharedReplacedby() const221 const QString & Connector::connectorSharedReplacedby() const {
222 if (m_connectorShared == NULL) return ___emptyString___;
223
224 return m_connectorShared->replacedby();
225 }
226
connectorSharedErcData()227 ErcData * Connector::connectorSharedErcData() {
228 if (m_connectorShared == NULL) return NULL;
229
230 return m_connectorShared->ercData();
231 }
232
busID()233 const QString & Connector::busID() {
234 if (m_bus == NULL) return ___emptyString___;
235
236 return m_bus->id();
237 }
238
bus()239 Bus * Connector::bus() {
240 return m_bus;
241 }
242
setBus(Bus * bus)243 void Connector::setBus(Bus * bus) {
244 m_bus = bus;
245 }
246
unprocess(ViewLayer::ViewID viewID,ViewLayer::ViewLayerID viewLayerID)247 void Connector::unprocess(ViewLayer::ViewID viewID, ViewLayer::ViewLayerID viewLayerID) {
248 SvgIdLayer * svgIdLayer = m_connectorShared->fullPinInfo(viewID, viewLayerID);
249 if (svgIdLayer != NULL) {
250 svgIdLayer->unprocess();
251 }
252 }
253
fullPinInfo(ViewLayer::ViewID viewID,ViewLayer::ViewLayerID viewLayerID)254 SvgIdLayer * Connector::fullPinInfo(ViewLayer::ViewID viewID, ViewLayer::ViewLayerID viewLayerID) {
255 if (m_connectorShared == NULL) return NULL;
256
257 return m_connectorShared->fullPinInfo(viewID, viewLayerID);
258 }
259
modelIndex()260 long Connector::modelIndex() {
261 if (m_modelPart != NULL) return m_modelPart->modelIndex();
262
263 DebugDialog::debug(QString("saving bus connector item: how is this supposed to work?"));
264 return 0;
265 }
266
267
modelPart()268 ModelPart * Connector::modelPart() {
269 return m_modelPart;
270 }
271
connectorItemCount()272 int Connector::connectorItemCount() {
273 return m_connectorItems.count();
274 }
275
viewItems()276 QList< QPointer<ConnectorItem> > Connector::viewItems() {
277 return m_connectorItems.values();
278 }
279
legID(ViewLayer::ViewID viewID,ViewLayer::ViewLayerID viewLayerID)280 const QString & Connector::legID(ViewLayer::ViewID viewID, ViewLayer::ViewLayerID viewLayerID) {
281 if (m_connectorShared) return m_connectorShared->legID(viewID, viewLayerID);
282
283 return ___emptyString___;
284 }
285
setConnectorLocalName(const QString & name)286 void Connector::setConnectorLocalName(const QString & name) {
287 if (m_connectorShared != NULL && name.compare(m_connectorShared->sharedName()) == 0) {
288 m_connectorLocalName.clear();
289 return;
290 }
291
292 m_connectorLocalName = name;
293 }
294
connectorLocalName()295 const QString & Connector::connectorLocalName() {
296 return m_connectorLocalName;
297 }
298
svgIdLayers() const299 const QList<SvgIdLayer *> Connector::svgIdLayers() const {
300 if (m_connectorShared) return m_connectorShared->svgIdLayers();
301
302 return EmptySvgIdLayerList;
303 }
304
addPin(ViewLayer::ViewID viewID,const QString & svgId,ViewLayer::ViewLayerID viewLayerId,const QString & terminalId,const QString & legId,bool hybrid)305 void Connector::addPin(ViewLayer::ViewID viewID, const QString & svgId, ViewLayer::ViewLayerID viewLayerId, const QString & terminalId, const QString & legId, bool hybrid)
306 {
307 if (m_connectorShared) m_connectorShared->addPin(viewID, svgId, viewLayerId, terminalId, legId, hybrid);
308 }
309