diff options
28 files changed, 1273 insertions, 1948 deletions
diff --git a/core/qmpmidioutfluid.cpp b/core/qmpmidioutfluid.cpp index 87c1207..649cb1c 100644 --- a/core/qmpmidioutfluid.cpp +++ b/core/qmpmidioutfluid.cpp @@ -12,6 +12,45 @@ qmpMidiOutFluid::~qmpMidiOutFluid() delete_fluid_settings(settings); settings=nullptr; } + +void qmpMidiOutFluid::registerOptions(qmpPluginAPI *coreapi) +{ + default_driver=-1; + fluid_settings_t *fsettings=new_fluid_settings(); + auto insert_driver=[](void* d,const char*,const char* driver)->void{ + qmpMidiOutFluid *me=static_cast<qmpMidiOutFluid*>(d); + me->drivers.push_back(std::string(driver)); +#ifdef WIN32 + if(std::string(driver)=="waveout") +#else + if(std::string(driver)=="pulseaudio") + me->default_driver=static_cast<int>(me->drivers.size()-1); +#endif + }; + fluid_settings_foreach_option(fsettings,"audio.driver",this,insert_driver); + delete_fluid_settings(fsettings); + coreapi->registerOptionEnumInt("Audio","Audio Driver","FluidSynth/AudioDriver",drivers,default_driver); + coreapi->registerOptionInt("Audio","Audio Buffer Size","FluidSynth/BufSize",64,8192, +#ifdef WIN32 + 512 +#else + 64 +#endif + ); + coreapi->registerOptionInt("Audio","Audio Buffer Count","FluidSynth/BufCnt",2,64, +#ifdef WIN32 + 8 +#else + 16 +#endif + ); + coreapi->registerOptionEnumInt("Audio","Sample Format","FluidSynth/SampleFormat",{"16bits","float"},0); + coreapi->registerOptionInt("Audio","Sample Rate","FluidSynth/SampleRate",8000,96000,48000); + coreapi->registerOptionInt("Audio","Max Polyphony","FluidSynth/Polyphony",1,65535,256); + coreapi->registerOptionInt("Audio","CPU Cores","FluidSynth/Threads",1,256,1); + coreapi->registerOptionBool("Audio","Auto Bank Select Mode","FluidSynth/AutoBS",true); + coreapi->registerOptionEnumInt("Audio","Bank Select Mode","FluidSynth/BankSelect",{"GM","GS","XG","MMA"},1); +} void qmpMidiOutFluid::deviceInit() { synth=new_fluid_synth(settings); diff --git a/core/qmpmidioutfluid.hpp b/core/qmpmidioutfluid.hpp index 9c84264..63963ee 100644 --- a/core/qmpmidioutfluid.hpp +++ b/core/qmpmidioutfluid.hpp @@ -25,10 +25,14 @@ class qmpMidiOutFluid:public qmpMidiOutDevice,public IFluidSettings fluid_audio_driver_t* adriver; std::vector<std::pair<uint16_t,std::string>> bnk; std::unordered_map<uint16_t,std::vector<std::string>> pst; + qmpPluginAPI* coreapi; + std::vector<std::string> drivers; + int default_driver=-1; void update_preset_list(); public: qmpMidiOutFluid(); ~qmpMidiOutFluid(); + void registerOptions(qmpPluginAPI *coreapi); void deviceInit(); void deviceDeinit(); void deviceDeinit(bool freshsettings); diff --git a/core/qmpmidiplay.hpp b/core/qmpmidiplay.hpp index 2fd81a0..f896338 100644 --- a/core/qmpmidiplay.hpp +++ b/core/qmpmidiplay.hpp @@ -125,6 +125,7 @@ class CMidiPlayer uint32_t isFinished(); void setResumed(); void setWaitVoice(bool wv); + void registerFluidOptions(qmpPluginAPI *coreapi); double getFtime(); void getCurrentTimeSignature(int *n,int *d); diff --git a/qmidiplayer-desktop/CMakeLists.txt b/qmidiplayer-desktop/CMakeLists.txt index 9d285c3..c34f258 100644 --- a/qmidiplayer-desktop/CMakeLists.txt +++ b/qmidiplayer-desktop/CMakeLists.txt @@ -13,6 +13,7 @@ set(qmpdesktop_SOURCES qmpplugin.hpp qmppresetselect.hpp qmpsettingswindow.hpp + qmpsettings.hpp main.cpp qdialskulpturestyle.cpp qmpchanneleditor.cpp @@ -28,6 +29,7 @@ set(qmpdesktop_SOURCES qmpplugin.cpp qmppresetselect.cpp qmpsettingswindow.cpp + qmpsettings.cpp qmpchanneleditor.ui qmpchannelswindow.ui qmpcustomizewindow.ui diff --git a/qmidiplayer-desktop/main.cpp b/qmidiplayer-desktop/main.cpp index 9f1d593..6bf21c0 100644 --- a/qmidiplayer-desktop/main.cpp +++ b/qmidiplayer-desktop/main.cpp @@ -37,6 +37,7 @@ int main(int argc,char **argv) QCoreApplication::setApplicationVersion(APP_VERSION); if(!qgetenv("QT_SCALE_FACTOR").length()&&!qgetenv("QT_SCREEN_SCALE_FACTORS").length()) QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + qSetMessagePattern("%{time} @ %{file} : %{line}, in %{function} : %{message}"); QApplication a(argc,argv); QTranslator qtTranslator; diff --git a/qmidiplayer-desktop/qmpchannelswindow.cpp b/qmidiplayer-desktop/qmpchannelswindow.cpp index 41f545e..0854e4c 100644 --- a/qmidiplayer-desktop/qmpchannelswindow.cpp +++ b/qmidiplayer-desktop/qmpchannelswindow.cpp @@ -236,8 +236,9 @@ qmpChannelsWindow::qmpChannelsWindow(QWidget *parent) : ui(new Ui::qmpChannelsWindow) { ui->setupUi(this); + mainwindow=qmpMainWindow::getInstance(); ui->tvChannels->setHorizontalHeader(new QHeaderView(Qt::Orientation::Horizontal)); - ui->tvChannels->setModel(chmodel=new qmpChannelsModel); + ui->tvChannels->setModel(chmodel=new qmpChannelsModel(ui->tvChannels)); ui->tvChannels->setItemDelegateForColumn(3,new qmpDeviceItemDelegate(false,ui->tvChannels)); ui->tvChannels->setAlternatingRowColors(true); ui->tvChannels->setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection); @@ -268,25 +269,6 @@ qmpChannelsWindow::qmpChannelsWindow(QWidget *parent) : emit this->noteOn(); } ,nullptr,false); - std::vector<std::string> devs=qmpMainWindow::getInstance()->getPlayer()->getMidiOutDevices(); - size_t devc=devs.size(); - std::set<std::string> devset; - for(auto dev:devs)devset.insert(dev); - std::string selecteddev; - for(auto setdev:qmpSettingsWindow::getSettingsIntf()->value("Midi/DevicePriority",QList<QVariant>{"Internal FluidSynth"}).toList()) - if(devset.find(setdev.toString().toStdString())!=devset.end()) - { - selecteddev=setdev.toString().toStdString(); - break; - } - for(int ch=0;ch<16;++ch) - { - for(size_t j=0;j<devc;++j) - { - if(selecteddev==devs[j]) - qmpMainWindow::getInstance()->getPlayer()->setChannelOutput(ch,j); - } - } qmpMainWindow::getInstance()->registerFunctionality( chnlf=new qmpChannelFunc(this), std::string("Channel"), @@ -295,42 +277,68 @@ qmpChannelsWindow::qmpChannelsWindow(QWidget *parent) : 0, true ); - if(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/ChnlW",QRect(-999,-999,999,999)).toRect()!=QRect(-999,-999,999,999)) - setGeometry(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/ChnlW",QRect(-999,-999,999,999)).toRect()); - if(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/ChnlWShown",0).toInt()) + if(mainwindow->getSettings()->getOptionRaw("DialogStatus/ChnlW",QRect(-999,-999,999,999)).toRect()!=QRect(-999,-999,999,999)) + setGeometry(mainwindow->getSettings()->getOptionRaw("DialogStatus/ChnlW",QRect(-999,-999,999,999)).toRect()); + if(mainwindow->getSettings()->getOptionRaw("DialogStatus/ChnlWShown",0).toInt()) {show();qmpMainWindow::getInstance()->setFuncState("Channel",true);} } void qmpChannelsWindow::showEvent(QShowEvent *event) { - if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt()) + if(mainwindow->getSettings()->getOptionBool("Behavior/DialogStatus")) { - qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/ChnlWShown",1); + mainwindow->getSettings()->setOptionRaw("DialogStatus/ChnlWShown",1); } - if(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/ChnlW",QRect(-999,-999,999,999)).toRect()!=QRect(-999,-999,999,999)) - setGeometry(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/ChnlW",QRect(-999,-999,999,999)).toRect()); + if(mainwindow->getSettings()->getOptionRaw("DialogStatus/ChnlW",QRect(-999,-999,999,999)).toRect()!=QRect(-999,-999,999,999)) + setGeometry(mainwindow->getSettings()->getOptionRaw("DialogStatus/ChnlW",QRect(-999,-999,999,999)).toRect()); event->accept(); } void qmpChannelsWindow::closeEvent(QCloseEvent *event) { - if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt()) + if(mainwindow->getSettings()->getOptionBool("Behavior/DialogStatus")) { - qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/ChnlW",geometry()); + mainwindow->getSettings()->setOptionRaw("DialogStatus/ChnlW",geometry()); } setVisible(false); - if(!qmpMainWindow::getInstance()->isFinalizing()&&qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt()) + if(!qmpMainWindow::getInstance()->isFinalizing()&&mainwindow->getSettings()->getOptionBool("Behavior/DialogStatus")) { - qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/ChnlWShown",0); + mainwindow->getSettings()->setOptionRaw("DialogStatus/ChnlWShown",0); } - qmpMainWindow::getInstance()->setFuncState("Channel",false); + mainwindow->setFuncState("Channel",false); event->accept(); } +void qmpChannelsWindow::selectDefaultDevice() +{ + std::string selecteddev; + std::vector<std::string> devs=mainwindow->getPlayer()->getMidiOutDevices(); + size_t devc=devs.size(); + std::set<std::string> devset; + for(auto dev:devs)devset.insert(dev); + QVariant *devpriov=static_cast<QVariant*>(qmpMainWindow::getInstance()->getSettings()->getOptionCustom("Midi/DevicePriority")); + QList<QVariant> devprio=devpriov->toList(); + delete devpriov; + for(auto &setdev:devprio) + if(devset.find(setdev.toString().toStdString())!=devset.end()) + { + selecteddev=setdev.toString().toStdString(); + break; + } + for(int ch=0;ch<16;++ch) + { + for(size_t j=0;j<devc;++j) + { + if(selecteddev==devs[j]) + mainwindow->getPlayer()->setChannelOutput(ch,j); + } + } +} + qmpChannelsWindow::~qmpChannelsWindow() { - qmpMainWindow::getInstance()->unregisterFunctionality("Channel"); - qmpMainWindow::getInstance()->getPlayer()->unregisterEventHandler(eh); + mainwindow->unregisterFunctionality("Channel"); + mainwindow->getPlayer()->unregisterEventHandler(eh); delete chnlf; delete chi;delete cha; delete ui; diff --git a/qmidiplayer-desktop/qmpchannelswindow.hpp b/qmidiplayer-desktop/qmpchannelswindow.hpp index 072f9d3..f78d032 100644 --- a/qmidiplayer-desktop/qmpchannelswindow.hpp +++ b/qmidiplayer-desktop/qmpchannelswindow.hpp @@ -20,6 +20,7 @@ namespace Ui { } class qmpChannelsWindow; +class qmpMainWindow; class qmpChannelFunc:public qmpFuncBaseIntf { @@ -78,6 +79,7 @@ class qmpChannelsWindow:public QWidget ~qmpChannelsWindow(); void showEvent(QShowEvent *event); void closeEvent(QCloseEvent *event); + void selectDefaultDevice(); public slots: void showChannelEditorWindow(int chid); void on_pbUnmute_clicked(); @@ -87,6 +89,7 @@ class qmpChannelsWindow:public QWidget void noteOn(); private: + qmpMainWindow* mainwindow; Ui::qmpChannelsWindow *ui; qmpPresetSelector *pselectw; qmpChannelEditor *ceditw; diff --git a/qmidiplayer-desktop/qmpcustomizewindow.cpp b/qmidiplayer-desktop/qmpcustomizewindow.cpp index a2ff19c..0ea3228 100644 --- a/qmidiplayer-desktop/qmpcustomizewindow.cpp +++ b/qmidiplayer-desktop/qmpcustomizewindow.cpp @@ -8,24 +8,11 @@ #include "qmpcustomizewindow.hpp" #include "ui_qmpcustomizewindow.h" -qmpCustomizeWindow::qmpCustomizeWindow(QWidget *parent) : +qmpCustomizeWindow::qmpCustomizeWindow(QWidget *parent): QDialog(parent), ui(new Ui::qmpCustomizeWindow) { ui->setupUi(this); - QSettings *s=qmpMainWindow::getInstance()->getSettingsWindow()->getSettingsIntf(); - QList<QVariant> defa={"FileInfo","Render","Panic","ReloadSynth"}; - QList<QVariant> defb={"Channel","Playlist","Effects","Visualization"}; - QList<QVariant> a=s->value("Behavior/Actions",QVariant(defa)).toList(); - QList<QVariant> b=s->value("Behavior/Toolbar",QVariant(defb)).toList(); - std::vector<std::string>& v=qmpMainWindow::getInstance()->getWidgets(1); - v.clear(); - for(int i=0;i<a.size();++i) - v.push_back(a[i].toString().toStdString()); - std::vector<std::string>& vv=qmpMainWindow::getInstance()->getWidgets(0); - vv.clear(); - for(int i=0;i<b.size();++i) - vv.push_back(b[i].toString().toStdString()); } qmpCustomizeWindow::~qmpCustomizeWindow() @@ -33,13 +20,14 @@ qmpCustomizeWindow::~qmpCustomizeWindow() delete ui; } -void qmpCustomizeWindow::launch(int w) +void qmpCustomizeWindow::load(void *data) { - show(); ui->lwAvail->clear(); ui->lwEnabled->clear(); - ow=w; - std::vector<std::string>& v=qmpMainWindow::getInstance()->getWidgets(w); + QList<QVariant> list=static_cast<QVariant*>(data)->toList(); + std::vector<std::string> v; + for(auto i:list) + v.push_back(i.toString().toStdString()); std::map<std::string,qmpFuncPrivate>& m=qmpMainWindow::getInstance()->getFunc(); std::set<std::string> s; for(auto i=v.begin();i!=v.end();++i) @@ -67,6 +55,16 @@ void qmpCustomizeWindow::launch(int w) } } +void *qmpCustomizeWindow::save() +{ + QList<QVariant> ret; + for(int i=0;i<ui->lwEnabled->count();++i) + { + ret.push_back(QVariant(ui->lwEnabled->item(i)->toolTip())); + } + return new QVariant(ret); +} + void qmpCustomizeWindow::on_tbAdd_clicked() { if(!ui->lwAvail->currentItem())return; @@ -82,21 +80,12 @@ void qmpCustomizeWindow::on_tbRemove_clicked() void qmpCustomizeWindow::on_buttonBox_accepted() { - std::vector<std::string>& v=qmpMainWindow::getInstance()->getWidgets(ow); - v.clear(); - QList<QVariant> ql; - for(int i=0;i<ui->lwEnabled->count();++i) - { - v.push_back(ui->lwEnabled->item(i)->toolTip().toStdString()); - ql.push_back(QVariant(ui->lwEnabled->item(i)->toolTip())); - } - QSettings *s=qmpMainWindow::getInstance()->getSettingsWindow()->getSettingsIntf(); - s->setValue(ow?"Behavior/Actions":"Behavior/Toolbar",ql); - qmpMainWindow::getInstance()->setupWidget(); + accept(); close(); } void qmpCustomizeWindow::on_buttonBox_rejected() { + reject(); close(); } diff --git a/qmidiplayer-desktop/qmpcustomizewindow.hpp b/qmidiplayer-desktop/qmpcustomizewindow.hpp index 0d0f529..321c22e 100644 --- a/qmidiplayer-desktop/qmpcustomizewindow.hpp +++ b/qmidiplayer-desktop/qmpcustomizewindow.hpp @@ -7,27 +7,24 @@ namespace Ui { class qmpCustomizeWindow; } -class qmpCustomizeWindow : public QDialog +class qmpCustomizeWindow:public QDialog { Q_OBJECT public: - explicit qmpCustomizeWindow(QWidget *parent = 0); + explicit qmpCustomizeWindow(QWidget *parent=nullptr); ~qmpCustomizeWindow(); - void launch(int w); + void load(void* data); + void* save(); private slots: void on_tbAdd_clicked(); - void on_tbRemove_clicked(); - void on_buttonBox_accepted(); - void on_buttonBox_rejected(); private: Ui::qmpCustomizeWindow *ui; - int ow; }; #endif // QMPCUSTOMIZEWINDOW_HPP diff --git a/qmidiplayer-desktop/qmpdeviceprioritydialog.cpp b/qmidiplayer-desktop/qmpdeviceprioritydialog.cpp index d26fb45..bf358d8 100644 --- a/qmidiplayer-desktop/qmpdeviceprioritydialog.cpp +++ b/qmidiplayer-desktop/qmpdeviceprioritydialog.cpp @@ -16,7 +16,6 @@ qmpDevicePriorityDialog::qmpDevicePriorityDialog(QWidget *parent) : ui->tvDevices->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeMode::ResizeToContents); ui->tvDevices->setSelectionBehavior(QAbstractItemView::SelectionBehavior::SelectRows); model->setHorizontalHeaderLabels({"E","Device","Connected?"}); - setdevs=qmpSettingsWindow::getSettingsIntf()->value("Midi/DevicePriority",QList<QVariant>{"Internal FluidSynth"}).toList(); } qmpDevicePriorityDialog::~qmpDevicePriorityDialog() @@ -30,6 +29,7 @@ void qmpDevicePriorityDialog::setupRegisteredDevices() auto conndevs=CMidiPlayer::getInstance()->getMidiOutDevices(); for(auto dev:conndevs) sconn.insert(dev); + model->removeRows(0,model->rowCount()); for(auto dev:setdevs) { QStandardItem *e=new QStandardItem; @@ -60,6 +60,21 @@ void qmpDevicePriorityDialog::setupRegisteredDevices() } } +void qmpDevicePriorityDialog::load(void *data) +{ + setdevs=static_cast<QVariant*>(data)->toList(); + setupRegisteredDevices(); +} + +void *qmpDevicePriorityDialog::save() +{ + QList<QVariant> ret; + for(int i=0;i<model->rowCount();++i) + if(model->item(i,0)->checkState()==Qt::CheckState::Checked) + ret.push_back(model->item(i,1)->text()); + return new QVariant(ret); +} + void qmpDevicePriorityDialog::on_pbUp_clicked() { const QModelIndex &idx=ui->tvDevices->selectionModel()->currentIndex(); @@ -88,9 +103,10 @@ void qmpDevicePriorityDialog::on_pbDown_clicked() void qmpDevicePriorityDialog::on_buttonBox_accepted() { - QList<QVariant> setdevs; - for(int i=0;i<model->rowCount();++i) - if(model->item(i,0)->checkState()==Qt::CheckState::Checked) - setdevs.push_back(model->item(i,1)->text()); - qmpSettingsWindow::getSettingsIntf()->setValue("Midi/DevicePriority",setdevs); + accept(); +} + +void qmpDevicePriorityDialog::on_buttonBox_rejected() +{ + reject(); } diff --git a/qmidiplayer-desktop/qmpdeviceprioritydialog.hpp b/qmidiplayer-desktop/qmpdeviceprioritydialog.hpp index d48a2aa..78ce3fa 100644 --- a/qmidiplayer-desktop/qmpdeviceprioritydialog.hpp +++ b/qmidiplayer-desktop/qmpdeviceprioritydialog.hpp @@ -9,24 +9,28 @@ namespace Ui { class qmpDevicePriorityDialog; } -class qmpDevicePriorityDialog : public QDialog +class qmpDevicePriorityDialog:public QDialog { Q_OBJECT public: explicit qmpDevicePriorityDialog(QWidget *parent=nullptr); ~qmpDevicePriorityDialog(); - void setupRegisteredDevices(); + void load(void* data); + void* save(); private slots: void on_pbUp_clicked(); void on_pbDown_clicked(); void on_buttonBox_accepted(); -private: + void on_buttonBox_rejected(); + + private: Ui::qmpDevicePriorityDialog *ui; QStandardItemModel *model; QList<QVariant> setdevs; + void setupRegisteredDevices(); }; #endif // QMPDEVICEPRIORITYDIALOG_HPP diff --git a/qmidiplayer-desktop/qmpdevpropdialog.cpp b/qmidiplayer-desktop/qmpdevpropdialog.cpp index 64c385d..3b9ccc4 100644 --- a/qmidiplayer-desktop/qmpdevpropdialog.cpp +++ b/qmidiplayer-desktop/qmpdevpropdialog.cpp @@ -21,15 +21,19 @@ qmpDevPropDialog::qmpDevPropDialog(QWidget *parent) : this->ui->twProps->edit(ui->twProps->model()->index(r,c)); if(c==3) { - QString p=QFileDialog::getOpenFileUrl(this,"Select Device Initialization File",QUrl()).toLocalFile(); + QString p=QFileDialog::getOpenFileUrl(this,tr("Select Device Initialization File"),QUrl()).toLocalFile(); if(p.length())this->ui->twProps->item(r,2)->setText(p); } }); connect(ui->twProps,&QTableWidget::cellChanged,this,[this](int r,int c){ if(c!=0)return; - QString connst("Disconnected"); + QString connst(tr("Disconnected")); for(auto&ds:qmpMainWindow::getInstance()->getPlayer()->getMidiOutDevices()) - if(ui->twProps->item(r,c)->text()==QString::fromStdString(ds)){connst="Connected";break;} + if(ui->twProps->item(r,c)->text()==QString::fromStdString(ds)) + { + connst=tr("Connected"); + break; + } ui->twProps->item(r,1)->setText(connst); }); } @@ -39,16 +43,31 @@ qmpDevPropDialog::~qmpDevPropDialog() delete ui; } -void qmpDevPropDialog::launch() +void qmpDevPropDialog::load(void *data) { - QSettings *s=qmpSettingsWindow::getSettingsIntf(); + QList<QVariant> lst=static_cast<QVariant*>(data)->toList(); ui->twProps->clearContents(); ui->twProps->setRowCount(0); - s->beginGroup("DevInit"); - for(auto&k:s->allKeys()) - setupRow(k,s->value(k).toString()); - s->endGroup(); - show(); + for(auto&i:lst) + { + QPair<QString,QString> p=i.value<QPair<QString,QString>>(); + setupRow(p.first,p.second); + } +} + +void *qmpDevPropDialog::save() +{ + QList<QVariant> ret; + for(int i=0;i<ui->twProps->rowCount();++i) + { + QPair<QString,QString> p + { + ui->twProps->item(i,0)->text(), + ui->twProps->item(i,2)->text() + }; + ret.push_back(QVariant::fromValue(p)); + } + return new QVariant(ret); } void qmpDevPropDialog::on_pbAdd_clicked() @@ -74,7 +93,7 @@ void qmpDevPropDialog::setupRow(const QString&dn,const QString&din) ui->twProps->setItem(r,3,new QTableWidgetItem("...")); if(din.length())ui->twProps->item(r,2)->setText(din); cbx->setFlags(Qt::ItemFlag::ItemIsEnabled|Qt::ItemFlag::ItemIsSelectable); - cbx->setText("Disconnected"); + cbx->setText(tr("Disconnected")); ui->twProps->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeMode::ResizeToContents); if(dn.length()) { @@ -89,14 +108,10 @@ void qmpDevPropDialog::setupRow(const QString&dn,const QString&din) void qmpDevPropDialog::on_buttonBox_accepted() { - QSettings *s=qmpSettingsWindow::getSettingsIntf(); - s->beginGroup("DevInit"); - s->remove(""); - for(int i=0;i<ui->twProps->rowCount();++i) - { - s->setValue(ui->twProps->item(i,0)->text(), - ui->twProps->item(i,2)->text()); - } - s->endGroup(); - s->sync(); + accept(); +} + +void qmpDevPropDialog::on_buttonBox_rejected() +{ + reject(); } diff --git a/qmidiplayer-desktop/qmpdevpropdialog.hpp b/qmidiplayer-desktop/qmpdevpropdialog.hpp index cd0d150..e98aba9 100644 --- a/qmidiplayer-desktop/qmpdevpropdialog.hpp +++ b/qmidiplayer-desktop/qmpdevpropdialog.hpp @@ -9,12 +9,13 @@ class qmpDevPropDialog; class qmpDevPropDialog : public QDialog { - Q_OBJECT + Q_OBJECT public: explicit qmpDevPropDialog(QWidget *parent = nullptr); - void launch(); ~qmpDevPropDialog(); + void load(void* data); + void* save(); private slots: void on_pbAdd_clicked(); @@ -23,6 +24,8 @@ class qmpDevPropDialog : public QDialog void on_buttonBox_accepted(); + void on_buttonBox_rejected(); + private: Ui::qmpDevPropDialog *ui; void setupRow(const QString &dn="",const QString &din=""); diff --git a/qmidiplayer-desktop/qmpefxwindow.cpp b/qmidiplayer-desktop/qmpefxwindow.cpp index 631ccdb..f8731ba 100644 --- a/qmidiplayer-desktop/qmpefxwindow.cpp +++ b/qmidiplayer-desktop/qmpefxwindow.cpp @@ -12,19 +12,19 @@ qmpEfxWindow::qmpEfxWindow(QWidget *parent) : QList<QDial*> dials=findChildren<QDial*>(); for(int i=0;i<dials.count();++i) dials.at(i)->setStyle(styl); - QSettings *settings=qmpSettingsWindow::getSettingsIntf(); - ui->cbEnabledC->setChecked(settings->value("Effects/ChorusEnabled",1).toInt()); - ui->cbEnabledR->setChecked(settings->value("Effects/ReverbEnabled",1).toInt()); - rr=settings->value("Effects/ReverbRoom",0.2).toDouble(); - rd=settings->value("Effects/ReverbDamp",0.0).toDouble(); - rw=settings->value("Effects/ReverbWidth",0.5).toDouble(); - rl=settings->value("Effects/ReverbLevel",0.9).toDouble(); - - cfb=settings->value("Effects/ChorusFeedbk",3).toInt(); - cl=settings->value("Effects/ChorusLevel",2.0).toDouble(); - cr=settings->value("Effects/ChorusRate",0.3).toDouble(); - cd=settings->value("Effects/ChorusDepth",8.0).toDouble(); - ct=settings->value("Effects/ChorusType",FLUID_CHORUS_MOD_SINE).toInt(); + qmpSettings *settings=qmpMainWindow::getInstance()->getSettings(); + ui->cbEnabledC->setChecked(settings->getOptionRaw("Effects/ChorusEnabled",1).toInt()); + ui->cbEnabledR->setChecked(settings->getOptionRaw("Effects/ReverbEnabled",1).toInt()); + rr=settings->getOptionRaw("Effects/ReverbRoom",0.2).toDouble(); + rd=settings->getOptionRaw("Effects/ReverbDamp",0.0).toDouble(); + rw=settings->getOptionRaw("Effects/ReverbWidth",0.5).toDouble(); + rl=settings->getOptionRaw("Effects/ReverbLevel",0.9).toDouble(); + + cfb=settings->getOptionRaw("Effects/ChorusFeedbk",3).toInt(); + cl=settings->getOptionRaw("Effects/ChorusLevel",2.0).toDouble(); + cr=settings->getOptionRaw("Effects/ChorusRate",0.3).toDouble(); + cd=settings->getOptionRaw("Effects/ChorusDepth",8.0).toDouble(); + ct=settings->getOptionRaw("Effects/ChorusType",FLUID_CHORUS_MOD_SINE).toInt(); qmpMainWindow::getInstance()->registerFunctionality( efxf=new qmpEfxFunc(this), std::string("Effects"), @@ -33,9 +33,9 @@ qmpEfxWindow::qmpEfxWindow(QWidget *parent) : 0, true ); - if(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/EfxW",QRect(-999,-999,999,999)).toRect()!=QRect(-999,-999,999,999)) - setGeometry(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/EfxW",QRect(-999,-999,999,999)).toRect()); - if(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/EfxWShown",0).toInt()) + if(settings->getOptionRaw("DialogStatus/EfxW",QRect(-999,-999,999,999)).toRect()!=QRect(-999,-999,999,999)) + setGeometry(settings->getOptionRaw("DialogStatus/EfxW",QRect(-999,-999,999,999)).toRect()); + if(settings->getOptionRaw("DialogStatus/EfxWShown",0).toInt()) {show();qmpMainWindow::getInstance()->setFuncState("Effects",true);} } @@ -49,14 +49,15 @@ qmpEfxWindow::~qmpEfxWindow() void qmpEfxWindow::closeEvent(QCloseEvent *event) { - if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt()) + qmpSettings *settings=qmpMainWindow::getInstance()->getSettings(); + if(settings->getOptionBool("Behavior/DialogStatus")) { - qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/EfxW",geometry()); + settings->setOptionRaw("DialogStatus/EfxW",geometry()); } setVisible(false); - if(!qmpMainWindow::getInstance()->isFinalizing()&&qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt()) + if(!qmpMainWindow::getInstance()->isFinalizing()&&settings->getOptionBool("Behavior/DialogStatus")) { - qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/EfxWShown",0); + settings->setOptionRaw("DialogStatus/EfxWShown",0); } qmpMainWindow::getInstance()->setFuncState("Effects",false); event->accept(); @@ -83,11 +84,12 @@ void qmpEfxWindow::showEvent(QShowEvent *event) if(ct==FLUID_CHORUS_MOD_SINE)ui->rbSine->setChecked(true),ui->rbTriangle->setChecked(false); if(ct==FLUID_CHORUS_MOD_TRIANGLE)ui->rbSine->setChecked(false),ui->rbTriangle->setChecked(true); initialized=true; - if(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/EfxW",QRect(-999,-999,999,999)).toRect()!=QRect(-999,-999,999,999)) - setGeometry(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/EfxW",QRect(-999,-999,999,999)).toRect()); - if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt()) + qmpSettings *settings=qmpMainWindow::getInstance()->getSettings(); + if(settings->getOptionRaw("DialogStatus/EfxW",QRect(-999,-999,999,999)).toRect()!=QRect(-999,-999,999,999)) + setGeometry(settings->getOptionRaw("DialogStatus/EfxW",QRect(-999,-999,999,999)).toRect()); + if(settings->getOptionBool("Behavior/DialogStatus")) { - qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/EfxWShown",1); + settings->setOptionRaw("DialogStatus/EfxWShown",1); } event->accept(); } @@ -105,19 +107,19 @@ void qmpEfxWindow::sendEfxChange(void *_fs) fs->setReverbPara(ui->cbEnabledR->isChecked()?1:0,rr,rd,rw,rl); fs->setChorusPara(ui->cbEnabledC->isChecked()?1:0,cfb,cl,cr,cd,ct); - QSettings *settings=qmpSettingsWindow::getSettingsIntf(); - settings->setValue("Effects/ChorusEnabled",ui->cbEnabledC->isChecked()?1:0); - settings->setValue("Effects/ReverbEnabled",ui->cbEnabledR->isChecked()?1:0); - settings->setValue("Effects/ReverbRoom",rr); - settings->setValue("Effects/ReverbDamp",rd); - settings->setValue("Effects/ReverbWidth",rw); - settings->setValue("Effects/ReverbLevel",rl); - - settings->setValue("Effects/ChorusFeedbk",cfb); - settings->setValue("Effects/ChorusLevel",cl); - settings->setValue("Effects/ChorusRate",cr); - settings->setValue("Effects/ChorusDepth",cd); - settings->setValue("Effects/ChorusType",ct); + qmpSettings *settings=qmpMainWindow::getInstance()->getSettings(); + settings->setOptionRaw("Effects/ChorusEnabled",ui->cbEnabledC->isChecked()?1:0); + settings->setOptionRaw("Effects/ReverbEnabled",ui->cbEnabledR->isChecked()?1:0); + settings->setOptionRaw("Effects/ReverbRoom",rr); + settings->setOptionRaw("Effects/ReverbDamp",rd); + settings->setOptionRaw("Effects/ReverbWidth",rw); + settings->setOptionRaw("Effects/ReverbLevel",rl); + + settings->setOptionRaw("Effects/ChorusFeedbk",cfb); + settings->setOptionRaw("Effects/ChorusLevel",cl); + settings->setOptionRaw("Effects/ChorusRate",cr); + settings->setOptionRaw("Effects/ChorusDepth",cd); + settings->setOptionRaw("Effects/ChorusType",ct); } void qmpEfxWindow::dailValueChange() diff --git a/qmidiplayer-desktop/qmpinfowindow.cpp b/qmidiplayer-desktop/qmpinfowindow.cpp index d1485be..c0b8892 100644 --- a/qmidiplayer-desktop/qmpinfowindow.cpp +++ b/qmidiplayer-desktop/qmpinfowindow.cpp @@ -47,22 +47,22 @@ void qmpInfoWindow::updateInfo() { char str[256]; CMidiPlayer* player=qmpMainWindow::getInstance()->getPlayer(); - QSettings* settings=qmpSettingsWindow::getSettingsIntf(); + std::string textencoding=qmpMainWindow::getInstance()->getSettings()->getOptionEnumIntOptName("Midi/TextEncoding"); ui->lbFileName->setText(QString("File name: ")+qmpMainWindow::getInstance()->getFileName()); if(player->getTitle()) { - if(settings->value("Midi/TextEncoding","").toString()!="Unicode") + if(textencoding!="Unicode") ui->lbTitle->setText(QString("Title: ")+ - QTextCodec::codecForName(settings->value("Midi/TextEncoding","").toString().toStdString().c_str())->toUnicode(player->getTitle())); + QTextCodec::codecForName(textencoding.c_str())->toUnicode(player->getTitle())); else ui->lbTitle->setText(QString("Title: ")+player->getTitle()); } else ui->lbTitle->setText(QString("Title: ")); if(player->getCopyright()) { - if(settings->value("Midi/TextEncoding","").toString()!="Unicode") + if(textencoding!="Unicode") ui->lbCopyright->setText(QString("Copyright: ")+ - QTextCodec::codecForName(settings->value("Midi/TextEncoding","").toString().toStdString().c_str())->toUnicode(player->getCopyright())); + QTextCodec::codecForName(textencoding.c_str())->toUnicode(player->getCopyright())); else ui->lbCopyright->setText(QString("Copyright: ")+player->getCopyright()); } diff --git a/qmidiplayer-desktop/qmpmainwindow.cpp b/qmidiplayer-desktop/qmpmainwindow.cpp index 94185c7..d2a0e6b 100644 --- a/qmidiplayer-desktop/qmpmainwindow.cpp +++ b/qmidiplayer-desktop/qmpmainwindow.cpp @@ -39,7 +39,8 @@ qmpMainWindow::qmpMainWindow(QCommandLineParser *_clp,QWidget *parent): setButtonHeight(ui->pbNext,36);setButtonHeight(ui->pbPlayPause,36);setButtonHeight(ui->pbAdd,36); setButtonHeight(ui->pbPrev,36);setButtonHeight(ui->pbSettings,36);setButtonHeight(ui->pbStop,36); playing=false;stopped=true;dragging=false;fin=false; - settingsw=new qmpSettingsWindow(this); + settings.reset(new qmpSettings()); + settingsw=new qmpSettingsWindow(settings.get(),this); player=nullptr;timer=nullptr;fluidrenderer=nullptr; } @@ -71,32 +72,33 @@ qmpMainWindow::~qmpMainWindow() void qmpMainWindow::init() { - if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus",0).toInt()) - { - QRect g=qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/MainW",QRect(-999,-999,999,999)).toRect(); - if(g!=QRect(-999,-999,999,999))setGeometry(g); - }show(); - + show(); ui->centralWidget->setEnabled(false); + + pmgr=new qmpPluginManager(); + registerMidiOptions(); + std::future<void> f=std::async(std::launch::async, [this] { player=new CMidiPlayer(); + reloadsynf=new qmpReloadSynthFunc(this); + player->registerFluidOptions(pmgr->pluginAPI); + playerSetup(player->fluid()); + player->fluid()->deviceInit(); + loadSoundFont(player->fluid()); auto rtdev=qmpRtMidiManager::getDevices(); for(auto &i:rtdev) - { player->registerMidiOutDevice(i.first,i.second); - QString di=qmpSettingsWindow::getSettingsIntf()->value(QString("DevInit/%1").arg(QString::fromStdString(i.second)),"").toString(); - if(di.length())i.first->setInitializerFile(di.toUtf8().data()); - } - reloadsynf=new qmpReloadSynthFunc(this); - playerSetup(player->fluid());player->fluid()->deviceInit(); - loadSoundFont(player->fluid()); } ); while(f.wait_for(std::chrono::milliseconds(100))==std::future_status::timeout); ui->centralWidget->setEnabled(true); + settingsw->registerSoundFontOption(); + registerBehaviorOptions(); + settingsw->registerCustomizeWidgetOptions(); + plistw=new qmpPlistWindow(this); chnlw=new qmpChannelsWindow(this); efxw=new qmpEfxWindow(this); @@ -110,17 +112,45 @@ void qmpMainWindow::init() plistw->emptyList(); for(auto&i:argfiles)plistw->insertItem(i); } + + if(settings->getOptionBool("Behavior/DialogStatus")) + { + QRect g=settings->getOptionRaw("DialogStatus/MainW",QRect(-999,-999,999,999)).toRect(); + if(g!=QRect(-999,-999,999,999))setGeometry(g); + } + registerFunctionality(renderf,"Render",tr("Render to wave").toStdString(),getThemedIconc(":/img/render.svg"),0,false); registerFunctionality(panicf,"Panic",tr("Panic").toStdString(),getThemedIconc(":/img/panic.svg"),0,false); registerFunctionality(reloadsynf,"ReloadSynth",tr("Restart fluidsynth").toStdString(),getThemedIconc(":/img/repeat-base.svg"),0,false); - pmgr=new qmpPluginManager(); const QStringList &qpp=clp->values("plugin"); std::vector<std::string> pp; for(auto s:qpp) pp.push_back(s.toStdString()); pmgr->scanPlugins(pp); - settingsw->updatePluginList(pmgr);pmgr->initPlugins(); - ui->vsMasterVol->setValue(qmpSettingsWindow::getSettingsIntf()->value("Audio/Gain",50).toInt()); + settingsw->registerPluginOption(pmgr); + settingsw->updatePluginList(pmgr); + pmgr->initPlugins(); + + settingsw->registerExtraMidiOptions(); + + QVariant* dinif_v=static_cast<QVariant*>(settings->getOptionCustom("Midi/DeviceInitializationFiles")); + QList<QVariant> devinif_list=dinif_v->toList(); + delete dinif_v; + QMap<QString,QString> devinif_map; + for(auto &i:devinif_list) + { + QPair<QString,QString> p=i.value<QPair<QString,QString>>(); + devinif_map[p.first]=p.second; + } + auto rtdev=qmpRtMidiManager::getDevices(); + for(auto &i:rtdev) + { + if(devinif_map.contains(QString(i.second.c_str()))) + i.first->setInitializerFile(devinif_map[QString(i.second.c_str())].toStdString().c_str()); + } + chnlw->selectDefaultDevice(); + + ui->vsMasterVol->setValue(settings->getOptionRaw("Audio/Gain",50).toInt()); connect(timer,&QTimer::timeout,this,&qmpMainWindow::updateWidgets); connect(timer,&QTimer::timeout,infow,&qmpInfoWindow::updateInfo); ui->pbNext->setIcon(QIcon(getThemedIcon(":/img/next.svg"))); @@ -141,7 +171,7 @@ int qmpMainWindow::parseArgs() { if(QFileInfo(args.at(i)).exists()) { - if(loadfolder||qmpSettingsWindow::getSettingsIntf()->value("Behavior/LoadFolder",0).toInt()) + if(loadfolder||settings->getOptionBool("Behavior/LoadFolder")) { QDirIterator di(QFileInfo(args.at(i)).absolutePath()); while(di.hasNext()) @@ -159,9 +189,9 @@ int qmpMainWindow::parseArgs() void qmpMainWindow::closeEvent(QCloseEvent *event) { - if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt()) + if(settings->getOptionBool("Behavior/DialogStatus")) { - qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/MainW",geometry()); + settings->setOptionRaw("DialogStatus/MainW",geometry()); } on_pbStop_clicked();fin=true; for(auto i=mfunc.begin();i!=mfunc.end();++i) @@ -261,7 +291,7 @@ void qmpMainWindow::switchTrack(QString s) player->playerInit(); invokeCallback("main.start",nullptr); player->fluid()->setGain(ui->vsMasterVol->value()/250.);efxw->sendEfxChange(); - player->setWaitVoice(qmpSettingsWindow::getSettingsIntf()->value("Midi/WaitVoice",1).toInt()); + player->setWaitVoice(settings->getOptionBool("Midi/WaitVoice")); playerTh=new std::thread(&CMidiPlayer::playerThread,player); #ifdef _WIN32 SetThreadPriority((void*)playerTh->native_handle(),THREAD_PRIORITY_TIME_CRITICAL); @@ -271,61 +301,51 @@ void qmpMainWindow::switchTrack(QString s) } std::string qmpMainWindow::getTitle() { - if(!qmpSettingsWindow::getSettingsIntf())return ""; - if(qmpSettingsWindow::getSettingsIntf()->value("Midi/TextEncoding","").toString() - =="Unicode")return std::string(player->getTitle()); + if(settings->getOptionEnumIntOptName("Midi/TextEncoding")=="Unicode") + return std::string(player->getTitle()); return QTextCodec::codecForName( - qmpSettingsWindow::getSettingsIntf()->value("Midi/TextEncoding",""). - toString().toStdString().c_str())-> + settings->getOptionEnumIntOptName("Midi/TextEncoding").c_str())-> toUnicode(player->getTitle()).toStdString(); } std::wstring qmpMainWindow::getWTitle() { - if(!qmpSettingsWindow::getSettingsIntf())return L""; - if(qmpSettingsWindow::getSettingsIntf()->value("Midi/TextEncoding","").toString() - =="Unicode")return QString(player->getTitle()).toStdWString(); + if(settings->getOptionEnumIntOptName("Midi/TextEncoding")=="Unicode") + return QString(player->getTitle()).toStdWString(); return QTextCodec::codecForName( - qmpSettingsWindow::getSettingsIntf()->value("Midi/TextEncoding",""). - toString().toStdString().c_str())-> + settings->getOptionEnumIntOptName("Midi/TextEncoding").c_str())-> toUnicode(player->getTitle()).toStdWString(); } void qmpMainWindow::playerSetup(IFluidSettings* fs) { - QSettings* settings=qmpSettingsWindow::getSettingsIntf(); - fs->setOptStr("audio.driver",settings->value("Audio/Driver","").toString().toStdString().c_str()); - fs->setOptInt("audio.period-size",settings->value("Audio/BufSize","").toInt()); - fs->setOptInt("audio.periods",settings->value("Audio/BufCnt","").toInt()); - fs->setOptStr("audio.sample-format",settings->value("Audio/Format","").toString().toStdString().c_str()); - fs->setOptNum("synth.sample-rate",settings->value("Audio/Frequency","").toInt()); - fs->setOptInt("synth.polyphony",settings->value("Audio/Polyphony","").toInt()); - fs->setOptInt("synth.cpu-cores",settings->value("Audio/Threads","").toInt()); - char bsmode[4]; - if(settings->value("Audio/AutoBS",1).toInt()&&player->getFileStandard()) + fs->setOptStr("audio.driver",settings->getOptionEnumIntOptName("FluidSynth/AudioDriver").c_str()); + fs->setOptInt("audio.period-size",settings->getOptionInt("FluidSynth/BufSize")); + fs->setOptInt("audio.periods",settings->getOptionInt("FluidSynth/BufCnt")); + fs->setOptStr("audio.sample-format",settings->getOptionEnumIntOptName("FluidSynth/SampleFormat").c_str()); + fs->setOptNum("synth.sample-rate",settings->getOptionInt("FluidSynth/SampleRate")); + fs->setOptInt("synth.polyphony",settings->getOptionInt("FluidSynth/Polyphony")); + fs->setOptInt("synth.cpu-cores",settings->getOptionInt("FluidSynth/Threads")); + std::string bsmode; + if(settings->getOptionBool("FluidSynth/AutoBS")&&player->getFileStandard()) switch(player->getFileStandard()) { - case 1:strcpy(bsmode,"gm");break; - case 2:strcpy(bsmode,"mma");break; - case 3:strcpy(bsmode,"gs");break; - case 4:strcpy(bsmode,"xg");break; + case 1:bsmode="gm";break; + case 2:bsmode="mma";break; + case 3:bsmode="gs";break; + case 4:bsmode="xg";break; } else { - if(settings->value("Audio/BankSelect","CC#0").toString()==QString("Ignored")) - strcpy(bsmode,"gm"); - if(settings->value("Audio/BankSelect","CC#0").toString()==QString("CC#0")) - strcpy(bsmode,"gs"); - if(settings->value("Audio/BankSelect","CC#0").toString()==QString("CC#32")) - strcpy(bsmode,"xg"); - if(settings->value("Audio/BankSelect","CC#0").toString()==QString("CC#0*128+CC#32")) - strcpy(bsmode,"mma"); + bsmode=settings->getOptionEnumIntOptName("FluidSynth/BankSelect"); + std::transform(bsmode.begin(),bsmode.end(),bsmode.begin(),[](char i){return tolower(i);}); } - fs->setOptStr("synth.midi-bank-select",bsmode); - player->sendSysX(settings->value("Midi/SendSysEx",1).toInt()); + fs->setOptStr("synth.midi-bank-select",bsmode.c_str()); + player->sendSysX(settings->getOptionBool("Midi/SendSysEx")); } void qmpMainWindow::loadSoundFont(IFluidSettings *fs) { - QList<QVariant> sflist=settingsw->getSettingsIntf()->value("Audio/SoundFonts",QList<QVariant>{}).toList(); + QVariant *data=static_cast<QVariant*>(settings->getOptionCustom("FluidSynth/SoundFonts")); + QList<QVariant> sflist=data->toList(); for(auto i=sflist.rbegin();i!=sflist.rend();++i) { if(i->toString().startsWith('#'))continue; @@ -338,6 +358,7 @@ void qmpMainWindow::loadSoundFont(IFluidSettings *fs) fs->loadSFont(sf.toStdString().c_str()); #endif } + delete data; } int qmpMainWindow::loadFile(QString fns) { @@ -357,6 +378,23 @@ int qmpMainWindow::loadFile(QString fns) return ret; } +void qmpMainWindow::registerMidiOptions() +{ + settings->registerOptionBool("MIDI","Disable MIDI Mapping","Midi/DisableMapping",false); + settings->registerOptionBool("MIDI","Send system exclusive messages","Midi/SendSysEx",true); + settings->registerOptionBool("MIDI","Wait for remaining voice before stopping","Midi/WaitVoice",true); + settings->registerOptionEnumInt("MIDI","Text encoding","Midi/TextEncoding",{"Unicode","Big5","Big5-HKSCS","CP949","EUC-JP","EUC-KR","GB18030","KOI8-R","KOI8-U","Macintosh","Shift-JIS"},0); +} + +void qmpMainWindow::registerBehaviorOptions() +{ + settings->registerOptionBool("Behavior","Restore last playlist on startup","Behavior/RestorePlaylist",false); + settings->registerOptionBool("Behavior","Add files in the same folder to playlist","Behavior/LoadFolder",false); + settings->registerOptionBool("Behavior","Save dialog status","Behavior/DialogStatus",false); + settings->registerOptionBool("Behavior","Show labels beside icon in toolbar buttons","Behavior/ShowButtonLabel",false); + settings->registerOptionEnumInt("Behavior","Icon Theme","Behavior/IconTheme",{"Auto","Dark","Light"},0); +} + void qmpMainWindow::on_pbPlayPause_clicked() { playing=!playing; @@ -378,7 +416,7 @@ void qmpMainWindow::on_pbPlayPause_clicked() player->playerInit(); invokeCallback("main.start",nullptr); player->fluid()->setGain(ui->vsMasterVol->value()/250.);efxw->sendEfxChange(); - player->setWaitVoice(qmpSettingsWindow::getSettingsIntf()->value("Midi/WaitVoice",1).toInt()); + player->setWaitVoice(settings->getOptionBool("Midi/WaitVoice")); playerTh=new std::thread(&CMidiPlayer::playerThread,player); #ifdef _WIN32 SetThreadPriority((void*)playerTh->native_handle(),THREAD_PRIORITY_TIME_CRITICAL); @@ -461,7 +499,7 @@ void qmpMainWindow::playerSeek(uint32_t percentage) void qmpMainWindow::on_vsMasterVol_valueChanged() { if(!stopped)player->fluid()->setGain(ui->vsMasterVol->value()/250.); - qmpSettingsWindow::getSettingsIntf()->setValue("Audio/Gain",ui->vsMasterVol->value()); + settings->setOptionRaw("Audio/Gain",ui->vsMasterVol->value()); } void qmpMainWindow::on_pbStop_clicked() @@ -567,11 +605,11 @@ void qmpMainWindow::setFuncEnabled(std::string name,bool enable) bool qmpMainWindow::isDarkTheme() { - if(!qmpSettingsWindow::getSettingsIntf()->value("Behavior/IconTheme",0).toInt()) + if(!settings->getOptionEnumInt("Behavior/IconTheme")) { return ui->centralWidget->palette().color(QPalette::Background).lightness()<128; } - else return 2-qmpSettingsWindow::getSettingsIntf()->value("Behavior/IconTheme",0).toInt(); + else return 2-settings->getOptionEnumInt("Behavior/IconTheme"); } void qmpMainWindow::startRender() @@ -614,16 +652,26 @@ void qmpMainWindow::reloadSynth() ui->centralWidget->setEnabled(true); } -std::vector<std::string>& qmpMainWindow::getWidgets(int w) -{return w?enabled_actions:enabled_buttons;} std::map<std::string,qmpFuncPrivate>& qmpMainWindow::getFunc() {return mfunc;} void qmpMainWindow::setupWidget() { for(auto i=mfunc.begin();i!=mfunc.end();++i) - i->second.setAssignedControl((QReflectiveAction*)nullptr), - i->second.setAssignedControl((QReflectivePushButton*)nullptr); + { + i->second.setAssignedControl(static_cast<QReflectiveAction*>(nullptr)); + i->second.setAssignedControl(static_cast<QReflectivePushButton*>(nullptr)); + } + QVariant *v=static_cast<QVariant*>(settings->getOptionCustom("Behavior/Toolbar")); + enabled_buttons.clear(); + for(auto i:v->toList()) + enabled_buttons.push_back(i.toString().toStdString()); + delete v; + v=static_cast<QVariant*>(settings->getOptionCustom("Behavior/Actions")); + enabled_actions.clear(); + for(auto i:v->toList()) + enabled_actions.push_back(i.toString().toStdString()); + delete v; QList<QWidget*>w=ui->buttonwidget->findChildren<QWidget*>("",Qt::FindDirectChildrenOnly); qDeleteAll(w); QList<QAction*>a=ui->lbFileName->actions(); @@ -641,7 +689,8 @@ void qmpMainWindow::setupWidget() enabled_buttons[i] ); setButtonHeight(pb,32); - if(getSettingsWindow()->getSettingsIntf()->value("Behavior/ShowButtonLabel",0).toInt()) + //!!TODO + if(settings->getOptionBool("Behavior/ShowButtonLabel")) { pb->setText(tr(mfunc[enabled_buttons[i]].desc().c_str())); pb->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed); diff --git a/qmidiplayer-desktop/qmpmainwindow.hpp b/qmidiplayer-desktop/qmpmainwindow.hpp index c8f3827..700b501 100644 --- a/qmidiplayer-desktop/qmpmainwindow.hpp +++ b/qmidiplayer-desktop/qmpmainwindow.hpp @@ -141,7 +141,7 @@ class qmpMainWindow:public QMainWindow void dragEnterEvent(QDragEnterEvent *event); ~qmpMainWindow(); CMidiPlayer* getPlayer(){return player;} - qmpSettingsWindow* getSettingsWindow(){return settingsw;} + qmpSettings* getSettings(){return settings.get();} QTimer* getTimer(){return timer;} bool isFinalizing(){return fin;} QString getFileName(); @@ -163,7 +163,6 @@ class qmpMainWindow:public QMainWindow void reloadSynth(); void setupWidget(); void invokeCallback(std::string cat,void *callerdat); - std::vector<std::string>& getWidgets(int w); std::map<std::string,qmpFuncPrivate>& getFunc(); private slots: @@ -200,8 +199,9 @@ class qmpMainWindow:public QMainWindow QPointer<qmpChannelsWindow> chnlw; QPointer<qmpEfxWindow> efxw; QPointer<qmpInfoWindow> infow; - QPointer<qmpSettingsWindow> settingsw; QPointer<qmpHelpWindow> helpw; + std::unique_ptr<qmpSettings> settings; + QPointer<qmpSettingsWindow> settingsw; std::map<std::string,qmpFuncPrivate> mfunc; std::unordered_map<std::string,std::map<int,std::pair<qmpCallBack,void*>>> muicb; qmpRenderFunc* renderf; @@ -215,6 +215,8 @@ class qmpMainWindow:public QMainWindow void playerSetup(IFluidSettings *fs); void loadSoundFont(IFluidSettings *fs); int loadFile(QString fns); + void registerMidiOptions(); + void registerBehaviorOptions(); private: static qmpMainWindow* ref; diff --git a/qmidiplayer-desktop/qmpplistwindow.cpp b/qmidiplayer-desktop/qmpplistwindow.cpp index b4b0c02..5b46fb6 100644 --- a/qmidiplayer-desktop/qmpplistwindow.cpp +++ b/qmidiplayer-desktop/qmpplistwindow.cpp @@ -12,7 +12,7 @@ #include "qmpmainwindow.hpp" #define setButtonHeight(x,h) {x->setMaximumHeight(h*(logicalDpiY()/96.));x->setMinimumHeight(h*(logicalDpiY()/96.));} -qmpPlistWindow::qmpPlistWindow(QWidget *parent) : +qmpPlistWindow::qmpPlistWindow(QWidget *parent): QWidget(parent,Qt::Dialog), ui(new Ui::qmpPlistWindow) { @@ -23,12 +23,13 @@ qmpPlistWindow::qmpPlistWindow(QWidget *parent) : setButtonHeight(ui->pbSave,36);setButtonHeight(ui->pbShuffle,36); connect(this,&qmpPlistWindow::selectionChanging,(qmpMainWindow*)parent,&qmpMainWindow::selectionChanged); repeat=0;shuffle=0; - if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/RestorePlaylist","").toInt()) + settings=qmpMainWindow::getInstance()->getSettings(); + if(settings->getOptionBool("Behavior/RestorePlaylist")) { QSettings* plist=new QSettings(QStandardPaths::writableLocation(QStandardPaths::StandardLocation::ConfigLocation)+QString("/qmpplist"), QSettings::IniFormat); int fc=plist->value("Playlist/FileCount",0).toInt(); - ui->lwFiles->clear();for(int i=1;i<=fc;++i) + ui->lwFiles->clear();for(int i=0;i<fc;++i) ui->lwFiles->addItem(plist->value("Playlist/File"+QString("%1").arg(i,5,10,QChar('0')),"").toString()); repeat=plist->value("Playlist/Repeat",0).toInt(); shuffle=plist->value("Playlist/Shuffle",0).toInt(); @@ -75,9 +76,9 @@ qmpPlistWindow::qmpPlistWindow(QWidget *parent) : 0, true ); - if(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/PListW",QRect(-999,-999,999,999)).toRect()!=QRect(-999,-999,999,999)) - setGeometry(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/PListW",QRect(-999,-999,999,999)).toRect()); - if(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/PListWShown",0).toInt()) + if(settings->getOptionRaw("DialogStatus/PListW",QRect(-999,-999,999,999)).toRect()!=QRect(-999,-999,999,999)) + setGeometry(settings->getOptionRaw("DialogStatus/PListW",QRect(-999,-999,999,999)).toRect()); + if(settings->getOptionRaw("DialogStatus/PListWShown",0).toInt()) {show();qmpMainWindow::getInstance()->setFuncState("Playlist",true);} } @@ -90,35 +91,35 @@ qmpPlistWindow::~qmpPlistWindow() void qmpPlistWindow::showEvent(QShowEvent *event) { - if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt()) + if(settings->getOptionBool("Behavior/DialogStatus")) { - qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/PListWShown",1); + settings->setOptionRaw("DialogStatus/PListWShown",1); } - if(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/PListW",QRect(-999,-999,999,999)).toRect()!=QRect(-999,-999,999,999)) - setGeometry(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/PListW",QRect(-999,-999,999,999)).toRect()); + if(settings->getOptionRaw("DialogStatus/PListW",QRect(-999,-999,999,999)).toRect()!=QRect(-999,-999,999,999)) + setGeometry(settings->getOptionRaw("DialogStatus/PListW",QRect(-999,-999,999,999)).toRect()); event->accept(); } void qmpPlistWindow::closeEvent(QCloseEvent *event) { - if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt()) + if(settings->getOptionBool("Behavior/DialogStatus")) { - qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/PListW",geometry()); + settings->setOptionRaw("DialogStatus/PListW",geometry()); } setVisible(false); if(!qmpMainWindow::getInstance()->isFinalizing()) while(ui->lwFiles->count()>1)delete ui->lwFiles->item(0); - if(!qmpMainWindow::getInstance()->isFinalizing()&&qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt()) + if(!qmpMainWindow::getInstance()->isFinalizing()&&settings->getOptionBool("Behavior/DialogStatus")) { - qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/PListWShown",0); + settings->setOptionRaw("DialogStatus/PListWShown",0); } - if(qmpMainWindow::getInstance()->isFinalizing()&&qmpSettingsWindow::getSettingsIntf()->value("Behavior/RestorePlaylist","").toInt()) + if(qmpMainWindow::getInstance()->isFinalizing()&&settings->getOptionBool("Behavior/RestorePlaylist")) { QSettings* plist=new QSettings(QStandardPaths::writableLocation(QStandardPaths::StandardLocation::ConfigLocation)+QString("/qmpplist"), QSettings::IniFormat); plist->setValue("Playlist/FileCount",ui->lwFiles->count()); for(int i=0;i<ui->lwFiles->count();++i) - plist->setValue("Playlist/File"+QString("%1").arg(i+1,5,10,QChar('0')),ui->lwFiles->item(i)->text()); + plist->setValue("Playlist/File"+QString("%1").arg(i,5,10,QChar('0')),ui->lwFiles->item(i)->text()); plist->setValue("Playlist/Repeat",repeat); plist->setValue("Playlist/Shuffle",shuffle); plist->sync(); @@ -158,16 +159,16 @@ void qmpPlistWindow::insertItems(QStringList il) int qmpPlistWindow::on_pbAdd_clicked() { QStringList sl; - if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt()) - sl=QFileDialog::getOpenFileNames(this,"Add File",qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/FileDialogPath","").toString(),"Midi files (*.mid *.midi)"); + if(settings->getOptionBool("Behavior/DialogStatus")) + sl=QFileDialog::getOpenFileNames(this,"Add File",settings->getOptionRaw("DialogStatus/FileDialogPath","").toString(),"Midi files (*.mid *.midi)"); else sl=QFileDialog::getOpenFileNames(this,"Add File","","Midi files (*.mid *.midi *.rmi)"); if(sl.empty())return 0; for(int i=0;i<sl.size();++i) ui->lwFiles->addItem(new QListWidgetItem(sl.at(i))); if(!isVisible())while(ui->lwFiles->count()>1)delete ui->lwFiles->item(0); - if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt()) - qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/FileDialogPath", + if(settings->getOptionBool("Behavior/DialogStatus")) + settings->setOptionRaw("DialogStatus/FileDialogPath", QUrl(sl.at(0)).toString(QUrl::RemoveFilename)); return 1; } @@ -293,7 +294,7 @@ void qmpPlistWindow::on_pbSave_clicked() QSettings::IniFormat); plist->setValue("Playlist/FileCount",ui->lwFiles->count()); for(int i=0;i<ui->lwFiles->count();++i) - plist->setValue("Playlist/File"+QString("%1").arg(i+1,5,10,QChar('0')),ui->lwFiles->item(i)->text()); + plist->setValue("Playlist/File"+QString("%1").arg(i,5,10,QChar('0')),ui->lwFiles->item(i)->text()); plist->setValue("Playlist/Repeat",repeat); plist->setValue("Playlist/Shuffle",shuffle); plist->sync(); @@ -306,7 +307,7 @@ void qmpPlistWindow::on_pbLoad_clicked() QSettings::IniFormat); int fc=plist->value("Playlist/FileCount",0).toInt(); if(!fc){delete plist;return;} - ui->lwFiles->clear();for(int i=1;i<=fc;++i) + ui->lwFiles->clear();for(int i=0;i<fc;++i) ui->lwFiles->addItem(plist->value("Playlist/File"+QString("%1").arg(i,5,10,QChar('0')),"").toString()); repeat=plist->value("Playlist/Repeat",0).toInt(); shuffle=plist->value("Playlist/Shuffle",0).toInt(); diff --git a/qmidiplayer-desktop/qmpplistwindow.hpp b/qmidiplayer-desktop/qmpplistwindow.hpp index 4fe0b50..afd3ae3 100644 --- a/qmidiplayer-desktop/qmpplistwindow.hpp +++ b/qmidiplayer-desktop/qmpplistwindow.hpp @@ -15,6 +15,7 @@ namespace Ui { } class qmpPlistWindow; +class qmpSettings; class qmpPlistFunc:public qmpFuncBaseIntf { @@ -65,6 +66,7 @@ class qmpPlistWindow:public QWidget qmpPlistFunc* plistf; Ui::qmpPlistWindow *ui; int shuffle,repeat;//rep 0=off 1=one 2=all + qmpSettings* settings; }; #endif // QMPPLISTWINDOW_H diff --git a/qmidiplayer-desktop/qmpplugin.cpp b/qmidiplayer-desktop/qmpplugin.cpp index 08959cb..8a156ba 100644 --- a/qmidiplayer-desktop/qmpplugin.cpp +++ b/qmidiplayer-desktop/qmpplugin.cpp @@ -9,9 +9,8 @@ #include "qmpplugin.hpp" #include "qmpmainwindow.hpp" #include "qmpsettingswindow.hpp" -qmpPluginAPI* pluginAPI; -qmpMainWindow* qmw; -qmpSettingsWindow* qsw; +qmpPluginAPI* qmpPluginManager::pluginAPI=nullptr; +qmpMainWindow* qmpPluginManager::mainwindow=nullptr; #ifdef _WIN32 #include <codecvt> #include <locale> @@ -93,8 +92,7 @@ void qmpPluginManager::scanPlugins(const std::vector<std::string> &pp) #endif qmpPluginManager::qmpPluginManager() { - qmw=qmpMainWindow::getInstance(); - qsw=qmw->getSettingsWindow(); + mainwindow=qmpMainWindow::getInstance(); pluginAPI=new qmpPluginAPI(); } qmpPluginManager::~qmpPluginManager() @@ -104,7 +102,7 @@ qmpPluginManager::~qmpPluginManager() if(plugins[i].initialized)plugins[i].pinterface->deinit(); delete plugins[i].pinterface; } - qmw=nullptr;qsw=nullptr;delete pluginAPI; + mainwindow=nullptr;delete pluginAPI; } std::vector<qmpPlugin> *qmpPluginManager::getPlugins() { @@ -130,6 +128,7 @@ void qmpPluginManager::deinitPlugins() qmpPluginAPI::~qmpPluginAPI(){} +#define qmw qmpPluginManager::mainwindow uint32_t qmpPluginAPI::getDivision() {return qmw&&qmw->getPlayer()?qmw->getPlayer()->getDivision():0;} uint32_t qmpPluginAPI::getRawTempo() @@ -244,26 +243,26 @@ void qmpPluginAPI::unregisterFileReadFinishHook(int id) {qmw->getPlayer()->unregisterFileReadFinishHook(id);} void qmpPluginAPI::registerOptionInt(std::string tab,std::string desc,std::string key,int min,int max,int defaultval) -{qsw->registerOptionInt(tab,desc,key,min,max,defaultval);} -int qmpPluginAPI::getOptionInt(std::string key){return qsw->getOptionInt(key);} -void qmpPluginAPI::setOptionInt(std::string key,int val){qsw->setOptionInt(key,val);} +{qmw->getSettings()->registerOptionInt(tab,desc,key,min,max,defaultval);} +int qmpPluginAPI::getOptionInt(std::string key){return qmw->getSettings()->getOptionInt(key);} +void qmpPluginAPI::setOptionInt(std::string key,int val){qmw->getSettings()->setOptionInt(key,val);} void qmpPluginAPI::registerOptionUint(std::string tab,std::string desc,std::string key,unsigned min,unsigned max,unsigned defaultval) -{qsw->registerOptionUint(tab,desc,key,min,max,defaultval);} -unsigned qmpPluginAPI::getOptionUint(std::string key){return qsw->getOptionUint(key);} -void qmpPluginAPI::setOptionUint(std::string key,unsigned val){qsw->setOptionUint(key,val);} +{qmw->getSettings()->registerOptionUint(tab,desc,key,min,max,defaultval);} +unsigned qmpPluginAPI::getOptionUint(std::string key){return qmw->getSettings()->getOptionUint(key);} +void qmpPluginAPI::setOptionUint(std::string key,unsigned val){qmw->getSettings()->setOptionUint(key,val);} void qmpPluginAPI::registerOptionBool(std::string tab,std::string desc,std::string key,bool defaultval) -{qsw->registerOptionBool(tab,desc,key,defaultval);} -bool qmpPluginAPI::getOptionBool(std::string key){return qsw->getOptionBool(key);} -void qmpPluginAPI::setOptionBool(std::string key,bool val){qsw->setOptionBool(key,val);} +{qmw->getSettings()->registerOptionBool(tab,desc,key,defaultval);} +bool qmpPluginAPI::getOptionBool(std::string key){return qmw->getSettings()->getOptionBool(key);} +void qmpPluginAPI::setOptionBool(std::string key,bool val){qmw->getSettings()->setOptionBool(key,val);} void qmpPluginAPI::registerOptionDouble(std::string tab,std::string desc,std::string key,double min,double max,double defaultval) -{qsw->registerOptionDouble(tab,desc,key,min,max,defaultval);} -double qmpPluginAPI::getOptionDouble(std::string key){return qsw->getOptionDouble(key);} -void qmpPluginAPI::setOptionDouble(std::string key,double val){qsw->setOptionDouble(key,val);} +{qmw->getSettings()->registerOptionDouble(tab,desc,key,min,max,defaultval);} +double qmpPluginAPI::getOptionDouble(std::string key){return qmw->getSettings()->getOptionDouble(key);} +void qmpPluginAPI::setOptionDouble(std::string key,double val){qmw->getSettings()->setOptionDouble(key,val);} void qmpPluginAPI::registerOptionString(std::string tab,std::string desc,std::string key,std::string defaultval,bool ispath) -{qsw->registerOptionString(tab,desc,key,defaultval,ispath);} -std::string qmpPluginAPI::getOptionString(std::string key){return qsw->getOptionString(key);} -void qmpPluginAPI::setOptionString(std::string key,std::string val){return qsw->setOptionString(key,val);} +{qmw->getSettings()->registerOptionString(tab,desc,key,defaultval,ispath);} +std::string qmpPluginAPI::getOptionString(std::string key){return qmw->getSettings()->getOptionString(key);} +void qmpPluginAPI::setOptionString(std::string key,std::string val){return qmw->getSettings()->setOptionString(key,val);} void qmpPluginAPI::registerOptionEnumInt(std::string tab,std::string desc,std::string key,std::vector<std::string> options,int defaultval) -{qsw->registerOptionEnumInt(tab,desc,key,options,defaultval);} -int qmpPluginAPI::getOptionEnumInt(std::string key){return qsw->getOptionEnumInt(key);} -void qmpPluginAPI::setOptionEnumInt(std::string key,int val){return qsw->setOptionEnumInt(key,val);} +{qmw->getSettings()->registerOptionEnumInt(tab,desc,key,options,defaultval);} +int qmpPluginAPI::getOptionEnumInt(std::string key){return qmw->getSettings()->getOptionEnumInt(key);} +void qmpPluginAPI::setOptionEnumInt(std::string key,int val){return qmw->getSettings()->setOptionEnumInt(key,val);} diff --git a/qmidiplayer-desktop/qmpplugin.hpp b/qmidiplayer-desktop/qmpplugin.hpp index be10b12..0020530 100644 --- a/qmidiplayer-desktop/qmpplugin.hpp +++ b/qmidiplayer-desktop/qmpplugin.hpp @@ -13,10 +13,15 @@ struct qmpPlugin qmpPlugin(std::string _n,std::string _v,std::string _p,qmpPluginIntf* _i) {name=_n;version=_v;path=_p;pinterface=_i;enabled=initialized=false;} }; +class qmpMainWindow; +class qmpSettings; class qmpPluginManager { private: std::vector<qmpPlugin> plugins; + static qmpPluginAPI* pluginAPI; + static qmpMainWindow* mainwindow; + static qmpSettings* settings; public: qmpPluginManager(); ~qmpPluginManager(); @@ -24,5 +29,7 @@ class qmpPluginManager void scanPlugins(const std::vector<std::string> &pp); void initPlugins(); void deinitPlugins(); + friend class qmpPluginAPI; + friend class qmpMainWindow; }; #endif // QMPPLUGIN_H diff --git a/qmidiplayer-desktop/qmppresetselect.cpp b/qmidiplayer-desktop/qmppresetselect.cpp index 8c28fe6..52b0b66 100644 --- a/qmidiplayer-desktop/qmppresetselect.cpp +++ b/qmidiplayer-desktop/qmppresetselect.cpp @@ -95,11 +95,11 @@ void qmpPresetSelector::on_pbOk_clicked() int b,p; b=ui->lwBankSelect->currentItem()->text().toInt(); p=ui->lwPresetSelect->currentItem()->text().split(' ').first().toInt(); - QString s=qmpSettingsWindow::getSettingsIntf()->value("Audio/BankSelect","CC#0").toString(); - if(s=="CC#32"){ + std::string s=qmpMainWindow::getInstance()->getSettings()->getOptionEnumIntOptName("FluidSynth/BankSelect"); + if(s=="XG"){ if(b==128)b=127<<7; } - else if(s=="CC#0")b<<=7; + else if(s=="GS")b<<=7; plyr->setChannelPreset(ch,b,p); } qmpMainWindow::getInstance()->invokeCallback("preset.set",nullptr); diff --git a/qmidiplayer-desktop/qmpsettings.cpp b/qmidiplayer-desktop/qmpsettings.cpp new file mode 100644 index 0000000..134b73b --- /dev/null +++ b/qmidiplayer-desktop/qmpsettings.cpp @@ -0,0 +1,233 @@ +#include "qmpsettings.hpp" +#include <QStandardPaths> + +QSettings* qmpSettings::settings=nullptr; +qmpSettings::qmpSettings() +{ + qRegisterMetaTypeStreamOperators<QPair<QString,QString>>(); + settings=new QSettings(QStandardPaths::writableLocation(QStandardPaths::StandardLocation::ConfigLocation)+QString("/qmprc"),QSettings::IniFormat); +} + +qmpSettings::~qmpSettings() +{ + delete settings; + settings=nullptr; +} + +void qmpSettings::registerOptionInt(std::string tab,std::string desc,std::string key,int min,int max,int defaultval) +{ + optionlist.push_back(key); + options[key]=qmpOption(tab,desc,qmpOption::ParameterType::parameter_int,nullptr,defaultval,min,max); +} +int qmpSettings::getOptionInt(std::string key) +{ + if(options.find(key)!=options.end()&&options[key].type==qmpOption::ParameterType::parameter_int) + return settings->value(QString(key.c_str()),options[key].defaultval).toInt(); + qWarning("Unregistered option or mismatching option type: %s.",key.c_str()); + return options[key].defaultval.toInt(); +} +void qmpSettings::setOptionInt(std::string key,int val) +{ + if(options.find(key)!=options.end()&&options[key].type==qmpOption::ParameterType::parameter_int) + settings->setValue(QString(key.c_str()),val); + else + qWarning("Unregistered option or mismatching option type: %s.",key.c_str()); + //call qmpSettingsWindow::load(key)? +} + +void qmpSettings::registerOptionUint(std::string tab,std::string desc,std::string key,unsigned min, unsigned max,unsigned defaultval) +{ + optionlist.push_back(key); + options[key]=qmpOption(tab,desc,qmpOption::ParameterType::parameter_uint,nullptr,defaultval,min,max); +} +unsigned qmpSettings::getOptionUint(std::string key) +{ + if(options.find(key)!=options.end()&&options[key].type==qmpOption::ParameterType::parameter_uint) + return settings->value(QString(key.c_str()),options[key].defaultval).toUInt(); + qWarning("Unregistered option or mismatching option type: %s.",key.c_str()); + return options[key].defaultval.toUInt(); +} +void qmpSettings::setOptionUint(std::string key,unsigned val) +{ + if(options.find(key)!=options.end()&&options[key].type==qmpOption::ParameterType::parameter_uint) + settings->setValue(QString(key.c_str()),val); + else + qWarning("Unregistered option or mismatching option type: %s.",key.c_str()); +} + +void qmpSettings::registerOptionBool(std::string tab,std::string desc,std::string key,bool defaultval) +{ + optionlist.push_back(key); + options[key]=qmpOption(tab,desc,qmpOption::ParameterType::parameter_bool,nullptr,defaultval); +} +bool qmpSettings::getOptionBool(std::string key) +{ + if(options.find(key)!=options.end()&&options[key].type==qmpOption::ParameterType::parameter_bool) + return settings->value(QString(key.c_str()),options[key].defaultval).toBool(); + qWarning("Unregistered option or mismatching option type: %s.",key.c_str()); + return options[key].defaultval.toBool(); +} +void qmpSettings::setOptionBool(std::string key,bool val) +{ + if(options.find(key)!=options.end()&&options[key].type==qmpOption::ParameterType::parameter_bool) + settings->setValue(QString(key.c_str()),val); + else + qWarning("Unregistered option or mismatching option type: %s.",key.c_str()); +} + +void qmpSettings::registerOptionDouble(std::string tab, std::string desc, std::string key, double min, double max, double defaultval) +{ + optionlist.push_back(key); + options[key]=qmpOption(tab,desc,qmpOption::ParameterType::parameter_double,nullptr,defaultval,min,max); +} +double qmpSettings::getOptionDouble(std::string key) +{ + if(options.find(key)!=options.end()&&options[key].type==qmpOption::ParameterType::parameter_double) + return settings->value(QString(key.c_str()),options[key].defaultval).toDouble(); + qWarning("Unregistered option or mismatching option type: %s.",key.c_str()); + return options[key].defaultval.toDouble(); +} +void qmpSettings::setOptionDouble(std::string key,double val) +{ + if(options.find(key)!=options.end()&&options[key].type==qmpOption::ParameterType::parameter_double) + settings->setValue(QString(key.c_str()),val); + else + qWarning("Unregistered option or mismatching option type: %s.",key.c_str()); +} + +void qmpSettings::registerOptionString(std::string tab,std::string desc,std::string key,std::string defaultval,bool is_url) +{ + optionlist.push_back(key); + options[key]=qmpOption(tab,desc, + is_url?qmpOption::ParameterType::parameter_url:qmpOption::ParameterType::parameter_str, + nullptr,QString(defaultval.c_str())); +} +std::string qmpSettings::getOptionString(std::string key) +{ + if(options.find(key)!=options.end()&& + (options[key].type==qmpOption::ParameterType::parameter_str||options[key].type==qmpOption::ParameterType::parameter_url)) + return settings->value(QString(key.c_str()),options[key].defaultval).toString().toStdString(); + qWarning("Unregistered option or mismatching option type: %s.",key.c_str()); + return options[key].defaultval.toString().toStdString(); +} +void qmpSettings::setOptionString(std::string key,std::string val) +{ + if(options.find(key)!=options.end()&& + (options[key].type==qmpOption::ParameterType::parameter_str||options[key].type==qmpOption::ParameterType::parameter_url)) + settings->setValue(QString(key.c_str()),QString(val.c_str())); + else + qWarning("Unregistered option or mismatching option type: %s.",key.c_str()); +} + +void qmpSettings::registerOptionEnumInt(std::string tab,std::string desc,std::string key,std::vector<std::string> enumlist,int defaultval) +{ + optionlist.push_back(key); + options[key]=qmpOption(tab,desc,qmpOption::ParameterType::parameter_enum,nullptr,defaultval); + options[key].enumlist=enumlist; +} +int qmpSettings::getOptionEnumInt(std::string key) +{ + if(options.find(key)!=options.end()&&options[key].type==qmpOption::ParameterType::parameter_enum) + { + std::string curitm=settings->value(QString(key.c_str()),options[key].defaultval).toString().toStdString(); + auto curidx=std::find(options[key].enumlist.begin(),options[key].enumlist.end(),curitm); + if(curidx!=options[key].enumlist.end()) + return static_cast<int>(curidx-options[key].enumlist.begin()); + else + { + qWarning("Invalid value set for option \"%s\".",key.c_str()); + return options[key].defaultval.toInt(); + } + } + qWarning("Unregistered option or mismatching option type: %s.",key.c_str()); + return options[key].defaultval.toInt(); +} + +std::string qmpSettings::getOptionEnumIntOptName(std::string key) +{ + if(options.find(key)!=options.end()&&options[key].type==qmpOption::ParameterType::parameter_enum) + { + std::string curitm=settings->value(QString(key.c_str()),options[key].defaultval).toString().toStdString(); + auto curidx=std::find(options[key].enumlist.begin(),options[key].enumlist.end(),curitm); + if(curidx!=options[key].enumlist.end()) + return curitm; + else + { + qWarning("Invalid value set for option \"%s\".",key.c_str()); + return options[key].enumlist[static_cast<size_t>(options[key].defaultval.toInt())]; + } + } + qWarning("Unregistered option or mismatching option type: %s.",key.c_str()); + return options[key].enumlist[static_cast<size_t>(options[key].defaultval.toInt())]; +} +void qmpSettings::setOptionEnumInt(std::string key,int val) +{ + if(options.find(key)!=options.end()&&options[key].type==qmpOption::ParameterType::parameter_enum) + { + if(static_cast<size_t>(val)<options[key].enumlist.size()) + settings->setValue(QString(key.c_str()),QString(options[key].enumlist[static_cast<size_t>(val)].c_str())); + else + qWarning("Trying to set invalid value for option \"%s\".",key.c_str()); + } + else + qWarning("Unregistered option or mismatching option type: %s.",key.c_str()); +} + +void qmpSettings::setOptionEnumIntOptName(std::string key,std::string valname) +{ + if(options.find(key)!=options.end()&&options[key].type==qmpOption::ParameterType::parameter_enum) + { + auto curidx=std::find(options[key].enumlist.begin(),options[key].enumlist.end(),valname); + if(curidx!=options[key].enumlist.end()) + settings->setValue(QString(key.c_str()),QString(valname.c_str())); + else + qWarning("Trying to set invalid value for option \"%s\".",key.c_str()); + } + else + qWarning("Unregistered option or mismatching option type: %s.",key.c_str()); +} + +void qmpSettings::registerOptionCustom(std::string tab,std::string desc,std::string key,void* widget, void* defaultval,std::function<void*()> save_func,std::function<void(void*)> load_func) +{ + optionlist.push_back(key); + options[key]=qmpOption(tab,desc,qmpOption::parameter_custom, + static_cast<QWidget*>(widget), + *static_cast<QVariant*>(defaultval), + QVariant(),QVariant(),save_func,load_func); +} +void* qmpSettings::getOptionCustom(std::string key) +{ + if(options.find(key)!=options.end()||options[key].type!=qmpOption::ParameterType::parameter_custom) + return static_cast<void*>(new QVariant(settings->value(QString(key.c_str()),options[key].defaultval))); + qWarning("Unregistered option or mismatching option type: %s.",key.c_str()); + return nullptr; +} +void qmpSettings::setOptionCustom(std::string key,void *val) +{ + if(options.find(key)!=options.end()||options[key].type!=qmpOption::ParameterType::parameter_custom) + settings->setValue(QString(key.c_str()),*static_cast<QVariant*>(val)); + else + qWarning("Unregistered option or mismatching option type: %s.",key.c_str()); +} + +void qmpSettings::setOptionRaw(QString key,QVariant val) +{ + settings->setValue(key,val); +} + +QVariant qmpSettings::getOptionRaw(QString key,QVariant defval) +{ + return settings->value(key,defval); +} + +QDataStream &operator<<(QDataStream &out,const QPair<QString,QString> &o) +{ + out<<o.first<<o.second; + return out; +} + +QDataStream &operator>>(QDataStream &in,QPair<QString,QString> &o) +{ + in>>o.first>>o.second; + return in; +} diff --git a/qmidiplayer-desktop/qmpsettings.hpp b/qmidiplayer-desktop/qmpsettings.hpp new file mode 100644 index 0000000..ff46970 --- /dev/null +++ b/qmidiplayer-desktop/qmpsettings.hpp @@ -0,0 +1,88 @@ +#ifndef QMPSETTINGS_H +#define QMPSETTINGS_H + +#include <functional> +#include <string> +#include <map> +#include <vector> +#include <QWidget> +#include <QSettings> + +struct qmpOption +{ + enum ParameterType{ + parameter_int=0, + parameter_uint, + parameter_bool, + parameter_double, + parameter_str, + parameter_enum, + parameter_url, + parameter_custom=0x100 + }; + + std::string tab; + std::string desc; + ParameterType type; + QWidget* widget; + QVariant defaultval,minv,maxv; + std::function<void*()> save_func; + std::function<void(void*)> load_func; + std::vector<std::string> enumlist; + + qmpOption():widget(nullptr){} + qmpOption(std::string _tab,std::string _desc, + ParameterType _t,QWidget* _w=nullptr, + QVariant _def=QVariant(),QVariant _min=QVariant(),QVariant _max=QVariant(), + std::function<void*()> _save=nullptr,std::function<void(void*)> _load=nullptr): + tab(_tab), + desc(_desc), + type(_t), + widget(_w), + defaultval(_def), + minv(_min), + maxv(_max), + save_func(_save), + load_func(_load){} +}; +class qmpSettings +{ + public: + qmpSettings(); + ~qmpSettings(); + void registerOptionInt(std::string tab,std::string desc,std::string key,int min,int max,int defaultval); + int getOptionInt(std::string key); + void setOptionInt(std::string key,int val); + void registerOptionUint(std::string tab,std::string desc,std::string key,unsigned min,unsigned max,unsigned defaultval); + unsigned getOptionUint(std::string key); + void setOptionUint(std::string key,unsigned val); + void registerOptionBool(std::string tab,std::string desc,std::string key,bool defaultval); + bool getOptionBool(std::string key); + void setOptionBool(std::string key,bool val); + void registerOptionDouble(std::string tab,std::string desc,std::string key,double min,double max,double defaultval); + double getOptionDouble(std::string key); + void setOptionDouble(std::string key,double val); + void registerOptionString(std::string tab,std::string desc,std::string key,std::string defaultval,bool is_url); + std::string getOptionString(std::string key); + void setOptionString(std::string key,std::string val); + void registerOptionEnumInt(std::string tab,std::string desc,std::string key,std::vector<std::string> enumlist,int defaultval); + int getOptionEnumInt(std::string key); + std::string getOptionEnumIntOptName(std::string key); + void setOptionEnumInt(std::string key,int val); + void setOptionEnumIntOptName(std::string key,std::string valname); + void registerOptionCustom(std::string tab,std::string desc,std::string key,void* widget,void* defaultval,std::function<void*()> save_func,std::function<void(void*)> load_func); + void* getOptionCustom(std::string key); + void setOptionCustom(std::string key,void* val); + + void setOptionRaw(QString key,QVariant val); + QVariant getOptionRaw(QString key,QVariant defval=QVariant()); + + private: + static QSettings *settings; + std::map<std::string,qmpOption> options; + std::vector<std::string> optionlist; + + friend class qmpSettingsWindow; +}; + +#endif diff --git a/qmidiplayer-desktop/qmpsettingswindow.cpp b/qmidiplayer-desktop/qmpsettingswindow.cpp index 17e16bf..fe75b76 100644 --- a/qmidiplayer-desktop/qmpsettingswindow.cpp +++ b/qmidiplayer-desktop/qmpsettingswindow.cpp @@ -1,51 +1,45 @@ -#include <set> #include <QLineEdit> #include <QToolButton> #include <QFileDialog> #include <QDir> #include <QMessageBox> #include <QStandardPaths> +#include <QHeaderView> +#include <QCheckBox> +#include <set> #include "qmpsettingswindow.hpp" #include "qmpdeviceprioritydialog.hpp" #include "ui_qmpsettingswindow.h" #include "qmpmainwindow.hpp" -QSettings* qmpSettingsWindow::settings=nullptr; - void qmpFluidForEachOpt(void* data,const char*,const char* option) { QComboBox *pcb=(QComboBox*)data; pcb->addItem(option); } -qmpSettingsWindow::qmpSettingsWindow(QWidget *parent) : +qmpSettingsWindow::qmpSettingsWindow(qmpSettings *qmpsettings,QWidget *parent) : QDialog(parent), ui(new Ui::qmpSettingsWindow) { ui->setupUi(this);customOptions.clear();customOptPages.clear(); connect(this,&qmpSettingsWindow::dialogClosing,(qmpMainWindow*)parent,&qmpMainWindow::dialogClosed); - settings=new QSettings(QStandardPaths::writableLocation(QStandardPaths::StandardLocation::ConfigLocation)+QString("/qmprc"),QSettings::IniFormat); - settingsInit(); - ui->pbAdd->setIcon(QIcon(getThemedIcon(":/img/add.svg"))); - ui->pbRemove->setIcon(QIcon(getThemedIcon(":/img/remove.svg"))); - ui->pbDown->setIcon(QIcon(getThemedIcon(":/img/down.svg"))); - ui->pbUp->setIcon(QIcon(getThemedIcon(":/img/up.svg"))); - cw=new qmpCustomizeWindow(this); + settings=qmpsettings; + cwt=new qmpCustomizeWindow(this); + cwa=new qmpCustomizeWindow(this); dps=new qmpDevPropDialog(this); devpriod=new qmpDevicePriorityDialog(this); } qmpSettingsWindow::~qmpSettingsWindow() { - delete cw;delete dps; - delete settings;settings=nullptr; delete ui; } void qmpSettingsWindow::closeEvent(QCloseEvent *event) { setVisible(false); - settings->sync(); + loadOption(); emit dialogClosing(); event->accept(); } @@ -57,336 +51,53 @@ void qmpSettingsWindow::hideEvent(QHideEvent *event) void qmpSettingsWindow::on_buttonBox_accepted() { - settingsUpdate(); + saveOption(); qmpMainWindow::getInstance()->setupWidget(); emit dialogClosing(); } void qmpSettingsWindow::on_buttonBox_rejected() { - settingsInit(); + loadOption(); emit dialogClosing(); } -void qmpSettingsWindow::settingsInit() -{ - fluid_settings_t *fsettings=new_fluid_settings(); - - settings->setValue("Midi/DisableMapping",settings->value("Midi/DisableMapping",0)); - ui->cbDisableMapping->setChecked(settings->value("Midi/DisableMapping",0).toInt()); - - settings->setValue("Midi/SendSysEx",settings->value("Midi/SendSysEx",1)); - ui->cbSendSysx->setChecked(settings->value("Midi/SendSysEx",1).toInt()); - - settings->setValue("Midi/WaitVoice",settings->value("Midi/WaitVoice",1)); - ui->cbWaitVoice->setChecked(settings->value("Midi/WaitVoice",1).toInt()); - - int selected=-1; - for(int i=0;i<ui->cbEncoding->count();++i) - if(ui->cbEncoding->itemText(i)==settings->value("Midi/TextEncoding","Unicode").toString()) - {selected=i;break;} - if(~selected)ui->cbEncoding->setCurrentIndex(selected); - settings->setValue("Midi/TextEncoding",ui->cbEncoding->currentText()); - - fluid_settings_foreach_option(fsettings,"audio.driver",(void*)ui->cbAudioDrv,qmpFluidForEachOpt); - selected=-1; - for(int i=0;i<ui->cbAudioDrv->count();++i) - if(ui->cbAudioDrv->itemText(i)==settings->value("Audio/Driver","pulseaudio").toString()) - {selected=i;break;} - if(~selected)ui->cbAudioDrv->setCurrentIndex(selected); - settings->setValue("Audio/Driver",ui->cbAudioDrv->currentText()); - -#ifdef _WIN32 -#define DefBufSize 256 -#else -#define DefBufSize 128 -#endif - selected=-1; - for(int i=0;i<ui->cbBufSize->count();++i) - if(ui->cbBufSize->itemText(i).toInt()==settings->value("Audio/BufSize",DefBufSize).toInt()) - {selected=i;break;} - if(~selected)ui->cbBufSize->setCurrentIndex(selected); - else if(settings->value("Audio/BufSize",DefBufSize).toInt()>=64&&settings->value("Audio/BufSize",DefBufSize).toInt()<=8192) - ui->cbBufSize->setCurrentText(settings->value("Audio/BufSize",DefBufSize).toString()); - else ui->cbBufSize->setCurrentText(QString::number(DefBufSize)); - settings->setValue("Audio/BufSize",ui->cbBufSize->currentText().toInt()); -#undef DefBufSize - -#ifdef _WIN32 -#define DefBufCnt 8 -#else -#define DefBufCnt 2 -#endif - selected=-1; - for(int i=0;i<ui->cbBufCnt->count();++i) - if(ui->cbBufCnt->itemText(i).toInt()==settings->value("Audio/BufCnt",DefBufCnt).toInt()) - {selected=i;break;} - if(~selected)ui->cbBufCnt->setCurrentIndex(selected); - else if(settings->value("Audio/BufCnt",DefBufCnt).toInt()>=2&&settings->value("Audio/BufCnt",DefBufCnt).toInt()<=64) - ui->cbBufCnt->setCurrentText(settings->value("Audio/BufCnt",DefBufCnt).toString()); - else ui->cbBufCnt->setCurrentText(QString::number(DefBufCnt)); - settings->setValue("Audio/BufCnt",ui->cbBufCnt->currentText().toInt()); -#undef DefBufCnt - - selected=-1; - for(int i=0;i<ui->cbFormat->count();++i) - if(ui->cbFormat->itemText(i)==settings->value("Audio/Format","16bits").toString()) - {selected=i;break;} - if(~selected)ui->cbFormat->setCurrentIndex(selected); - settings->setValue("Audio/Format",ui->cbFormat->currentText()); - - selected=-1; - for(int i=0;i<ui->cbFrequency->count();++i) - if(ui->cbFormat->itemText(i).toInt()==settings->value("Audio/Frequency",48000).toInt()) - {selected=i;break;} - if(~selected)ui->cbFrequency->setCurrentIndex(selected); - settings->setValue("Audio/Frequency",ui->cbFrequency->currentText()); - - ui->sbPolyphony->setValue(settings->value("Audio/Polyphony",2048).toInt()); - if(ui->sbPolyphony->value()<1||ui->sbPolyphony->value()>65535)ui->sbPolyphony->setValue(2048); - settings->setValue("Audio/Polyphony",ui->sbPolyphony->value()); - - ui->sbCPUCores->setValue(settings->value("Audio/Threads",1).toInt()); - if(ui->sbCPUCores->value()<1||ui->sbCPUCores->value()>256)ui->sbCPUCores->setValue(1); - settings->setValue("Audio/Threads",ui->sbCPUCores->value()); - - settings->setValue("Audio/AutoBS",settings->value("Audio/AutoBS",1)); - ui->cbAutoBS->setChecked(settings->value("Audio/AutoBS",1).toInt()); - ui->lbBSMode->setText(ui->cbAutoBS->isChecked()?"Fallback bank select mode":"Bank select mode"); - - selected=-1; - for(int i=0;i<ui->cbBSMode->count();++i) - if(ui->cbBSMode->itemText(i)==settings->value("Audio/BankSelect","CC#0").toString()) - {selected=i;break;} - if(~selected)ui->cbBSMode->setCurrentIndex(selected); - settings->setValue("Audio/BankSelect",ui->cbBSMode->currentText()); - settings->setValue("Audio/Gain",settings->value("Audio/Gain",50)); - - QList<QVariant> sflist=settings->value("Audio/SoundFonts",QList<QVariant>{}).toList(); - ui->twSoundfont->clear(); - for(int i=0;i<sflist.size();++i) - { - ui->twSoundfont->insertRow(i); - QTableWidgetItem *sfn,*sfe; - QString sf=sflist[i].toString(); - bool enabled=!sf.startsWith('#'); - if(!enabled)sf=sf.mid(1); - ui->twSoundfont->setItem(i,1,sfn=new QTableWidgetItem(sf)); - ui->twSoundfont->setItem(i,0,sfe=new QTableWidgetItem()); - sfn->setFlags(Qt::ItemFlag::ItemIsEnabled|Qt::ItemFlag::ItemIsSelectable); - sfe->setFlags(Qt::ItemFlag::ItemIsEnabled|Qt::ItemFlag::ItemIsSelectable|Qt::ItemFlag::ItemIsUserCheckable); - sfe->setCheckState(enabled?Qt::CheckState::Checked:Qt::CheckState::Unchecked); - } - ui->twSoundfont->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeMode::ResizeToContents); - QStringList qs{"E","Path"}; - ui->twSoundfont->setHorizontalHeaderLabels(qs); - - settings->setValue("Behavior/RestorePlaylist",settings->value("Behavior/RestorePlaylist",0)); - ui->cbRestorePlaylist->setChecked(settings->value("Behavior/RestorePlaylist",0).toInt()); - - settings->setValue("Behavior/LoadFolder",settings->value("Behavior/LoadFolder",0)); - ui->cbLoadFolder->setChecked(settings->value("Behavior/LoadFolder",0).toInt()); - - settings->setValue("Behavior/DialogStatus",settings->value("Behavior/DialogStatus",1)); - ui->cbDialogStatus->setChecked(settings->value("Behavior/DialogStatus",1).toInt()); - - settings->setValue("Behavior/SaveEfxParam",settings->value("Behavior/SaveEfxParam",1)); - ui->cbSaveEfxParam->setChecked(settings->value("Behavior/SaveEfxParam",1).toInt()); - - settings->setValue("Behavior/SingleInstance",settings->value("Behavior/SingleInstance",0)); - ui->cbPersistentfs->setChecked(settings->value("Behavior/SingleInstance",0).toInt()); - - settings->setValue("Behavior/ShowButtonLabel",settings->value("Behavior/ShowButtonLabel",0)); - ui->cbShowLabel->setChecked(settings->value("Behavior/ShowButtonLabel",0).toInt()); - - settings->setValue("Behavior/IconTheme",settings->value("Behavior/IconTheme",0)); - ui->cbIconTheme->setCurrentIndex(settings->value("Behavior/IconTheme",0).toInt()); - - settings->sync(); - delete_fluid_settings(fsettings); -} - -void qmpSettingsWindow::settingsUpdate() -{ - settings->setValue("Midi/DisableMapping",ui->cbDisableMapping->isChecked()?1:0); - - settings->setValue("Midi/SendSysEx",ui->cbSendSysx->isChecked()?1:0); - - settings->setValue("Midi/WaitVoice",ui->cbWaitVoice->isChecked()?1:0); - - settings->setValue("Midi/TextEncoding",ui->cbEncoding->currentText()); - - settings->setValue("Audio/Driver",ui->cbAudioDrv->currentText()); - - settings->setValue("Audio/BufSize",ui->cbBufSize->currentText().toInt()); - - settings->setValue("Audio/BufCnt",ui->cbBufCnt->currentText().toInt()); - - settings->setValue("Audio/Format",ui->cbFormat->currentText()); - - settings->setValue("Audio/Frequency",ui->cbFrequency->currentText()); - - settings->setValue("Audio/Polyphony",ui->sbPolyphony->value()); - - settings->setValue("Audio/Threads",ui->sbCPUCores->value()); - - settings->setValue("Audio/AutoBS",ui->cbAutoBS->isChecked()?1:0); - - settings->setValue("Audio/BankSelect",ui->cbBSMode->currentText()); - - QList<QVariant> sflist; - for(int i=0;i<ui->twSoundfont->rowCount();++i) - { - QString sfs=ui->twSoundfont->item(i,1)->text(); - if(ui->twSoundfont->item(i,0)->checkState()==Qt::CheckState::Unchecked)sfs="#"+sfs; - sflist.push_back(sfs); - } - settings->setValue("Audio/SoundFonts",sflist); - - settings->setValue("Behavior/RestorePlaylist",ui->cbRestorePlaylist->isChecked()?1:0); - - settings->setValue("Behavior/LoadFolder",ui->cbLoadFolder->isChecked()?1:0); - - settings->setValue("Behavior/DialogStatus",ui->cbDialogStatus->isChecked()?1:0); - - settings->setValue("Behavior/SingleInstance",ui->cbPersistentfs->isChecked()?1:0); - - settings->setValue("Behavior/ShowButtonLabel",ui->cbShowLabel->isChecked()?1:0); - - settings->setValue("Behavior/IconTheme",ui->cbIconTheme->currentIndex()); - - if(!ui->cbDialogStatus->isChecked()) - { - settings->remove("DialogStatus/MainW"); - settings->remove("DialogStatus/PListW"); - settings->remove("DialogStatus/PListWShown"); - settings->remove("DialogStatus/ChnlW"); - settings->remove("DialogStatus/ChnlWShown"); - settings->remove("DialogStatus/EfxW"); - settings->remove("DialogStatus/EfxWShown"); - settings->remove("DialogStatus/FileDialogPath"); - } - - settings->setValue("Behavior/SaveEfxParam",ui->cbSaveEfxParam->isChecked()?1:0); - if(!ui->cbSaveEfxParam->isChecked()) - { - settings->remove("Effects/ChorusEnabled"); - settings->remove("Effects/ReverbEnabled"); - settings->remove("Effects/ReverbRoom"); - settings->remove("Effects/ReverbDamp"); - settings->remove("Effects/ReverbWidth"); - settings->remove("Effects/ReverbLevel"); - - settings->remove("Effects/ChorusFeedbk"); - settings->remove("Effects/ChorusLevel"); - settings->remove("Effects/ChorusRate"); - settings->remove("Effects/ChorusDepth"); - settings->remove("Effects/ChorusType"); - } - - for(int i=0;i<ui->twPluginList->rowCount();++i) - settings->setValue( - QString("PluginSwitch/")+ui->twPluginList->item(i,1)->text(), - ui->twPluginList->item(i,0)->checkState()==Qt::CheckState::Checked?1:0); - updateCustomOptions(); - settings->sync(); -} - -void qmpSettingsWindow::on_cbBufSize_currentTextChanged(const QString &s) -{ - if(s.toInt()<64||s.toInt()>8192)ui->cbBufSize->setCurrentIndex(1); -} - -void qmpSettingsWindow::on_cbBufCnt_currentTextChanged(const QString &s) -{ - if(s.toInt()<2||s.toInt()>64)ui->cbBufCnt->setCurrentIndex(1); -} - -void qmpSettingsWindow::on_pbAdd_clicked() -{ - QStringList sl=QFileDialog::getOpenFileNames(this,"Add File","","SoundFont files (*.sf2)"); - for(int i=0;i<sl.size();++i){ - ui->twSoundfont->insertRow(ui->twSoundfont->rowCount()); - QTableWidgetItem *sfn,*sfe; - ui->twSoundfont->setItem(ui->twSoundfont->rowCount()-1,1,sfn=new QTableWidgetItem(sl[i])); - ui->twSoundfont->setItem(ui->twSoundfont->rowCount()-1,0,sfe=new QTableWidgetItem()); - sfn->setFlags(Qt::ItemFlag::ItemIsEnabled|Qt::ItemFlag::ItemIsSelectable); - sfe->setFlags(Qt::ItemFlag::ItemIsEnabled|Qt::ItemFlag::ItemIsSelectable|Qt::ItemFlag::ItemIsUserCheckable); - } -} - -void qmpSettingsWindow::on_pbRemove_clicked() -{ - QList<QTableWidgetItem*> sl=ui->twSoundfont->selectedItems(); - for(int i=0;i<sl.size();++i) - { - ui->twSoundfont->removeRow(ui->twSoundfont->row(sl[i])); - } -} - -void qmpSettingsWindow::on_pbUp_clicked() -{ - int cid=ui->twSoundfont->currentRow();if(!cid)return; - QTableWidgetItem *ci=ui->twSoundfont->takeItem(cid,1); - QTableWidgetItem *ce=ui->twSoundfont->takeItem(cid,0); - ui->twSoundfont->removeRow(cid); - ui->twSoundfont->insertRow(cid-1); - ui->twSoundfont->setItem(cid-1,0,ce); - ui->twSoundfont->setItem(cid-1,1,ci); - ui->twSoundfont->setCurrentCell(cid-1,1); -} - -void qmpSettingsWindow::on_pbDown_clicked() -{ - int cid=ui->twSoundfont->currentRow();if(cid==ui->twSoundfont->rowCount()-1)return; - QTableWidgetItem *ci=ui->twSoundfont->takeItem(cid,1); - QTableWidgetItem *ce=ui->twSoundfont->takeItem(cid,0); - ui->twSoundfont->removeRow(cid); - ui->twSoundfont->insertRow(cid+1); - ui->twSoundfont->setItem(cid+1,0,ce); - ui->twSoundfont->setItem(cid+1,1,ci); - ui->twSoundfont->setCurrentCell(cid+1,1); -} - -void qmpSettingsWindow::on_cbAutoBS_stateChanged() -{ - ui->lbBSMode->setText(ui->cbAutoBS->isChecked()?"Fallback bank select mode":"Bank select mode"); -} - void qmpSettingsWindow::updatePluginList(qmpPluginManager *pmgr) { std::vector<qmpPlugin> *plugins=pmgr->getPlugins(); + QVariant *data=static_cast<QVariant*>(settings->getOptionCustom("DisabledPlugins")); + QList<QVariant> disabled_plugins_l=static_cast<QVariant*>(data)->toList(); + delete data; + std::set<std::string> disabled_plugins_s; + for(auto &i:disabled_plugins_l) + disabled_plugins_s.insert(i.toString().toStdString()); for(unsigned i=0;i<plugins->size();++i) { - ui->twPluginList->insertRow(i); - QTableWidgetItem *icb; - ui->twPluginList->setItem(i,0,icb=new QTableWidgetItem()); - bool enabled=settings->value(QString("PluginSwitch/")+QString(plugins->at(i).name.c_str()),1).toInt(); - icb->setCheckState(enabled?Qt::CheckState::Checked:Qt::CheckState::Unchecked); - icb->setFlags(Qt::ItemFlag::ItemIsEnabled|Qt::ItemFlag::ItemIsSelectable|Qt::ItemFlag::ItemIsUserCheckable); + bool enabled=disabled_plugins_s.find(plugins->at(i).name)==disabled_plugins_s.end(); plugins->at(i).enabled=enabled; - ui->twPluginList->setItem(i,1,new QTableWidgetItem(plugins->at(i).name.c_str())); - ui->twPluginList->setItem(i,2,new QTableWidgetItem(plugins->at(i).version.c_str())); - ui->twPluginList->setItem(i,3,new QTableWidgetItem(plugins->at(i).path.c_str())); - for(int j=1;j<=3;++j) - ui->twPluginList->item(i,j)->setFlags(ui->twPluginList->item(i,j)->flags()^Qt::ItemIsEditable); } - ui->twPluginList->setColumnWidth(0,22); - ui->twPluginList->setColumnWidth(1,192); - ui->twPluginList->setColumnWidth(2,64); - ui->twPluginList->setColumnWidth(3,128); } void qmpSettingsWindow::postInit() { + setupWidgets(); int sf=0; - for(int i=0;i<ui->twSoundfont->rowCount();++i) - if(ui->twSoundfont->item(i,0)->checkState()==Qt::CheckState::Checked)++sf; + QVariant *data=static_cast<QVariant*>(settings->getOptionCustom("FluidSynth/SoundFonts")); + for(auto i:data->toList()) + if(!i.toString().startsWith('#')) + { + sf=1; + break; + } + delete data; std::string selecteddev; std::vector<std::string> devs=qmpMainWindow::getInstance()->getPlayer()->getMidiOutDevices(); std::set<std::string> devset; for(auto dev:devs)devset.insert(dev); - for(auto setdev:qmpSettingsWindow::getSettingsIntf()->value("Midi/DevicePriority",QList<QVariant>{"Internal FluidSynth"}).toList()) + QVariant *devpriov=static_cast<QVariant*>(qmpMainWindow::getInstance()->getSettings()->getOptionCustom("Midi/DevicePriority")); + QList<QVariant> devprio=devpriov->toList(); + delete devpriov; + for(auto &setdev:devprio) if(devset.find(setdev.toString().toStdString())!=devset.end()) { selecteddev=setdev.toString().toStdString(); @@ -400,338 +111,458 @@ void qmpSettingsWindow::postInit() "Would you like to setup soundfonts now? You may have to reload the internal synth afterwards."))==QMessageBox::Yes) { show(); - ui->tabWidget->setCurrentWidget(ui->tab_3); + ui->tabWidget->setCurrentWidget(qobject_cast<QWidget*>(pageForTab("SoundFonts")->parent())); } } - devpriod->setupRegisteredDevices(); } -void qmpSettingsWindow::updateCustomOptions() -{ - for(auto i=customOptions.begin();i!=customOptions.end();++i) - switch(i->second.type) - { - case 0: - { - QSpinBox* sb=(QSpinBox*)i->second.widget;if(!i->second.widget)break; - settings->setValue(QString(i->first.c_str()),sb->value()); - break; - } - case 1: - { - QHexSpinBox* sb=(QHexSpinBox*)i->second.widget;if(!i->second.widget)break; - int v=sb->value(); - settings->setValue(QString(i->first.c_str()),*reinterpret_cast<unsigned int*>(&v)); - break; - } - case 2: - { - if(!i->second.widget)break; - settings->setValue(QString(i->first.c_str()),((QCheckBox*)i->second.widget)->isChecked()?1:0); - break; +void qmpSettingsWindow::registerCustomizeWidgetOptions() +{ + QPushButton *pbCustomizeToolbar=new QPushButton(tr("Customize...")); + QPushButton *pbCustomizeActions=new QPushButton(tr("Customize...")); + QVariant toolbar_def_val=QList<QVariant>({"Channel","Playlist","Effects","Visualization"}); + QVariant actions_def_val=QList<QVariant>({"FileInfo","Render","Panic","ReloadSynth"}); + settings->registerOptionCustom("Behavior","Customize toolbar","Behavior/Toolbar",pbCustomizeToolbar,&toolbar_def_val,std::bind(&qmpCustomizeWindow::save,cwt),std::bind(&qmpCustomizeWindow::load,cwt,std::placeholders::_1)); + settings->registerOptionCustom("Behavior","Customize actions","Behavior/Actions",pbCustomizeActions,&actions_def_val,std::bind(&qmpCustomizeWindow::save,cwa),std::bind(&qmpCustomizeWindow::load,cwa,std::placeholders::_1)); + connect(pbCustomizeToolbar,&QPushButton::clicked,[this]{loadOption("Behavior/Toolbar");cwt->show();}); + connect(pbCustomizeActions,&QPushButton::clicked,[this]{loadOption("Behavior/Actions");cwa->show();}); + connect(cwt,&QDialog::accepted,[this]{saveOption("Behavior/Toolbar");qmpMainWindow::getInstance()->setupWidget();}); + connect(cwa,&QDialog::accepted,[this]{saveOption("Behavior/Actions");qmpMainWindow::getInstance()->setupWidget();}); + connect(cwt,&QDialog::rejected,[this]{loadOption("Behavior/Toolbar");}); + connect(cwa,&QDialog::rejected,[this]{loadOption("Behavior/Actions");}); + qmpMainWindow::getInstance()->setupWidget(); +} + +void qmpSettingsWindow::registerSoundFontOption() +{ + QWidget *sfpanel=new QWidget(); + sfpanel->setLayout(new QVBoxLayout); + sfpanel->layout()->setMargin(0); + QTableWidget *twsf=new QTableWidget(); + twsf->setColumnCount(2); + twsf->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeMode::ResizeToContents); + twsf->setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection); + twsf->setSelectionBehavior(QAbstractItemView::SelectionBehavior::SelectRows); + twsf->setHorizontalHeaderLabels({tr("E"),tr("Path")}); + twsf->setHorizontalScrollMode(QAbstractItemView::ScrollMode::ScrollPerPixel); + twsf->setVerticalScrollMode(QAbstractItemView::ScrollMode::ScrollPerPixel); + sfpanel->layout()->addWidget(twsf); + QWidget *controls=new QWidget(); + controls->setLayout(new QHBoxLayout); + controls->layout()->setMargin(0); + QPushButton *pbsfadd=new QPushButton(style()->standardIcon(QStyle::StandardPixmap::SP_DialogOpenButton),QString()); + QPushButton *pbsfrem=new QPushButton(style()->standardIcon(QStyle::StandardPixmap::SP_DialogDiscardButton),QString()); + QPushButton *pbsfmup=new QPushButton(style()->standardIcon(QStyle::StandardPixmap::SP_ArrowUp),QString()); + QPushButton *pbsfmdn=new QPushButton(style()->standardIcon(QStyle::StandardPixmap::SP_ArrowDown),QString()); + controls->layout()->addWidget(pbsfadd); + controls->layout()->addWidget(pbsfrem); + controls->layout()->addWidget(pbsfmup); + controls->layout()->addWidget(pbsfmdn); + sfpanel->layout()->addWidget(controls); + + connect(pbsfadd,&QPushButton::clicked,[twsf,this]{ + QStringList sl=QFileDialog::getOpenFileNames(this,"Add File","","SoundFont files (*.sf2)"); + for(int i=0;i<sl.size();++i){ + twsf->insertRow(twsf->rowCount()); + QTableWidgetItem *sfn,*sfe; + twsf->setItem(twsf->rowCount()-1,1,sfn=new QTableWidgetItem(sl[i])); + twsf->setItem(twsf->rowCount()-1,0,sfe=new QTableWidgetItem()); + sfe->setCheckState(Qt::CheckState::Unchecked); + sfn->setFlags(Qt::ItemFlag::ItemIsEnabled|Qt::ItemFlag::ItemIsSelectable); + sfe->setFlags(Qt::ItemFlag::ItemIsEnabled|Qt::ItemFlag::ItemIsSelectable|Qt::ItemFlag::ItemIsUserCheckable); } - case 3: + }); + connect(pbsfrem,&QPushButton::clicked,[twsf]{ + QList<QTableWidgetItem*> sl=twsf->selectedItems(); + for(int i=0;i<sl.size();++i) + twsf->removeRow(twsf->row(sl[i])); + }); + connect(pbsfmup,&QPushButton::clicked,[twsf]{ + int cid=twsf->currentRow();if(!cid)return; + QTableWidgetItem *ci=twsf->takeItem(cid,1); + QTableWidgetItem *ce=twsf->takeItem(cid,0); + twsf->removeRow(cid); + twsf->insertRow(cid-1); + twsf->setItem(cid-1,0,ce); + twsf->setItem(cid-1,1,ci); + twsf->setCurrentCell(cid-1,1); + }); + connect(pbsfmdn,&QPushButton::clicked,[twsf]{ + int cid=twsf->currentRow();if(cid==twsf->rowCount()-1)return; + QTableWidgetItem *ci=twsf->takeItem(cid,1); + QTableWidgetItem *ce=twsf->takeItem(cid,0); + twsf->removeRow(cid); + twsf->insertRow(cid+1); + twsf->setItem(cid+1,0,ce); + twsf->setItem(cid+1,1,ci); + twsf->setCurrentCell(cid+1,1); + }); + + QVariant sf_def_val=QList<QVariant>(); + auto save_func=[twsf]()->void*{ + QList<QVariant> sflist; + for(int i=0;i<twsf->rowCount();++i) { - QDoubleSpinBox* sb=(QDoubleSpinBox*)i->second.widget;if(!i->second.widget)break; - settings->setValue(QString(i->first.c_str()),sb->value()); - break; + QString sfs=twsf->item(i,1)->text(); + if(twsf->item(i,0)->checkState()==Qt::CheckState::Unchecked) + sfs="#"+sfs; + sflist.push_back(sfs); } - case 4: + return new QVariant(sflist); + }; + auto load_func=[twsf](void* data){ + QList<QVariant> sflist=static_cast<QVariant*>(data)->toList(); + twsf->clearContents(); + twsf->setRowCount(0); + for(int i=0;i<sflist.size();++i) { - QLineEdit* te=(QLineEdit*)i->second.widget;if(!i->second.widget)break; - settings->setValue(QString(i->first.c_str()),te->text()); - break; + twsf->insertRow(i); + QTableWidgetItem *sfn,*sfe; + QString sf=sflist[i].toString(); + bool enabled=!sf.startsWith('#'); + if(!enabled)sf=sf.mid(1); + twsf->setItem(i,1,sfn=new QTableWidgetItem(sf)); + twsf->setItem(i,0,sfe=new QTableWidgetItem()); + sfn->setFlags(Qt::ItemFlag::ItemIsEnabled|Qt::ItemFlag::ItemIsSelectable); + sfe->setFlags(Qt::ItemFlag::ItemIsEnabled|Qt::ItemFlag::ItemIsSelectable|Qt::ItemFlag::ItemIsUserCheckable); + sfe->setCheckState(enabled?Qt::CheckState::Checked:Qt::CheckState::Unchecked); } - case 5: + }; + settings->registerOptionCustom("SoundFonts","","FluidSynth/SoundFonts",sfpanel,&sf_def_val,save_func,load_func); +} + +void qmpSettingsWindow::registerPluginOption(qmpPluginManager *pmgr) +{ + QTableWidget *twplugins=new QTableWidget(); + twplugins->setColumnCount(4); + twplugins->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeMode::ResizeToContents); + twplugins->setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection); + twplugins->setSelectionBehavior(QAbstractItemView::SelectionBehavior::SelectRows); + twplugins->setHorizontalHeaderLabels({tr("E"),tr("Plugin Name"),tr("Version"),tr("Path")}); + twplugins->setHorizontalScrollMode(QAbstractItemView::ScrollMode::ScrollPerPixel); + twplugins->setVerticalScrollMode(QAbstractItemView::ScrollMode::ScrollPerPixel); + QVariant ep_def_val=QList<QVariant>(); + auto save_func=[twplugins,this]()->void*{ + QVariant *data=static_cast<QVariant*>(settings->getOptionCustom("DisabledPlugins")); + QList<QVariant> disabled_plugins_ol=static_cast<QVariant*>(data)->toList(); + delete data; + std::set<std::string> disabled_plugins_s; + for(auto &i:disabled_plugins_ol) + disabled_plugins_s.insert(i.toString().toStdString()); + for(int i=0;i<twplugins->rowCount();++i) { - QComboBox* cb=(QComboBox*)i->second.widget;if(!i->second.widget)break; - settings->setValue(QString(i->first.c_str()),cb->currentIndex()); - break; + QString pn=twplugins->item(i,1)->text(); + if(twplugins->item(i,0)->checkState()==Qt::CheckState::Unchecked) + disabled_plugins_s.insert(pn.toStdString()); + else + disabled_plugins_s.erase(pn.toStdString()); } - case 6: + QList<QVariant> disabled_plugins; + for(auto &i:disabled_plugins_s) + disabled_plugins.push_back(QString(i.c_str())); + return new QVariant(disabled_plugins); + }; + auto load_func=[twplugins,pmgr](void* data){ + QList<QVariant> disabled_plugins_l=static_cast<QVariant*>(data)->toList(); + std::set<std::string> disabled_plugins; + for(auto i:disabled_plugins_l) + disabled_plugins.insert(i.toString().toStdString()); + + twplugins->clearContents(); + twplugins->setRowCount(0); + + std::vector<qmpPlugin> *plugins=pmgr->getPlugins(); + for(int i=0;static_cast<size_t>(i)<plugins->size();++i) { - QFileEdit* fe=(QFileEdit*)i->second.widget;if(!i->second.widget)break; - settings->setValue(QString(i->first.c_str()),fe->text()); - break; + twplugins->insertRow(i); + qmpPlugin &p=plugins->at(static_cast<size_t>(i)); + QTableWidgetItem *icb; + twplugins->setItem(i,0,icb=new QTableWidgetItem()); + bool enabled=disabled_plugins.find(p.name)==disabled_plugins.end(); + icb->setCheckState(enabled?Qt::CheckState::Checked:Qt::CheckState::Unchecked); + icb->setFlags(Qt::ItemFlag::ItemIsEnabled|Qt::ItemFlag::ItemIsSelectable|Qt::ItemFlag::ItemIsUserCheckable); + twplugins->setItem(i,1,new QTableWidgetItem(p.name.c_str())); + twplugins->setItem(i,2,new QTableWidgetItem(p.version.c_str())); + twplugins->setItem(i,3,new QTableWidgetItem(p.path.c_str())); + for(int j=1;j<=3;++j) + twplugins->item(i,j)->setFlags(Qt::ItemFlag::ItemIsEnabled|Qt::ItemFlag::ItemIsSelectable); } - } + }; + settings->registerOptionCustom("Plugins","","DisabledPlugins",twplugins,&ep_def_val,save_func,load_func); } -void qmpSettingsWindow::registerOptionInt(std::string tab,std::string desc,std::string key,int min,int max,int defaultval) -{ - customOptions[key].widget=nullptr; - customOptions[key].desc=desc; - customOptions[key].defaultval=defaultval; - customOptions[key].minv=min; - customOptions[key].maxv=max; - customOptions[key].type=0; - if(desc.length()) - { - QGridLayout* page=nullptr; - if(customOptPages[tab])page=customOptPages[tab]; - else - { - QWidget* w=new QWidget; - page=new QGridLayout(w); - w->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); - ui->tabWidget->addTab(w,QString(tab.c_str())); - customOptPages[tab]=page; - } - QSpinBox* sb=new QSpinBox(page->parentWidget()); - QLabel* lb=new QLabel(desc.c_str(),page->parentWidget()); - customOptions[key].widget=sb; - sb->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Fixed); - lb->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); - int row=page->rowCount(); - page->addWidget(lb,row,0); - page->addWidget(sb,row,1); - sb->setMaximum(max); - sb->setMinimum(min); - sb->setValue(settings->value(QString(key.c_str()),defaultval).toInt()); - } -} -int qmpSettingsWindow::getOptionInt(std::string key) +void qmpSettingsWindow::registerExtraMidiOptions() { - return settings->value(QString(key.c_str()),customOptions[key].defaultval).toInt(); -} -void qmpSettingsWindow::setOptionInt(std::string key,int val) -{ - settings->setValue(QString(key.c_str()),val); - if(customOptions[key].widget) - ((QSpinBox*)customOptions[key].widget)->setValue(val); + QPushButton *pbDevPrio=new QPushButton("..."); + connect(pbDevPrio,&QPushButton::clicked,[this]{loadOption("Midi/DevicePriority");devpriod->show();}); + connect(devpriod,&QDialog::accepted,[this]{saveOption("Midi/DevicePriority");}); + connect(devpriod,&QDialog::rejected,[this]{loadOption("Midi/DevicePriority");}); + QVariant devprio_def_val=QList<QVariant>({"Internal FluidSynth"}); + settings->registerOptionCustom("MIDI","Select MIDI output devices","Midi/DevicePriority",pbDevPrio,&devprio_def_val,std::bind(&qmpDevicePriorityDialog::save,devpriod),std::bind(&qmpDevicePriorityDialog::load,devpriod,std::placeholders::_1)); + + QPushButton *pbDevProp=new QPushButton("..."); + connect(pbDevProp,&QPushButton::clicked,[this]{loadOption("Midi/DeviceInitializationFiles");dps->show();}); + connect(dps,&QDialog::accepted,[this]{saveOption("Midi/DeviceInitializationFiles");}); + connect(dps,&QDialog::rejected,[this]{loadOption("Midi/DeviceInitializationFiles");}); + QVariant devprop_def_val=QList<QVariant>({}); + settings->registerOptionCustom("MIDI","External MIDI device setup","Midi/DeviceInitializationFiles",pbDevProp,&devprop_def_val,std::bind(&qmpDevPropDialog::save,dps),std::bind(&qmpDevPropDialog::load,dps,std::placeholders::_1)); } -void qmpSettingsWindow::registerOptionUint(std::string tab,std::string desc,std::string key,unsigned min,unsigned max,unsigned defaultval) +void qmpSettingsWindow::saveOption(std::string key) { - customOptions[key].widget=nullptr; - customOptions[key].desc=desc; - customOptions[key].defaultval=defaultval; - customOptions[key].minv=min; - customOptions[key].maxv=max; - customOptions[key].type=1; - if(desc.length()) + auto save_opt=[this](std::string& key)->QVariant { - QGridLayout* page=nullptr; - if(customOptPages[tab])page=customOptPages[tab]; - else + qmpOption &o=settings->options[key]; + QVariant ret; + switch(o.type) { - QWidget* w=new QWidget; - page=new QGridLayout(w); - w->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); - ui->tabWidget->addTab(w,QString(tab.c_str())); - customOptPages[tab]=page; + case qmpOption::ParameterType::parameter_int: + { + QSpinBox *sb=qobject_cast<QSpinBox*>(o.widget); + if(sb) + ret=sb->value(); + } + break; + case qmpOption::ParameterType::parameter_uint: + { + QHexSpinBox *sb=qobject_cast<QHexSpinBox*>(o.widget); + if(sb) + { + int val=sb->value(); + ret=reinterpret_cast<unsigned&>(val); + } + } + break; + case qmpOption::ParameterType::parameter_bool: + { + QCheckBox *cb=qobject_cast<QCheckBox*>(o.widget); + if(cb) + ret=cb->isChecked(); + } + break; + case qmpOption::ParameterType::parameter_double: + { + QDoubleSpinBox *sb=qobject_cast<QDoubleSpinBox*>(o.widget); + if(sb) + ret=sb->value(); + } + break; + case qmpOption::ParameterType::parameter_str: + { + QLineEdit *le=qobject_cast<QLineEdit*>(o.widget); + if(le) + ret=le->text(); + } + break; + case qmpOption::ParameterType::parameter_enum: + { + QComboBox *cb=qobject_cast<QComboBox*>(o.widget); + if(cb) + ret=cb->currentText(); + } + break; + case qmpOption::ParameterType::parameter_url: + { + QFileEdit *fe=qobject_cast<QFileEdit*>(o.widget); + if(fe) + ret=fe->text(); + } + break; + default: + if(o.save_func) + { + QVariant* var=static_cast<QVariant*>(o.save_func()); + ret=QVariant(*var); + delete var; + } + break; } - QHexSpinBox* sb=new QHexSpinBox(page->parentWidget()); - QLabel* lb=new QLabel(desc.c_str(),page->parentWidget()); - customOptions[key].widget=sb; - sb->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Fixed); - lb->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); - int row=page->rowCount(); - page->addWidget(lb,row,0); - page->addWidget(sb,row,1); - //sb->setMaximum(i(max));sb->setMinimum(i(min)); - sb->setValue(settings->value(QString(key.c_str()),defaultval).toUInt()); + return ret; + }; + if(key.length()) + { + QVariant r=save_opt(key); + if(r.isValid()) + settings->settings->setValue(QString(key.c_str()),r); } -} -unsigned qmpSettingsWindow::getOptionUint(std::string key) -{ - return settings->value(QString(key.c_str()),customOptions[key].defaultval).toUInt(); -} -void qmpSettingsWindow::setOptionUint(std::string key,unsigned val) -{ - settings->setValue(QString(key.c_str()),val); - if(customOptions[key].widget) - ((QHexSpinBox*)customOptions[key].widget)->setValue(val); -} - -void qmpSettingsWindow::registerOptionBool(std::string tab,std::string desc,std::string key,bool defaultval) -{ - customOptions[key].widget=nullptr; - customOptions[key].desc=desc; - customOptions[key].defaultval=defaultval; - customOptions[key].type=2; - if(desc.length()) + else for(std::string& key:settings->optionlist) { - QGridLayout* page=nullptr; - if(customOptPages[tab])page=customOptPages[tab]; - else - { - QWidget* w=new QWidget; - page=new QGridLayout(w); - w->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); - ui->tabWidget->addTab(w,QString(tab.c_str())); - customOptPages[tab]=page; - } - QCheckBox* cb=new QCheckBox(desc.c_str(),page->parentWidget()); - customOptions[key].widget=cb; - cb->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); - int row=page->rowCount(); - page->addWidget(cb,row,0,1,2); - cb->setChecked(settings->value(QString(key.c_str()),(int)defaultval).toInt()); + QVariant r=save_opt(key); + if(r.isValid()) + settings->settings->setValue(QString(key.c_str()),r); } -} -bool qmpSettingsWindow::getOptionBool(std::string key) -{ - return settings->value(QString(key.c_str()),(int)customOptions[key].defaultval.toBool()).toInt(); -} -void qmpSettingsWindow::setOptionBool(std::string key,bool val) -{ - settings->setValue(QString(key.c_str()),val?1:0); - if(customOptions[key].widget) - ((QCheckBox*)customOptions[key].widget)->setChecked(val); + settings->settings->sync(); } -void qmpSettingsWindow::registerOptionDouble(std::string tab,std::string desc,std::string key,double min,double max,double defaultval) +void qmpSettingsWindow::loadOption(std::string key) { - customOptions[key].widget=nullptr; - customOptions[key].desc=desc; - customOptions[key].defaultval=defaultval; - customOptions[key].minv=min; - customOptions[key].maxv=max; - customOptions[key].type=3; - if(desc.length()) + auto load_opt=[this](std::string& key) { - QGridLayout* page=nullptr; - if(customOptPages[tab])page=customOptPages[tab]; - else + qmpOption &o=settings->options[key]; + switch(o.type) { - QWidget* w=new QWidget; - page=new QGridLayout(w); - w->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); - ui->tabWidget->addTab(w,QString(tab.c_str())); - customOptPages[tab]=page; + case qmpOption::ParameterType::parameter_int: + { + QSpinBox *sb=qobject_cast<QSpinBox*>(o.widget); + if(sb) + sb->setValue(settings->getOptionInt(key)); + } + break; + case qmpOption::ParameterType::parameter_uint: + { + QHexSpinBox *sb=qobject_cast<QHexSpinBox*>(o.widget); + if(sb) + sb->setValue(settings->getOptionUint(key)); + } + break; + case qmpOption::ParameterType::parameter_bool: + { + QCheckBox *cb=qobject_cast<QCheckBox*>(o.widget); + if(cb) + cb->setChecked(settings->getOptionBool(key)); + } + break; + case qmpOption::ParameterType::parameter_double: + { + QDoubleSpinBox *sb=qobject_cast<QDoubleSpinBox*>(o.widget); + if(sb) + sb->setValue(settings->getOptionDouble(key)); + } + break; + case qmpOption::ParameterType::parameter_str: + { + QLineEdit *le=qobject_cast<QLineEdit*>(o.widget); + if(le) + le->setText(QString(settings->getOptionString(key).c_str())); + } + break; + case qmpOption::ParameterType::parameter_enum: + { + QComboBox *cb=qobject_cast<QComboBox*>(o.widget); + if(cb) + cb->setCurrentIndex(settings->getOptionEnumInt(key)); + } + break; + case qmpOption::ParameterType::parameter_url: + { + QFileEdit *fe=qobject_cast<QFileEdit*>(o.widget); + if(fe) + fe->setText(QString(settings->getOptionString(key).c_str())); + } + break; + default: + if(o.load_func) + { + void *var=settings->getOptionCustom(key); + o.load_func(var); + delete static_cast<QVariant*>(var); + } + break; } - QDoubleSpinBox* sb=new QDoubleSpinBox(page->parentWidget()); - QLabel* lb=new QLabel(desc.c_str(),page->parentWidget()); - customOptions[key].widget=sb; - sb->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Fixed); - lb->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); - int row=page->rowCount(); - page->addWidget(lb,row,0); - page->addWidget(sb,row,1); - sb->setMaximum(max); - sb->setMinimum(min); - sb->setValue(settings->value(QString(key.c_str()),defaultval).toDouble()); - } -} -double qmpSettingsWindow::getOptionDouble(std::string key) -{ - return settings->value(QString(key.c_str()),customOptions[key].defaultval).toDouble(); -} -void qmpSettingsWindow::setOptionDouble(std::string key,double val) -{ - settings->setValue(QString(key.c_str()),val); - if(customOptions[key].widget) - ((QDoubleSpinBox*)customOptions[key].widget)->setValue(val); + }; + if(key.length())load_opt(key); + else for(std::string& key:settings->optionlist) + load_opt(key); } -void qmpSettingsWindow::registerOptionString(std::string tab,std::string desc,std::string key,std::string defaultval,bool ispath) +void qmpSettingsWindow::setupWidgets() { - customOptions[key].widget=nullptr; - customOptions[key].desc=desc; - customOptions[key].defaultval=QString(defaultval.c_str()); - customOptions[key].type=4; - if(ispath)customOptions[key].type=6; - if(desc.length()) + for(std::string& key:settings->optionlist) { - QGridLayout* page=nullptr; - if(customOptPages[tab])page=customOptPages[tab]; - else + if(!settings->options[key].desc.length()&&settings->options[key].type!=qmpOption::ParameterType::parameter_custom) + continue; + QWidget *optw=nullptr; + qmpOption &o=settings->options[key]; + switch(o.type) { - QWidget* w=new QWidget; - page=new QGridLayout(w); - w->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); - ui->tabWidget->addTab(w,QString(tab.c_str())); - customOptPages[tab]=page; - } - int row=page->rowCount(); - if(ispath) - { - QFileEdit* fe=new QFileEdit(page->parentWidget()); - fe->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Fixed); - customOptions[key].widget=fe; - fe->setText(settings->value(QString(key.c_str()),defaultval.c_str()).toString()); - page->addWidget(fe,row,1); + case qmpOption::ParameterType::parameter_int: + { + QSpinBox *sb=new QSpinBox; + sb->setMinimum(o.minv.toInt()); + sb->setMaximum(o.maxv.toInt()); + sb->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Fixed); + optw=sb; + } + break; + case qmpOption::ParameterType::parameter_uint: + { + QHexSpinBox *sb=new QHexSpinBox; + sb->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Fixed); + optw=sb; + } + break; + case qmpOption::ParameterType::parameter_bool: + { + QCheckBox *cb=new QCheckBox(QString(o.desc.c_str())); + cb->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); + optw=cb; + } + break; + case qmpOption::ParameterType::parameter_double: + { + QDoubleSpinBox *sb=new QDoubleSpinBox; + sb->setMinimum(o.minv.toDouble()); + sb->setMaximum(o.maxv.toDouble()); + sb->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Fixed); + optw=sb; + } + break; + case qmpOption::ParameterType::parameter_str: + { + QLineEdit* te=new QLineEdit(); + te->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Fixed); + optw=te; + } + break; + case qmpOption::ParameterType::parameter_enum: + { + QComboBox* cb=new QComboBox(); + for(std::string& item:o.enumlist)cb->addItem(QString(item.c_str())); + cb->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Fixed); + optw=cb; + } + break; + case qmpOption::ParameterType::parameter_url: + { + QFileEdit* fe=new QFileEdit(); + fe->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Fixed); + optw=fe; + } + break; + default: + optw=o.widget; + break; } - else + o.widget=optw; + QGridLayout* page=pageForTab(o.tab); + if(o.type==qmpOption::ParameterType::parameter_bool|| + (o.type==qmpOption::parameter_custom&&!o.desc.length())) { - QLineEdit* te=new QLineEdit(page->parentWidget()); - te->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Fixed); - customOptions[key].widget=te; - te->setText(settings->value(QString(key.c_str()),defaultval.c_str()).toString()); - page->addWidget(te,row,1); + int row=page->rowCount(); + page->addWidget(o.widget,row,0,1,2); } - QLabel* lb=new QLabel(desc.c_str(),page->parentWidget()); - lb->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); - page->addWidget(lb,row,0); - } -} -std::string qmpSettingsWindow::getOptionString(std::string key) -{ - return settings->value(QString(key.c_str()),customOptions[key].defaultval).toString().toStdString(); -} -void qmpSettingsWindow::setOptionString(std::string key,std::string val) -{ - settings->setValue(QString(key.c_str()),QString(val.c_str())); - if(customOptions[key].widget) - { - if(customOptions[key].type==4) - ((QLineEdit*)customOptions[key].widget)->setText(val.c_str()); - else if(customOptions[key].type==6) - ((QFileEdit*)customOptions[key].widget)->setText(val.c_str()); - } -} - -void qmpSettingsWindow::registerOptionEnumInt(std::string tab,std::string desc,std::string key,std::vector<std::string> options,int defaultval) -{ - customOptions[key].widget=nullptr; - customOptions[key].desc=desc; - customOptions[key].defaultval=defaultval; - customOptions[key].type=5; - if(desc.length()) - { - QGridLayout* page=nullptr; - if(customOptPages[tab])page=customOptPages[tab]; else { - QWidget* w=new QWidget; - page=new QGridLayout(w); - w->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); - ui->tabWidget->addTab(w,QString(tab.c_str())); - customOptPages[tab]=page; + QLabel* lb=new QLabel(o.desc.c_str(),page->parentWidget()); + lb->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); + int row=page->rowCount(); + page->addWidget(lb,row,0); + page->addWidget(o.widget,row,1); } - QComboBox* sb=new QComboBox(page->parentWidget()); - QLabel* lb=new QLabel(desc.c_str(),page->parentWidget()); - customOptions[key].widget=sb; - for(unsigned i=0;i<options.size();++i)sb->addItem(options[i].c_str()); - sb->setCurrentIndex(settings->value(QString(key.c_str()),defaultval).toInt()); - sb->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Fixed); - lb->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); - int row=page->rowCount(); - page->addWidget(lb,row,0); - page->addWidget(sb,row,1); - } -} -int qmpSettingsWindow::getOptionEnumInt(std::string key) -{ - return settings->value(QString(key.c_str()),customOptions[key].defaultval).toInt(); -} -void qmpSettingsWindow::setOptionEnumInt(std::string key,int val) -{ - settings->setValue(QString(key.c_str()),val); - if(customOptions[key].widget) - ((QComboBox*)customOptions[key].widget)->setCurrentIndex(val); -} - -void qmpSettingsWindow::on_pbCustomizeTb_clicked() -{ - cw->launch(0); + loadOption(); } -void qmpSettingsWindow::on_pbCustomizeAct_clicked() +QGridLayout* qmpSettingsWindow::pageForTab(std::string tab) { - cw->launch(1); + if(customOptPages.find(tab)!=customOptPages.end()) + return customOptPages[tab]; + QWidget* w=new QWidget; + QGridLayout* page=new QGridLayout(w); + w->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); + ui->tabWidget->addTab(w,QString(tab.c_str())); + customOptPages[tab]=page; + return page; } QFileEdit::QFileEdit(QWidget *par):QWidget(par) @@ -752,13 +583,3 @@ void QFileEdit::chooseFile() QString s=QFileDialog::getOpenFileName(nullptr,tr("Select a file"),QFileInfo(text()).dir().absolutePath()); if(s.length())setText(s); } - -void qmpSettingsWindow::on_pbExtDevSetup_clicked() -{ - dps->launch(); -} - -void qmpSettingsWindow::on_pbDevPrio_clicked() -{ - devpriod->show(); -} diff --git a/qmidiplayer-desktop/qmpsettingswindow.hpp b/qmidiplayer-desktop/qmpsettingswindow.hpp index c1ae410..5243ca9 100644 --- a/qmidiplayer-desktop/qmpsettingswindow.hpp +++ b/qmidiplayer-desktop/qmpsettingswindow.hpp @@ -12,6 +12,7 @@ #include <QComboBox> #include <QSpinBox> #include <QFormLayout> +#include "qmpsettings.hpp" #include "qmpplugin.hpp" #include "qmpcustomizewindow.hpp" #include "qmpdevpropdialog.hpp" @@ -20,13 +21,6 @@ namespace Ui { class qmpSettingsWindow; } -struct qmpCustomOption -{ - QWidget* widget; - std::string desc;int type; - QVariant defaultval,minv,maxv; -}; - class QLineEdit; class QToolButton; class QFileEdit:public QWidget @@ -60,7 +54,7 @@ class QHexSpinBox:public QSpinBox } int valueFromText(const QString &text)const { - return i(text.toUInt(0,16)); + return i(text.toUInt(nullptr,16)); } QValidator::State validate(QString &input,int &pos)const { @@ -74,9 +68,9 @@ class QHexSpinBox:public QSpinBox return QValidator::Acceptable; } inline unsigned int u(int i)const - {return *reinterpret_cast<unsigned int*>(&i);} + {return reinterpret_cast<unsigned&>(i);} inline int i(unsigned int u)const - {return *reinterpret_cast<int*>(&u);} + {return reinterpret_cast<int&>(u);} }; class qmpDevicePriorityDialog; @@ -86,31 +80,16 @@ class qmpSettingsWindow:public QDialog Q_OBJECT public: - explicit qmpSettingsWindow(QWidget *parent=nullptr); + explicit qmpSettingsWindow(qmpSettings *qmpsettings,QWidget *parent=nullptr); ~qmpSettingsWindow(); void closeEvent(QCloseEvent *event); void hideEvent(QHideEvent *event); - void settingsInit(); void updatePluginList(qmpPluginManager *pmgr); - void registerOptionInt(std::string tab,std::string desc,std::string key,int min,int max,int defaultval); - int getOptionInt(std::string key); - void setOptionInt(std::string key,int val); - void registerOptionUint(std::string tab,std::string desc,std::string key,unsigned min,unsigned max,unsigned defaultval); - unsigned getOptionUint(std::string key); - void setOptionUint(std::string key,unsigned val); - void registerOptionBool(std::string tab,std::string desc,std::string key,bool defaultval); - bool getOptionBool(std::string key); - void setOptionBool(std::string key,bool val); - void registerOptionDouble(std::string tab,std::string desc,std::string key,double min,double max,double defaultval); - double getOptionDouble(std::string key); - void setOptionDouble(std::string key,double val); - void registerOptionString(std::string tab,std::string desc,std::string key,std::string defaultval,bool ispath); - std::string getOptionString(std::string key); - void setOptionString(std::string key,std::string val); - void registerOptionEnumInt(std::string tab,std::string desc,std::string key,std::vector<std::string> options,int defaultval); - int getOptionEnumInt(std::string key); - void setOptionEnumInt(std::string key,int val); void postInit(); + void registerCustomizeWidgetOptions(); + void registerSoundFontOption(); + void registerPluginOption(qmpPluginManager *pmgr); + void registerExtraMidiOptions(); signals: void dialogClosing(); @@ -118,36 +97,18 @@ class qmpSettingsWindow:public QDialog void on_buttonBox_accepted(); void on_buttonBox_rejected(); - void on_cbBufSize_currentTextChanged(const QString &s); - void on_cbBufCnt_currentTextChanged(const QString &s); - - void on_pbAdd_clicked(); - void on_pbRemove_clicked(); - void on_pbUp_clicked(); - void on_pbDown_clicked(); - - void on_cbAutoBS_stateChanged(); - - void on_pbCustomizeTb_clicked(); - - void on_pbCustomizeAct_clicked(); - - void on_pbExtDevSetup_clicked(); - - void on_pbDevPrio_clicked(); - private: Ui::qmpSettingsWindow *ui; - void settingsUpdate(); - std::map<std::string,qmpCustomOption> customOptions; + std::map<std::string,qmpOption> customOptions; std::map<std::string,QGridLayout*> customOptPages; - void updateCustomOptions(); - qmpCustomizeWindow *cw; + void saveOption(std::string key=std::string()); + void loadOption(std::string key=std::string()); + void setupWidgets(); + QGridLayout* pageForTab(std::string tab); + qmpCustomizeWindow *cwt,*cwa; qmpDevPropDialog *dps; qmpDevicePriorityDialog *devpriod; - static QSettings *settings; - public: - static QSettings* getSettingsIntf(){return settings;} + qmpSettings *settings; }; #endif // QMPSETTINGSWINDOW_H diff --git a/qmidiplayer-desktop/qmpsettingswindow.ui b/qmidiplayer-desktop/qmpsettingswindow.ui index 6cdd665..addf886 100644 --- a/qmidiplayer-desktop/qmpsettingswindow.ui +++ b/qmidiplayer-desktop/qmpsettingswindow.ui @@ -23,743 +23,8 @@ <item> <widget class="QTabWidget" name="tabWidget"> <property name="currentIndex"> - <number>0</number> + <number>-1</number> </property> - <widget class="QWidget" name="tab"> - <attribute name="title"> - <string>Midi</string> - </attribute> - <layout class="QVBoxLayout" name="verticalLayout_4"> - <item> - <widget class="QCheckBox" name="cbDisableMapping"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Disable Midi Mapping</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="cbSendSysx"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Send SysEx</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="cbWaitVoice"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Wait for remaining voices before stopping</string> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_7"> - <item> - <widget class="QLabel" name="lbEncoding"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Text Encoding</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="cbEncoding"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <item> - <property name="text"> - <string>Unicode</string> - </property> - </item> - <item> - <property name="text"> - <string>Big5</string> - </property> - </item> - <item> - <property name="text"> - <string>Big5-HKSCS</string> - </property> - </item> - <item> - <property name="text"> - <string>CP949</string> - </property> - </item> - <item> - <property name="text"> - <string>EUC-JP</string> - </property> - </item> - <item> - <property name="text"> - <string>EUC-KR</string> - </property> - </item> - <item> - <property name="text"> - <string>GB18030</string> - </property> - </item> - <item> - <property name="text"> - <string>KOI8-R</string> - </property> - </item> - <item> - <property name="text"> - <string>KOI8-U</string> - </property> - </item> - <item> - <property name="text"> - <string>Macintosh</string> - </property> - </item> - <item> - <property name="text"> - <string>Shift-JIS</string> - </property> - </item> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_8"> - <item> - <widget class="QLabel" name="lbDevPrio"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Select MIDI output devices</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="pbDevPrio"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>...</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_5"> - <item> - <widget class="QLabel" name="lbExtDevSetup"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>External MIDI output device setup</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="pbExtDevSetup"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>...</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - <widget class="QWidget" name="tab_2"> - <attribute name="title"> - <string>Synth</string> - </attribute> - <layout class="QGridLayout" name="gridLayout_2"> - <item row="2" column="0"> - <widget class="QLabel" name="lbBufCnt"> - <property name="text"> - <string>Audio Buffer Count</string> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="lbBufSize"> - <property name="text"> - <string>Audio Buffer Size</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QComboBox" name="cbBufSize"> - <property name="editable"> - <bool>true</bool> - </property> - <property name="currentIndex"> - <number>1</number> - </property> - <item> - <property name="text"> - <string>64</string> - </property> - </item> - <item> - <property name="text"> - <string>128</string> - </property> - </item> - <item> - <property name="text"> - <string>256</string> - </property> - </item> - <item> - <property name="text"> - <string>512</string> - </property> - </item> - <item> - <property name="text"> - <string>1024</string> - </property> - </item> - <item> - <property name="text"> - <string>2048</string> - </property> - </item> - <item> - <property name="text"> - <string>4096</string> - </property> - </item> - <item> - <property name="text"> - <string>8192</string> - </property> - </item> - </widget> - </item> - <item row="4" column="0"> - <widget class="QLabel" name="lbFrequency"> - <property name="text"> - <string>Sample Rate</string> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QComboBox" name="cbBufCnt"> - <property name="editable"> - <bool>true</bool> - </property> - <item> - <property name="text"> - <string>2</string> - </property> - </item> - <item> - <property name="text"> - <string>4</string> - </property> - </item> - <item> - <property name="text"> - <string>8</string> - </property> - </item> - <item> - <property name="text"> - <string>16</string> - </property> - </item> - <item> - <property name="text"> - <string>32</string> - </property> - </item> - <item> - <property name="text"> - <string>64</string> - </property> - </item> - </widget> - </item> - <item row="0" column="0"> - <widget class="QLabel" name="lbAudioDrv"> - <property name="text"> - <string>Audio Driver</string> - </property> - </widget> - </item> - <item row="3" column="1"> - <widget class="QComboBox" name="cbFormat"> - <item> - <property name="text"> - <string>16bits</string> - </property> - </item> - <item> - <property name="text"> - <string>float</string> - </property> - </item> - </widget> - </item> - <item row="0" column="1"> - <widget class="QComboBox" name="cbAudioDrv"/> - </item> - <item row="4" column="1"> - <widget class="QComboBox" name="cbFrequency"> - <property name="currentIndex"> - <number>2</number> - </property> - <item> - <property name="text"> - <string>22050</string> - </property> - </item> - <item> - <property name="text"> - <string>44100</string> - </property> - </item> - <item> - <property name="text"> - <string>48000</string> - </property> - </item> - <item> - <property name="text"> - <string>96000</string> - </property> - </item> - </widget> - </item> - <item row="3" column="0"> - <widget class="QLabel" name="lbFormat"> - <property name="text"> - <string>Sample Format</string> - </property> - </widget> - </item> - <item row="5" column="1"> - <widget class="QSpinBox" name="sbPolyphony"> - <property name="minimum"> - <number>1</number> - </property> - <property name="maximum"> - <number>65535</number> - </property> - <property name="value"> - <number>2048</number> - </property> - </widget> - </item> - <item row="5" column="0"> - <widget class="QLabel" name="lbPolyphony"> - <property name="text"> - <string>Max Polyphony</string> - </property> - </widget> - </item> - <item row="7" column="0"> - <widget class="QCheckBox" name="cbAutoBS"> - <property name="text"> - <string>Auto bank select mode</string> - </property> - </widget> - </item> - <item row="8" column="0"> - <widget class="QLabel" name="lbBSMode"> - <property name="text"> - <string>Bank select mode</string> - </property> - </widget> - </item> - <item row="8" column="1"> - <widget class="QComboBox" name="cbBSMode"> - <property name="currentIndex"> - <number>1</number> - </property> - <item> - <property name="text"> - <string>Ignored</string> - </property> - </item> - <item> - <property name="text"> - <string>CC#0</string> - </property> - </item> - <item> - <property name="text"> - <string>CC#32</string> - </property> - </item> - <item> - <property name="text"> - <string>CC#0*128+CC#32</string> - </property> - </item> - </widget> - </item> - <item row="6" column="0"> - <widget class="QLabel" name="lbCPUCores"> - <property name="text"> - <string>CPU Cores</string> - </property> - </widget> - </item> - <item row="6" column="1"> - <widget class="QSpinBox" name="sbCPUCores"> - <property name="minimum"> - <number>1</number> - </property> - <property name="maximum"> - <number>256</number> - </property> - </widget> - </item> - </layout> - </widget> - <widget class="QWidget" name="tab_3"> - <attribute name="title"> - <string>Soundfonts</string> - </attribute> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <item> - <widget class="QTableWidget" name="twSoundfont"> - <property name="dragDropMode"> - <enum>QAbstractItemView::InternalMove</enum> - </property> - <property name="selectionMode"> - <enum>QAbstractItemView::SingleSelection</enum> - </property> - <property name="selectionBehavior"> - <enum>QAbstractItemView::SelectRows</enum> - </property> - <column> - <property name="text"> - <string>E</string> - </property> - </column> - <column> - <property name="text"> - <string>Path</string> - </property> - </column> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QPushButton" name="pbAdd"> - <property name="text"> - <string/> - </property> - <property name="icon"> - <iconset resource="resources.qrc"> - <normaloff>:/img/add.svg</normaloff>:/img/add.svg</iconset> - </property> - <property name="iconSize"> - <size> - <width>24</width> - <height>24</height> - </size> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="pbRemove"> - <property name="text"> - <string/> - </property> - <property name="icon"> - <iconset resource="resources.qrc"> - <normaloff>:/img/remove.svg</normaloff>:/img/remove.svg</iconset> - </property> - <property name="iconSize"> - <size> - <width>24</width> - <height>24</height> - </size> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="pbUp"> - <property name="text"> - <string/> - </property> - <property name="icon"> - <iconset resource="resources.qrc"> - <normaloff>:/img/up.svg</normaloff>:/img/up.svg</iconset> - </property> - <property name="iconSize"> - <size> - <width>24</width> - <height>24</height> - </size> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="pbDown"> - <property name="text"> - <string/> - </property> - <property name="icon"> - <iconset resource="resources.qrc"> - <normaloff>:/img/down.svg</normaloff>:/img/down.svg</iconset> - </property> - <property name="iconSize"> - <size> - <width>24</width> - <height>24</height> - </size> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - <widget class="QWidget" name="tab_4"> - <attribute name="title"> - <string>Behavior</string> - </attribute> - <layout class="QVBoxLayout" name="verticalLayout_3"> - <item> - <widget class="QCheckBox" name="cbRestorePlaylist"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Restore last playlist on startup</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="cbLoadFolder"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Load files in the same folder</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="cbDialogStatus"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Save dialog status</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="cbSaveEfxParam"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Save parameters in effects window</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="cbPersistentfs"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Persistent fluidsynth instance</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="cbShowLabel"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Show label beside icon in toolbar buttons</string> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_2"> - <item> - <widget class="QLabel" name="label"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Icon Theme</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="cbIconTheme"> - <item> - <property name="text"> - <string>Auto</string> - </property> - </item> - <item> - <property name="text"> - <string>Dark</string> - </property> - </item> - <item> - <property name="text"> - <string>Light</string> - </property> - </item> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_3"> - <item> - <widget class="QLabel" name="lbCustomizeTb"> - <property name="text"> - <string>Customize toolbar</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="pbCustomizeTb"> - <property name="text"> - <string>Customize</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_4"> - <item> - <widget class="QLabel" name="lbCustomizeAct"> - <property name="text"> - <string>Customize actions</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="pbCustomizeAct"> - <property name="text"> - <string>Customize</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - <widget class="QWidget" name="tab_5"> - <attribute name="title"> - <string>Plugins</string> - </attribute> - <layout class="QVBoxLayout" name="verticalLayout_5"> - <item> - <widget class="QTableWidget" name="twPluginList"> - <property name="selectionMode"> - <enum>QAbstractItemView::SingleSelection</enum> - </property> - <property name="selectionBehavior"> - <enum>QAbstractItemView::SelectRows</enum> - </property> - <column> - <property name="text"> - <string>E</string> - </property> - </column> - <column> - <property name="text"> - <string>Name</string> - </property> - </column> - <column> - <property name="text"> - <string>Version</string> - </property> - </column> - <column> - <property name="text"> - <string>Path</string> - </property> - </column> - </widget> - </item> - </layout> - </widget> </widget> </item> <item> @@ -774,9 +39,7 @@ </item> </layout> </widget> - <resources> - <include location="resources.qrc"/> - </resources> + <resources/> <connections> <connection> <sender>buttonBox</sender> diff --git a/qmidiplayer-desktop/translations/qmp_zh_CN.ts b/qmidiplayer-desktop/translations/qmp_zh_CN.ts index 233129e..4721a3a 100644 --- a/qmidiplayer-desktop/translations/qmp_zh_CN.ts +++ b/qmidiplayer-desktop/translations/qmp_zh_CN.ts @@ -4,7 +4,7 @@ <context> <name>QFileEdit</name> <message> - <location filename="../qmpsettingswindow.cpp" line="752"/> + <location filename="../qmpsettingswindow.cpp" line="583"/> <source>Select a file</source> <translation type="unfinished">选择文件</translation> </message> @@ -12,27 +12,27 @@ <context> <name>main</name> <message> - <location filename="../main.cpp" line="59"/> + <location filename="../main.cpp" line="60"/> <source>A cross-platform MIDI player.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.cpp" line="62"/> + <location filename="../main.cpp" line="63"/> <source>midi files to play (optional).</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.cpp" line="63"/> + <location filename="../main.cpp" line="64"/> <source>Load a plugin from <plugin library>.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.cpp" line="64"/> + <location filename="../main.cpp" line="65"/> <source>Load all files from the same folder.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../main.cpp" line="66"/> + <location filename="../main.cpp" line="67"/> <source>Keep console window open.</source> <translation type="unfinished"></translation> </message> @@ -288,7 +288,7 @@ <translation>取消全部独奏</translation> </message> <message> - <location filename="../qmpchannelswindow.cpp" line="293"/> + <location filename="../qmpchannelswindow.cpp" line="275"/> <source>Channel</source> <translation type="unfinished"></translation> </message> @@ -348,6 +348,22 @@ <source>-</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../qmpdevpropdialog.cpp" line="24"/> + <source>Select Device Initialization File</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../qmpdevpropdialog.cpp" line="30"/> + <location filename="../qmpdevpropdialog.cpp" line="96"/> + <source>Disconnected</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../qmpdevpropdialog.cpp" line="34"/> + <source>Connected</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>qmpDevicePriorityDialog</name> @@ -572,27 +588,27 @@ <translation type="vanished">输出到wav文件</translation> </message> <message> - <location filename="../qmpmainwindow.cpp" line="113"/> + <location filename="../qmpmainwindow.cpp" line="122"/> <source>Render to wave</source> <translation>输出wav文件</translation> </message> <message> - <location filename="../qmpmainwindow.cpp" line="114"/> + <location filename="../qmpmainwindow.cpp" line="123"/> <source>Panic</source> <translation>关闭所有音符</translation> </message> <message> - <location filename="../qmpmainwindow.cpp" line="115"/> + <location filename="../qmpmainwindow.cpp" line="124"/> <source>Restart fluidsynth</source> <translation>重新载入FluidSynth</translation> </message> <message> - <location filename="../qmpmainwindow.cpp" line="353"/> + <location filename="../qmpmainwindow.cpp" line="374"/> <source>Error</source> <translation>错误</translation> </message> <message> - <location filename="../qmpmainwindow.cpp" line="353"/> + <location filename="../qmpmainwindow.cpp" line="374"/> <source>%1 is not a valid midi file.</source> <translation>%1是无效的midi文件。</translation> </message> @@ -601,7 +617,7 @@ <name>qmpPlistWindow</name> <message> <location filename="../qmpplistwindow.ui" line="29"/> - <location filename="../qmpplistwindow.cpp" line="73"/> + <location filename="../qmpplistwindow.cpp" line="74"/> <source>Playlist</source> <translation>播放列表</translation> </message> @@ -617,15 +633,15 @@ </message> <message> <location filename="../qmpplistwindow.ui" line="161"/> - <location filename="../qmpplistwindow.cpp" line="213"/> - <location filename="../qmpplistwindow.cpp" line="329"/> + <location filename="../qmpplistwindow.cpp" line="214"/> + <location filename="../qmpplistwindow.cpp" line="330"/> <source>Repeat Off</source> <translation>循环关</translation> </message> <message> <location filename="../qmpplistwindow.ui" line="257"/> - <location filename="../qmpplistwindow.cpp" line="238"/> - <location filename="../qmpplistwindow.cpp" line="322"/> + <location filename="../qmpplistwindow.cpp" line="239"/> + <location filename="../qmpplistwindow.cpp" line="323"/> <source>Shuffle Off</source> <translation>随机关</translation> </message> @@ -650,30 +666,30 @@ <translation>清空</translation> </message> <message> - <location filename="../qmpplistwindow.cpp" line="217"/> - <location filename="../qmpplistwindow.cpp" line="333"/> + <location filename="../qmpplistwindow.cpp" line="218"/> + <location filename="../qmpplistwindow.cpp" line="334"/> <source>Repeat One</source> <translation>循环当前</translation> </message> <message> - <location filename="../qmpplistwindow.cpp" line="221"/> - <location filename="../qmpplistwindow.cpp" line="337"/> + <location filename="../qmpplistwindow.cpp" line="222"/> + <location filename="../qmpplistwindow.cpp" line="338"/> <source>Repeat All</source> <translation>循环全部</translation> </message> <message> - <location filename="../qmpplistwindow.cpp" line="233"/> - <location filename="../qmpplistwindow.cpp" line="317"/> + <location filename="../qmpplistwindow.cpp" line="234"/> + <location filename="../qmpplistwindow.cpp" line="318"/> <source>Shuffle On</source> <translation>随机开</translation> </message> <message> - <location filename="../qmpplistwindow.cpp" line="292"/> + <location filename="../qmpplistwindow.cpp" line="293"/> <source>Save playlist</source> <translation>保存播放列表</translation> </message> <message> - <location filename="../qmpplistwindow.cpp" line="305"/> + <location filename="../qmpplistwindow.cpp" line="306"/> <source>Load playlist</source> <translation>加载播放列表</translation> </message> @@ -727,279 +743,99 @@ <translation>选项</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="30"/> <source>Midi</source> - <translation>MIDI选项</translation> + <translation type="vanished">MIDI选项</translation> </message> <message> <source>Default Output Device</source> <translation type="vanished">默认输出设备</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="42"/> <source>Disable Midi Mapping</source> - <translation>只使用默认输出设备</translation> + <translation type="vanished">只使用默认输出设备</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="55"/> <source>Send SysEx</source> - <translation>发送SysEx指令</translation> + <translation type="vanished">发送SysEx指令</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="68"/> <source>Wait for remaining voices before stopping</source> - <translation>停止前等待复音数降为0</translation> + <translation type="vanished">停止前等待复音数降为0</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="83"/> <source>Text Encoding</source> - <translation type="unfinished">文本编码</translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="97"/> - <source>Unicode</source> - <translation type="unfinished"></translation> + <translation type="obsolete">文本编码</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="102"/> - <source>Big5</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="107"/> - <source>Big5-HKSCS</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="112"/> - <source>CP949</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="117"/> - <source>EUC-JP</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="122"/> - <source>EUC-KR</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="127"/> - <source>GB18030</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="132"/> - <source>KOI8-R</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="137"/> - <source>KOI8-U</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="142"/> - <source>Macintosh</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="147"/> - <source>Shift-JIS</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="165"/> <source>Select MIDI output devices</source> - <translation type="unfinished">选择MIDI输出设备</translation> + <translation type="obsolete">选择MIDI输出设备</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="178"/> - <location filename="../qmpsettingswindow.ui" line="208"/> - <source>...</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="195"/> <source>External MIDI output device setup</source> - <translation type="unfinished">外部MIDI设备设置</translation> + <translation type="obsolete">外部MIDI设备设置</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="218"/> <source>Synth</source> - <translation type="unfinished">合成器</translation> + <translation type="obsolete">合成器</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="224"/> <source>Audio Buffer Count</source> - <translation>音频缓冲区数量</translation> + <translation type="vanished">音频缓冲区数量</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="231"/> <source>Audio Buffer Size</source> - <translation>音频缓冲区大小</translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="245"/> - <location filename="../qmpsettingswindow.ui" line="324"/> - <source>64</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="250"/> - <source>128</source> - <translation type="unfinished"></translation> + <translation type="vanished">音频缓冲区大小</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="255"/> - <source>256</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="260"/> - <source>512</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="265"/> - <source>1024</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="270"/> - <source>2048</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="275"/> - <source>4096</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="280"/> - <source>8192</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="288"/> <source>Sample Rate</source> - <translation type="unfinished">采样率</translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="299"/> - <source>2</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="304"/> - <source>4</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="309"/> - <source>8</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="314"/> - <source>16</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="319"/> - <source>32</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="340"/> - <source>16bits</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="345"/> - <source>float</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="360"/> - <source>22050</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="365"/> - <source>44100</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="370"/> - <source>48000</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="375"/> - <source>96000</source> - <translation type="unfinished"></translation> + <translation type="obsolete">采样率</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="383"/> <source>Sample Format</source> - <translation type="unfinished">采样格式</translation> + <translation type="obsolete">采样格式</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="648"/> <source>Show label beside icon in toolbar buttons</source> - <translation type="unfinished">工具栏按钮中显示文字标签</translation> + <translation type="obsolete">工具栏按钮中显示文字标签</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="663"/> <source>Icon Theme</source> - <translation type="unfinished">图标主题</translation> + <translation type="obsolete">图标主题</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="671"/> <source>Auto</source> - <translation type="unfinished">自动</translation> + <translation type="obsolete">自动</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="676"/> <source>Dark</source> - <translation type="unfinished">暗色</translation> + <translation type="obsolete">暗色</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="681"/> <source>Light</source> - <translation type="unfinished">亮色</translation> + <translation type="obsolete">亮色</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="693"/> <source>Customize toolbar</source> - <translation type="unfinished">自定义工具栏</translation> + <translation type="obsolete">自定义工具栏</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="700"/> - <location filename="../qmpsettingswindow.ui" line="718"/> <source>Customize</source> - <translation type="unfinished">设置</translation> + <translation type="obsolete">设置</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="711"/> <source>Customize actions</source> - <translation type="unfinished">自定义右键菜单</translation> + <translation type="obsolete">自定义右键菜单</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="728"/> <source>Plugins</source> - <translation type="unfinished">插件</translation> + <translation type="obsolete">插件</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="746"/> <source>Name</source> - <translation type="unfinished">名称</translation> + <translation type="obsolete">名称</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="751"/> + <location filename="../qmpsettingswindow.cpp" line="241"/> <source>Version</source> <translation type="unfinished">版本</translation> </message> @@ -1008,110 +844,89 @@ <translation type="vanished">采样频率</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="332"/> <source>Audio Driver</source> - <translation>音频驱动</translation> + <translation type="vanished">音频驱动</translation> </message> <message> <source>Audio Format</source> <translation type="vanished">音频格式</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="403"/> <source>Max Polyphony</source> - <translation>最大复音数</translation> + <translation type="vanished">最大复音数</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="410"/> <source>Auto bank select mode</source> - <translation>自动确定乐器库选择方式</translation> + <translation type="vanished">自动确定乐器库选择方式</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="417"/> <source>Bank select mode</source> - <translation>乐器库选择方式</translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="428"/> - <source>Ignored</source> - <translation type="unfinished"></translation> + <translation type="vanished">乐器库选择方式</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="433"/> - <source>CC#0</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="438"/> - <source>CC#32</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="443"/> - <source>CC#0*128+CC#32</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../qmpsettingswindow.ui" line="451"/> <source>CPU Cores</source> - <translation>合成器线程数</translation> + <translation type="vanished">合成器线程数</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="469"/> <source>Soundfonts</source> - <translation>音源</translation> + <translation type="vanished">音源</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="485"/> - <location filename="../qmpsettingswindow.ui" line="741"/> + <location filename="../qmpsettingswindow.cpp" line="146"/> + <location filename="../qmpsettingswindow.cpp" line="241"/> <source>E</source> <translation>启用</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="490"/> - <location filename="../qmpsettingswindow.ui" line="756"/> + <location filename="../qmpsettingswindow.cpp" line="146"/> + <location filename="../qmpsettingswindow.cpp" line="241"/> <source>Path</source> <translation>路径</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="571"/> <source>Behavior</source> - <translation>行为设定</translation> + <translation type="vanished">行为设定</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="583"/> <source>Restore last playlist on startup</source> - <translation>启动时,恢复上次的播放列表</translation> + <translation type="vanished">启动时,恢复上次的播放列表</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="596"/> <source>Load files in the same folder</source> - <translation>添加同一文件夹下的所有文件</translation> + <translation type="vanished">添加同一文件夹下的所有文件</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="609"/> <source>Save dialog status</source> - <translation>保存对话框状态</translation> + <translation type="vanished">保存对话框状态</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="622"/> <source>Save parameters in effects window</source> - <translation>保存效果窗口内的设定</translation> + <translation type="vanished">保存效果窗口内的设定</translation> </message> <message> - <location filename="../qmpsettingswindow.ui" line="635"/> <source>Persistent fluidsynth instance</source> - <translation>单一fluidsynth实例</translation> + <translation type="vanished">单一fluidsynth实例</translation> </message> <message> - <location filename="../qmpsettingswindow.cpp" line="398"/> + <location filename="../qmpsettingswindow.cpp" line="109"/> <source>No soundfont loaded</source> <translation>未选择soundfont</translation> </message> <message> - <location filename="../qmpsettingswindow.cpp" line="399"/> + <location filename="../qmpsettingswindow.cpp" line="110"/> <source>Internal fluidsynth is the only available MIDI output but it has no soundfont set. Would you like to setup soundfonts now? You may have to reload the internal synth afterwards.</source> <translation>仅有FluidSynth输出可用,但未选择其使用的soundfont。需要现在进行设置吗?(设置完毕后需要重新加载FluidSynth。)</translation> </message> + <message> + <location filename="../qmpsettingswindow.cpp" line="121"/> + <location filename="../qmpsettingswindow.cpp" line="122"/> + <source>Customize...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../qmpsettingswindow.cpp" line="241"/> + <source>Plugin Name</source> + <translation type="unfinished"></translation> + </message> </context> </TS> |