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 "schematicsketchwidget.h"
28 #include "../debugdialog.h"
29 #include "../items/virtualwire.h"
30 #include "../items/symbolpaletteitem.h"
31 #include "../items/tracewire.h"
32 #include "../items/partlabel.h"
33 #include "../connectors/connectoritem.h"
34 #include "../waitpushundostack.h"
35 #include "../items/moduleidnames.h"
36 #include "../fsvgrenderer.h"
37 #include "../utils/graphicsutils.h"
38 #include "../version/version.h"
39 
40 #include <limits>
41 
42 QSizeF SchematicSketchWidget::m_jumperItemSize = QSizeF(0, 0);
43 
44 static QString SchematicTraceColor = "black";
45 static const double TraceHoverStrokeFactor = 3;
46 static const double TraceWidthMils = 9.7222;
47 static const double TraceWidthMilsOld = 33.3333;
48 
sameGround(ConnectorItem * c1,ConnectorItem * c2)49 bool sameGround(ConnectorItem * c1, ConnectorItem * c2)
50 {
51 	bool c1Grounded = c1->isGrounded();
52 	bool c2Grounded = c2->isGrounded();
53 
54 	return (c1Grounded == c2Grounded);
55 }
56 
57 ///////////////////////////////////////////////////
58 
SchematicSketchWidget(ViewLayer::ViewID viewID,QWidget * parent)59 SchematicSketchWidget::SchematicSketchWidget(ViewLayer::ViewID viewID, QWidget *parent)
60     : PCBSketchWidget(viewID, parent)
61 {
62     m_oldSchematic = m_convertSchematic = false;
63 	m_shortName = QObject::tr("schem");
64 	m_viewName = QObject::tr("Schematic View");
65 	initBackgroundColor();
66 
67 	m_cleanType = ninetyClean;
68 
69 	m_updateDotsTimer.setInterval(20);
70 	m_updateDotsTimer.setSingleShot(true);
71 	connect(&m_updateDotsTimer, SIGNAL(timeout()), this, SLOT(updateBigDots()));
72 }
73 
addViewLayers()74 void SchematicSketchWidget::addViewLayers() {
75 	setViewLayerIDs(ViewLayer::Schematic, ViewLayer::SchematicTrace, ViewLayer::Schematic, ViewLayer::SchematicRuler, ViewLayer::SchematicNote);
76 	addViewLayersAux(ViewLayer::layersForView(ViewLayer::SchematicView), ViewLayer::layersForViewFromBelow(ViewLayer::SchematicView));
77 }
78 
getDragWireViewLayerID(ConnectorItem *)79 ViewLayer::ViewLayerID SchematicSketchWidget::getDragWireViewLayerID(ConnectorItem *) {
80 	return ViewLayer::SchematicTrace;
81 }
82 
getWireViewLayerID(const ViewGeometry & viewGeometry,ViewLayer::ViewLayerPlacement viewLayerPlacement)83 ViewLayer::ViewLayerID SchematicSketchWidget::getWireViewLayerID(const ViewGeometry & viewGeometry, ViewLayer::ViewLayerPlacement viewLayerPlacement) {
84 	if (viewGeometry.getAnyTrace()) {
85 		return ViewLayer::SchematicTrace;
86 	}
87 
88 	if (viewGeometry.getRatsnest()) {
89 		return ViewLayer::SchematicWire;
90 	}
91 
92 	return SketchWidget::getWireViewLayerID(viewGeometry, viewLayerPlacement);
93 }
94 
initWire(Wire * wire,int penWidth)95 void SchematicSketchWidget::initWire(Wire * wire, int penWidth) {
96 	Q_UNUSED(penWidth);
97 	if (wire->getRatsnest()) {
98 		return;
99 	}
100 
101 	wire->setPenWidth(getTraceWidth(), this, getTraceWidth() * TraceHoverStrokeFactor);
102 	wire->setColorString("black", 1.0, false);
103 }
104 
autorouteTypePCB()105 bool SchematicSketchWidget::autorouteTypePCB() {
106 	return false;
107 }
108 
tidyWires()109 void SchematicSketchWidget::tidyWires() {
110 	QList<Wire *> wires;
111 	QList<Wire *> visited;
112 	foreach (QGraphicsItem * item, scene()->selectedItems()) {
113 		Wire * wire = dynamic_cast<Wire *>(item);
114 		if (wire == NULL) continue;
115 		if ((wire->getViewGeometry().wireFlags() & ViewGeometry::SchematicTraceFlag) == 0) continue;
116 		if (visited.contains(wire)) continue;
117 	}
118 }
119 
ensureTraceLayersVisible()120 void SchematicSketchWidget::ensureTraceLayersVisible() {
121 	ensureLayerVisible(ViewLayer::SchematicTrace);
122 }
123 
ensureTraceLayerVisible()124 void SchematicSketchWidget::ensureTraceLayerVisible() {
125 	ensureLayerVisible(ViewLayer::SchematicTrace);
126 }
127 
setClipEnds(ClipableWire * vw,bool)128 void SchematicSketchWidget::setClipEnds(ClipableWire * vw, bool) {
129 	vw->setClipEnds(false);
130 }
131 
getBendpointWidths(Wire * wire,double width,double & bendpointWidth,double & bendpoint2Width,bool & negativeOffsetRect)132 void SchematicSketchWidget::getBendpointWidths(Wire * wire, double width, double & bendpointWidth, double & bendpoint2Width, bool & negativeOffsetRect)
133 {
134 	Q_UNUSED(wire);
135 	bendpointWidth = -width - 1;
136 	bendpoint2Width = width + ((m_oldSchematic) ? 3 : 1);
137 	negativeOffsetRect = true;
138 }
139 
getLabelFont(QFont & font,QColor & color,ItemBase *)140 void SchematicSketchWidget::getLabelFont(QFont & font, QColor & color, ItemBase *) {
141 	font.setFamily("Droid Sans");
142 	font.setPointSize(getLabelFontSizeSmall());
143 	font.setBold(false);
144 	font.setItalic(false);
145 	color.setAlpha(255);
146 	color.setRgb(0);
147 }
148 
setNewPartVisible(ItemBase * itemBase)149 void SchematicSketchWidget::setNewPartVisible(ItemBase * itemBase) {
150 	switch (itemBase->itemType()) {
151 		case ModelPart::Logo:
152             if (itemBase->moduleID().contains("schematic", Qt::CaseInsensitive)) break;
153 		case ModelPart::Breadboard:
154 		case ModelPart::Jumper:
155 		case ModelPart::CopperFill:
156 		case ModelPart::Via:
157 		case ModelPart::Hole:
158 			// don't need to see the breadboard in the other views
159 			// but it's there so connections can be more easily synched between views
160 			itemBase->setVisible(false);
161 			itemBase->setEverVisible(false);
162 			return;
163 		default:
164 		    if (itemBase->moduleID().endsWith(ModuleIDNames::PadModuleIDName)) {
165 				itemBase->setVisible(false);
166 				itemBase->setEverVisible(false);
167 				return;
168 			}
169 
170 			break;
171 	}
172 }
173 
canDropModelPart(ModelPart * modelPart)174 bool SchematicSketchWidget::canDropModelPart(ModelPart * modelPart) {
175 	if (!SketchWidget::canDropModelPart(modelPart)) return false;
176 
177 	switch (modelPart->itemType()) {
178 		case ModelPart::Logo:
179             if (modelPart->moduleID().contains("schematic", Qt::CaseInsensitive)) return true;
180 		case ModelPart::Jumper:
181 		case ModelPart::CopperFill:
182 		case ModelPart::Board:
183 		case ModelPart::ResizableBoard:
184 		case ModelPart::Breadboard:
185 		case ModelPart::Via:
186 		case ModelPart::Hole:
187 			return false;
188 		case ModelPart::Symbol:
189 		case ModelPart::SchematicSubpart:
190 			return true;
191 		default:
192 			break;
193 	}
194 
195 	if (modelPart->moduleID().endsWith(ModuleIDNames::SchematicFrameModuleIDName)) return true;
196 	if (modelPart->moduleID().endsWith(ModuleIDNames::PadModuleIDName)) return false;
197 	if (modelPart->moduleID().endsWith(ModuleIDNames::CopperBlockerModuleIDName)) return false;
198 
199 	return PCBSketchWidget::canDropModelPart(modelPart);
200 }
201 
includeSymbols()202 bool SchematicSketchWidget::includeSymbols() {
203 	return true;
204 }
205 
hasBigDots()206 bool SchematicSketchWidget::hasBigDots() {
207 	return true;
208 }
209 
updateBigDots()210 void SchematicSketchWidget::updateBigDots()
211 {
212 	QList<ConnectorItem *> connectorItems;
213 	foreach (QGraphicsItem * item, scene()->items()) {
214 		ConnectorItem * connectorItem = dynamic_cast<ConnectorItem *>(item);
215 		if (connectorItem == NULL) continue;
216 		if (connectorItem->attachedToItemType() != ModelPart::Wire) continue;
217 
218 		TraceWire * traceWire = qobject_cast<TraceWire *>(connectorItem->attachedTo());
219 		if (traceWire == NULL) continue;
220 
221 		//DebugDialog::debug(QString("update big dot %1 %2").arg(traceWire->id()).arg(connectorItem->connectorSharedID()));
222 
223 		connectorItems.append(connectorItem);
224 	}
225 
226     QList<ConnectorItem *> visited;
227 	foreach (ConnectorItem * connectorItem, connectorItems) {
228 	    connectorItem->restoreColor(visited);
229 	}
230 }
231 
changeConnection(long fromID,const QString & fromConnectorID,long toID,const QString & toConnectorID,ViewLayer::ViewLayerPlacement viewLayerPlacement,bool connect,bool doEmit,bool updateConnections)232 void SchematicSketchWidget::changeConnection(long fromID, const QString & fromConnectorID,
233 									long toID, const QString & toConnectorID,
234 									ViewLayer::ViewLayerPlacement viewLayerPlacement,
235 									bool connect, bool doEmit, bool updateConnections)
236 {
237 	m_updateDotsTimer.stop();
238 	SketchWidget::changeConnection(fromID, fromConnectorID, toID, toConnectorID, viewLayerPlacement, connect,  doEmit,  updateConnections);
239 	m_updateDotsTimer.start();
240 }
241 
setInstanceTitle(long itemID,const QString & oldText,const QString & newText,bool isUndoable,bool doEmit)242 void SchematicSketchWidget::setInstanceTitle(long itemID, const QString & oldText, const QString & newText, bool isUndoable, bool doEmit) {
243 	// isUndoable is true when setInstanceTitle is called from the infoview
244 
245     if (isUndoable) {
246 	    SymbolPaletteItem * sitem = qobject_cast<SymbolPaletteItem *>(findItem(itemID));
247 	    if (sitem && sitem->isOnlyNetLabel()) {
248             setProp(sitem, "label", ItemBase::TranslatedPropertyNames.value("label"), oldText, newText, true);
249             return;
250         }
251     }
252 
253     SketchWidget::setInstanceTitle(itemID, oldText, newText, isUndoable, doEmit);
254 }
255 
setProp(ItemBase * itemBase,const QString & prop,const QString & trProp,const QString & oldValue,const QString & newValue,bool redraw)256 void SchematicSketchWidget::setProp(ItemBase * itemBase, const QString & prop, const QString & trProp, const QString & oldValue, const QString & newValue, bool redraw)
257 {
258     if (prop =="label") {
259         SymbolPaletteItem * sitem = qobject_cast<SymbolPaletteItem *>(itemBase);
260         if (sitem != NULL && sitem->isOnlyNetLabel()) {
261             if (sitem->getLabel() == newValue) {
262                 return;
263             }
264 
265             QUndoCommand * parentCommand =  new QUndoCommand();
266 	        parentCommand->setText(tr("Change label from %1 to %2").arg(oldValue).arg(newValue));
267 
268 	        new CleanUpWiresCommand(this, CleanUpWiresCommand::UndoOnly, parentCommand);
269 	        new CleanUpRatsnestsCommand(this, CleanUpWiresCommand::UndoOnly, parentCommand);
270 
271 	        QList<Wire *> done;
272 	        foreach (ConnectorItem * toConnectorItem, sitem->connector0()->connectedToItems()) {
273 		        Wire * w = qobject_cast<Wire *>(toConnectorItem->attachedTo());
274 		        if (w == NULL) continue;
275 		        if (done.contains(w)) continue;
276 
277 		        QList<ConnectorItem *> ends;
278 		        removeWire(w, ends, done, parentCommand);
279 	        }
280 
281 	        new SetPropCommand(this, itemBase->id(), "label", oldValue, newValue, true, parentCommand);
282             new ChangeLabelTextCommand(this, itemBase->id(), oldValue, newValue, parentCommand);
283 
284 	        new CleanUpRatsnestsCommand(this, CleanUpWiresCommand::RedoOnly, parentCommand);
285 	        new CleanUpWiresCommand(this, CleanUpWiresCommand::RedoOnly, parentCommand);
286 
287 	        m_undoStack->waitPush(parentCommand, PropChangeDelay);
288             return;
289         }
290     }
291 
292     SketchWidget::setProp(itemBase, prop, trProp, oldValue, newValue, redraw);
293 }
294 
setVoltage(double v,bool doEmit)295 void SchematicSketchWidget::setVoltage(double v, bool doEmit)
296 {
297 	Q_UNUSED(doEmit);
298 
299 	PaletteItem * item = getSelectedPart();
300 	if (item == NULL) return;
301 
302 	if (item->itemType() != ModelPart::Symbol) return;
303 
304 	SymbolPaletteItem * sitem = qobject_cast<SymbolPaletteItem *>(item);
305 	if (sitem == NULL) return;
306 
307 	if (sitem->moduleID().compare("ground symbol", Qt::CaseInsensitive) == 0) return;
308 	if (v == sitem->voltage()) return;
309 
310 	QUndoCommand * parentCommand =  new QUndoCommand();
311 	parentCommand->setText(tr("Change voltage from %1 to %2").arg(sitem->voltage()).arg(v));
312 
313 	new CleanUpWiresCommand(this, CleanUpWiresCommand::UndoOnly, parentCommand);
314 	new CleanUpRatsnestsCommand(this, CleanUpWiresCommand::UndoOnly, parentCommand);
315 
316 	QList<Wire *> done;
317 	foreach (ConnectorItem * toConnectorItem, sitem->connector0()->connectedToItems()) {
318 		Wire * w = qobject_cast<Wire *>(toConnectorItem->attachedTo());
319 		if (w == NULL) continue;
320 		if (done.contains(w)) continue;
321 
322 		QList<ConnectorItem *> ends;
323 		removeWire(w, ends, done, parentCommand);
324 	}
325 
326 	new SetPropCommand(this, item->id(), "voltage", QString::number(sitem->voltage()), QString::number(v), true, parentCommand);
327 
328 	new CleanUpRatsnestsCommand(this, CleanUpWiresCommand::RedoOnly, parentCommand);
329 	new CleanUpWiresCommand(this, CleanUpWiresCommand::RedoOnly, parentCommand);
330 
331 	m_undoStack->waitPush(parentCommand, PropChangeDelay);
332 }
333 
defaultGridSizeInches()334 double SchematicSketchWidget::defaultGridSizeInches() {
335 	return GraphicsUtils::StandardSchematicSeparation10thinMils / 1000;
336 }
337 
getLabelViewLayerID(ItemBase *)338 ViewLayer::ViewLayerID SchematicSketchWidget::getLabelViewLayerID(ItemBase *) {
339 	return ViewLayer::SchematicLabel;
340 }
341 
traceColor(ConnectorItem *)342 const QString & SchematicSketchWidget::traceColor(ConnectorItem *) {
343 	if (m_lastColorSelected.isEmpty()) return SchematicTraceColor;
344 
345 	else return m_lastColorSelected;
346 }
347 
traceColor(ViewLayer::ViewLayerPlacement)348 const QString & SchematicSketchWidget::traceColor(ViewLayer::ViewLayerPlacement) {
349 	return SchematicTraceColor;
350 }
351 
isInLayers(ConnectorItem * connectorItem,ViewLayer::ViewLayerPlacement viewLayerPlacement)352 bool SchematicSketchWidget::isInLayers(ConnectorItem * connectorItem, ViewLayer::ViewLayerPlacement viewLayerPlacement) {
353 	Q_UNUSED(connectorItem);
354 	Q_UNUSED(viewLayerPlacement);
355 	return true;
356 }
357 
routeBothSides()358 bool SchematicSketchWidget::routeBothSides() {
359 	return false;
360 }
361 
addDefaultParts()362 void SchematicSketchWidget::addDefaultParts() {
363 	SketchWidget::addDefaultParts();
364 }
365 
sameElectricalLayer2(ViewLayer::ViewLayerID,ViewLayer::ViewLayerID)366 bool SchematicSketchWidget::sameElectricalLayer2(ViewLayer::ViewLayerID, ViewLayer::ViewLayerID) {
367 	// schematic is always one layer
368 	return true;
369 }
370 
getKeepout()371 double SchematicSketchWidget::getKeepout() {
372 	return 0.1 * GraphicsUtils::SVGDPI;  // in pixels
373 }
374 
acceptsTrace(const ViewGeometry & viewGeometry)375 bool SchematicSketchWidget::acceptsTrace(const ViewGeometry & viewGeometry) {
376 	return viewGeometry.getSchematicTrace();
377 }
378 
getTraceFlag()379 ViewGeometry::WireFlag SchematicSketchWidget::getTraceFlag() {
380 	return ViewGeometry::SchematicTraceFlag;
381 }
382 
getTraceWidth()383 double SchematicSketchWidget::getTraceWidth() {
384 	return GraphicsUtils::SVGDPI * ((m_oldSchematic ) ? TraceWidthMilsOld : TraceWidthMils) / 1000;
385 }
386 
getAutorouterTraceWidth()387 double SchematicSketchWidget::getAutorouterTraceWidth() {
388 	return getTraceWidth();
389 }
390 
extraRenderSvgStep(ItemBase * itemBase,QPointF offset,double dpi,double printerScale,QString & outputSvg)391 void SchematicSketchWidget::extraRenderSvgStep(ItemBase * itemBase, QPointF offset, double dpi, double printerScale, QString & outputSvg)
392 {
393 	TraceWire * traceWire = qobject_cast<TraceWire *>(itemBase);
394 	if (traceWire == NULL) return;
395 
396 	if (traceWire->connector0()->isBigDot()) {
397 		double r = traceWire->connector0()->rect().width();
398 		outputSvg += makeCircleSVG(traceWire->connector0()->sceneAdjustedTerminalPoint(NULL), r, offset, dpi, printerScale);
399 	}
400 	if (traceWire->connector1()->isBigDot()) {
401 		double r = traceWire->connector0()->rect().width();
402 		outputSvg += makeCircleSVG(traceWire->connector1()->sceneAdjustedTerminalPoint(NULL), r, offset, dpi, printerScale);
403 	}
404 
405 }
406 
makeCircleSVG(QPointF p,double r,QPointF offset,double dpi,double printerScale)407 QString SchematicSketchWidget::makeCircleSVG(QPointF p, double r, QPointF offset, double dpi, double printerScale)
408 {
409 	double cx = (p.x() - offset.x()) * dpi / printerScale;
410 	double cy = (p.y() - offset.y()) * dpi / printerScale;
411 	double rr = r * dpi / printerScale;
412 
413 	QString stroke = "black";
414 	return QString("<circle  fill=\"black\" cx=\"%1\" cy=\"%2\" r=\"%3\" stroke-width=\"0\" stroke=\"none\" />")
415 			.arg(cx)
416 			.arg(cy)
417 			.arg(rr);
418 }
419 
generateCopperFillUnit(ItemBase * itemBase,QPointF whereToStart)420 QString SchematicSketchWidget::generateCopperFillUnit(ItemBase * itemBase, QPointF whereToStart)
421 {
422 	Q_UNUSED(itemBase);
423 	Q_UNUSED(whereToStart);
424 	return "";
425 }
426 
createWireViewLayerPlacement(ConnectorItem * from,ConnectorItem * to)427 ViewLayer::ViewLayerPlacement SchematicSketchWidget::createWireViewLayerPlacement(ConnectorItem * from, ConnectorItem * to) {
428 	return SketchWidget::createWireViewLayerPlacement(from, to);
429 }
430 
getWireStrokeWidth(Wire *,double wireWidth)431 double SchematicSketchWidget::getWireStrokeWidth(Wire *, double wireWidth)
432 {
433 	return wireWidth * TraceHoverStrokeFactor;
434 }
435 
createTempWireForDragging(Wire * fromWire,ModelPart * wireModel,ConnectorItem * connectorItem,ViewGeometry & viewGeometry,ViewLayer::ViewLayerPlacement spec)436 Wire * SchematicSketchWidget::createTempWireForDragging(Wire * fromWire, ModelPart * wireModel, ConnectorItem * connectorItem, ViewGeometry & viewGeometry, ViewLayer::ViewLayerPlacement spec)
437 {
438 	viewGeometry.setSchematicTrace(true);
439 	Wire * wire =  SketchWidget::createTempWireForDragging(fromWire, wireModel, connectorItem, viewGeometry, spec);
440 	if (fromWire) {
441 		wire->setColorString(fromWire->colorString(), fromWire->opacity(), false);
442 	}
443 	else {
444 		wire->setProperty(PCBSketchWidget::FakeTraceProperty, true);
445 	    wire->setColorString(traceColor(connectorItem), 1.0, false);
446 	}
447 	return wire;
448 }
449 
rotatePartLabels(double degrees,QTransform & transform,QPointF center,QUndoCommand * parentCommand)450 void SchematicSketchWidget::rotatePartLabels(double degrees, QTransform & transform, QPointF center, QUndoCommand * parentCommand)
451 {
452 	PCBSketchWidget::rotatePartLabels(degrees, transform, center, parentCommand);
453 }
454 
loadFromModelParts(QList<ModelPart * > & modelParts,BaseCommand::CrossViewType crossViewType,QUndoCommand * parentCommand,bool offsetPaste,const QRectF * boundingRect,bool seekOutsideConnections,QList<long> & newIDs)455 void SchematicSketchWidget::loadFromModelParts(QList<ModelPart *> & modelParts, BaseCommand::CrossViewType crossViewType, QUndoCommand * parentCommand,
456 						bool offsetPaste, const QRectF * boundingRect, bool seekOutsideConnections, QList<long> & newIDs)
457 {
458 	SketchWidget::loadFromModelParts(modelParts, crossViewType, parentCommand, offsetPaste, boundingRect, seekOutsideConnections, newIDs);
459 }
460 
selectAllWires(ViewGeometry::WireFlag flag)461 void SchematicSketchWidget::selectAllWires(ViewGeometry::WireFlag flag)
462 {
463    SketchWidget::selectAllWires(flag);
464 }
465 
canConnect(Wire *,ItemBase *)466 bool SchematicSketchWidget::canConnect(Wire *, ItemBase *) {
467     return true;
468 }
469 
checkDroppedModuleID(const QString & moduleID)470 QString SchematicSketchWidget::checkDroppedModuleID(const QString & moduleID) {
471     return moduleID;
472 }
473 
routingLayers(ViewLayer::ViewLayerPlacement)474 LayerList SchematicSketchWidget::routingLayers(ViewLayer::ViewLayerPlacement) {
475     LayerList layerList;
476     layerList << ViewLayer::Schematic;
477     return layerList;
478 }
479 
attachedToBottomLayer(ConnectorItem * connectorItem)480 bool SchematicSketchWidget::attachedToBottomLayer(ConnectorItem * connectorItem) {
481     return (connectorItem->attachedToViewLayerID() == ViewLayer::Schematic) ||
482            (connectorItem->attachedToViewLayerID() == ViewLayer::SchematicTrace);
483 }
484 
attachedToTopLayer(ConnectorItem *)485 bool SchematicSketchWidget::attachedToTopLayer(ConnectorItem *) {
486     return false;
487 }
488 
jumperItemSize()489 QSizeF SchematicSketchWidget::jumperItemSize() {
490     if (SchematicSketchWidget::m_jumperItemSize.width() == 0) {
491 	    long newID = ItemBase::getNextID();
492 	    ViewGeometry viewGeometry;
493 	    viewGeometry.setLoc(QPointF(0, 0));
494 	    ItemBase * itemBase = addItem(referenceModel()->retrieveModelPart(ModuleIDNames::NetLabelModuleIDName), defaultViewLayerPlacement(NULL), BaseCommand::SingleView, viewGeometry, newID, -1, NULL);
495 	    if (itemBase) {
496 		    SymbolPaletteItem * netLabel = qobject_cast<SymbolPaletteItem *>(itemBase);
497             netLabel->setLabel("00");
498             SchematicSketchWidget::m_jumperItemSize = netLabel->boundingRect().size();
499             deleteItem(itemBase, true, false, false);
500         }
501     }
502 
503 	return SchematicSketchWidget::m_jumperItemSize;
504 }
505 
getAutorouterSettings()506 QHash<QString, QString> SchematicSketchWidget::getAutorouterSettings() {
507     return SketchWidget::getAutorouterSettings();
508 }
509 
setAutorouterSettings(QHash<QString,QString> & autorouterSettings)510 void SchematicSketchWidget::setAutorouterSettings(QHash<QString, QString> & autorouterSettings) {
511     SketchWidget::setAutorouterSettings(autorouterSettings);
512 }
513 
getDroppedItemViewLayerPlacement(ModelPart * modelPart,ViewLayer::ViewLayerPlacement & viewLayerPlacement)514 void SchematicSketchWidget::getDroppedItemViewLayerPlacement(ModelPart * modelPart, ViewLayer::ViewLayerPlacement & viewLayerPlacement) {
515     SketchWidget::getDroppedItemViewLayerPlacement(modelPart, viewLayerPlacement);
516 }
517 
getViewLayerPlacement(ModelPart * modelPart,QDomElement & instance,QDomElement & view,ViewGeometry & viewGeometry)518 ViewLayer::ViewLayerPlacement SchematicSketchWidget::getViewLayerPlacement(ModelPart * modelPart, QDomElement & instance, QDomElement & view, ViewGeometry & viewGeometry)
519 {
520     return SketchWidget::getViewLayerPlacement(modelPart, instance, view, viewGeometry);
521 }
522 
523 
viewGeometryConversionHack(ViewGeometry & viewGeometry,ModelPart * modelPart)524 void SchematicSketchWidget::viewGeometryConversionHack(ViewGeometry & viewGeometry, ModelPart * modelPart) {
525     if (!m_convertSchematic) return;
526     if (modelPart->itemType() == ModelPart::Wire) return;
527     if (viewGeometry.transform().isIdentity()) return;
528 
529 	ViewGeometry vg;
530     ItemBase * itemBase = addItemAuxTemp(modelPart, ViewLayer::NewTop, vg, 0, true, viewID(), true);
531     double rotation;
532     if (GraphicsUtils::isFlipped(viewGeometry.transform().toAffine(), rotation)) {
533         itemBase->flipItem(Qt::Horizontal);
534     }
535     itemBase->rotateItem(rotation, false);
536     itemBase->saveGeometry();
537     viewGeometry.setTransform(itemBase->getViewGeometry().transform());
538 
539     foreach (ItemBase * kin, itemBase->layerKin()) delete kin;
540     delete itemBase;
541 }
542 
setOldSchematic(bool old)543 void SchematicSketchWidget::setOldSchematic(bool old) {
544     m_oldSchematic = old;
545 }
546 
isOldSchematic()547 bool SchematicSketchWidget::isOldSchematic() {
548     return m_oldSchematic;
549 }
550 
setConvertSchematic(bool convert)551 void SchematicSketchWidget::setConvertSchematic(bool convert) {
552     m_convertSchematic = convert;
553 }
554 
resizeWires()555 void SchematicSketchWidget::resizeWires() {
556     double tw = getTraceWidth();
557     double sw = getWireStrokeWidth(NULL, tw);
558     foreach (QGraphicsItem * item, scene()->items()) {
559         Wire * wire = dynamic_cast<Wire *>(item);
560         if (wire == NULL) continue;
561         if (!wire->isTraceType(getTraceFlag())) continue;
562 
563         wire->setWireWidth(tw, this, sw);
564     }
565 }
566 
resizeLabels()567 void SchematicSketchWidget::resizeLabels() {
568 
569     double fontSize = getLabelFontSizeSmall();
570     foreach (QGraphicsItem * item, scene()->items()) {
571         ItemBase * itemBase = dynamic_cast<ItemBase *>(item);
572         if (itemBase == NULL) continue;
573 
574         if (itemBase->hasPartLabel() && itemBase->partLabel() != NULL) {
575             itemBase->partLabel()->setFontPointSize(fontSize);
576         }
577     }
578 }
579