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
= ui
->modelsList
->currentRow();
179 QApplication::setOverrideCursor(Qt::WaitCursor
);
180 checkAndInitModel( row
);
181 ModelData
&model
= radioData
.models
[row
- 1];
182 ModelEdit
*t
= new ModelEdit(this, radioData
, (row
- 1), GetCurrentFirmware()/*firmware*/);
183 t
->setWindowTitle(tr("Editing model %1: ").arg(row
) + model
.name
);
184 connect(t
, SIGNAL(modified()), this, SLOT(setModified()));
186 QApplication::restoreOverrideCursor();
190 void MdiChild::wizardEdit()
192 int row
= ui
->modelsList
->currentRow();
194 checkAndInitModel(row
);
195 WizardDialog
* wizard
= new WizardDialog(radioData
.generalSettings
, row
, this);
197 if (wizard
->mix
.complete
/*TODO rather test the exec() result?*/) {
198 radioData
.models
[row
- 1] = wizard
->mix
;
204 void MdiChild::openEditWindow()
206 int row
= ui
->modelsList
->currentRow();
211 ModelData
&model
= radioData
.models
[row
- 1];
212 if (model
.isempty() && g
.useWizard()) {
221 void MdiChild::newFile()
223 static int sequenceNumber
= 1;
226 curFile
= QString("document%1.eepe").arg(sequenceNumber
++);
230 bool MdiChild::loadFile(const QString
&fileName
, bool resetCurrentFile
)
232 QFile
file(fileName
);
234 if (!file
.exists()) {
235 QMessageBox::critical(this, tr("Error"), tr("Unable to find file %1!").arg(fileName
));
239 int fileType
= getFileType(fileName
);
242 if (fileType
==FILE_TYPE_XML
) {
243 if (!file
.open(QIODevice::ReadOnly
| QIODevice::Text
)) { //reading HEX TEXT file
244 QMessageBox::critical(this, tr("Error"),
245 tr("Error opening file %1:\n%2.")
247 .arg(file
.errorString()));
250 QTextStream
inputStream(&file
);
251 XmlInterface(inputStream
).load(radioData
);
255 if (fileType
==FILE_TYPE_HEX
|| fileType
==FILE_TYPE_EEPE
) { //read HEX file
256 if (!file
.open(QIODevice::ReadOnly
| QIODevice::Text
)) { //reading HEX TEXT file
257 QMessageBox::critical(this, tr("Error"),
258 tr("Error opening file %1:\n%2.")
260 .arg(file
.errorString()));
264 QDomDocument
doc(ER9X_EEPROM_FILE_TYPE
);
265 bool xmlOK
= doc
.setContent(&file
);
267 if (loadEEpromXml(radioData
, doc
)){
268 ui
->modelsList
->refreshList();
269 if(resetCurrentFile
) setCurrentFile(fileName
);
275 QTextStream
inputStream(&file
);
277 if (fileType
==FILE_TYPE_EEPE
) { // read EEPE file header
278 QString hline
= inputStream
.readLine();
279 if (hline
!=EEPE_EEPROM_FILE_HEADER
) {
285 QByteArray
eeprom(EESIZE_MAX
, 0);
286 int eeprom_size
= HexInterface(inputStream
).load((uint8_t *)eeprom
.data(), EESIZE_MAX
);
288 QMessageBox::critical(this, tr("Error"),
289 tr("Invalid EEPROM File %1")
297 if (!loadEEprom(radioData
, (uint8_t *)eeprom
.data(), eeprom_size
)) {
298 QMessageBox::critical(this, tr("Error"),
299 tr("Invalid EEPROM File %1")
304 ui
->modelsList
->refreshList();
305 if(resetCurrentFile
) setCurrentFile(fileName
);
309 else if (fileType
==FILE_TYPE_BIN
) { //read binary
310 int eeprom_size
= file
.size();
312 if (!file
.open(QFile::ReadOnly
)) { //reading binary file - TODO HEX support
313 QMessageBox::critical(this, tr("Error"),
314 tr("Error opening file %1:\n%2.")
316 .arg(file
.errorString()));
319 uint8_t *eeprom
= (uint8_t *)malloc(eeprom_size
);
320 memset(eeprom
, 0, eeprom_size
);
321 long result
= file
.read((char*)eeprom
, eeprom_size
);
324 if (result
!= eeprom_size
) {
325 QMessageBox::critical(this, tr("Error"),
326 tr("Error reading file %1:\n%2.")
328 .arg(file
.errorString()));
333 if (!loadEEprom(radioData
, eeprom
, eeprom_size
) && !::loadBackup(radioData
, eeprom
, eeprom_size
, 0)) {
334 QMessageBox::critical(this, tr("Error"),
335 tr("Invalid binary EEPROM File %1")
340 ui
->modelsList
->refreshList();
341 if(resetCurrentFile
) setCurrentFile(fileName
);
350 bool MdiChild::save()
356 return saveFile(curFile
);
360 bool MdiChild::saveAs(bool isNew
)
363 if (IS_SKY9X(GetEepromInterface()->getBoard())) {
364 curFile
.replace(".eepe", ".bin");
365 QFileInfo
fi(curFile
);
367 fileName
= QFileDialog::getSaveFileName(this, tr("Save As"), g
.eepromDir() + "/" +fi
.fileName());
369 fileName
= QFileDialog::getSaveFileName(this, tr("Save As"), g
.eepromDir() + "/" +fi
.fileName(), tr(BIN_FILES_FILTER
));
373 QFileInfo
fi(curFile
);
375 fileName
= QFileDialog::getSaveFileName(this, tr("Save As"), g
.eepromDir() + "/" +fi
.fileName());
377 fileName
= QFileDialog::getSaveFileName(this, tr("Save As"), g
.eepromDir() + "/" +fi
.fileName(), tr(EEPROM_FILES_FILTER
));
380 if (fileName
.isEmpty())
382 g
.eepromDir( QFileInfo(fileName
).dir().absolutePath() );
384 return saveFile(fileName
);
386 return saveFile(fileName
,true);
389 bool MdiChild::saveFile(const QString
&fileName
, bool setCurrent
)
393 if (IS_SKY9X(GetEepromInterface()->getBoard())) {
394 myFile
.replace(".eepe", ".bin");
398 int fileType
= getFileType(myFile
);
400 uint8_t *eeprom
= (uint8_t*)malloc(GetEepromInterface()->getEEpromSize());
403 if (fileType
!= FILE_TYPE_XML
) {
404 eeprom_size
= GetEepromInterface()->save(eeprom
, radioData
, GetCurrentFirmware()->getVariantNumber(), 0/*last version*/);
406 QMessageBox::warning(this, tr("Error"),tr("Cannot write file %1:\n%2.").arg(myFile
).arg(file
.errorString()));
411 if (!file
.open(fileType
== FILE_TYPE_BIN
? QIODevice::WriteOnly
: (QIODevice::WriteOnly
| QIODevice::Text
))) {
412 QMessageBox::warning(this, tr("Error"),tr("Cannot write file %1:\n%2.").arg(myFile
).arg(file
.errorString()));
416 QTextStream
outputStream(&file
);
419 if (fileType
==FILE_TYPE_XML
) {
420 if (!XmlInterface(outputStream
).save(radioData
)) {
421 QMessageBox::warning(this, tr("Error"),tr("Cannot write file %1:\n%2.").arg(myFile
).arg(file
.errorString()));
428 if (fileType
==FILE_TYPE_HEX
|| fileType
==FILE_TYPE_EEPE
) { // write hex
429 if (fileType
==FILE_TYPE_EEPE
)
430 outputStream
<< EEPE_EEPROM_FILE_HEADER
<< "\n";
432 if (!HexInterface(outputStream
).save(eeprom
, eeprom_size
)) {
433 QMessageBox::warning(this, tr("Error"),tr("Cannot write file %1:\n%2.").arg(myFile
).arg(file
.errorString()));
438 else if (fileType
==FILE_TYPE_BIN
) // write binary
440 long result
= file
.write((char*)eeprom
, eeprom_size
);
441 if(result
!=eeprom_size
) {
442 QMessageBox::warning(this, tr("Error"),tr("Error writing file %1:\n%2.").arg(myFile
).arg(file
.errorString()));
447 QMessageBox::warning(this, tr("Error"),tr("Error writing file %1:\n%2.").arg(myFile
).arg("Unknown format"));
451 free(eeprom
); // TODO free in all cases ...
453 if(setCurrent
) setCurrentFile(myFile
);
458 QString
MdiChild::userFriendlyCurrentFile()
460 return strippedName(curFile
);
463 void MdiChild::closeEvent(QCloseEvent
*event
)
473 void MdiChild::documentWasModified()
475 setWindowModified(fileChanged
);
478 bool MdiChild::maybeSave()
481 QMessageBox::StandardButton ret
;
482 ret
= QMessageBox::warning(this, tr("Companion"),
483 tr("%1 has been modified.\n"
484 "Do you want to save your changes?").arg(userFriendlyCurrentFile()),
485 QMessageBox::Save
| QMessageBox::Discard
| QMessageBox::Cancel
);
487 if (ret
== QMessageBox::Save
)
489 else if (ret
== QMessageBox::Cancel
)
495 void MdiChild::setCurrentFile(const QString
&fileName
)
497 curFile
= QFileInfo(fileName
).canonicalFilePath();
500 setWindowModified(false);
502 int MaxRecentFiles
= g
.historySize();
503 QStringList files
= g
.recentFiles();
504 files
.removeAll(fileName
);
505 files
.prepend(fileName
);
506 while (files
.size() > MaxRecentFiles
)
509 g
.recentFiles( files
);
512 QString
MdiChild::strippedName(const QString
&fullFileName
)
514 return QFileInfo(fullFileName
).fileName();
517 void MdiChild::writeEeprom() // write to Tx
519 QString tempFile
= generateProcessUniqueTempFileName("temp.bin");
520 saveFile(tempFile
, false);
521 if(!QFileInfo(tempFile
).exists()) {
522 QMessageBox::critical(this, tr("Error"), tr("Cannot write temporary file!"));
526 FlashEEpromDialog
*cd
= new FlashEEpromDialog(this, tempFile
);
530 void MdiChild::simulate()
532 if (ui
->modelsList
->currentRow() >= 1) {
533 startSimulation(this, radioData
, ui
->modelsList
->currentRow()-1);
537 void MdiChild::print(int model
, QString filename
)
539 PrintDialog
* pd
= NULL
;
541 if (model
>=0 && !filename
.isEmpty()) {
542 pd
= new PrintDialog(this, GetCurrentFirmware()/*firmware*/, &radioData
.generalSettings
, &radioData
.models
[model
], filename
);
544 else if (ui
->modelsList
->currentRow() > 0) {
545 pd
= new PrintDialog(this, GetCurrentFirmware()/*firmware*/, &radioData
.generalSettings
, &radioData
.models
[ui
->modelsList
->currentRow()-1]);
549 pd
->setAttribute(Qt::WA_DeleteOnClose
, true);
554 void MdiChild::viableModelSelected(bool viable
)
556 emit
copyAvailable(viable
);
559 void MdiChild::setEEpromAvail(int eavail
)
564 bool MdiChild::loadBackup()
566 QString fileName
= QFileDialog::getOpenFileName(this, tr("Open backup Models and Settings file"), g
.eepromDir(),tr(EEPROM_FILES_FILTER
));
567 if (fileName
.isEmpty())
569 QFile
file(fileName
);
571 if (!file
.exists()) {
572 QMessageBox::critical(this, tr("Error"), tr("Unable to find file %1!").arg(fileName
));
575 if(ui
->modelsList
->currentRow()<1) return false;
576 int index
=ui
->modelsList
->currentRow()-1;
578 int eeprom_size
= file
.size();
579 if (!file
.open(QFile::ReadOnly
)) { //reading binary file - TODO HEX support
580 QMessageBox::critical(this, tr("Error"),
581 tr("Error opening file %1:\n%2.")
583 .arg(file
.errorString()));
586 QByteArray
eeprom(eeprom_size
, 0);
587 long result
= file
.read((char*)eeprom
.data(), eeprom_size
);
590 if (result
!= eeprom_size
) {
591 QMessageBox::critical(this, tr("Error"),
592 tr("Error reading file %1:\n%2.")
594 .arg(file
.errorString()));
599 if (!::loadBackup(radioData
, (uint8_t *)eeprom
.data(), eeprom_size
, index
)) {
600 QMessageBox::critical(this, tr("Error"),
601 tr("Invalid binary backup File %1")
606 ui
->modelsList
->refreshList();