// MainWindow class implementation // // QATSH Copyright 2009 Jean-Philippe MEURET #include #include #include #include #include #include #include #include #include "IATSAnalysis.h" #include "DocumentWindow.h" #include "PreferencesDialog.h" #include "AnalysisParamsDialog.h" #include "MainWindow.h" #include "ui_MainWindow.h" // Constructors / Destructor =============================================== MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { init(); } MainWindow::MainWindow(const QString &qsFileName, QWidget *parent) : QMainWindow(parent) { init(); if (QFileInfo(qsFileName).suffix().toLower() == "ats") loadFile(qsFileName); else analyseFile(qsFileName); } MainWindow::MainWindow(const QString &qsFileName, IATSAnalysis* pAnalysis, QWidget *parent) : QMainWindow(parent) { init(); analyseFile(qsFileName, pAnalysis); } void MainWindow::init() { _pui = new Ui::MainWindow; _pui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose); _pqwDocWin = 0; _bIsUntitled = true; setWindowTitle(QString("%1 %2").arg(qApp->applicationName()).arg(qApp->applicationVersion())); resize(QSize(640, 480)); // Connect actions to local slots. connect(_pui->qaNewFile, SIGNAL(triggered()), this, SLOT(newFile())); connect(_pui->qaOpenFile, SIGNAL(triggered()), this, SLOT(openFile())); connect(_pui->qaSaveFile, SIGNAL(triggered()), this, SLOT(saveFile())); connect(_pui->qaSaveFileAs, SIGNAL(triggered()), this, SLOT(saveFileAs())); connect(_pui->qaFileProperties, SIGNAL(triggered()), this, SLOT(showFileProperties())); connect(_pui->qaPreferences, SIGNAL(triggered()), this, SLOT(preferences())); connect(_pui->qaReAnalyse, SIGNAL(triggered()), this, SLOT(showAnalysisTool())); connect(_pui->qaReSynthesize, SIGNAL(triggered()), this, SLOT(showSynthesisTool())); connect(_pui->qaPlaySynthSound, SIGNAL(triggered()), this, SLOT(startPlayingSynthesisResult())); connect(_pui->qaWinPartials, SIGNAL(triggered()), this, SLOT(showPartialsSpectrogram())); connect(_pui->qaWinResidual, SIGNAL(triggered()), this, SLOT(showResidualsSpectrogram())); connect(_pui->qaZoomIn, SIGNAL(triggered()), this, SLOT(zoomIn())); connect(_pui->qaZoomOut, SIGNAL(triggered()), this, SLOT(zoomOut())); connect(_pui->qaZoomAll, SIGNAL(triggered()), this, SLOT(zoomAll())); connect(_pui->qaZoomSel, SIGNAL(triggered()), this, SLOT(zoomSelection())); connect(_pui->qaAbout, SIGNAL(triggered()), this, SLOT(about())); // Setup action list for enableAction() member function. _qlActions << _pui->qaNewFile << _pui->qaOpenFile << _pui->qaSaveFile << _pui->qaSaveFileAs << _pui->qaFileProperties << _pui->qaPreferences << _pui->qaReAnalyse << _pui->qaReSynthesize << _pui->qaWinPartials << _pui->qaWinResidual << _pui->qaAbout; // Disable some actions for the moment. enableAction(eSaveFile, false); enableAction(eSaveFileAs, false); enableAction(eFileProperties, false); enableAction(eReAnalyse, false); enableAction(eReSynthesize, false); enableAction(eWinPartials, false); enableAction(eWinResidual, false); } MainWindow::~MainWindow() { delete _pui; } // Private slots =========================================================== void MainWindow::enableAction(EActionId eActionId, bool bEnable) { if (eActionId >= 0 && eActionId < eActionNumber) _qlActions[eActionId]->setEnabled(bEnable); } void MainWindow::newFile() { const QString qsFileName = QFileDialog::getOpenFileName(this, tr("Choose a sound file"), "", // TODO: get from settings tr("Sound files " "(*.wav *.aif* *.au *.caf *.raw *.flac *.w64 " "*.voc *.snd *.sf *.pcm *.iff *.svx *.nist *.sph)")); if (!qsFileName.isEmpty()) analyseFile(qsFileName); } void MainWindow::openFile() { const QString qsFileName = QFileDialog::getOpenFileName(this, tr("Choose an ATS File"), "", // TODO: get path from settings tr("ATS files (*.ats)")); if (!qsFileName.isEmpty()) { QApplication::setOverrideCursor(Qt::WaitCursor); if (!_pqwDocWin) { loadFile(qsFileName); } else { MainWindow *pqmwNew = new MainWindow(qsFileName, (QWidget*)0); if (pqmwNew->isUntitled()) delete pqmwNew; else { pqmwNew->move(x() + 40, y() + 40); pqmwNew->show(); } } QApplication::restoreOverrideCursor(); } } bool MainWindow::saveFile() { if (isUntitled()) { return saveFileAs(); } else if (isWindowModified()) { return storeFile(_qsCurFileName); } return true; } bool MainWindow::saveFileAs() { const QString qsFileName = QFileDialog::getSaveFileName(this, tr("Save ATS file as"), _qsCurFileName); if (qsFileName.isEmpty()) return false; return storeFile(qsFileName); } void MainWindow::preferences() { PreferencesDialog prefsDlg(this); prefsDlg.exec(); } void MainWindow::showFileProperties() { if (_pqwDocWin) _pqwDocWin->showFileProperties(); } void MainWindow::showAnalysisTool() { if (_pqwDocWin) { if (_pui->qaReAnalyse->isChecked()) { _pqwDocWin->showAnalysisTool(); _pui->qaReSynthesize->setChecked(false); } else _pqwDocWin->showSelectionEditionTool(); } } void MainWindow::showSynthesisTool() { if (_pqwDocWin) { if (_pui->qaReSynthesize->isChecked()) { _pqwDocWin->showSynthesisTool(); _pui->qaReAnalyse->setChecked(false); } else _pqwDocWin->showSelectionEditionTool(); } } void MainWindow::startPlayingSynthesisResult() { if (_pqwDocWin) _pqwDocWin->onStartPlayingSynthesisResult(); } void MainWindow::showSelectionEditionTool() { if (_pqwDocWin) { _pui->qaReAnalyse->setChecked(false); _pui->qaReSynthesize->setChecked(false); _pqwDocWin->showSelectionEditionTool(); } } void MainWindow::showPartialsSpectrogram() { if (_pqwDocWin) { if (_pui->qaWinPartials->isChecked()) { _pqwDocWin->showGraphicalView(DocumentWindow::ePartialsSpectrogram); _pui->qaWinResidual->setChecked(false); } else // Inhibit user uncheck : he must click on qaWinResidual to do that _pui->qaWinPartials->setChecked(true); } } void MainWindow::showResidualsSpectrogram() { if (_pqwDocWin) { if (_pui->qaWinResidual->isChecked()) { _pqwDocWin->showGraphicalView(DocumentWindow::eResidualsSpectrogram); _pui->qaWinPartials->setChecked(false); } else // Inhibit user uncheck : he must click on qaWinPartials to do that _pui->qaWinResidual->setChecked(true); } } void MainWindow::zoomIn() { if (_pqwDocWin) _pqwDocWin->zoomIn(); } void MainWindow::zoomOut() { if (_pqwDocWin) _pqwDocWin->zoomOut(); } void MainWindow::zoomAll() { if (_pqwDocWin) _pqwDocWin->zoomAll(); } void MainWindow::zoomSelection() { if (_pqwDocWin) _pqwDocWin->zoomSelection(); } void MainWindow::undo() { statusBar()->showMessage(tr("Invoked Edit|Undo")); } void MainWindow::redo() { statusBar()->showMessage(tr("Invoked Edit|Redo")); } void MainWindow::about() { statusBar()->showMessage(tr("Invoked Help|About")); QMessageBox::about(this, tr("About %1").arg(qApp->applicationName()), tr("%1 %2\n\nA Qt 4 GUI for ATSA\n\n" "Copyright 2009 Jean-Philippe Meuret \n\n" "Based on ATSA library and heavily inspired from WATSH\n" "by Oscar Pablo Di Liscia / Pete Moss / Juan Pampin\n" "") .arg(qApp->applicationName()).arg(qApp->applicationVersion())); } // Private member functions =============================================== bool MainWindow::isUntitled() const { return _bIsUntitled; } bool MainWindow::maybeSave() { if (isWindowModified()) { QMessageBox::StandardButton ret; ret = QMessageBox::warning(this, qApp->applicationName(), tr("The document has been modified.\n" "Do you want to save your changes ?"), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); if (ret == QMessageBox::Save) return saveFile(); else if (ret == QMessageBox::Cancel) return false; } return true; } void MainWindow::setCurrentFile(const QString &qsFileName) { static int nNoNameDocNum = 1; _bIsUntitled = qsFileName.isEmpty(); if (_bIsUntitled) _qsCurFileName = tr("NoName%1.ats").arg(nNoNameDocNum++); else _qsCurFileName = QFileInfo(qsFileName).canonicalFilePath(); setWindowTitle(tr("%1[*] - %2 %3").arg(simpleFileName(_qsCurFileName)) .arg(qApp->applicationName()).arg(qApp->applicationVersion())); //setWindowModified(_bIsUntitled); } QString MainWindow::simpleFileName(const QString &qsFullFileName) { return QFileInfo(qsFullFileName).fileName(); } void MainWindow::layoutDocumentWindow(DocumentWindow* pqwDocWin) { QVBoxLayout* qvblMainLayout = new QVBoxLayout(_pui->qwCentralWidget); qvblMainLayout->setObjectName(QString::fromUtf8("qvblMainLayout")); qvblMainLayout->setContentsMargins(2, 2, 2, 2); qvblMainLayout->addWidget(pqwDocWin); } void MainWindow::analyseFile(const QString& qsFileName) { AnalysisParamsDialog anaParDlg(this); if (anaParDlg.exec() == QDialog::Accepted) { if (!_pqwDocWin) { analyseFile(qsFileName, anaParDlg.analysisParams()); } else { MainWindow *pqmwNew = new MainWindow(qsFileName, anaParDlg.analysisParams(), 0); pqmwNew->move(x() + 40, y() + 40); pqmwNew->show(); } } } void MainWindow::analyseFile(const QString &qsFileName, IATSAnalysis* pAnalysis) { layoutDocumentWindow(_pqwDocWin = new DocumentWindow(this)); statusBar()->showMessage(tr("Analysing file ...")); if (_pqwDocWin->analyseFile(qsFileName, pAnalysis)) { _pqwDocWin->show(); setCurrentFile(""); statusBar()->showMessage(tr("Analysis done"), 2000); } else { delete _pqwDocWin; _pqwDocWin = 0; statusBar()->showMessage(tr("Analysis failed"), 2000); QMessageBox::warning(this, qApp->applicationName(), tr("Analysis failed for file %1.").arg(qsFileName)); } } void MainWindow::loadFile(const QString &qsFileName) { layoutDocumentWindow(_pqwDocWin = new DocumentWindow(this)); statusBar()->showMessage(tr("Loading file ...")); if (_pqwDocWin->loadFile(qsFileName)) { _pqwDocWin->show(); setCurrentFile(qsFileName); statusBar()->showMessage(tr("File loaded"), 2000); } else { delete _pqwDocWin; _pqwDocWin = 0; statusBar()->showMessage(tr("Failed to load file"), 2000); QMessageBox::warning(this, qApp->applicationName(), tr("Could not load file %1.").arg(qsFileName)); } } bool MainWindow::storeFile(const QString &qsFileName) { bool bSavedOld = true; statusBar()->showMessage(tr("Saving file ...")); // Save old version of target file if present. QFile qfOut(qsFileName); if (qfOut.exists()) { QFile qfOldOut(qsFileName+"~"); if (qfOldOut.exists()) bSavedOld = qfOldOut.remove(); if (bSavedOld) bSavedOld = qfOut.rename(qfOldOut.fileName()); if (!bSavedOld) QMessageBox::warning(this, qApp->applicationName(), tr("Failed to save old %1 ;\ngiving up.").arg(qsFileName)); } bool bStored = bSavedOld; if (bSavedOld) { // Try and store data to the target file. QApplication::setOverrideCursor(Qt::WaitCursor); bStored = _pqwDocWin->storeFile(qsFileName); QApplication::restoreOverrideCursor(); if (bStored) { setCurrentFile(qsFileName); } else { QMessageBox::warning(this, qApp->applicationName(), tr("Could not write file %1 ;\n" "reverting to old version if any.").arg(qsFileName)); // If storing the new data failed, revert to old target file version. QFile qfOut(qsFileName); if (qfOut.exists()) { bool bRestoredOld = qfOut.remove(); QFile qfOldOut(qsFileName+"~"); if (bRestoredOld && qfOldOut.exists()) bRestoredOld = qfOldOut.rename(qfOut.fileName()); if (!bRestoredOld) QMessageBox::warning(this, qApp->applicationName(), tr("Failed to revert %1 to saved version.").arg(qsFileName)); } } } if (bStored) { statusBar()->showMessage(tr("File saved"), 2000); setWindowModified(false); } else { statusBar()->showMessage(tr("Failed to save file"), 2000); } return bStored; } void MainWindow::closeEvent(QCloseEvent *pqEvent) { // Ask user to save anything necessary if any. if (maybeSave()) pqEvent->accept(); else pqEvent->ignore(); // Save window size if something loaded/analysed. QSettings qSettings; if (_pqwDocWin) qSettings.setValue("Window/Size", size()); }