1 /*
2 Copyright 2006-2019 The QElectroTech Team
3 This file is part of QElectroTech.
4
5 QElectroTech is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 2 of the License, or
8 (at your option) any later version.
9
10 QElectroTech is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
17 */
18 #include "elementinfowidget.h"
19 #include "ui_elementinfowidget.h"
20 #include "qetapp.h"
21 #include "changeelementinformationcommand.h"
22 #include "diagram.h"
23 #include "elementinfopartwidget.h"
24 #include "element.h"
25
26 /**
27 * @brief ElementInfoWidget::ElementInfoWidget
28 * Constructor
29 * @param elmt element to edit information
30 * @param parent parent widget
31 */
ElementInfoWidget(Element * elmt,QWidget * parent)32 ElementInfoWidget::ElementInfoWidget(Element *elmt, QWidget *parent) :
33 AbstractElementPropertiesEditorWidget(parent),
34 ui(new Ui::ElementInfoWidget),
35 m_first_activation (false)
36 {
37 ui->setupUi(this);
38 buildInterface();
39 setElement(elmt);
40 }
41
42 /**
43 * @brief ElementInfoWidget::~ElementInfoWidget
44 * Destructor
45 */
~ElementInfoWidget()46 ElementInfoWidget::~ElementInfoWidget()
47 {
48 qDeleteAll(m_eipw_list);
49 delete ui;
50 }
51
52 /**
53 * @brief ElementInfoWidget::setElement
54 * Set @element to be the edited element
55 * @param element
56 */
setElement(Element * element)57 void ElementInfoWidget::setElement(Element *element)
58 {
59 if (m_element == element) return;
60
61 if (m_element)
62 disconnect(m_element.data(), &Element::elementInfoChange, this, &ElementInfoWidget::elementInfoChange);
63
64 m_element = element;
65 updateUi();
66
67 ElementInfoPartWidget *f = infoPartWidgetForKey("formula");
68 ElementInfoPartWidget *l = infoPartWidgetForKey("label");
69
70 if (f && l)
71 {
72 if (f->text().isEmpty())
73 l->setEnabled(true);
74 else
75 l->setDisabled(true);
76
77 connect(f, &ElementInfoPartWidget::textChanged, [l](const QString text)
78 {
79 l->setEnabled(text.isEmpty()? true : false);
80 });
81 }
82
83 connect(m_element.data(), &Element::elementInfoChange, this, &ElementInfoWidget::elementInfoChange);
84 }
85
86 /**
87 * @brief ElementInfoWidget::apply
88 * Apply the new information with a new undo command (got with method associatedUndo)
89 * pushed to the stack of element project.
90 */
apply()91 void ElementInfoWidget::apply()
92 {
93 if (QUndoCommand *undo = associatedUndo())
94 m_element -> diagram() -> undoStack().push(undo);
95 }
96
97 /**
98 * @brief ElementInfoWidget::associatedUndo
99 * If the edited info is different of the actual element info,
100 * return a QUndoCommand with the change.
101 * If no change return nullptr;
102 * @return
103 */
associatedUndo() const104 QUndoCommand* ElementInfoWidget::associatedUndo() const
105 {
106 DiagramContext new_info = currentInfo();
107 DiagramContext old_info = m_element -> elementInformations();
108
109 if (old_info != new_info)
110 return (new ChangeElementInformationCommand(m_element, old_info, new_info));
111
112 return nullptr;
113 }
114
115 /**
116 * @brief ElementInfoWidget::setLiveEdit
117 * @param live_edit true : enable the live edit mode, false disable
118 * @return always true;
119 */
setLiveEdit(bool live_edit)120 bool ElementInfoWidget::setLiveEdit(bool live_edit)
121 {
122 if (m_live_edit == live_edit) return true;
123 m_live_edit = live_edit;
124
125 if (m_live_edit)
126 enableLiveEdit();
127 else
128 disableLiveEdit();
129
130 return true;
131 }
132
133 /**
134 * @brief ElementInfoWidget::event
135 * Reimplemented from QWidget::event
136 * Only give focus to the first line edit at first activation.
137 * After send the event to QWidget.
138 * @param event
139 * @return
140 */
event(QEvent * event)141 bool ElementInfoWidget::event(QEvent *event)
142 {
143 if (m_first_activation)
144 {
145 if (event -> type() == QEvent::WindowActivate || event -> type() == QEvent::Show)
146 {
147 QTimer::singleShot(250, this, SLOT(firstActivated()));
148 m_first_activation = false;
149 }
150 }
151 return(QWidget::event(event));
152 }
153
154 /**
155 * @brief ElementInfoWidget::enableLiveEdit
156 * Enable the live edit mode
157 */
enableLiveEdit()158 void ElementInfoWidget::enableLiveEdit()
159 {
160 for (ElementInfoPartWidget *eipw : m_eipw_list)
161 connect(eipw, &ElementInfoPartWidget::textChanged, this, &ElementInfoWidget::apply);
162 }
163
164 /**
165 * @brief ElementInfoWidget::disableLiveEdit
166 * disable the live edit mode
167 */
disableLiveEdit()168 void ElementInfoWidget::disableLiveEdit()
169 {
170 for (ElementInfoPartWidget *eipw : m_eipw_list)
171 disconnect(eipw, &ElementInfoPartWidget::textChanged, this, &ElementInfoWidget::apply);
172 }
173
174 /**
175 * @brief ElementInfoWidget::buildInterface
176 * Build the widget
177 */
buildInterface()178 void ElementInfoWidget::buildInterface()
179 {
180 foreach (QString str, QETApp::elementInfoKeys())
181 {
182 ElementInfoPartWidget *eipw = new ElementInfoPartWidget(str, QETApp::elementTranslatedInfoKey(str), this);
183 ui->scroll_vlayout->addWidget(eipw);
184 m_eipw_list << eipw;
185 }
186 ui->scroll_vlayout->addStretch();
187 }
188
189 /**
190 * @brief ElementInfoWidget::infoPartWidgetForKey
191 * @param key
192 * @return the ElementInfoPartWidget with key @key, if not found return nullptr;
193 */
infoPartWidgetForKey(const QString & key) const194 ElementInfoPartWidget *ElementInfoWidget::infoPartWidgetForKey(const QString &key) const
195 {
196 foreach (ElementInfoPartWidget *eipw, m_eipw_list)
197 {
198 if (eipw->key() == key)
199 return eipw;
200 }
201
202 return nullptr;
203 }
204
205 /**
206 * @brief ElementInfoWidget::updateUi
207 * fill information fetch in m_element_info to the
208 * corresponding line edit
209 */
updateUi()210 void ElementInfoWidget::updateUi()
211 {
212 //We disable live edit to avoid wrong undo when we fill the line edit with new text
213 if (m_live_edit) disableLiveEdit();
214
215 DiagramContext element_info = m_element->elementInformations();
216
217 for (ElementInfoPartWidget *eipw : m_eipw_list) {
218 eipw -> setText (element_info[eipw->key()].toString());
219 }
220
221 if (m_live_edit) {
222 enableLiveEdit();
223 }
224 }
225
226 /**
227 * @brief ElementInfoWidget::currentInfo
228 * @return the info currently edited
229 */
currentInfo() const230 DiagramContext ElementInfoWidget::currentInfo() const
231 {
232 DiagramContext info_;
233
234 for (ElementInfoPartWidget *eipw : m_eipw_list)
235 {
236 //add value only if they're something to store
237 if (!eipw->text().isEmpty())
238 {
239 QString txt = eipw->text();
240 //remove line feed and carriage return
241 txt.remove("\r");
242 txt.remove("\n");
243 info_.addValue(eipw->key(), txt);
244 }
245 }
246
247 return info_;
248 }
249
250 /**
251 * @brief ElementInfoWidget::firstActivated
252 * Slot activated when this widget is show.
253 * Set the focus to the first line edit provided by this widget
254 */
firstActivated()255 void ElementInfoWidget::firstActivated() {
256 m_eipw_list.first() -> setFocusTolineEdit();
257 }
258
259 /**
260 * @brief ElementInfoWidget::elementInfoChange
261 * This slot is called when m_element::elementInformation change.
262 */
elementInfoChange()263 void ElementInfoWidget::elementInfoChange()
264 {
265 if(currentInfo() != m_element->elementInformations())
266 updateUi();
267 }
268