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 <QVBoxLayout>
19 #include <QLabel>
20 #include <QTreeView>
21 #include <QDialogButtonBox>
22 #include <QPushButton>
23 #include <QtConcurrent>
24
25 #include "elementdialog.h"
26 #include "qetapp.h"
27 #include "qfilenameedit.h"
28 #include "elementcollectionitem.h"
29 #include "elementscollectionmodel.h"
30 #include "qetmessagebox.h"
31
32 /**
33 * @brief ElementDialog::ElementDialog
34 * @param mode
35 * @param parent
36 */
ElementDialog(uint mode,QWidget * parent)37 ElementDialog::ElementDialog(uint mode, QWidget *parent) :
38 QDialog(parent),
39 m_mode(mode)
40 {
41 setUpWidget();
42 setUpConnection();
43 }
44
45 /**
46 * @brief ElementDialog::setUpWidget
47 * Build and setup the widgets of this dialog
48 */
setUpWidget()49 void ElementDialog::setUpWidget()
50 {
51 setWindowModality(Qt::WindowModal);
52 #ifdef Q_OS_MAC
53 setWindowFlags(Qt::Sheet);
54 #endif
55
56 QVBoxLayout *layout = new QVBoxLayout(this);
57
58 QString title_, label_;
59 switch (m_mode)
60 {
61 case OpenElement:
62 title_ = tr("Ouvrir un élément", "dialog title");
63 label_ = tr("Choisissez l'élément que vous souhaitez ouvrir.", "dialog content");
64 break;
65 case SaveElement:
66 title_ = tr("Enregistrer un élément", "dialog title");
67 label_ = tr("Choisissez l'élément dans lequel vous souhaitez enregistrer votre définition.", "dialog content");
68 break;
69 case OpenCategory:
70 title_ = tr("Ouvrir une catégorie", "dialog title");
71 label_ = tr("Choisissez une catégorie.", "dialog content");
72 break;
73 case SaveCategory:
74 title_ = tr("Enregistrer une catégorie", "dialog title");
75 label_ = tr("Choisissez une catégorie.", "dialog content");
76 break;
77 default:
78 title_ = tr("Titre");
79 label_ = tr("Label");
80 break;
81 }
82 setWindowTitle(title_);
83
84 layout->addWidget(new QLabel(label_));
85
86
87 m_tree_view = new QTreeView(this);
88
89 m_model = new ElementsCollectionModel(m_tree_view);
90
91 QList <QETProject *> prjs;
92 foreach(QETProject *prj, QETApp::registeredProjects())
93 prjs.append(prj);
94
95 if (m_mode == OpenElement)
96 m_model->loadCollections(true, true, prjs);
97 else
98 m_model->loadCollections(false, true, prjs);
99
100 m_tree_view->setModel(m_model);
101 m_tree_view->setHeaderHidden(true);
102 layout->addWidget(m_tree_view);
103
104 m_buttons_box = new QDialogButtonBox(this);
105
106 if (m_mode == SaveCategory || m_mode == SaveElement)
107 {
108 m_buttons_box->setStandardButtons(QDialogButtonBox::Save | QDialogButtonBox::Cancel);
109 m_buttons_box->button(QDialogButtonBox::Save)->setDisabled(true);
110
111 m_text_field = new QFileNameEdit();
112 m_text_field->setDisabled(true);
113 m_text_field->setPlaceholderText(m_mode == SaveCategory? tr("Nom du nouveau dossier") : tr("Nom du nouvel élément"));
114
115 layout->addWidget(m_text_field);
116 }
117 else
118 {
119 m_buttons_box->setStandardButtons(QDialogButtonBox::Open | QDialogButtonBox::Cancel);
120 m_buttons_box->button(QDialogButtonBox::Open)->setDisabled(true);
121 }
122
123 layout->addWidget(m_buttons_box);
124 }
125
126 /**
127 * @brief ElementDialog::setUpConnection
128 * Setup connection of this dialog
129 */
setUpConnection()130 void ElementDialog::setUpConnection()
131 {
132 connect(m_tree_view, &QTreeView::clicked, this, &ElementDialog::indexClicked);
133 connect(m_buttons_box, &QDialogButtonBox::accepted, this, &ElementDialog::checkAccept);
134 connect(m_buttons_box, &QDialogButtonBox::rejected, this, &QDialog::reject);
135
136 if (m_text_field) { connect(m_text_field, &QFileNameEdit::textChanged, this, &ElementDialog::checkCurrentLocation); }
137 }
138
139 /**
140 * @brief ElementDialog::indexClicked
141 * @param index
142 */
indexClicked(const QModelIndex & index)143 void ElementDialog::indexClicked(const QModelIndex &index)
144 {
145 ElementCollectionItem *eci = static_cast<ElementCollectionItem*> (m_model->itemFromIndex(index));
146 m_location = ElementsLocation(eci->collectionPath());
147 checkCurrentLocation();
148 }
149
150 /**
151 * @brief ElementDialog::checkCurrentLocation
152 * Update this dialog according to the current selected location and the current mode
153 */
checkCurrentLocation()154 void ElementDialog::checkCurrentLocation()
155 {
156 if (m_mode == OpenElement) {
157 m_buttons_box->button(QDialogButtonBox::Open)->setEnabled(m_location.isElement() && m_location.exist());
158 }
159 else if (m_mode == SaveElement)
160 {
161 m_buttons_box->button(QDialogButtonBox::Save)->setDisabled(true);
162
163 //Location doesn't exist
164 if (!m_location.exist()) { return; }
165
166 if (m_location.isElement())
167 {
168 m_text_field->setDisabled(true);
169 m_buttons_box->button(QDialogButtonBox::Save)->setEnabled(true);
170 }
171 else if (m_location.isDirectory())
172 {
173 m_text_field->setEnabled(true);
174
175 if (m_text_field->text().isEmpty()) { return; }
176
177 //Only enable save button if the location at path :
178 //m_location.collectionPath + m_text_filed.text doesn't exist.
179 QString new_path = m_text_field->text();
180 if (!new_path.endsWith(".elmt")) new_path += ".elmt";
181
182 ElementsLocation loc = m_location;
183 loc.addToPath(new_path);
184
185 m_buttons_box->button(QDialogButtonBox::Save)->setDisabled(loc.exist() ? true : false);
186 }
187 }
188 }
189
checkAccept()190 void ElementDialog::checkAccept()
191 {
192 ElementsLocation loc = location();
193
194 if (m_mode == OpenElement)
195 {
196 if (loc.isElement() && loc.exist()) {accept();}
197 if (!loc.exist())
198 {
199 QET::QetMessageBox::critical(this,
200 tr("Sélection inexistante", "message box title"),
201 tr("La sélection n'existe pas.", "message box content"));
202 return;
203 }
204 else if (!loc.isElement())
205 {
206 QET::QetMessageBox::critical(this,
207 tr("Sélection incorrecte", "message box title"),
208 tr("La sélection n'est pas un élément.", "message box content"));
209 return;
210 }
211 }
212 else if (m_mode == SaveElement)
213 {
214 if (loc.isElement())
215 {
216 if (loc.exist())
217 {
218 QMessageBox::StandardButton answer = QET::QetMessageBox::question(this,
219 tr("Écraser l'élément ?", "message box title"),
220 tr("L'élément existe déjà. Voulez-vous l'écraser ?", "message box content"),
221 QMessageBox::Yes | QMessageBox::No,
222 QMessageBox::No);
223 if (answer == QMessageBox::Yes) {accept();}
224 else {return;}
225 }
226 else {accept();}
227 }
228 else
229 {
230 QET::QetMessageBox::critical(this,
231 tr("Sélection incorrecte", "message box title"),
232 tr("Vous devez sélectionner un élément ou une catégorie avec un nom pour l'élément.", "message box content"));
233 return;
234 }
235 }
236 }
237
238 /**
239 * @brief ElementDialog::location
240 * @return The selected location or a null location if user has selected nothing
241 * or selection isn't compatible with the curent mode
242 */
location() const243 ElementsLocation ElementDialog::location() const
244 {
245 if (m_mode == OpenElement)
246 {
247 if (m_location.isElement()) { return m_location; }
248 else {return ElementsLocation(); }
249 }
250
251 else if (m_mode == SaveElement)
252 {
253 //Current selected location is element, we return this location
254 if (m_location.isElement()) { return m_location; }
255
256 //Current selected location is directory, we return a location at path :
257 //m_location->collectionPath + m_text_field->text
258 else if (m_location.isDirectory())
259 {
260 QString new_path = m_text_field->text();
261 if (new_path.isEmpty()) { return ElementsLocation(); }
262
263 if (!new_path.endsWith(".elmt")) { new_path += ".elmt"; }
264
265 ElementsLocation loc = m_location;
266 loc.addToPath(new_path);
267 return loc;
268 }
269 }
270
271 return ElementsLocation();
272 }
273
274 /**
275 * @brief ElementDialog::getOpenElementLocation
276 * Display a dialog for open an element through her location
277 * @param parentWidget
278 * @return The location of the selected element
279 */
getOpenElementLocation(QWidget * parentWidget)280 ElementsLocation ElementDialog::getOpenElementLocation(QWidget *parentWidget) {
281 return(ElementDialog::execConfiguredDialog(ElementDialog::OpenElement, parentWidget));
282 }
283
284 /**
285 * @brief ElementDialog::getSaveElementLocation
286 * Display a dialog that allow to user to select an element (existing or not) who he want to save
287 * @param parentWidget
288 * @return The location where the element must be save
289 */
getSaveElementLocation(QWidget * parentWidget)290 ElementsLocation ElementDialog::getSaveElementLocation(QWidget *parentWidget) {
291 return(ElementDialog::execConfiguredDialog(ElementDialog::SaveElement, parentWidget));
292 }
293
294 /**
295 * @brief ElementDialog::execConfiguredDialog
296 * launch a dialog with the chosen mode
297 * @param mode : mode of the dialog
298 * @param parentWidget : parent widget of the dialog
299 * @return the chosen location
300 */
execConfiguredDialog(int mode,QWidget * parentWidget)301 ElementsLocation ElementDialog::execConfiguredDialog(int mode, QWidget *parentWidget)
302 {
303 ElementDialog *element_dialog = new ElementDialog(mode, parentWidget);
304 element_dialog->exec();
305 ElementsLocation location = element_dialog->location();
306 delete element_dialog;
307 return(location);
308 }
309