|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the Qt Mobility Components. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 #include "qcrmlgen.h" |
|
42 #include "qcrmlparser_p.h" |
|
43 |
|
44 #include <QTableWidget> |
|
45 #include <QHBoxLayout> |
|
46 #include <QVBoxLayout> |
|
47 #include <QLabel> |
|
48 #include <QLineEdit> |
|
49 #include <QHeaderView> |
|
50 #include <QPushButton> |
|
51 #include <QAction> |
|
52 #include <QMenuBar> |
|
53 #include <QMenu> |
|
54 #include <QComboBox> |
|
55 #include <QMessageBox> |
|
56 #include <QFileDialog> |
|
57 #include <QRegExpValidator> |
|
58 #include <QRadioButton> |
|
59 #include <QButtonGroup> |
|
60 #include <QDebug> |
|
61 #include <QCloseEvent> |
|
62 |
|
63 QTM_USE_NAMESPACE |
|
64 |
|
65 bool checkID(const QString &id) |
|
66 { |
|
67 if (id.length() > 8 || id.length() < 0) |
|
68 return false; |
|
69 bool ok = false; |
|
70 id.toUInt(&ok, 16); |
|
71 return ok; |
|
72 } |
|
73 |
|
74 #ifdef INCL_TYPE |
|
75 TypeDelegate::TypeDelegate(QTableWidget *parent) |
|
76 : QItemDelegate(parent), m_parentTable(parent) |
|
77 { |
|
78 } |
|
79 |
|
80 QWidget *TypeDelegate::createEditor(QWidget *parent, |
|
81 const QStyleOptionViewItem &, |
|
82 const QModelIndex &) const { |
|
83 QComboBox *editor = new QComboBox(parent); |
|
84 editor->addItem("int"); |
|
85 editor->addItem("real"); |
|
86 editor->addItem("string"); |
|
87 editor->addItem("string8"); |
|
88 editor->addItem("binary"); |
|
89 |
|
90 return editor; |
|
91 } |
|
92 |
|
93 void TypeDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const |
|
94 { |
|
95 QTableWidgetItem * item = m_parentTable->item(index.row(), index.column()); |
|
96 QComboBox *comboBox = qobject_cast<QComboBox *>(editor); |
|
97 if (!item->text().isEmpty() && comboBox->findText(item->text()) != -1) { |
|
98 comboBox->setCurrentIndex(comboBox->findText(item->text())); |
|
99 } |
|
100 } |
|
101 |
|
102 void TypeDelegate::setModelData(QWidget *editor, |
|
103 QAbstractItemModel *, |
|
104 const QModelIndex &index) const{ |
|
105 |
|
106 QComboBox *comboBox = qobject_cast<QComboBox *>(editor); |
|
107 m_parentTable->item(index.row(), index.column())->setText(comboBox->currentText()); |
|
108 } |
|
109 #endif |
|
110 |
|
111 KeyIdDelegate::KeyIdDelegate(QTableWidget *parent) |
|
112 : QItemDelegate(parent), m_parentTable(parent) |
|
113 { |
|
114 } |
|
115 |
|
116 QWidget *KeyIdDelegate::createEditor(QWidget *parent, |
|
117 const QStyleOptionViewItem &, |
|
118 const QModelIndex &) const { |
|
119 QLineEdit *editor = new QLineEdit(parent); |
|
120 QTableWidgetItem *item = m_parentTable->currentItem(); |
|
121 if (!item->text().isEmpty()) { |
|
122 editor->setText(item->text()); |
|
123 } |
|
124 QRegExpValidator *validator = |
|
125 new QRegExpValidator(QRegExp(QLatin1String("([0-9]|[A-F]|[a-f]){1,8}")), editor); |
|
126 editor->setValidator(validator); |
|
127 |
|
128 return editor; |
|
129 } |
|
130 |
|
131 void KeyIdDelegate::setModelData(QWidget *editor, |
|
132 QAbstractItemModel *, |
|
133 const QModelIndex &index) const{ |
|
134 |
|
135 QLineEdit *lineEdit = qobject_cast<QLineEdit *>(editor); |
|
136 m_parentTable->item(index.row(), index.column())->setText(lineEdit->text()); |
|
137 } |
|
138 |
|
139 PathDelegate::PathDelegate(QTableWidget *parent) |
|
140 : QItemDelegate(parent), m_parentTable(parent) |
|
141 { |
|
142 } |
|
143 |
|
144 QWidget *PathDelegate::createEditor(QWidget *parent, |
|
145 const QStyleOptionViewItem &, |
|
146 const QModelIndex &) const { |
|
147 QLineEdit *editor = new QLineEdit(parent); |
|
148 QTableWidgetItem *item = m_parentTable->currentItem(); |
|
149 if (!item->text().isEmpty()) { |
|
150 editor->setText(item->text()); |
|
151 } |
|
152 |
|
153 return editor; |
|
154 } |
|
155 |
|
156 void PathDelegate::setModelData(QWidget *editor, |
|
157 QAbstractItemModel *, |
|
158 const QModelIndex &index) const{ |
|
159 QLineEdit *lineEdit = qobject_cast<QLineEdit *>(editor); |
|
160 m_parentTable->item(index.row(), index.column())->setText(lineEdit->text()); |
|
161 } |
|
162 |
|
163 EditorWidget::EditorWidget():m_isModified(false) { |
|
164 m_RPropRadio = new QRadioButton(QLatin1String("RProperty")); |
|
165 m_CRepRadio = new QRadioButton(QLatin1String("CRepository")); |
|
166 QButtonGroup *targetGroup = new QButtonGroup(this); |
|
167 targetGroup->addButton(m_CRepRadio); |
|
168 targetGroup->addButton(m_RPropRadio); |
|
169 targetGroup->setExclusive(true); |
|
170 connect(targetGroup, SIGNAL(buttonClicked(QAbstractButton *)), this, SLOT(targetChanged(QAbstractButton *))); |
|
171 |
|
172 QHBoxLayout *targetLayout = new QHBoxLayout; |
|
173 targetLayout->addWidget(m_RPropRadio); |
|
174 targetLayout->addWidget(m_CRepRadio); |
|
175 |
|
176 m_RPropRadio->setChecked(true); |
|
177 m_repoLabel = new QLabel(tr("Category ID"), this); |
|
178 m_repoUID = new QLineEdit(this); |
|
179 QRegExpValidator *validator = |
|
180 new QRegExpValidator(QRegExp(QLatin1String("([0-9]|[A-F]|[a-f]){1,8}")), this); |
|
181 m_repoUID->setValidator(validator); |
|
182 connect(m_repoUID, SIGNAL(textEdited(const QString &)), this, SLOT(setModified())); |
|
183 m_repoUID->setToolTip(tr("Must be a hexidecimal number no longer than 8 digits")); |
|
184 |
|
185 QHBoxLayout *repoLayout = new QHBoxLayout; |
|
186 repoLayout->addWidget(m_repoLabel); |
|
187 repoLayout->addWidget(m_repoUID); |
|
188 |
|
189 QStringList headers; |
|
190 headers << tr("Key ID") << tr("Key path"); |
|
191 |
|
192 #ifdef INCL_TYPE |
|
193 headers << tr("Type"); |
|
194 #endif |
|
195 |
|
196 m_tableWidget = new QTableWidget(0,headers.count()); |
|
197 connect(m_tableWidget, SIGNAL(cellChanged(int,int)), this, SLOT(setModified())); |
|
198 m_tableWidget->setHorizontalHeaderLabels(headers); |
|
199 m_tableWidget->horizontalHeader()->setResizeMode(QHeaderView::Stretch); |
|
200 m_tableWidget->setSelectionMode(QAbstractItemView::SingleSelection); |
|
201 |
|
202 m_keyIdDelegate = new KeyIdDelegate(m_tableWidget); |
|
203 m_tableWidget->setItemDelegateForColumn(EditorWidget::KeyId, m_keyIdDelegate); |
|
204 |
|
205 m_pathDelegate = new PathDelegate(m_tableWidget); |
|
206 m_tableWidget->setItemDelegateForColumn(EditorWidget::Path, m_pathDelegate); |
|
207 |
|
208 #ifdef INCL_TYPE |
|
209 m_typeDelegate = new TypeDelegate(m_tableWidget); |
|
210 m_tableWidget->setItemDelegateForColumn(EditorWidget::Type,m_typeDelegate); |
|
211 #endif |
|
212 |
|
213 m_addRowButton = new QPushButton(tr("Add Row"), this); |
|
214 connect(m_addRowButton, SIGNAL(clicked()), this, SLOT(addRow())); |
|
215 m_removeRowButton = new QPushButton(tr("Remove Row"), this); |
|
216 connect(m_removeRowButton, SIGNAL(clicked()), this, SLOT(removeRow())); |
|
217 QPushButton *upButton = new QPushButton(tr("/\\"), this); |
|
218 connect(upButton, SIGNAL(clicked()), this, SLOT(moveRowUp())); |
|
219 QPushButton *downButton = new QPushButton(tr("\\/"), this); |
|
220 connect(downButton, SIGNAL(clicked()), this, SLOT(moveRowDown())); |
|
221 |
|
222 QHBoxLayout *buttonsLayout = new QHBoxLayout; |
|
223 buttonsLayout->addWidget(m_addRowButton); |
|
224 buttonsLayout->addWidget(m_removeRowButton); |
|
225 buttonsLayout->addWidget(upButton); |
|
226 buttonsLayout->addWidget(downButton); |
|
227 |
|
228 QVBoxLayout *mainLayout = new QVBoxLayout(); |
|
229 mainLayout->addLayout(targetLayout); |
|
230 mainLayout->addLayout(repoLayout); |
|
231 mainLayout->addWidget(m_tableWidget); |
|
232 mainLayout->addLayout(buttonsLayout); |
|
233 setLayout(mainLayout); |
|
234 |
|
235 addRow(); |
|
236 setModified(false); |
|
237 } |
|
238 |
|
239 void EditorWidget::addRow() |
|
240 { |
|
241 int row = m_tableWidget->rowCount(); |
|
242 m_tableWidget->insertRow(row); |
|
243 |
|
244 QTableWidgetItem *item; |
|
245 item = new QTableWidgetItem; |
|
246 item->setToolTip(tr("Must be a hexidecimal number no longer than 8 digits")); |
|
247 m_tableWidget->setItem(row, EditorWidget::KeyId, item); |
|
248 |
|
249 item = new QTableWidgetItem(QLatin1String("/")); |
|
250 item->setToolTip(tr("Must not be empty and must start with a /")); |
|
251 m_tableWidget->setItem(row, EditorWidget::Path, item); |
|
252 |
|
253 #ifdef INCL_TYPE |
|
254 item = new QTableWidgetItem(tr("int")); |
|
255 m_tableWidget->setItem(row, EditorWidget::Type, item); |
|
256 #endif |
|
257 |
|
258 setModified(true); |
|
259 } |
|
260 |
|
261 void EditorWidget::removeRow() |
|
262 { |
|
263 int row = m_tableWidget->currentRow(); |
|
264 m_tableWidget->removeRow(row); |
|
265 row = m_tableWidget->currentRow(); |
|
266 m_tableWidget->setCurrentCell(row, 0); |
|
267 setModified(true); |
|
268 } |
|
269 |
|
270 void EditorWidget::initNew() |
|
271 { |
|
272 m_repoUID->clear(); |
|
273 |
|
274 for(int i = m_tableWidget->rowCount() -1; i >= 0; --i) { |
|
275 m_tableWidget->removeRow(i); |
|
276 } |
|
277 addRow(); |
|
278 setModified(false); |
|
279 } |
|
280 |
|
281 void EditorWidget::save(const QString &filePath) |
|
282 { |
|
283 QFile file(filePath); |
|
284 if (!file.open(QFile::ReadWrite)) { |
|
285 QMessageBox::warning(this, tr("File Error"), |
|
286 tr("%1 could not be opened").arg(filePath)); |
|
287 return; |
|
288 |
|
289 } |
|
290 file.resize(0); |
|
291 |
|
292 QString repoUID = m_repoUID->text(); |
|
293 QString keyId; |
|
294 QString path; |
|
295 #ifdef INCL_TYPE |
|
296 QString type; |
|
297 #endif |
|
298 QString documentStart(QLatin1String("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")); |
|
299 file.write(documentStart.toUtf8()); |
|
300 |
|
301 QString repositoryElementStart(QLatin1String("<repository target=\"%1\" uidValue=\"0x%2\">\n")); |
|
302 QString target = m_RPropRadio->isChecked() ? QLatin1String("RProperty") : QLatin1String("CRepository"); |
|
303 file.write(repositoryElementStart.arg(target).arg(repoUID).toUtf8()); |
|
304 #ifdef INCL_TYPE |
|
305 QString keyElementStart(QLatin1String(" <key int=\"0x%1\" type=\"%2\" ref=\"%3\">\n")); |
|
306 #else |
|
307 QString keyElementStart(QLatin1String(" <key int=\"0x%1\" ref=\"%2\">\n")); |
|
308 #endif |
|
309 QString keyElementEnd(QLatin1String(" </key>\n")); |
|
310 |
|
311 for(int i=0; i < m_tableWidget->rowCount(); i++) { |
|
312 keyId = m_tableWidget->item(i, EditorWidget::KeyId)->text(); |
|
313 path = m_tableWidget-> item(i, EditorWidget::Path)->text().remove(0,1); |
|
314 #ifdef INCL_TYPE |
|
315 type = m_tableWidget->item(i, EditorWidget::Type)->text(); |
|
316 file.write(keyElementStart.arg(keyId).arg(type).arg(path).toUtf8()); |
|
317 #else |
|
318 file.write(keyElementStart.arg(keyId).arg(path).toUtf8()); |
|
319 #endif |
|
320 |
|
321 file.write(keyElementEnd.toUtf8()); |
|
322 } |
|
323 |
|
324 QString repositoryElementEnd(QLatin1String("</repository>\n")); |
|
325 file.write(repositoryElementEnd.toUtf8()); |
|
326 file.close(); |
|
327 setModified(false); |
|
328 } |
|
329 |
|
330 void EditorWidget::open(const QString &filePath) |
|
331 { |
|
332 QFile file(filePath); |
|
333 if (!file.open(QFile::ReadWrite)) { |
|
334 QMessageBox::warning(this, tr("File Error"), |
|
335 tr("%1 could not be opened").arg(filePath)); |
|
336 return; |
|
337 } |
|
338 |
|
339 for(int i = m_tableWidget->rowCount() - 1; i >=0; i--) { |
|
340 m_tableWidget->removeRow(i); |
|
341 } |
|
342 |
|
343 QList<KeyData> keyData; |
|
344 QCrmlParser parser; |
|
345 keyData = parser.parseQCrml(filePath); |
|
346 if (parser.error() != QCrmlParser::NoError) { |
|
347 QMessageBox::warning(this, tr("Parse Error"), |
|
348 tr("%1 is not a valid qcrml file").arg(filePath)); |
|
349 qWarning() << "Parsing error:" << parser.errorString(); |
|
350 return; |
|
351 } |
|
352 |
|
353 for (int i = 0; i < keyData.count(); ++i) { |
|
354 if (i == 0) { |
|
355 m_repoUID->setText(QString::number(keyData.at(i).repoId(),16)); |
|
356 if (keyData.at(i).target() == KeyData::RProperty) |
|
357 m_RPropRadio->click(); |
|
358 else |
|
359 m_CRepRadio->click(); |
|
360 } |
|
361 |
|
362 addRow(); |
|
363 m_tableWidget->item(i, EditorWidget::KeyId)->setText(QString::number(keyData.at(i).keyId(),16)); |
|
364 m_tableWidget->item(i, EditorWidget::Path)->setText(keyData.at(i).path()); |
|
365 #ifdef INCL_TYPE |
|
366 m_tableWidget->item(i, EditorWidget::Type)->setText("int"); |
|
367 #endif |
|
368 } |
|
369 setModified(false); |
|
370 } |
|
371 |
|
372 bool EditorWidget::isModified() |
|
373 { |
|
374 if (!m_isModified) { |
|
375 //check if the user has started a cell editor but hadn't |
|
376 //committed it's contents to the table by pressing enter |
|
377 QWidget *editorWidget = m_tableWidget->cellWidget(m_tableWidget->currentRow(), |
|
378 m_tableWidget->currentColumn()); |
|
379 if (editorWidget) { |
|
380 switch(m_tableWidget->currentColumn()) { |
|
381 case(EditorWidget::KeyId): |
|
382 case(EditorWidget::Path): { |
|
383 QLineEdit *lineEdit = qobject_cast<QLineEdit *>(editorWidget); |
|
384 if (lineEdit->text() != m_tableWidget->currentItem()->text()) |
|
385 m_isModified = true; |
|
386 break; |
|
387 } |
|
388 #ifdef INCL_TYPE |
|
389 case(EditorWidget::Type): { |
|
390 QComboBox *comboBox = qobject_cast<QComboBox *>(editorWidget); |
|
391 if (comboBox->currentText() != m_tableWidget->currentItem()->text()) |
|
392 m_isModified = true; |
|
393 break; |
|
394 } |
|
395 #endif |
|
396 default: |
|
397 qWarning() << "EditorWidget::isModified():- unknown widget type"; |
|
398 } |
|
399 } |
|
400 } |
|
401 return m_isModified; |
|
402 } |
|
403 |
|
404 bool EditorWidget::verifyContents() |
|
405 { |
|
406 //If any cells are currently edited add their contents |
|
407 //to the tableWidget |
|
408 QWidget *cellWidget = m_tableWidget->cellWidget(m_tableWidget->currentRow(), m_tableWidget->currentColumn()); |
|
409 if (cellWidget) { |
|
410 QAbstractItemDelegate *delegate = m_tableWidget->itemDelegateForColumn(m_tableWidget->currentColumn()); |
|
411 if (delegate) { |
|
412 delegate->setModelData(cellWidget,m_tableWidget->model(),m_tableWidget->currentIndex()); |
|
413 } |
|
414 } |
|
415 |
|
416 QString repoUID = m_repoUID->text(); |
|
417 if (!checkID(repoUID)) { |
|
418 QMessageBox::warning(this, tr("Invalid input"), |
|
419 tr("The '%1' field is invalid, " |
|
420 "it must be a hexidecimal number no longer than 8 digits.") |
|
421 .arg(m_repoLabel->text())); |
|
422 m_repoUID->setFocus(); |
|
423 return false; |
|
424 } |
|
425 |
|
426 QString keyId; |
|
427 QString path; |
|
428 #ifdef INCL_TYPE |
|
429 QString type; |
|
430 #endif |
|
431 for(int i=0; i < m_tableWidget->rowCount(); i++) { |
|
432 keyId = m_tableWidget->item(i, EditorWidget::KeyId)->text(); |
|
433 if (!checkID(keyId)) { |
|
434 QMessageBox::warning(this, tr("Invalid Key ID"), |
|
435 tr("The Key ID field is invalid, it must be a hexidecimal number no longer than 8 digits")); |
|
436 m_tableWidget->setCurrentCell(i, EditorWidget::KeyId); |
|
437 m_tableWidget->setFocus(); |
|
438 return false; |
|
439 } |
|
440 |
|
441 path = m_tableWidget->item(i, EditorWidget::Path)->text(); |
|
442 if (path.isEmpty() || !path.startsWith(QLatin1Char('/'))) { |
|
443 QMessageBox::warning(this, tr("Invalid Path"), |
|
444 tr("The Key Path field is invalid, it must not be empty and start with a /")); |
|
445 m_tableWidget->setCurrentCell(i, EditorWidget::Path); |
|
446 m_tableWidget->setFocus(); |
|
447 return false; |
|
448 } |
|
449 |
|
450 #ifdef INCL_TYPE |
|
451 type = m_tableWidget->item(i, EditorWidget::Type)->text(); |
|
452 if (type.isEmpty()) { |
|
453 QMessageBox::warning(this, tr("Invalid Type"), |
|
454 tr("The Type field is invalid, it must not be empty")); |
|
455 m_tableWidget->setCurrentCell(i, EditorWidget::Type); |
|
456 m_tableWidget->setFocus(); |
|
457 return false; |
|
458 } |
|
459 #endif |
|
460 } |
|
461 return true; |
|
462 } |
|
463 |
|
464 void EditorWidget::setModified(bool b) { |
|
465 m_isModified = b; |
|
466 } |
|
467 |
|
468 void EditorWidget::moveRowUp() |
|
469 { |
|
470 int currentRow = m_tableWidget->currentRow(); |
|
471 int currentColumn = m_tableWidget->currentColumn(); |
|
472 if (currentRow < 1) { |
|
473 return; |
|
474 } |
|
475 |
|
476 m_tableWidget->insertRow(currentRow - 1); |
|
477 |
|
478 for (int i = 0; i < m_tableWidget->columnCount(); ++i) { |
|
479 m_tableWidget->setItem(currentRow - 1, i, |
|
480 m_tableWidget->takeItem(currentRow + 1, i)); |
|
481 } |
|
482 |
|
483 m_tableWidget->setCurrentCell(currentRow -1, currentColumn); |
|
484 m_tableWidget->removeRow(currentRow+1); |
|
485 } |
|
486 |
|
487 void EditorWidget::moveRowDown() |
|
488 { |
|
489 int currentRow = m_tableWidget->currentRow(); |
|
490 int currentColumn = m_tableWidget->currentColumn(); |
|
491 if (currentRow == -1 || currentRow == m_tableWidget->rowCount() - 1) { |
|
492 return; |
|
493 } |
|
494 m_tableWidget->insertRow(currentRow + 2); |
|
495 |
|
496 for (int i = 0; i < m_tableWidget->columnCount(); ++i) { |
|
497 m_tableWidget->setItem(currentRow + 2, i, |
|
498 m_tableWidget->takeItem(currentRow, i)); |
|
499 } |
|
500 |
|
501 m_tableWidget->setCurrentCell(currentRow + 2, currentColumn); |
|
502 m_tableWidget->removeRow(currentRow); |
|
503 } |
|
504 |
|
505 void EditorWidget::targetChanged(QAbstractButton *button) |
|
506 { |
|
507 if (button == m_RPropRadio) |
|
508 m_repoLabel->setText(tr("Category ID")); |
|
509 else |
|
510 m_repoLabel->setText(tr("Repository ID")); |
|
511 } |
|
512 |
|
513 QCrmlGenerator::QCrmlGenerator() |
|
514 { |
|
515 QMenu *fileMenu = menuBar()->addMenu(tr("&File")); |
|
516 newAction = new QAction(tr("&New"), this); |
|
517 connect(newAction, SIGNAL(triggered()) , this, SLOT(newFile())); |
|
518 |
|
519 openAction = new QAction(tr("&Open"), this); |
|
520 connect(openAction, SIGNAL(triggered()), this, SLOT(openFile())); |
|
521 saveAction = new QAction(tr("&Save"), this); |
|
522 connect(saveAction, SIGNAL(triggered()), this, SLOT(saveFile())); |
|
523 saveAsAction = new QAction(tr("Save &As..."), this); |
|
524 connect(saveAsAction, SIGNAL(triggered()), this, SLOT(saveFileAs())); |
|
525 |
|
526 exitAction = new QAction(tr("&Exit"), this); |
|
527 connect(exitAction, SIGNAL(triggered()), this, SLOT(close())); |
|
528 |
|
529 fileMenu->addAction(newAction); |
|
530 fileMenu->addAction(openAction); |
|
531 fileMenu->addSeparator(); |
|
532 fileMenu->addAction(saveAction); |
|
533 fileMenu->addAction(saveAsAction); |
|
534 fileMenu->addSeparator(); |
|
535 fileMenu->addAction(exitAction); |
|
536 |
|
537 m_editorWidget = new EditorWidget; |
|
538 setCentralWidget(m_editorWidget); |
|
539 } |
|
540 |
|
541 void QCrmlGenerator::newFile() { |
|
542 |
|
543 if (safeToClear()) { |
|
544 m_editorWidget->initNew(); |
|
545 m_saveFile.clear(); |
|
546 } |
|
547 } |
|
548 |
|
549 void QCrmlGenerator::openFile() { |
|
550 if (safeToClear()) { |
|
551 QFileDialog openDialog(this, tr("Open"), QString(), tr("QCrml (*.qcrml);;Any Files(*)")); |
|
552 openDialog.setFileMode(QFileDialog::ExistingFile); |
|
553 openDialog.setAcceptMode(QFileDialog::AcceptOpen); |
|
554 if (openDialog.exec() == QDialog::Accepted) { |
|
555 if (openDialog.selectedFiles().count() > 0) { |
|
556 m_saveFile = openDialog.selectedFiles().at(0); |
|
557 m_editorWidget->open(m_saveFile); |
|
558 } |
|
559 } |
|
560 } |
|
561 } |
|
562 |
|
563 void QCrmlGenerator::saveFile() |
|
564 { |
|
565 if (m_saveFile.isEmpty()) { |
|
566 saveFileAs(); |
|
567 } |
|
568 else { |
|
569 if (m_editorWidget->verifyContents()) |
|
570 m_editorWidget->save(m_saveFile); |
|
571 } |
|
572 } |
|
573 |
|
574 void QCrmlGenerator::saveFileAs() |
|
575 { |
|
576 if (m_editorWidget->verifyContents()) { |
|
577 QFileDialog saveDialog(this, tr("Save As"), QString(), tr("QCrml (*.qcrml);;Any Files (*)")); |
|
578 saveDialog.setDefaultSuffix(QLatin1String("qcrml")); |
|
579 saveDialog.setFileMode(QFileDialog::AnyFile); |
|
580 saveDialog.setAcceptMode(QFileDialog::AcceptSave); |
|
581 if (saveDialog.exec() == QDialog::Accepted) { |
|
582 if (saveDialog.selectedFiles().count() > 0) { |
|
583 m_saveFile = saveDialog.selectedFiles().at(0); |
|
584 m_editorWidget->save(m_saveFile); |
|
585 } |
|
586 } |
|
587 } |
|
588 } |
|
589 |
|
590 void QCrmlGenerator::closeEvent(QCloseEvent *event) |
|
591 { |
|
592 if (safeToClear()) |
|
593 event->accept(); |
|
594 else |
|
595 event->ignore(); |
|
596 } |
|
597 |
|
598 bool QCrmlGenerator::safeToClear() |
|
599 { |
|
600 if (m_editorWidget->isModified()) { |
|
601 int ret = QMessageBox::warning(this, tr("Save changes?"), |
|
602 tr("Modifications have been made. Do you want to save your changes? "), |
|
603 QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Save); |
|
604 switch (ret) { |
|
605 case QMessageBox::Save: |
|
606 saveFile(); |
|
607 return true; |
|
608 case QMessageBox::Discard: |
|
609 return true; |
|
610 default: |
|
611 return false; |
|
612 } |
|
613 } |
|
614 return true; |
|
615 } |