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: 6984 $:
22 $Author: irascibl@gmail.com $:
23 $Date: 2013-04-22 23:44:56 +0200 (Mo, 22. Apr 2013) $
24
25 ********************************************************************/
26
27 #include "tracewire.h"
28 #include "../sketch/infographicsview.h"
29 #include "../connectors/connectoritem.h"
30 #include "../utils/focusoutcombobox.h"
31
32
33 #include <QComboBox>
34
35 const int TraceWire::MinTraceWidthMils = 8;
36 const int TraceWire::MaxTraceWidthMils = 128;
37
38 /////////////////////////////////////////////////////////
39
TraceWire(ModelPart * modelPart,ViewLayer::ViewID viewID,const ViewGeometry & viewGeometry,long id,QMenu * itemMenu)40 TraceWire::TraceWire( ModelPart * modelPart, ViewLayer::ViewID viewID, const ViewGeometry & viewGeometry, long id, QMenu * itemMenu )
41 : ClipableWire(modelPart, viewID, viewGeometry, id, itemMenu, true)
42 {
43 m_canChainMultiple = true;
44 m_wireDirection = TraceWire::NoDirection;
45 }
46
47
~TraceWire()48 TraceWire::~TraceWire()
49 {
50 }
51
createWidthComboBox(double m,QWidget * parent)52 QComboBox * TraceWire::createWidthComboBox(double m, QWidget * parent)
53 {
54 QComboBox * comboBox = new FocusOutComboBox(parent); // new QComboBox(parent);
55 comboBox->setEditable(true);
56 QIntValidator * intValidator = new QIntValidator(comboBox);
57 intValidator->setRange(MinTraceWidthMils, MaxTraceWidthMils);
58 comboBox->setValidator(intValidator);
59 comboBox->setToolTip(tr("Select from the dropdown, or type in any value from %1 to %2").arg(MinTraceWidthMils).arg(MaxTraceWidthMils));
60
61 int ix = 0;
62 if (!Wire::widths.contains(m)) {
63 Wire::widths.append(m);
64 qSort(Wire::widths.begin(), Wire::widths.end());
65 }
66 foreach(long widthValue, Wire::widths) {
67 QString widthName = Wire::widthTrans.value(widthValue, "");
68 QVariant val((int) widthValue);
69 comboBox->addItem(widthName.isEmpty() ? QString::number(widthValue) : widthName, val);
70 if (qAbs(m - widthValue) < .01) {
71 comboBox->setCurrentIndex(ix);
72 }
73 ix++;
74 }
75
76 return comboBox;
77
78 }
79
80
collectExtraInfo(QWidget * parent,const QString & family,const QString & prop,const QString & value,bool swappingEnabled,QString & returnProp,QString & returnValue,QWidget * & returnWidget,bool & hide)81 bool TraceWire::collectExtraInfo(QWidget * parent, const QString & family, const QString & prop, const QString & value, bool swappingEnabled, QString & returnProp, QString & returnValue, QWidget * & returnWidget, bool & hide)
82 {
83 if (prop.compare("width", Qt::CaseInsensitive) == 0) {
84 if (viewID() != ViewLayer::PCBView) {
85 // only in pcb view for now
86 hide = true;
87 return false;
88 }
89
90 returnProp = tr("width");
91 QComboBox * comboBox = createWidthComboBox(mils(), parent);
92 comboBox->setEnabled(swappingEnabled);
93 comboBox->setObjectName("infoViewComboBox");
94
95 connect(comboBox, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(widthEntry(const QString &)));
96 returnWidget = comboBox;
97 returnValue = comboBox->currentText();
98
99 return true;
100 }
101
102 bool result = ClipableWire::collectExtraInfo(parent, family, prop, value, swappingEnabled, returnProp, returnValue, returnWidget, hide);
103 if (prop.compare("layer") == 0 && returnWidget != NULL) {
104 bool disabled = !canSwitchLayers();
105 if (!disabled) {
106 InfoGraphicsView * infoGraphicsView = InfoGraphicsView::getInfoGraphicsView(this);
107 if (infoGraphicsView == NULL || infoGraphicsView->boardLayers() == 1) disabled = true;
108 }
109 returnWidget->setDisabled(disabled);
110 }
111
112 return result;
113
114
115 return result;
116 }
117
118
widthEntry(const QString & text)119 void TraceWire::widthEntry(const QString & text) {
120
121 int w = widthEntry(text, sender());
122 if (w == 0) return;
123
124 InfoGraphicsView * infoGraphicsView = InfoGraphicsView::getInfoGraphicsView(this);
125 if (infoGraphicsView != NULL) {
126 infoGraphicsView->changeWireWidthMils(QString::number(w));
127 }
128 }
129
widthEntry(const QString & text,QObject * sender)130 int TraceWire::widthEntry(const QString & text, QObject * sender) {
131
132 QComboBox * comboBox = qobject_cast<QComboBox *>(sender);
133 if (comboBox == NULL) return 0;
134
135 int w = comboBox->itemData(comboBox->currentIndex()).toInt();
136 if (w == 0) {
137 // user typed in a number
138 w = text.toInt();
139 }
140 if (!Wire::widths.contains(w)) {
141 Wire::widths.append(w);
142 qSort(Wire::widths.begin(), Wire::widths.end());
143 }
144
145 return w;
146 }
147
setColorFromElement(QDomElement & element)148 void TraceWire::setColorFromElement(QDomElement & element) {
149 switch (m_viewLayerID) {
150 case ViewLayer::Copper0Trace:
151 element.setAttribute("color", ViewLayer::Copper0WireColor);
152 break;
153 case ViewLayer::Copper1Trace:
154 element.setAttribute("color", ViewLayer::Copper1WireColor);
155 break;
156 case ViewLayer::SchematicTrace:
157 //element.setAttribute("color", "#000000");
158 default:
159 break;
160 }
161
162 Wire::setColorFromElement(element);
163 }
164
canSwitchLayers()165 bool TraceWire::canSwitchLayers() {
166 QList<Wire *> wires;
167 QList<ConnectorItem *> ends;
168 collectChained(wires, ends);
169
170 foreach (ConnectorItem * end, ends) {
171 if (end->getCrossLayerConnectorItem() == NULL) return false;
172 }
173
174 return true;
175 }
176
setWireDirection(TraceWire::WireDirection wireDirection)177 void TraceWire::setWireDirection(TraceWire::WireDirection wireDirection) {
178 m_wireDirection = wireDirection;
179 }
180
wireDirection()181 TraceWire::WireDirection TraceWire::wireDirection() {
182 return m_wireDirection;
183 }
184
getTrace(ConnectorItem * connectorItem)185 TraceWire * TraceWire::getTrace(ConnectorItem * connectorItem)
186 {
187 return qobject_cast<TraceWire *>(connectorItem->attachedTo());
188 }
189
setSchematic(bool schematic)190 void TraceWire::setSchematic(bool schematic) {
191 m_viewGeometry.setSchematicTrace(schematic);
192 }
193
prepareProps(ModelPart * modelPart,bool wantDebug,QStringList & keys)194 QHash<QString, QString> TraceWire::prepareProps(ModelPart * modelPart, bool wantDebug, QStringList & keys)
195 {
196 QHash<QString, QString> props = ClipableWire::prepareProps(modelPart, wantDebug, keys);
197
198 if (m_viewID != ViewLayer::PCBView) return props;
199 if (!m_viewGeometry.getPCBTrace()) return props;
200
201 keys.append("layer");
202 props.insert("layer", ViewLayer::topLayers().contains(m_viewLayerID) ? "top" : "bottom");
203 return props;
204 }
205
collectValues(const QString & family,const QString & prop,QString & value)206 QStringList TraceWire::collectValues(const QString & family, const QString & prop, QString & value) {
207 if (prop.compare("layer") == 0) {
208 QStringList values = ClipableWire::collectValues(family, prop, value);
209 if (values.count() == 0) {
210 values << TranslatedPropertyNames.value("bottom") << TranslatedPropertyNames.value("top");
211 if (ViewLayer::bottomLayers().contains(m_viewLayerID)) {
212 value = values.at(0);
213 }
214 else {
215 value = values.at(1);
216 }
217 }
218 return values;
219 }
220
221 return ClipableWire::collectValues(family, prop, value);
222 }
223