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