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