#include "buttonmanager.h" #include "ui_buttonmanager.h" #include "addnewwhat.h" #include "editsample.h" #include "sound.h" #include #include #include ButtonManager::ButtonManager(Config& conf, MainWindow* parent) : ConfigDialog(conf, parent), ui(new Ui::ButtonManager), mainW(parent) { ui->setupUi(this); loadConfig(); QStringList labels; labels.push_back("Name"); labels.push_back("Samples"); labels.push_back("Shortcut"); ui->buttonTreeWidget->setHeaderLabels(labels); ui->buttonTreeWidget->setColumnWidth(0, 420); ui->buttonTreeWidget->header()->setStretchLastSection(false); ui->buttonTreeWidget->header()->setSectionResizeMode(QHeaderView::ResizeToContents); QShortcut* sc = new QShortcut(QKeySequence(QKeySequence::Save), this); QObject::connect(sc, SIGNAL( activated() ), this, SLOT( saveChanges() )); } ButtonManager::~ButtonManager() { delete ui; } void ButtonManager::addButton() { AddNewWhat whatshouldbeadded(this); whatshouldbeadded.exec(); AddNewWhat::ReturnCode type = whatshouldbeadded.returnCode; if(type == AddNewWhat::ReturnCode::Row) { // create new row RowItem* row = addNewRow(); //select the new row select(row); return; } if(type == AddNewWhat::ReturnCode::Button) { //get row to create button in RowItem* row = getCurrentRow(); if(row) { //create new button in config row->getConfig().push_back({}); // create new button GUI ButtonItem* newButton = new ButtonItem(row, row->getConfig().size()-1, workingConfig); //select the new button select(newButton); // start editing ui->buttonTreeWidget->editItem(newButton, 0); } else { Log::error << "no row selected"; } return; } if(type == AddNewWhat::ReturnCode::Sample) { // create new sample ButtonItem* btn = getCurrentButton(); if(btn) { // button to add sample to exists -> start sample editor QFileDialog fileselector(this); fileselector.setFileMode(QFileDialog::ExistingFile); fileselector.setDirectory(QString::fromStdString(Sound::FOLDER)); fileselector.exec(); QStringList filelist = fileselector.selectedFiles(); if(filelist.size() != 1) { Log::error << "no file selected"; return; } else { QString qfile = filelist.at(0); std::string file = qfile.toStdString(); if(file.find(Sound::FOLDER) != 0) { Log::error << "file outside of " << Sound::FOLDER << " was selected, that is not allowed"; return; } file = file.substr(file.rfind('/')+1); // remove path; only keep filename Log::info << "selected file: " << file; //spawn edit dialog EditSample esample(file, this); esample.exec(); if(esample.result() == 0) { Log::info << "Dialog failed"; return; } // create sample Config::SampleConfig sample; sample.file = file; sample.offset = esample.getStartTime(); sample.length = esample.getLength(); sample.volume = 1.0f; btn->getConfig().samples.push_back(sample); // create SampleItem in GUI SampleItem* item = new SampleItem(btn, btn->getConfig().samples.size()-1, workingConfig); btn->setExpanded(true); select(item); } } else { Log::error << "no button selected"; } return; } } void ButtonManager::editButton() { perform<&ButtonManagerItem::edit>(); } void ButtonManager::deleteButton() { QTreeWidgetItem* currentSelectedItem = getSelectedItem(); perform<&ButtonManagerItem::remove>(); delete currentSelectedItem; } void ButtonManager::upButton() { QTreeWidgetItem* currentSelectedItem = getSelectedItem(); perform<&ButtonManagerItem::moveUp>(); select(currentSelectedItem); } void ButtonManager::downButton() { QTreeWidgetItem* currentSelectedItem = getSelectedItem(); perform<&ButtonManagerItem::moveDown>(); select(currentSelectedItem); } void ButtonManager::itemSelected() { Log::debug << "item selected"; ButtonManagerItem* item = getSelectedItem(); if(item) { // set buttons ui->editButton->setEnabled(item->hasEdit()); ui->deleteButton->setEnabled(item->hasRemove()); ui->moveUpButton->setEnabled(item->hasMoveUp()); ui->moveDownButton->setEnabled(item->hasMoveDown()); } else { Log::info << "no valid item selected"; ui->editButton->setEnabled(false); ui->deleteButton->setEnabled(false); ui->moveUpButton->setEnabled(false); ui->moveDownButton->setEnabled(false); } } void ButtonManager::itemChanged(QTreeWidgetItem* item, int column) { // only handle own items (should never trigger anyways) if(!dynamic_cast(item)) return; if(ButtonItem* button = dynamic_cast(item)) { if(column == 0) { // name button->nameWasChanged(); } else if(column == 2) { //shortcut button->keyWasChanged(); } } } void ButtonManager::itemDoubleClicked(QTreeWidgetItem* item) { if(SampleItem* sample = dynamic_cast(item)) { const Config::SampleConfig& sampleconf = sample->getConfig(); Sound::instance().addPlayback(sampleconf.file, sampleconf.volume, sampleconf.offset, sampleconf.length); } } void ButtonManager::saveChanges() { // store working config to main config and save ConfigDialog::saveChanges(); mainW->reloadButtonConfig(); } void ButtonManager::loadConfig() { ConfigDialog::loadConfig(); while(ui->buttonTreeWidget->invisibleRootItem()->childCount()) { auto kid = ui->buttonTreeWidget->invisibleRootItem()->takeChild(0); delete kid; } QTreeWidgetItem* root = ui->buttonTreeWidget->invisibleRootItem(); for(uint8_t rownr = 0; rownr < workingConfig.buttons.size(); ++rownr) { RowItem* row = new RowItem(root, rownr, workingConfig); (void) row; } } QDialogButtonBox* ButtonManager::getButtonBox() { return ui->buttonBox; } void ButtonManager::select(QTreeWidgetItem* item) { QList selected = ui->buttonTreeWidget->selectedItems(); for(QTreeWidgetItem* selectedItem : selected) { ui->buttonTreeWidget->setItemSelected(selectedItem, false); } ui->buttonTreeWidget->setItemSelected(item, true); } QTreeWidgetItem* ButtonManager::getSelectedItem() const { QList items = ui->buttonTreeWidget->selectedItems(); if(items.size() != 1) { return nullptr; // not exectly one selected } return items.at(0); } template T* ButtonManager::getSelectedItem() const { return dynamic_cast(getSelectedItem()); } RowItem* ButtonManager::getCurrentRow(bool create, bool onlyIfSelected) { QTreeWidgetItem* selectedItem = getSelectedItem(); // no item selected and its allowed to use alternative messures if(!selectedItem && !onlyIfSelected) { // no item selected // search for a empty row for(uint8_t rownr = 0; rownr < workingConfig.buttons.size(); ++rownr) { if(workingConfig.buttons.at(rownr).empty()) { //first empty row RowItem* row = dynamic_cast(ui->buttonTreeWidget->invisibleRootItem()->child(rownr)); if(row) return row; } } // no empty row -> create new row if(create) { return addNewRow(); } return nullptr; } // is current selected item a row? if(RowItem* row = dynamic_cast(selectedItem)) { return row; } // selected item is button -> take parent if(ButtonItem* button = dynamic_cast(selectedItem)) { return button->getParent(); } // selected item is sample -> take grand parent if(SampleItem* sample = dynamic_cast(selectedItem)) { if(ButtonItem* button = sample->getParent()) return button->getParent(); } return nullptr; } ButtonItem* ButtonManager::getCurrentButton(bool create) const { // currently unused (void) create; QTreeWidgetItem* selectedItem = getSelectedItem(); if(!selectedItem) { // no item selected //TODO: search for first empty button, create a new button return nullptr; } // is current selected item a button? if(ButtonItem* btn = dynamic_cast(selectedItem)) { return btn; } // a sample is selected -> use its parent if(SampleItem* sample = dynamic_cast(selectedItem)) { return sample->getParent(); } // a row is selected use the first empty button if(RowItem* row = dynamic_cast(selectedItem)) { // search for empty button in current row auto& rowConf = row->getConfig(); for(uint8_t buttonnr = 0; buttonnr < rowConf.size(); ++buttonnr) { if(rowConf.at(buttonnr).samples.empty()) { return row->getChild(buttonnr); } } } return nullptr; } RowItem* ButtonManager::addNewRow() { //TODO: when a row is selected: add after the selected row workingConfig.buttons.push_back({}); // create a empty vector RowItem* row = new RowItem(ui->buttonTreeWidget->invisibleRootItem(), workingConfig.buttons.size()-1, workingConfig); return row; } template void ButtonManager::perform() { ButtonManagerItem* item = getSelectedItem(); if(item) { (item->*T)(); } else { Log::info << "no valid item selected"; } }