/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /*************************************************************************** * mainwindow.cc * * Tue Nov 10 10:21:04 CET 2009 * Copyright 2009 Bent Bisballe Nyeng * deva@aasimon.org ****************************************************************************/ /* * This file is part of DrumGizmo. * * DrumGizmo is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * DrumGizmo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with DrumGizmo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include "mainwindow.h" #include #include #include #include #include #include #include #include #include #include #include "settings.h" #include "projectdialog.h" #include "renderdialog.h" #include "channeldialog.h" #include "instrumentdialog.h" #include "projectserialiser.h" #include "instrumentwidget.h" #include "channelswidget.h" #include "aboutdialog.h" #include "imageeditor.h" #define MAXVAL 10000000L MainWindow::MainWindow(Settings& settings) : settings(settings) { tab_widget = new QTabWidget(); tab_widget->setTabsClosable(true); tab_widget->setMovable(true); connect(tab_widget, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int))); setCentralWidget(tab_widget); QMenu* fileMenu = menuBar()->addMenu(tr("&File")); QAction* act_new_project = new QAction(tr("&New Project"), this); fileMenu->addAction(act_new_project); connect(act_new_project, SIGNAL(triggered()), this, SLOT(newProject())); QAction* act_load_project = new QAction(tr("&Load Project..."), this); fileMenu->addAction(act_load_project); connect(act_load_project, SIGNAL(triggered()), this, SLOT(loadProject())); act_save_project = new QAction(tr("&Save Project"), this); act_save_project->setShortcut(QKeySequence::Save); fileMenu->addAction(act_save_project); connect(act_save_project, SIGNAL(triggered()), this, SLOT(saveProject())); QAction* act_save_project_as = new QAction(tr("Save Project As..."), this); fileMenu->addAction(act_save_project_as); connect(act_save_project_as, SIGNAL(triggered()), this, SLOT(saveProjectAs())); QAction* act_quit = new QAction(tr("&Quit"), this); fileMenu->addAction(act_quit); connect(act_quit, SIGNAL(triggered()), this, SLOT(close())); QMenu* projectMenu = menuBar()->addMenu(tr("&Project")); QAction* act_render = new QAction(tr("&Export..."), this); projectMenu->addAction(act_render); connect(act_render, SIGNAL(triggered()), this, SLOT(render())); QAction* act_edit_project = new QAction(tr("&Edit Project..."), this); projectMenu->addAction(act_edit_project); connect(act_edit_project, SIGNAL(triggered()), this, SLOT(editProject())); // QMenu* testMenu = menuBar()->addMenu(tr("Test")); // QAction* act_test = new QAction(tr("Test"), this); // testMenu->addAction(act_test); // connect(act_test, SIGNAL(triggered()), this, SLOT(test())); QMenu* helpMenu = menuBar()->addMenu(tr("Help")); QAction* act_about = new QAction(tr("About"), this); helpMenu->addAction(act_about); connect(act_about, SIGNAL(triggered()), this, SLOT(showAbout())); instruments_dock = new QDockWidget(tr("Instruments:"), this); instruments_dock->setObjectName("instruments_dock"); instruments_dock->setAllowedAreas(Qt::LeftDockWidgetArea); instruments_dock->setFeatures(QDockWidget::DockWidgetMovable); { auto w = new QWidget(); auto l = new QVBoxLayout(); w->setLayout(l); auto tools = new QToolBar(); auto add = new QToolButton(); add->setIcon(QPixmap(":icons/add_instrument.png")); connect(add, SIGNAL(clicked()), this, SLOT(addInstrument())); auto rem = new QToolButton(); rem->setIcon(QPixmap(":icons/remove_instrument.png")); connect(rem, SIGNAL(clicked()), this, SLOT(removeInstrument())); auto edt = new QToolButton(); edt->setIcon(QPixmap(":icons/edit_instrument.png")); connect(edt, SIGNAL(clicked()), this, SLOT(editInstrument())); tools->addWidget(add); tools->addWidget(rem); tools->addWidget(edt); instrument_list = new QListWidget(); connect(instrument_list, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(instrumentDoubleClicked(QListWidgetItem*))); l->addWidget(tools); l->addWidget(instrument_list); instruments_dock->setWidget(w); } addDockWidget(Qt::LeftDockWidgetArea, instruments_dock); channels_dock = new QDockWidget(tr("Kit channels:"), this); channels_dock->setObjectName("channels_dock"); channels_dock->setAllowedAreas(Qt::LeftDockWidgetArea); channels_dock->setFeatures(QDockWidget::DockWidgetMovable); { auto w = new QWidget(); auto l = new QVBoxLayout(); w->setLayout(l); auto tools = new QToolBar(); auto add = new QToolButton(); add->setIcon(QPixmap(":icons/add_channel.png")); connect(add, SIGNAL(clicked()), this, SLOT(addChannel())); auto rem = new QToolButton(); rem->setIcon(QPixmap(":icons/remove_channel.png")); connect(rem, SIGNAL(clicked()), this, SLOT(removeChannel())); tools->addWidget(add); tools->addWidget(rem); channel_list = new QListWidget(); connect(channel_list, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(channelDoubleClicked(QListWidgetItem*))); l->addWidget(tools); l->addWidget(channel_list); channels_dock->setWidget(w); addDockWidget(Qt::LeftDockWidgetArea, channels_dock); } loadSettings(); statusBar()->showMessage(tr("Ready")); connect(&project, SIGNAL(projectChanged()), this, SLOT(projectChanged())); updateWindowTitle(); setWindowEnabled(false); } MainWindow::~MainWindow() { } void MainWindow::addInstrument() { auto id = project.createInstrument(); auto& instrument = project.getInstrument(id); InstrumentDialog dlg(this, instrument); dlg.show(); dlg.exec(); auto item = new QListWidgetItem(); item->setIcon(QPixmap(":icons/instrument.png")); item->setText(instrument.getInstrumentName()); item->setData(Qt::UserRole, id); instrument_list->addItem(item); } void MainWindow::editInstrument() { auto items = instrument_list->selectedItems(); for(auto item : items) { auto id = item->data(Qt::UserRole).toInt(); auto& instrument = project.getInstrument(id); InstrumentDialog dlg(this, instrument); dlg.show(); dlg.exec(); item->setText(instrument.getInstrumentName()); // Also update tab name if open for(int i = 0; i < tab_widget->count(); ++i) { if(tab_widget->widget(i)->property("id").toInt() == id) { tab_widget->setTabText(i, instrument.getInstrumentName()); } } } } void MainWindow::removeInstrument() { int ret = QMessageBox::question(this, tr("Delete Instrument"), tr("Are you sure you want to delete the selected " "instrument(s)?"), QMessageBox::Yes | QMessageBox::Cancel); if(ret != QMessageBox::Yes) { return; } auto items = instrument_list->selectedItems(); for(auto item : items) { auto id = item->data(Qt::UserRole).toInt(); // Also close tab if open. for(int i = 0; i < tab_widget->count(); ++i) { if(tab_widget->widget(i)->property("id").toInt() == id) { tab_widget->removeTab(i); } } project.deleteInstrument(id); delete item; } } void MainWindow::instrumentDoubleClicked(QListWidgetItem *item) { int id = item->data(Qt::UserRole).toInt(); auto& instr = project.getInstrument(id); for(int i = 0; i < tab_widget->count(); ++i) { if(tab_widget->widget(i)->property("id").toInt() == id) { tab_widget->setCurrentIndex(i); return; } } // Tab wasn't open already. Create it. tab_widget->addTab(new InstrumentWidget(settings, instr), QPixmap(":icons/instrument.png"), instr.getInstrumentName()); // Make new tab active tab_widget->setCurrentIndex(tab_widget->count() - 1); } void MainWindow::addChannel() { auto id = project.createChannel(); auto& channel = project.getChannel(id); ChannelDialog dlg(this, channel); dlg.show(); dlg.exec(); auto item = new QListWidgetItem(); item->setIcon(QPixmap(":icons/channel.png")); item->setData(Qt::UserRole, id); item->setText(channel.getChannelName()); channel_list->addItem(item); } void MainWindow::removeChannel() { int ret = QMessageBox::question(this, tr("Delete Channel"), tr("Are you sure you want to delete the selected " "channel(s)?"), QMessageBox::Yes | QMessageBox::Cancel); if(ret != QMessageBox::Yes) { return; } auto items = channel_list->selectedItems(); for(auto item : items) { auto id = item->data(Qt::UserRole).toInt(); auto instrument_ids = project.getInstrumentList(); for(auto instrument_id : instrument_ids) { auto& instrument = project.getInstrument(instrument_id); auto audiofile_ids = instrument.getAudioFileList(); for(auto audiofile_id : audiofile_ids) { auto& audiofile = instrument.getAudioFile(audiofile_id); if(audiofile.getChannelMapId() == id) { audiofile.setChannelMapId(-1); // Unset channel map } } } project.deleteChannel(id); delete item; } } void MainWindow::channelDoubleClicked(QListWidgetItem *item) { // Tab wasn't open already. Create it. tab_widget->addTab(new ChannelsWidget(settings, project), QPixmap(":icons/channel.png"), tr("Channels")); // Make new tab active tab_widget->setCurrentIndex(tab_widget->count() - 1); } void MainWindow::updateWindowTitle() { auto project_string = project.getProjectName(); if(project_string == "") { project_string = tr("[Untitled Project]"); } if(project.getProjectFile() != "") { project_string += " (" + QFileInfo(project.getProjectFile()).fileName() + ")"; } act_save_project->setEnabled(project.getProjectFile() != ""); if(project_dirty) { project_string += "*"; } setWindowTitle("DGEdit - " + project_string); } void MainWindow::closeEvent(QCloseEvent* event) { if(!checkDirty()) { event->ignore(); return; } saveSettings(); QApplication::quit(); } bool MainWindow::checkDirty() { if(project_dirty) { int ret = QMessageBox::question(this, tr("Save before closing project?"), tr("The project has changed. Do you want to save " "before closing?"), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel); switch(ret) { case QMessageBox::Yes: saveProject(); if(project_dirty) { // Project still dirty - it was not saved (user pressed cancel?) return false; } break; case QMessageBox::No: // Proceed to quit break; case QMessageBox::Cancel: return false; default: break; } } return true; // not dirty or user chose not to save } void MainWindow::reset() { // Close all tabs while(tab_widget->count()) { tab_widget->removeTab(0); } instrument_list->clear(); channel_list->clear(); project.reset(); updateWindowTitle(); } void MainWindow::setWindowEnabled(bool enabled) { instruments_dock->setEnabled(enabled); channels_dock->setEnabled(enabled); tab_widget->setEnabled(enabled); } void MainWindow::loadSettings() { QByteArray state; QByteArray geometry; settings.loadGeometry(state, geometry); restoreGeometry(geometry); restoreState(state); // TODO: lineed_exportp->setText(settings.loadExportPath()); } void MainWindow::saveSettings() { settings.saveGeometry(saveState(), saveGeometry()); // TODO: settings.saveExportPath(lineed_exportp->text()); } void MainWindow::newProject() { if(!checkDirty()) { return; } reset(); ProjectDialog dlg(this, project); dlg.show(); dlg.exec(); setWindowEnabled(true); } void MainWindow::loadProject() { if(!checkDirty()) { return; } QString filename = QFileDialog::getOpenFileName(this, tr("Load DGEdit Project"), "", tr("DGEdit Project Files (*.dgedit)")); if(filename == "") { // User clicked cancel return; } loadProject(filename); } void MainWindow::loadProject(QString filename) { QFile file(filename); if(!file.open(QIODevice::ReadOnly)) { return; } reset(); QString xml(file.readAll()); file.close(); ProjectSerialiser ser; ser.deserialise(xml, project); project.setProjectFile(filename); project_dirty = false; updateWindowTitle(); instrument_list->clear(); auto instrument_ids = project.getInstrumentList(); for(auto id : instrument_ids) { auto& instrument = project.getInstrument(id); auto item = new QListWidgetItem(); item->setIcon(QPixmap(":icons/instrument.png")); item->setText(instrument.getInstrumentName()); item->setData(Qt::UserRole, id); instrument_list->addItem(item); } channel_list->clear(); auto channel_ids = project.getChannelList(); for(auto id : channel_ids) { auto& channel = project.getChannel(id); auto item = new QListWidgetItem(); item->setIcon(QPixmap(":icons/channel.png")); item->setText(channel.getChannelName()); item->setData(Qt::UserRole, id); channel_list->addItem(item); } statusBar()->showMessage(tr("Loaded")); setWindowEnabled(true); } void MainWindow::saveProject() { QString filename = project.getProjectFile(); if(filename == "") { saveProjectAs(); return; } QFile file(filename); if(!file.open(QIODevice::WriteOnly)) { return; } ProjectSerialiser ser; auto xml = ser.serialise(project); file.write(xml.toUtf8()); project_dirty = false; updateWindowTitle(); statusBar()->showMessage(tr("Saved")); } void MainWindow::saveProjectAs() { QString filename = QFileDialog::getSaveFileName(this, tr("Save DGEdit Project"), "", tr("DGEdit Project Files (*.dgedit)")); if(filename == "") { // User clicked cancel return; } if(filename.right(7) != ".dgedit") { filename += ".dgedit"; } project.setProjectFile(filename); saveProject(); } void MainWindow::projectChanged() { project_dirty = true; updateWindowTitle(); } void MainWindow::closeTab(int tab) { tab_widget->removeTab(tab); } void MainWindow::test() { ImageEditor* e = new ImageEditor(nullptr); e->setImage("/mnt/atuin/misc/stuff/deva/CrocellKit/crocellkit01.png"); e->show(); } void MainWindow::render() { RenderDialog renderDialog(this, project); renderDialog.exec(); } void MainWindow::editProject() { ProjectDialog dlg(this, project); dlg.show(); dlg.exec(); } void MainWindow::showAbout() { AboutDialog dlg(this, Qt::Dialog); dlg.show(); dlg.exec(); }