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: 6112 $:
22 $Author: cohen@irascible.com $:
23 $Date: 2012-06-28 00:18:10 +0200 (Do, 28. Jun 2012) $
24
25 ********************************************************************/
26
27 #include "pinlabeldialog.h"
28 #include "../debugdialog.h"
29
30 #include <QDialogButtonBox>
31 #include <QHBoxLayout>
32 #include <QVBoxLayout>
33 #include <QGridLayout>
34 #include <QLabel>
35 #include <QScrollArea>
36 #include <QKeyEvent>
37
38 // TODO:
39 //
40 // would be nice to update schematic view with new pin labels
41 //
42 // reasons for not doing save:
43 // undo would require a lot of work to implement and would require saving the old dom document
44 // every instance of the part in all open documents would have to be updated
45
PinLabelUndoCommand(PinLabelDialog * pinLabelDialog,int index,QLineEdit * lineEdit,const QString & previous,const QString & next)46 PinLabelUndoCommand::PinLabelUndoCommand(PinLabelDialog * pinLabelDialog, int index, QLineEdit * lineEdit, const QString & previous, const QString & next) : QUndoCommand()
47 {
48 m_pinLabelDialog = pinLabelDialog;
49 m_previous = previous;
50 m_next = next;
51 m_index = index;
52 m_lineEdit = lineEdit;
53 }
54
undo()55 void PinLabelUndoCommand::undo() {
56 m_pinLabelDialog->setLabelText(m_index, m_lineEdit, m_previous);
57 }
58
redo()59 void PinLabelUndoCommand::redo() {
60 m_pinLabelDialog->setLabelText(m_index, m_lineEdit, m_next);
61 }
62
63 /////////////////////////////////////////////////////////
64
PinLabelDialog(const QStringList & labels,bool singleRow,const QString & chipLabel,bool isCore,QWidget * parent)65 PinLabelDialog::PinLabelDialog(const QStringList & labels, bool singleRow, const QString & chipLabel, bool isCore, QWidget *parent)
66 : QDialog(parent)
67 {
68 m_isCore = isCore;
69 m_labels = labels;
70 m_doSaveAs = true;
71 this->setWindowTitle(QObject::tr("Pin Label Editor"));
72
73 QVBoxLayout * vLayout = new QVBoxLayout(this);
74
75 QScrollArea * scrollArea = new QScrollArea(this);
76 scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
77
78 QFrame * frame = new QFrame(this);
79 QHBoxLayout * hLayout = new QHBoxLayout(frame);
80
81 QFrame * labelsFrame = initLabels(labels, singleRow, chipLabel);
82
83 QFrame * textFrame = new QFrame();
84 QVBoxLayout * textLayout = new QVBoxLayout(frame);
85
86 QLabel * label = new QLabel("<html><body>" +
87 tr("<p><h2>Pin Label Editor</h2></p>") +
88 tr("<p>Click on a label next to a pin number to rename that pin.") + " " +
89 tr("You can use the tab key to move through the labels in order.</p>") +
90 "</body></html>");
91 label->setMaximumWidth(150);
92 label->setWordWrap(true);
93
94 textLayout->addWidget(label);
95 textLayout->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Expanding));
96 textFrame->setLayout(textLayout);
97
98 hLayout->addWidget(labelsFrame);
99 hLayout->addSpacing(15);
100 hLayout->addWidget(textFrame);
101 frame->setLayout(hLayout);
102
103 scrollArea->setWidget(frame);
104
105 QDialogButtonBox * buttonBox = new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::Cancel);
106
107 QPushButton * cancelButton = buttonBox->button(QDialogButtonBox::Cancel);
108 cancelButton->setText(tr("Cancel"));
109 cancelButton->setDefault(false);
110
111 m_saveAsButton = buttonBox->button(QDialogButtonBox::Save);
112 m_saveAsButton->setText(tr("Save"));
113 m_saveAsButton->setEnabled(false);
114 m_saveAsButton->setDefault(false);
115
116 m_undoButton = new QPushButton(tr("Undo"));
117 m_undoButton->setEnabled(false);
118 m_undoButton->setDefault(false);
119
120 m_redoButton = new QPushButton(tr("Redo"));
121 m_redoButton->setEnabled(false);
122 m_redoButton->setDefault(false);
123
124 buttonBox->addButton(m_undoButton, QDialogButtonBox::ResetRole);
125 buttonBox->addButton(m_redoButton, QDialogButtonBox::ResetRole);
126
127 connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
128 connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
129
130 vLayout->addWidget(scrollArea);
131 vLayout->addWidget(buttonBox);
132 this->setLayout(vLayout);
133
134 connect(buttonBox, SIGNAL(clicked(QAbstractButton *)), this, SLOT(buttonClicked(QAbstractButton *)));
135 connect(&m_undoStack, SIGNAL(canRedoChanged(bool)), this, SLOT(undoChanged(bool)));
136 connect(&m_undoStack, SIGNAL(canUndoChanged(bool)), this, SLOT(undoChanged(bool)));
137 connect(&m_undoStack, SIGNAL(cleanChanged(bool)), this, SLOT(undoChanged(bool)));
138
139 }
140
~PinLabelDialog()141 PinLabelDialog::~PinLabelDialog()
142 {
143 }
144
initLabels(const QStringList & labels,bool singleRow,const QString & chipLabel)145 QFrame * PinLabelDialog::initLabels(const QStringList & labels, bool singleRow, const QString & chipLabel)
146 {
147 QFrame * frame = new QFrame();
148 QVBoxLayout * vLayout = new QVBoxLayout();
149
150 QLabel * label = new QLabel("<h2>" + chipLabel + "</h2>");
151 label->setAlignment(Qt::AlignCenter);
152
153 QFrame * subFrame = new QFrame();
154 if (singleRow) {
155 QGridLayout * gridLayout = new QGridLayout();
156 gridLayout->setMargin(0);
157 gridLayout->setSpacing(3);
158
159 for (int i = 0; i < labels.count(); i++) {
160 makeOnePinEntry(i, labels.at(i), Qt::AlignLeft, i, gridLayout);
161 }
162
163 subFrame->setLayout(gridLayout);
164 }
165 else {
166 QHBoxLayout * hLayout = new QHBoxLayout();
167
168 QFrame * lFrame = new QFrame();
169 QGridLayout * lLayout = new QGridLayout;
170 lLayout->setMargin(0);
171 lLayout->setSpacing(3);
172 for (int i = 0; i < labels.count() / 2; i++) {
173 makeOnePinEntry(i, labels.at(i), Qt::AlignLeft, i, lLayout);
174 }
175 lFrame->setLayout(lLayout);
176
177 QFrame * rFrame = new QFrame();
178 QGridLayout * rLayout = new QGridLayout;
179 rLayout->setMargin(0);
180 rLayout->setSpacing(3);
181 int row = labels.count() - 1;
182 for (int i = labels.count() / 2; i < labels.count(); i++) {
183 makeOnePinEntry(i, labels.at(i), Qt::AlignRight, row--, rLayout);
184 }
185 rFrame->setLayout(rLayout);
186
187 hLayout->addWidget(lFrame);
188 hLayout->addSpacing(15);
189 hLayout->addWidget(rFrame);
190
191 subFrame->setLayout(hLayout);
192 }
193
194 vLayout->addWidget(label);
195 vLayout->addWidget(subFrame);
196 frame->setLayout(vLayout);
197
198 return frame;
199 }
200
makeOnePinEntry(int index,const QString & text,Qt::Alignment alignment,int row,QGridLayout * gridLayout)201 void PinLabelDialog::makeOnePinEntry(int index, const QString & text, Qt::Alignment alignment, int row, QGridLayout * gridLayout)
202 {
203 QLineEdit * label = new QLineEdit();
204 label->setText(QString::number(index + 1));
205 label->setMaximumWidth(20);
206 label->setMinimumWidth(20);
207 label->setFrame(false);
208 label->setEnabled(false);
209
210 QLineEdit * lEdit = new QLineEdit();
211 lEdit->setMaximumWidth(65);
212 lEdit->setAlignment(alignment);
213 lEdit->setText(text);
214 lEdit->setProperty("index", index);
215 lEdit->setProperty("prev", text);
216 connect(lEdit, SIGNAL(editingFinished()), this, SLOT(labelChanged()));
217 connect(lEdit, SIGNAL(textEdited(const QString &)), this, SLOT(labelEdited(const QString &)));
218
219 if (alignment == Qt::AlignLeft) {
220 label->setAlignment(Qt::AlignRight);
221 gridLayout->addWidget(label, row, 0);
222 gridLayout->addWidget(lEdit, row, 1);
223 }
224 else {
225 label->setAlignment(Qt::AlignLeft);
226 gridLayout->addWidget(lEdit, row, 0);
227 gridLayout->addWidget(label, row, 1);
228 }
229 }
230
labelChanged()231 void PinLabelDialog::labelChanged() {
232 QLineEdit * lineEdit = qobject_cast<QLineEdit *>(sender());
233 if (lineEdit == NULL) return;
234
235 bool ok;
236 int index = lineEdit->property("index").toInt(&ok);
237 if (!ok) return;
238
239 if (index < 0) return;
240 if (index >= m_labels.count()) return;
241
242 PinLabelUndoCommand * pluc = new PinLabelUndoCommand(this, index, lineEdit, lineEdit->property("prev").toString(), lineEdit->text());
243 lineEdit->setProperty("prev", lineEdit->text());
244
245 m_undoStack.push(pluc);
246 }
247
labelEdited(const QString &)248 void PinLabelDialog::labelEdited(const QString &)
249 {
250 m_saveAsButton->setEnabled(true);
251 }
252
labels()253 const QStringList & PinLabelDialog::labels() {
254 return m_labels;
255 }
256
setLabelText(int index,QLineEdit * lineEdit,const QString & text)257 void PinLabelDialog::setLabelText(int index, QLineEdit * lineEdit, const QString & text)
258 {
259 m_labels.replace(index, text);
260 lineEdit->setText(text);
261 lineEdit->setProperty("prev", text);
262 }
263
buttonClicked(QAbstractButton * button)264 void PinLabelDialog::buttonClicked(QAbstractButton * button) {
265
266 if (button == m_undoButton) {
267 m_undoStack.undo();
268 }
269 else if (button == m_redoButton) {
270 m_undoStack.redo();
271 }
272 }
273
doSaveAs()274 bool PinLabelDialog::doSaveAs() {
275 return m_doSaveAs;
276 }
277
undoChanged(bool)278 void PinLabelDialog::undoChanged(bool)
279 {
280 bool redo = false;
281 bool undo = false;
282 bool saveAs = false;
283
284 if (m_undoStack.canUndo()) {
285 saveAs = undo = true;
286 }
287 if (m_undoStack.canRedo()) {
288 redo = true;
289 }
290
291 m_saveAsButton->setEnabled(saveAs);
292 m_undoButton->setEnabled(undo);
293 m_redoButton->setEnabled(redo);
294 }
295
keyPressEvent(QKeyEvent * e)296 void PinLabelDialog::keyPressEvent(QKeyEvent *e)
297 {
298 switch (e->key()) {
299 case Qt::Key_Escape:
300 case Qt::Key_Enter:
301 case Qt::Key_Return:
302 return;
303 default:
304 QDialog::keyPressEvent(e);
305 }
306 }
307