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: 6904 $:
22 $Author: irascibl@gmail.com $:
23 $Date: 2013-02-26 16:26:03 +0100 (Di, 26. Feb 2013) $
24 
25 ********************************************************************/
26 
27 
28 
29 #include <QtAlgorithms>
30 
31 #include "hashpopulatewidget.h"
32 #include "../debugdialog.h"
33 #include "../utils/misc.h"
34 
HashLineEdit(const QString & text,bool defaultValue,QWidget * parent)35 HashLineEdit::HashLineEdit(const QString &text, bool defaultValue, QWidget *parent) : QLineEdit(text, parent)
36 {
37     connect(this, SIGNAL(editingFinished()), parent, SLOT(lineEditChanged()));
38 	m_firstText = text;
39 	m_isDefaultValue = defaultValue;
40 	if(defaultValue) {
41 		setStyleSheet("font-style: italic;");
42 		connect(this,SIGNAL(textChanged(QString)),this,SLOT(updateObjectName()));
43 	} else {
44 		setStyleSheet("font-style: normal;");
45 	}
46 }
47 
textIfSetted()48 QString HashLineEdit::textIfSetted() {
49 	if(m_isDefaultValue && !hasChanged()) {
50 		return "";
51 	} else {
52 		return text();
53 	}
54 }
55 
updateObjectName()56 void HashLineEdit::updateObjectName() {
57 	if(m_isDefaultValue) {
58 		if(!isModified() && !hasChanged()) {
59 			setStyleSheet("font-style: italic;");
60 		} else {
61 			setStyleSheet("font-style: normal;");
62 		}
63 	}
64 }
65 
mousePressEvent(QMouseEvent * event)66 void HashLineEdit::mousePressEvent(QMouseEvent * event) {
67 	if(m_isDefaultValue && !isModified() && !hasChanged()) {
68 		setText("");
69 	}
70 	QLineEdit::mousePressEvent(event);
71 }
72 
hasChanged()73 bool HashLineEdit::hasChanged() {
74 	return m_firstText != text();
75 }
76 
focusOutEvent(QFocusEvent * event)77 void HashLineEdit::focusOutEvent(QFocusEvent * event) {
78 	if(text().isEmpty()) {
79 		setText(m_firstText);
80 	}
81 	QLineEdit::focusOutEvent(event);
82 }
83 
HashPopulateWidget(const QString & title,const QHash<QString,QString> & initValues,const QStringList & readOnlyKeys,bool keysOnly,QWidget * parent)84 HashPopulateWidget::HashPopulateWidget(const QString & title, const QHash<QString,QString> &initValues, const QStringList &readOnlyKeys, bool keysOnly, QWidget *parent) : QFrame(parent) {
85     m_keysOnly = keysOnly;
86 	m_lastLabel = NULL;
87 	m_lastValue = NULL;
88 
89     QGridLayout *layout = new QGridLayout();
90 	layout->setColumnStretch(0,0);
91 	layout->setColumnStretch(1,1);
92 	layout->setColumnStretch(2,0);
93 
94     if (!title.isEmpty()) {
95 	    layout->addWidget(new QLabel(title),0,0,0);
96     }
97 
98 	QList<QString> keys = initValues.keys();
99 	qSort(keys);
100 
101 	for(int i=0; i < keys.count(); i++) {
102 		HashLineEdit *name = new HashLineEdit(keys[i],false,this);
103         HashLineEdit *value = new HashLineEdit(initValues[keys[i]],false,this);
104         if (m_keysOnly) value->hide();
105 
106         int ix = layout->rowCount();
107 
108 		if(readOnlyKeys.contains(keys[i])) {
109 			name->setEnabled(false);
110 		} else {
111 			HashRemoveButton *button = createRemoveButton(name, value);
112 			layout->addWidget(button,ix,3);
113 		}
114 
115 		layout->addWidget(name,ix,0);
116 		layout->addWidget(value,ix,1,1,2);
117 	}
118 
119 	addRow(layout);
120 
121 
122 	this->setLayout(layout);
123 }
124 
createRemoveButton(HashLineEdit * label,HashLineEdit * value)125 HashRemoveButton *HashPopulateWidget::createRemoveButton(HashLineEdit* label, HashLineEdit* value) {
126 	HashRemoveButton *button = new HashRemoveButton(label, value, this);
127 	connect(button, SIGNAL(clicked(HashRemoveButton*)), this, SLOT(removeRow(HashRemoveButton*)));
128 	return button;
129 }
130 
hash()131 const QHash<QString,QString> &HashPopulateWidget::hash() {
132 	static QHash<QString,QString> theHash;
133 
134 	theHash.clear();
135 	for(int i=1 /*i==0 is title*/; i < gridLayout()->rowCount() /*last one is always an empty one*/; i++) {
136 		QString label;
137 		HashLineEdit *labelEdit = lineEditAt(i,0);
138 		if(labelEdit) {
139 			label = labelEdit->textIfSetted();
140 		}
141 
142 		QString value;
143 		HashLineEdit *valueEdit = lineEditAt(i,1);
144 		if(valueEdit) {
145 			value = valueEdit->textIfSetted();
146 		}
147 
148 		if(!label.isEmpty() /*&& !value.isEmpty()*/) {
149 			theHash.insert(label, value);
150 		}
151 	}
152 	return theHash;
153 }
154 
lineEditAt(int row,int col)155 HashLineEdit* HashPopulateWidget::lineEditAt(int row, int col) {
156 	QLayoutItem *litem = gridLayout()->itemAtPosition(row,col);
157 	return litem ? qobject_cast<HashLineEdit*>(litem->widget()) : NULL;
158 }
159 
addRow(QGridLayout * layout)160 void HashPopulateWidget::addRow(QGridLayout *layout) {
161 	if(layout == NULL) {
162 		layout = gridLayout();
163 	}
164 
165 	if(m_lastLabel) {
166 		disconnect(m_lastLabel,SIGNAL(editingFinished()),this,SLOT(lastRowEditionCompleted()));
167 	}
168 
169 	if(m_lastValue) {
170 		disconnect(m_lastValue,SIGNAL(editingFinished()),this,SLOT(lastRowEditionCompleted()));
171 	}
172 
173     int ix = layout->rowCount();
174 
175 	m_lastLabel = new HashLineEdit(QObject::tr("a label"),true,this);
176 	layout->addWidget(m_lastLabel,ix,0);
177 	connect(m_lastLabel,SIGNAL(editingFinished()),this,SLOT(lastRowEditionCompleted()));
178 
179 	m_lastValue = new HashLineEdit(QObject::tr("a value"),true,this);
180 	layout->addWidget(m_lastValue,ix,1,1,2);
181 	connect(m_lastValue,SIGNAL(editingFinished()),this,SLOT(lastRowEditionCompleted()));
182     if (m_keysOnly) m_lastValue->hide();
183 
184 	emit editionStarted();
185 }
186 
gridLayout()187 QGridLayout * HashPopulateWidget::gridLayout() {
188 	return qobject_cast<QGridLayout *>(this->layout());
189 }
190 
lastRowEditionCompleted()191 void HashPopulateWidget::lastRowEditionCompleted() {
192 	if(	m_lastLabel && !m_lastLabel->text().isEmpty() && m_lastLabel->hasChanged()) {
193 		if(m_lastLabel->text().isEmpty() && m_lastValue->text().isEmpty()) {
194 			// removeRow() ?;
195 		} else {
196 			HashRemoveButton *button = createRemoveButton(m_lastLabel, m_lastValue);
197             for (int i = 0; i < gridLayout()->rowCount(); i++) {
198                 HashLineEdit * label = lineEditAt(i, 0);
199                 if (m_lastLabel == label) {
200                     gridLayout()->addWidget(button,i,3);
201                     break;
202                 }
203             }
204 			addRow();
205 		}
206 	}
207 }
208 
removeRow(HashRemoveButton * button)209 void HashPopulateWidget::removeRow(HashRemoveButton* button) {
210 	QLayout *lo = layout();
211 	QList<QWidget*> widgs;
212 	widgs << button->label() << button->value() << button;
213 	foreach(QWidget* w, widgs) {
214 		lo->removeWidget(w);
215 		//w->hide();
216         //delete w;
217 	}
218 	lo->update();
219     emit changed();
220 }
221 
lineEditChanged()222 void HashPopulateWidget::lineEditChanged() {
223     emit changed();
224 }
225