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: 6976 $:
22 $Author: irascibl@gmail.com $:
23 $Date: 2013-04-21 09:50:09 +0200 (So, 21. Apr 2013) $
24 
25 ********************************************************************/
26 
27 #include "viewlayer.h"
28 #include "debugdialog.h"
29 #include <qmath.h>
30 
31 double ViewLayer::zIncrement = 0.00001;  // 0.000000001;
32 
33 QHash<ViewLayer::ViewLayerID, NamePair * > ViewLayer::names;
34 QMultiHash<ViewLayer::ViewLayerID, ViewLayer::ViewLayerID> ViewLayer::alternatives;
35 QMultiHash<ViewLayer::ViewLayerID, ViewLayer::ViewLayerID> ViewLayer::unconnectables;
36 QHash<QString, ViewLayer::ViewLayerID> ViewLayer::xmlHash;
37 
38 const QString ViewLayer::Copper0Color = "#f9a435";  // "#FFCB33"; //Bottom
39 const QString ViewLayer::Copper1Color = "#fdde68";  // "#F28A00"; //Top
40 const QString ViewLayer::Copper0WireColor = "#f28a00";
41 const QString ViewLayer::Copper1WireColor = "#f2c600";
42 const QString ViewLayer::Silkscreen0Color = "#444444";
43 const QString ViewLayer::Silkscreen1Color = "#000000";
44 const QString ViewLayer::BoardColor = "#ffffff";
45 
46 static LayerList CopperBottomLayers;
47 static LayerList CopperTopLayers;
48 static LayerList NonCopperLayers;  // just NonCopperLayers in pcb view
49 
50 static LayerList IconViewLayerList;
51 static LayerList BreadboardViewLayerList;
52 static LayerList SchematicViewLayerList;
53 static LayerList PCBViewLayerList;
54 static LayerList EmptyLayerList;
55 static LayerList PCBViewFromBelowLayerList;
56 
NamePair(QString xml,QString display)57 NamePair::NamePair(QString xml, QString display)
58 {
59     xmlName = xml;
60     displayName = display;
61 }
62 
63 //////////////////////////////////////////////
64 
65 class NameTriple {
66 
67 public:
NameTriple(const QString & _xmlName,const QString & _viewName,const QString & _naturalName)68 	NameTriple(const QString & _xmlName, const QString & _viewName, const QString & _naturalName) {
69 		m_xmlName = _xmlName;
70 		m_viewName = _viewName;
71 		m_naturalName = _naturalName;
72 	}
73 
xmlName()74 	QString & xmlName() {
75 		return m_xmlName;
76 	}
77 
viewName()78 	QString & viewName() {
79 		return m_viewName;
80 	}
81 
naturalName()82 	QString & naturalName() {
83 		return m_naturalName;
84 	}
85 
86 protected:
87 	QString m_xmlName;
88 	QString m_naturalName;
89 	QString m_viewName;
90 };
91 
92 //////////////////////////////////////////////
93 
ViewLayer(ViewLayerID viewLayerID,bool visible,double initialZ)94 ViewLayer::ViewLayer(ViewLayerID viewLayerID, bool visible, double initialZ)
95 {
96     m_fromBelow = false;
97 	m_viewLayerID = viewLayerID;
98 	m_visible = visible;
99 	m_action = NULL;
100 	m_initialZFromBelow = m_initialZ = initialZ;
101     m_nextZ = 0;
102 	m_parentLayer = NULL;
103 	m_active = true;
104 	m_includeChildLayers = true;
105 }
106 
~ViewLayer()107 ViewLayer::~ViewLayer() {
108 }
109 
initNames()110 void ViewLayer::initNames() {
111 	if (CopperBottomLayers.isEmpty()) {
112 		CopperBottomLayers << ViewLayer::GroundPlane0 << ViewLayer::Copper0 << ViewLayer::Copper0Trace;
113 	}
114 	if (CopperTopLayers.isEmpty()) {
115 		CopperTopLayers << ViewLayer::GroundPlane1 << ViewLayer::Copper1 << ViewLayer::Copper1Trace;
116 	}
117 	if (NonCopperLayers.isEmpty()) {
118 		NonCopperLayers << ViewLayer::Silkscreen0 << ViewLayer::Silkscreen0Label
119 						<< ViewLayer::Silkscreen1 << ViewLayer::Silkscreen1Label
120 						<< ViewLayer::PartImage;
121 	}
122 
123 	if (names.count() == 0) {
124 		// xmlname, displayname
125 		names.insert(ViewLayer::Icon, new NamePair("icon", QObject::tr("Icon")));
126 		names.insert(ViewLayer::BreadboardBreadboard, new NamePair("breadboardbreadboard", QObject::tr("Breadboard")));
127 		names.insert(ViewLayer::Breadboard, new NamePair("breadboard", QObject::tr("Parts")));
128 		names.insert(ViewLayer::BreadboardWire,  new NamePair("breadboardWire", QObject::tr("Wires")));
129 		names.insert(ViewLayer::BreadboardLabel,  new NamePair("breadboardLabel", QObject::tr("Part Labels")));
130 		names.insert(ViewLayer::BreadboardRatsnest, new NamePair("breadboardRatsnest", QObject::tr("Ratsnest")));
131 		names.insert(ViewLayer::BreadboardNote,  new NamePair("breadboardNote", QObject::tr("Notes")));
132 		names.insert(ViewLayer::BreadboardRuler,  new NamePair("breadboardRuler", QObject::tr("Rulers")));
133 
134 		names.insert(ViewLayer::SchematicFrame,  new NamePair("schematicframe", QObject::tr("Frame")));
135 		names.insert(ViewLayer::Schematic,  new NamePair("schematic", QObject::tr("Parts")));
136 		names.insert(ViewLayer::SchematicText,  new NamePair("schematicText", QObject::tr("Text")));
137 		names.insert(ViewLayer::SchematicWire,  new NamePair("schematicWire",QObject::tr("Ratsnest")));
138 		names.insert(ViewLayer::SchematicTrace,  new NamePair("schematicTrace",QObject::tr("Wires")));
139 		names.insert(ViewLayer::SchematicLabel,  new NamePair("schematicLabel", QObject::tr("Part Labels")));
140 		names.insert(ViewLayer::SchematicNote,  new NamePair("schematicNote", QObject::tr("Notes")));
141 		names.insert(ViewLayer::SchematicRuler,  new NamePair("schematicRuler", QObject::tr("Rulers")));
142 
143 		names.insert(ViewLayer::Board,  new NamePair("board", QObject::tr("Board")));
144 		names.insert(ViewLayer::Silkscreen1,  new NamePair("silkscreen", QObject::tr("Silkscreen Top")));			// really should be silkscreen1
145 		names.insert(ViewLayer::Silkscreen1Label,  new NamePair("silkscreenLabel", QObject::tr("Silkscreen Top (Part Labels)")));
146 		names.insert(ViewLayer::GroundPlane0,  new NamePair("groundplane", QObject::tr("Copper Fill Bottom")));
147 		names.insert(ViewLayer::Copper0,  new NamePair("copper0", QObject::tr("Copper Bottom")));
148 		names.insert(ViewLayer::Copper0Trace,  new NamePair("copper0trace", QObject::tr("Copper Bottom Trace")));
149 		names.insert(ViewLayer::GroundPlane1,  new NamePair("groundplane1", QObject::tr("Copper Fill Top")));
150 		names.insert(ViewLayer::Copper1,  new NamePair("copper1", QObject::tr("Copper Top")));
151 		names.insert(ViewLayer::Copper1Trace,  new NamePair("copper1trace", QObject::tr("Copper Top Trace")));
152 		names.insert(ViewLayer::PcbRatsnest, new NamePair("ratsnest", QObject::tr("Ratsnest")));
153 		names.insert(ViewLayer::Silkscreen0,  new NamePair("silkscreen0", QObject::tr("Silkscreen Bottom")));
154 		names.insert(ViewLayer::Silkscreen0Label,  new NamePair("silkscreen0Label", QObject::tr("Silkscreen Bottom (Part Labels)")));
155 		//names.insert(ViewLayer::Soldermask,  new NamePair("soldermask",  QObject::tr("Solder mask")));
156 		//names.insert(ViewLayer::Outline,  new NamePair("outline",  QObject::tr("Outline")));
157 		//names.insert(ViewLayer::Keepout, new NamePair("keepout", QObject::tr("Keep out")));
158 		names.insert(ViewLayer::PartImage, new NamePair("partimage", QObject::tr("Part Image")));
159 		names.insert(ViewLayer::PcbNote,  new NamePair("pcbNote", QObject::tr("Notes")));
160 		names.insert(ViewLayer::PcbRuler,  new NamePair("pcbRuler", QObject::tr("Rulers")));
161 
162 		foreach (ViewLayerID key, names.keys()) {
163 			xmlHash.insert(names.value(key)->xmlName, key);
164 		}
165 
166 		names.insert(ViewLayer::UnknownLayer,  new NamePair("unknown", QObject::tr("Unknown Layer")));
167 
168 		alternatives.insert(ViewLayer::Copper0, ViewLayer::Copper1);
169 		alternatives.insert(ViewLayer::Copper1, ViewLayer::Copper0);
170 
171         LayerList l0, l1;
172         l0 << ViewLayer::Copper0 << ViewLayer::Copper0Trace << ViewLayer::GroundPlane0;
173         l1 << ViewLayer::Copper1 << ViewLayer::Copper1Trace << ViewLayer::GroundPlane1;
174         foreach (ViewLayer::ViewLayerID viewLayerID0, l0) {
175             foreach (ViewLayer::ViewLayerID viewLayerID1, l1) {
176                 unconnectables.insert(viewLayerID0, viewLayerID1);
177                 unconnectables.insert(viewLayerID1, viewLayerID0);
178             }
179         }
180 	}
181 
182 	if (ViewIDNames.count() == 0) {
183 		ViewIDNames.insert(ViewLayer::IconView, new NameTriple("iconView", QObject::tr("icon view"), "icon"));
184 		ViewIDNames.insert(ViewLayer::BreadboardView, new NameTriple("breadboardView", QObject::tr("breadboard view"), "breadboard"));
185 		ViewIDNames.insert(ViewLayer::SchematicView, new NameTriple("schematicView", QObject::tr("schematic view"), "schematic"));
186 		ViewIDNames.insert(ViewLayer::PCBView, new NameTriple("pcbView", QObject::tr("pcb view"), "pcb"));
187 	}
188 
189 	if (BreadboardViewLayerList.count() == 0) {
190 		IconViewLayerList << ViewLayer::Icon;
191 		BreadboardViewLayerList << ViewLayer::BreadboardBreadboard << ViewLayer::Breadboard
192 			<< ViewLayer::BreadboardWire << ViewLayer::BreadboardLabel
193 			<< ViewLayer::BreadboardRatsnest
194 			<< ViewLayer::BreadboardNote << ViewLayer::BreadboardRuler;
195 		SchematicViewLayerList << ViewLayer::SchematicFrame << ViewLayer::Schematic
196 			<< ViewLayer::SchematicText << ViewLayer::SchematicWire
197 			<< ViewLayer::SchematicTrace << ViewLayer::SchematicLabel
198 			<< ViewLayer::SchematicNote <<  ViewLayer::SchematicRuler;
199 		PCBViewLayerList << ViewLayer::Board
200             << ViewLayer::GroundPlane0
201 			<< ViewLayer::Silkscreen0 << ViewLayer::Silkscreen0Label
202 			<< ViewLayer::Copper0  << ViewLayer::Copper0Trace
203             << ViewLayer::GroundPlane1
204 			<< ViewLayer::Copper1 << ViewLayer::Copper1Trace
205 			<< ViewLayer::PcbRatsnest
206 			<< ViewLayer::Silkscreen1 << ViewLayer::Silkscreen1Label
207 			<< ViewLayer::PartImage
208 			<< ViewLayer::PcbNote << ViewLayer::PcbRuler;
209 		PCBViewFromBelowLayerList << ViewLayer::Board
210             << ViewLayer::GroundPlane1
211 			<< ViewLayer::Silkscreen1 << ViewLayer::Silkscreen1Label
212 			<< ViewLayer::Copper1 << ViewLayer::Copper1Trace
213             << ViewLayer::GroundPlane0
214 			<< ViewLayer::Copper0 << ViewLayer::Copper0Trace
215 			<< ViewLayer::PcbRatsnest
216 			<< ViewLayer::Silkscreen0 << ViewLayer::Silkscreen0Label
217 			<< ViewLayer::PartImage
218 			<< ViewLayer::PcbNote << ViewLayer::PcbRuler;
219 	}
220 }
221 
displayName()222 QString & ViewLayer::displayName() {
223 	return names[m_viewLayerID]->displayName;
224 }
225 
setAction(QAction * action)226 void ViewLayer::setAction(QAction * action) {
227 	m_action = action;
228 }
229 
action()230 QAction* ViewLayer::action() {
231 	return m_action;
232 }
233 
visible()234 bool ViewLayer::visible() {
235 	return m_visible;
236 }
237 
setVisible(bool visible)238 void ViewLayer::setVisible(bool visible) {
239 	m_visible = visible;
240 	if (m_action) {
241 		m_action->setChecked(visible);
242 	}
243 }
244 
nextZ()245 double ViewLayer::nextZ() {
246 	double temp = m_nextZ + (m_fromBelow ? m_initialZFromBelow : m_initialZ);
247 	m_nextZ += zIncrement;
248 	return temp;
249 }
250 
viewLayerIDFromXmlString(const QString & viewLayerName)251 ViewLayer::ViewLayerID ViewLayer::viewLayerIDFromXmlString(const QString & viewLayerName) {
252 	return xmlHash.value(viewLayerName, ViewLayer::UnknownLayer);
253 }
254 
viewLayerID()255 ViewLayer::ViewLayerID ViewLayer::viewLayerID() {
256 	return m_viewLayerID;
257 }
258 
incrementZ(double z)259 double ViewLayer::incrementZ(double z) {
260 	return (z + zIncrement);
261 }
262 
getZIncrement()263 double ViewLayer::getZIncrement() {
264 	return zIncrement;
265 }
266 
viewLayerNameFromID(ViewLayerID viewLayerID)267 const QString & ViewLayer::viewLayerNameFromID(ViewLayerID viewLayerID) {
268 	NamePair * sp = names.value(viewLayerID);
269 	if (sp == NULL) return ___emptyString___;
270 
271 	return sp->displayName;
272 }
273 
viewLayerXmlNameFromID(ViewLayerID viewLayerID)274 const QString & ViewLayer::viewLayerXmlNameFromID(ViewLayerID viewLayerID) {
275 	NamePair * sp = names.value(viewLayerID);
276 	if (sp == NULL) return ___emptyString___;
277 
278 	return sp->xmlName;
279 }
280 
parentLayer()281 ViewLayer * ViewLayer::parentLayer() {
282 	return m_parentLayer;
283 }
284 
setParentLayer(ViewLayer * parent)285 void ViewLayer::setParentLayer(ViewLayer * parent) {
286 	m_parentLayer = parent;
287 	if (parent) {
288 		parent->m_childLayers.append(this);
289 	}
290 }
291 
childLayers()292 const QList<ViewLayer *> & ViewLayer::childLayers() {
293 	return m_childLayers;
294 }
295 
alreadyInLayer(double z)296 bool ViewLayer::alreadyInLayer(double z) {
297     if (m_fromBelow) {
298 	    return (z >= m_initialZFromBelow && z <= m_initialZFromBelow + m_nextZ);
299     }
300 
301 	return (z >= m_initialZ && z <= m_initialZ + m_nextZ);
302 }
303 
cleanup()304 void ViewLayer::cleanup() {
305 	foreach (NamePair * sp, names.values()) {
306 		delete sp;
307 	}
308 	names.clear();
309 
310 	foreach (NameTriple * nameTriple, ViewIDNames) {
311 		delete nameTriple;
312 	}
313 	ViewIDNames.clear();
314 }
315 
resetNextZ(double z)316 void ViewLayer::resetNextZ(double z) {
317 	m_nextZ = z - floor(z);
318 }
319 
findAlternativeLayers(ViewLayer::ViewLayerID id)320 LayerList ViewLayer::findAlternativeLayers(ViewLayer::ViewLayerID id)
321 {
322 	LayerList alts = alternatives.values(id);
323 	return alts;
324 }
325 
canConnect(ViewLayer::ViewLayerID v1,ViewLayer::ViewLayerID v2)326 bool ViewLayer::canConnect(ViewLayer::ViewLayerID v1, ViewLayer::ViewLayerID v2) {
327 	if (v1 == v2) return true;
328 
329  	LayerList uncs = unconnectables.values(v1);
330 	return (!uncs.contains(v2));
331 }
332 
isActive()333 bool ViewLayer::isActive() {
334 	return m_active;
335 }
336 
setActive(bool a)337 void ViewLayer::setActive(bool a) {
338 	m_active = a;
339 }
340 
specFromID(ViewLayer::ViewLayerID viewLayerID)341 ViewLayer::ViewLayerPlacement ViewLayer::specFromID(ViewLayer::ViewLayerID viewLayerID)
342 {
343 	switch (viewLayerID) {
344 		case Copper1:
345 		case Copper1Trace:
346 		case GroundPlane1:
347 			return ViewLayer::NewTop;
348 		default:
349 			return ViewLayer::NewBottom;
350 	}
351 }
352 
isCopperLayer(ViewLayer::ViewLayerID viewLayerID)353 bool ViewLayer::isCopperLayer(ViewLayer::ViewLayerID viewLayerID) {
354 	if (CopperTopLayers.contains(viewLayerID)) return true;
355 	if (CopperBottomLayers.contains(viewLayerID)) return true;
356 
357 	return false;
358 }
359 
360 
copperLayers(ViewLayer::ViewLayerPlacement viewLayerPlacement)361 const LayerList & ViewLayer::copperLayers(ViewLayer::ViewLayerPlacement viewLayerPlacement)
362 {
363 	if (viewLayerPlacement == ViewLayer::NewTop) return CopperTopLayers;
364 
365 	return CopperBottomLayers;
366 }
367 
maskLayers(ViewLayer::ViewLayerPlacement viewLayerPlacement)368 const LayerList & ViewLayer::maskLayers(ViewLayer::ViewLayerPlacement viewLayerPlacement) {
369 	static LayerList bottom;
370 	static LayerList top;
371 	if (bottom.isEmpty()) {
372 		bottom << ViewLayer::Copper0;
373 	}
374 	if (top.isEmpty()) {
375 		top << ViewLayer::Copper1;
376 	}
377 	if (viewLayerPlacement == ViewLayer::NewTop) return top;
378 
379 	return bottom;
380 }
381 
silkLayers(ViewLayer::ViewLayerPlacement viewLayerPlacement)382 const LayerList & ViewLayer::silkLayers(ViewLayer::ViewLayerPlacement viewLayerPlacement) {
383 	static LayerList bottom;
384 	static LayerList top;
385 	if (bottom.isEmpty()) {
386 		bottom << ViewLayer::Silkscreen0 << ViewLayer::Silkscreen0Label;
387 	}
388 	if (top.isEmpty()) {
389 		top << ViewLayer::Silkscreen1 << ViewLayer::Silkscreen1Label;
390 	}
391 	if (viewLayerPlacement == ViewLayer::NewTop) return top;
392 
393 	return bottom;
394 }
395 
outlineLayers()396 const LayerList & ViewLayer::outlineLayers() {
397 	static LayerList layerList;
398 	if (layerList.isEmpty()) {
399 		layerList << ViewLayer::Board;
400 	}
401 
402 	return layerList;
403 }
404 
drillLayers()405 const LayerList & ViewLayer::drillLayers() {
406 	static LayerList layerList;
407 	if (layerList.isEmpty()) {
408 		layerList << ViewLayer::Copper0 << ViewLayer::Copper1;
409 	}
410 
411 	return layerList;
412 }
413 
silkLayers()414 const LayerList & ViewLayer::silkLayers() {
415 	static LayerList layerList;
416 	if (layerList.isEmpty()) {
417 		layerList << ViewLayer::Silkscreen0 << ViewLayer::Silkscreen1;
418 	}
419 
420 	return layerList;
421 }
422 
topLayers()423 const LayerList & ViewLayer::topLayers() {
424 	static LayerList layerList;
425 	if (layerList.isEmpty()) {
426 		layerList << ViewLayer::Copper1 << ViewLayer::Copper1Trace << ViewLayer::Silkscreen1 << ViewLayer::Silkscreen1Label << ViewLayer::GroundPlane1;
427 	}
428 
429 	return layerList;
430 }
431 
bottomLayers()432 const LayerList & ViewLayer::bottomLayers() {
433 	static LayerList layerList;
434 	if (layerList.isEmpty()) {
435 		layerList << ViewLayer::Copper0 << ViewLayer::Copper0Trace << ViewLayer::Silkscreen0 << ViewLayer::Silkscreen0Label << ViewLayer::GroundPlane0;
436 	}
437 
438 	return layerList;
439 }
440 
441 
442 
443 
444 
isNonCopperLayer(ViewLayer::ViewLayerID viewLayerID)445 bool ViewLayer::isNonCopperLayer(ViewLayer::ViewLayerID viewLayerID) {
446 	// for pcb view layers only
447 	return NonCopperLayers.contains(viewLayerID);
448 }
449 
450 
includeChildLayers()451 bool ViewLayer::includeChildLayers() {
452 	return m_includeChildLayers;
453 }
454 
setIncludeChildLayers(bool incl)455 void ViewLayer::setIncludeChildLayers(bool incl) {
456 	m_includeChildLayers = incl;
457 }
458 
459 /////////////////////////////////
460 
461 QHash <ViewLayer::ViewID, NameTriple * > ViewLayer::ViewIDNames;
462 
viewIDName(ViewLayer::ViewID viewID)463 QString & ViewLayer::viewIDName(ViewLayer::ViewID viewID) {
464 	if (viewID < 0 || viewID >= ViewLayer::ViewCount) {
465 		throw "ViewLayer::viewIDName bad identifier";
466 	}
467 
468 	return ViewIDNames[viewID]->viewName();
469 }
470 
viewIDXmlName(ViewLayer::ViewID viewID)471 QString & ViewLayer::viewIDXmlName(ViewLayer::ViewID viewID) {
472 	if (viewID < 0 || viewID >= ViewLayer::ViewCount) {
473 		throw "ViewLayer::viewIDXmlName bad identifier";
474 	}
475 
476 	return ViewIDNames[viewID]->xmlName();
477 }
478 
viewIDNaturalName(ViewLayer::ViewID viewID)479 QString & ViewLayer::viewIDNaturalName(ViewLayer::ViewID viewID) {
480 	if (viewID < 0 || viewID >= ViewLayer::ViewCount) {
481 		throw "ViewLayer::viewIDNaturalName bad identifier";
482 	}
483 
484 	return ViewIDNames[viewID]->naturalName();
485 }
486 
idFromXmlName(const QString & name)487 ViewLayer::ViewID ViewLayer::idFromXmlName(const QString & name) {
488 	foreach (ViewID id, ViewIDNames.keys()) {
489 		NameTriple * nameTriple = ViewIDNames.value(id);
490 		if (name.compare(nameTriple->xmlName()) == 0) return id;
491 	}
492 
493 	return UnknownView;
494 }
495 
layersForView(ViewLayer::ViewID viewID)496 const LayerList & ViewLayer::layersForView(ViewLayer::ViewID viewID) {
497 	switch(viewID) {
498 		case IconView:
499 			return IconViewLayerList;
500 		case BreadboardView:
501 			return BreadboardViewLayerList;
502 		case SchematicView:
503 			return SchematicViewLayerList;
504 		case PCBView:
505 			return PCBViewLayerList;
506 		default:
507 			return EmptyLayerList;
508 	}
509 }
510 
layersForViewFromBelow(ViewLayer::ViewID viewID)511 const LayerList & ViewLayer::layersForViewFromBelow(ViewLayer::ViewID viewID) {
512 	switch(viewID) {
513 		case IconView:
514 			return IconViewLayerList;
515 		case BreadboardView:
516 			return BreadboardViewLayerList;
517 		case SchematicView:
518 			return SchematicViewLayerList;
519 		case PCBView:
520 			return PCBViewFromBelowLayerList;
521 		default:
522 			return EmptyLayerList;
523 	}
524 }
525 
viewHasLayer(ViewLayer::ViewID viewID,ViewLayer::ViewLayerID viewLayerID)526 bool ViewLayer::viewHasLayer(ViewLayer::ViewID viewID, ViewLayer::ViewLayerID viewLayerID) {
527 	return layersForView(viewID).contains(viewLayerID);
528 }
529 
530 
getConnectorPElement(const QDomElement & element,ViewLayer::ViewID viewID)531 QDomElement ViewLayer::getConnectorPElement(const QDomElement & element, ViewLayer::ViewID viewID)
532 {
533     QString viewName = ViewLayer::viewIDXmlName(viewID);
534     QDomElement views = element.firstChildElement("views");
535     QDomElement view = views.firstChildElement(viewName);
536     return view.firstChildElement("p");
537 }
538 
getConnectorSvgIDs(QDomElement & element,ViewLayer::ViewID viewID,QString & id,QString & terminalID)539 bool ViewLayer::getConnectorSvgIDs(QDomElement & element, ViewLayer::ViewID viewID, QString & id, QString & terminalID) {
540     QDomElement p = getConnectorPElement(element, viewID);
541     if (p.isNull()) {
542 		return false;
543 	}
544 
545     id = p.attribute("svgId");
546     if (id.isEmpty()) {
547 		return false;
548 	}
549 
550     terminalID = p.attribute("terminalId");
551     return true;
552 }
553 
fromBelow()554 bool ViewLayer::fromBelow() {
555     return m_fromBelow;
556 }
557 
setFromBelow(bool fromBelow)558 void ViewLayer::setFromBelow(bool fromBelow) {
559     m_fromBelow = fromBelow;
560 }
561 
setInitialZFromBelow(double initialZ)562 void ViewLayer::setInitialZFromBelow(double initialZ) {
563     m_initialZFromBelow = initialZ;
564 }
565 
getZFromBelow(double currentZ,bool fromBelow)566 double ViewLayer::getZFromBelow(double currentZ, bool fromBelow) {
567     double frac = currentZ - m_initialZ;
568     if (qAbs(frac) > 1) {
569         frac = currentZ - m_initialZFromBelow;
570     }
571     return frac + (fromBelow ? m_initialZFromBelow : m_initialZ);
572 }
573 
574