1 /****************************************************************************
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the examples of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
11 ** Licensees holding valid Qt Commercial licenses may use this file in
12 ** accordance with the Qt Commercial License Agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and Nokia.
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.
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.
28 ** GNU General Public License Usage
29 ** Alternatively, this file may be used under the terms of the GNU
30 ** General Public License version 3.0 as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL included in the
32 ** packaging of this file. Please review the following information to
33 ** ensure the GNU General Public License version 3.0 requirements will be
34 ** met: http://www.gnu.org/copyleft/gpl.html.
36 ** If you have questions regarding the use of this file, please contact
37 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
43 #include "ui_mdichild.h"
44 #include "xmlinterface.h"
45 #include "hexinterface.h"
46 #include "mainwindow.h"
47 #include "modeledit/modeledit.h"
48 #include "generaledit/generaledit.h"
49 #include "burnconfigdialog.h"
50 #include "printdialog.h"
51 #include "flasheepromdialog.h"
54 #include "wizarddialog.h"
55 #include "flashfirmwaredialog.h"
58 #if defined WIN32 || !defined __GNUC__
60 #define sleep(x) Sleep(x*1000)
68 firmware(GetCurrentFirmware()),
73 setWindowIcon(CompanionIcon("open.png"));
74 ui
->SimulateTxButton
->setIcon(CompanionIcon("simulate.png"));
75 setAttribute(Qt::WA_DeleteOnClose
);
77 eepromInterfaceChanged();
79 if (!(this->isMaximized() || this->isMinimized())) {
89 void MdiChild::qSleep(int ms
)
94 #if defined WIN32 || !defined __GNUC__
97 struct timespec ts
= { ms
/ 1000, (ms
% 1000) * 1000 * 1000 };
102 void MdiChild::eepromInterfaceChanged()
104 ui
->modelsList
->refreshList();
105 ui
->SimulateTxButton
->setEnabled(GetCurrentFirmware()/*firmware*/->getCapability(Simulation
));
111 ui
->modelsList
->cut();
114 void MdiChild::copy()
116 ui
->modelsList
->copy();
119 void MdiChild::paste()
121 ui
->modelsList
->paste();
124 bool MdiChild::hasPasteData()
126 return ui
->modelsList
->hasPasteData();
129 bool MdiChild::hasSelection()
131 return ui
->modelsList
->hasSelection();
134 void MdiChild::updateTitle()
136 QString title
= userFriendlyCurrentFile() + "[*]" + " (" + GetCurrentFirmware()->getName() + QString(")");
137 if (!IS_SKY9X(GetCurrentFirmware()->getBoard()))
138 title
+= QString(" - %1 ").arg(EEPromAvail
) + tr("free bytes");
139 setWindowTitle(title
);
142 void MdiChild::setModified()
144 ui
->modelsList
->refreshList();
147 documentWasModified();
150 void MdiChild::on_SimulateTxButton_clicked()
152 startSimulation(this, radioData
, -1);
155 void MdiChild::checkAndInitModel(int row
)
157 ModelData
&model
= radioData
.models
[row
- 1];
158 if (model
.isEmpty()) {
159 model
.setDefaultValues(row
- 1, radioData
.generalSettings
);
164 void MdiChild::generalEdit()
166 GeneralEdit
*t
= new GeneralEdit(this, radioData
, GetCurrentFirmware()/*firmware*/);
167 connect(t
, SIGNAL(modified()), this, SLOT(setModified()));
171 void MdiChild::modelEdit()
173 int row
= getCurrentRow();
179 QApplication::setOverrideCursor(Qt::WaitCursor
);
180 checkAndInitModel( row
);
181 ModelData
& model
= radioData
.models
[row
- 1];
182 gStopwatch
.restart();
183 gStopwatch
.report("ModelEdit creation");
184 ModelEdit
*t
= new ModelEdit(this, radioData
, (row
- 1), GetCurrentFirmware()/*firmware*/);
185 gStopwatch
.report("ModelEdit created");
186 t
->setWindowTitle(tr("Editing model %1: ").arg(row
) + model
.name
);
187 connect(t
, SIGNAL(modified()), this, SLOT(setModified()));
188 gStopwatch
.report("STARTING MODEL EDIT");
190 QApplication::restoreOverrideCursor();
191 gStopwatch
.report("ModelEdit shown");
195 void MdiChild::wizardEdit()
197 int row
= getCurrentRow();
199 checkAndInitModel(row
);
200 WizardDialog
* wizard
= new WizardDialog(radioData
.generalSettings
, row
, this);
202 if (wizard
->mix
.complete
/*TODO rather test the exec() result?*/) {
203 radioData
.models
[row
- 1] = wizard
->mix
;
209 void MdiChild::openEditWindow()
211 int row
= getCurrentRow();
216 ModelData
& model
= radioData
.models
[row
- 1];
217 if (model
.isEmpty() && g
.useWizard()) {
226 void MdiChild::newFile()
228 static int sequenceNumber
= 1;
231 curFile
= QString("document%1.eepe").arg(sequenceNumber
++);
235 bool MdiChild::loadFile(const QString
&fileName
, bool resetCurrentFile
)
237 QFile
file(fileName
);
239 if (!file
.exists()) {
240 QMessageBox::critical(this, tr("Error"), tr("Unable to find file %1!").arg(fileName
));
244 int fileType
= getFileType(fileName
);
247 if (fileType
==FILE_TYPE_XML
) {
248 if (!file
.open(QIODevice::ReadOnly
| QIODevice::Text
)) { //reading HEX TEXT file
249 QMessageBox::critical(this, tr("Error"),
250 tr("Error opening file %1:\n%2.")
252 .arg(file
.errorString()));
255 QTextStream
inputStream(&file
);
256 XmlInterface(inputStream
).load(radioData
);
260 if (fileType
==FILE_TYPE_HEX
|| fileType
==FILE_TYPE_EEPE
) { //read HEX file
261 if (!file
.open(QIODevice::ReadOnly
| QIODevice::Text
)) { //reading HEX TEXT file
262 QMessageBox::critical(this, tr("Error"),
263 tr("Error opening file %1:\n%2.")
265 .arg(file
.errorString()));
269 QDomDocument
doc(ER9X_EEPROM_FILE_TYPE
);
270 bool xmlOK
= doc
.setContent(&file
);
272 std::bitset
<NUM_ERRORS
> errors((unsigned long long)LoadEepromXml(radioData
, doc
));
273 if (errors
.test(ALL_OK
)) {
274 ui
->modelsList
->refreshList();
275 if(resetCurrentFile
) setCurrentFile(fileName
);
281 QTextStream
inputStream(&file
);
283 if (fileType
==FILE_TYPE_EEPE
) { // read EEPE file header
284 QString hline
= inputStream
.readLine();
285 if (hline
!=EEPE_EEPROM_FILE_HEADER
) {
291 QByteArray
eeprom(EESIZE_MAX
, 0);
292 int eeprom_size
= HexInterface(inputStream
).load((uint8_t *)eeprom
.data(), EESIZE_MAX
);
294 QMessageBox::critical(this, tr("Error"),
295 tr("Invalid EEPROM File %1")
303 std::bitset
<NUM_ERRORS
> errors((unsigned long long)LoadEeprom(radioData
, (uint8_t *)eeprom
.data(), eeprom_size
));
304 if (!errors
.test(ALL_OK
)) {
305 ShowEepromErrors(this, tr("Error"), tr("Invalid EEPROM File %1").arg(fileName
), errors
.to_ulong());
308 if (errors
.test(HAS_WARNINGS
)) {
309 ShowEepromWarnings(this, tr("Warning"), errors
.to_ulong());
312 ui
->modelsList
->refreshList();
313 if(resetCurrentFile
) setCurrentFile(fileName
);
317 else if (fileType
==FILE_TYPE_BIN
) { //read binary
318 int eeprom_size
= file
.size();
320 if (!file
.open(QFile::ReadOnly
)) { //reading binary file - TODO HEX support
321 QMessageBox::critical(this, tr("Error"),
322 tr("Error opening file %1:\n%2.")
324 .arg(file
.errorString()));
327 uint8_t *eeprom
= (uint8_t *)malloc(eeprom_size
);
328 memset(eeprom
, 0, eeprom_size
);
329 long result
= file
.read((char*)eeprom
, eeprom_size
);
332 if (result
!= eeprom_size
) {
333 QMessageBox::critical(this, tr("Error"),
334 tr("Error reading file %1:\n%2.")
336 .arg(file
.errorString()));
341 std::bitset
<NUM_ERRORS
> errorsEeprom((unsigned long long)LoadEeprom(radioData
, eeprom
, eeprom_size
));
342 if (!errorsEeprom
.test(ALL_OK
)) {
343 std::bitset
<NUM_ERRORS
> errorsBackup((unsigned long long)LoadBackup(radioData
, eeprom
, eeprom_size
, 0));
344 if (!errorsBackup
.test(ALL_OK
)) {
345 ShowEepromErrors(this, tr("Error"), tr("Invalid binary EEPROM File %1").arg(fileName
), (errorsEeprom
| errorsBackup
).to_ulong());
348 if (errorsBackup
.test(HAS_WARNINGS
)) {
349 ShowEepromWarnings(this, tr("Warning"), errorsBackup
.to_ulong());
351 } else if (errorsEeprom
.test(HAS_WARNINGS
)) {
352 ShowEepromWarnings(this, tr("Warning"), errorsEeprom
.to_ulong());
355 ui
->modelsList
->refreshList();
356 if(resetCurrentFile
) setCurrentFile(fileName
);
365 bool MdiChild::save()
371 return saveFile(curFile
);
375 bool MdiChild::saveAs(bool isNew
)
378 if (IS_SKY9X(GetEepromInterface()->getBoard())) {
379 curFile
.replace(".eepe", ".bin");
380 QFileInfo
fi(curFile
);
382 fileName
= QFileDialog::getSaveFileName(this, tr("Save As"), g
.eepromDir() + "/" +fi
.fileName());
384 fileName
= QFileDialog::getSaveFileName(this, tr("Save As"), g
.eepromDir() + "/" +fi
.fileName(), tr(BIN_FILES_FILTER
));
388 QFileInfo
fi(curFile
);
390 fileName
= QFileDialog::getSaveFileName(this, tr("Save As"), g
.eepromDir() + "/" +fi
.fileName());
392 fileName
= QFileDialog::getSaveFileName(this, tr("Save As"), g
.eepromDir() + "/" +fi
.fileName(), tr(EEPROM_FILES_FILTER
));
395 if (fileName
.isEmpty())
397 g
.eepromDir( QFileInfo(fileName
).dir().absolutePath() );
399 return saveFile(fileName
);
401 return saveFile(fileName
,true);
404 bool MdiChild::saveFile(const QString
&fileName
, bool setCurrent
)
408 if (IS_SKY9X(GetEepromInterface()->getBoard())) {
409 myFile
.replace(".eepe", ".bin");
413 int fileType
= getFileType(myFile
);
415 uint8_t *eeprom
= (uint8_t*)malloc(GetEepromInterface()->getEEpromSize());
418 if (fileType
!= FILE_TYPE_XML
) {
419 eeprom_size
= GetEepromInterface()->save(eeprom
, radioData
, GetCurrentFirmware()->getVariantNumber(), 0/*last version*/);
421 QMessageBox::warning(this, tr("Error"),tr("Cannot write file %1:\n%2.").arg(myFile
).arg(file
.errorString()));
426 if (!file
.open(fileType
== FILE_TYPE_BIN
? QIODevice::WriteOnly
: (QIODevice::WriteOnly
| QIODevice::Text
))) {
427 QMessageBox::warning(this, tr("Error"),tr("Cannot write file %1:\n%2.").arg(myFile
).arg(file
.errorString()));
431 QTextStream
outputStream(&file
);
434 if (fileType
==FILE_TYPE_XML
) {
435 if (!XmlInterface(outputStream
).save(radioData
)) {
436 QMessageBox::warning(this, tr("Error"),tr("Cannot write file %1:\n%2.").arg(myFile
).arg(file
.errorString()));
443 if (fileType
==FILE_TYPE_HEX
|| fileType
==FILE_TYPE_EEPE
) { // write hex
444 if (fileType
==FILE_TYPE_EEPE
)
445 outputStream
<< EEPE_EEPROM_FILE_HEADER
<< "\n";
447 if (!HexInterface(outputStream
).save(eeprom
, eeprom_size
)) {
448 QMessageBox::warning(this, tr("Error"),tr("Cannot write file %1:\n%2.").arg(myFile
).arg(file
.errorString()));
453 else if (fileType
==FILE_TYPE_BIN
) // write binary
455 long result
= file
.write((char*)eeprom
, eeprom_size
);
456 if(result
!=eeprom_size
) {
457 QMessageBox::warning(this, tr("Error"),tr("Error writing file %1:\n%2.").arg(myFile
).arg(file
.errorString()));
462 QMessageBox::warning(this, tr("Error"),tr("Error writing file %1:\n%2.").arg(myFile
).arg("Unknown format"));
466 free(eeprom
); // TODO free in all cases ...
468 if(setCurrent
) setCurrentFile(myFile
);
473 QString
MdiChild::userFriendlyCurrentFile()
475 return strippedName(curFile
);
478 void MdiChild::closeEvent(QCloseEvent
*event
)
488 void MdiChild::documentWasModified()
490 setWindowModified(fileChanged
);
493 bool MdiChild::maybeSave()
496 QMessageBox::StandardButton ret
;
497 ret
= QMessageBox::warning(this, tr("Companion"),
498 tr("%1 has been modified.\n"
499 "Do you want to save your changes?").arg(userFriendlyCurrentFile()),
500 QMessageBox::Save
| QMessageBox::Discard
| QMessageBox::Cancel
);
502 if (ret
== QMessageBox::Save
)
504 else if (ret
== QMessageBox::Cancel
)
510 void MdiChild::setCurrentFile(const QString
&fileName
)
512 curFile
= QFileInfo(fileName
).canonicalFilePath();
515 setWindowModified(false);
517 int MaxRecentFiles
= g
.historySize();
518 QStringList files
= g
.recentFiles();
519 files
.removeAll(fileName
);
520 files
.prepend(fileName
);
521 while (files
.size() > MaxRecentFiles
)
524 g
.recentFiles( files
);
527 QString
MdiChild::strippedName(const QString
&fullFileName
)
529 return QFileInfo(fullFileName
).fileName();
532 void MdiChild::writeEeprom() // write to Tx
534 QString tempFile
= generateProcessUniqueTempFileName("temp.bin");
535 saveFile(tempFile
, false);
536 if(!QFileInfo(tempFile
).exists()) {
537 QMessageBox::critical(this, tr("Error"), tr("Cannot write temporary file!"));
541 FlashEEpromDialog
*cd
= new FlashEEpromDialog(this, tempFile
);
545 void MdiChild::simulate()
547 if (getCurrentRow() > 0) {
548 startSimulation(this, radioData
, getCurrentRow()-1);
552 void MdiChild::print(int model
, QString filename
)
554 PrintDialog
* pd
= NULL
;
556 if (model
>=0 && !filename
.isEmpty()) {
557 pd
= new PrintDialog(this, GetCurrentFirmware()/*firmware*/, radioData
.generalSettings
, radioData
.models
[model
], filename
);
559 else if (getCurrentRow() > 0) {
560 pd
= new PrintDialog(this, GetCurrentFirmware()/*firmware*/, radioData
.generalSettings
, radioData
.models
[getCurrentRow()-1]);
564 pd
->setAttribute(Qt::WA_DeleteOnClose
, true);
569 void MdiChild::viableModelSelected(bool viable
)
571 emit
copyAvailable(viable
);
574 void MdiChild::setEEpromAvail(int eavail
)
579 int MdiChild::getCurrentRow() const
581 return ui
->modelsList
->currentRow();
584 bool MdiChild::loadBackup()
586 QString fileName
= QFileDialog::getOpenFileName(this, tr("Open backup Models and Settings file"), g
.eepromDir(),tr(EEPROM_FILES_FILTER
));
587 if (fileName
.isEmpty())
589 QFile
file(fileName
);
591 if (!file
.exists()) {
592 QMessageBox::critical(this, tr("Error"), tr("Unable to find file %1!").arg(fileName
));
595 if(getCurrentRow() < 1) return false;
596 int index
= getCurrentRow() - 1;
598 int eeprom_size
= file
.size();
599 if (!file
.open(QFile::ReadOnly
)) { //reading binary file - TODO HEX support
600 QMessageBox::critical(this, tr("Error"),
601 tr("Error opening file %1:\n%2.")
603 .arg(file
.errorString()));
606 QByteArray
eeprom(eeprom_size
, 0);
607 long result
= file
.read((char*)eeprom
.data(), eeprom_size
);
610 if (result
!= eeprom_size
) {
611 QMessageBox::critical(this, tr("Error"),
612 tr("Error reading file %1:\n%2.")
614 .arg(file
.errorString()));
619 std::bitset
<NUM_ERRORS
> errorsEeprom((unsigned long long)LoadBackup(radioData
, (uint8_t *)eeprom
.data(), eeprom_size
, index
));
620 if (!errorsEeprom
.test(ALL_OK
)) {
621 ShowEepromErrors(this, tr("Error"), tr("Invalid binary backup File %1").arg(fileName
), (errorsEeprom
).to_ulong());
624 if (errorsEeprom
.test(HAS_WARNINGS
)) {
625 ShowEepromWarnings(this, tr("Warning"), errorsEeprom
.to_ulong());
628 ui
->modelsList
->refreshList();