#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "preferencedialog.hpp" #include "settings.hpp" PreferenceDialog::PreferenceDialog(SettingsRegistry *sr, QWidget *parent) : QDialog(parent) { this->sr = sr; tw = new QTabWidget(this); bb = new QDialogButtonBox(QDialogButtonBox::StandardButton::Ok | QDialogButtonBox::StandardButton::Cancel, this); this->setWindowTitle("Preferences"); QVBoxLayout *l = new QVBoxLayout(); this->setLayout(l); l->addWidget(tw); l->addWidget(bb); QObject::connect(bb, &QDialogButtonBox::accepted, this, &PreferenceDialog::accept); QObject::connect(bb, &QDialogButtonBox::rejected, this, &PreferenceDialog::reject); setup_widgets(); } void PreferenceDialog::open() { load_widget_status(); QDialog::open(); } void PreferenceDialog::accept() { save_widget_status(); QDialog::accept(); } void PreferenceDialog::setup_widgets() { for (auto &i : sr->tabs) { QWidget *container = new QWidget(); QGridLayout *l = new QGridLayout(container); tw->addTab(container, i); tabs.push_back(l); } for (auto &k : sr->klist) { auto &p = sr->smap[k]; QWidget *w = nullptr; QGridLayout *l = p.tab < tabs.size() ? tabs[p.tab] : nullptr; if (!l) continue; switch (p.type) { case SettingsItem::ParameterType::_int: { QSpinBox *sb = new QSpinBox(); sb->setMinimum(p.min.value()); sb->setMaximum(p.max.value()); w = sb; } break; case SettingsItem::ParameterType::_bool: { QCheckBox *cb = new QCheckBox(p.desc); w = cb; } break; case SettingsItem::ParameterType::_double: { QDoubleSpinBox *sb = new QDoubleSpinBox(); sb->setMinimum(p.min.value()); sb->setMaximum(p.max.value()); sb->setSingleStep((sb->maximum() - sb->minimum()) / 100.); w = sb; } break; case SettingsItem::ParameterType::_keyseq: break; default: break; } if (!w) continue; p.w = w; if (p.type == SettingsItem::ParameterType::_bool) { l->addWidget(w, l->rowCount(), 0, 1, 2); } else { QLabel *lb = new QLabel(p.desc); lb->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); int r = l->rowCount(); l->addWidget(lb, r, 0); l->addWidget(w, r, 1); } } } void PreferenceDialog::set_hkactions(int tab, std::map defmap, std::map actmap) { this->defmap = defmap; this->actmap = actmap; this->hktv = new QTableView(); this->hkim = new QStandardItemModel(); this->tabs[tab]->addWidget(hktv, 0, 0); this->hktv->setModel(hkim); this->hktv->setSortingEnabled(false); this->hktv->setSelectionMode(QAbstractItemView::SelectionMode::NoSelection); this->hktv->setItemDelegateForColumn(1, new ShortcutEditorDelegate); } void PreferenceDialog::load_widget_status() { for (auto &k : sr->klist) { auto &p = sr->smap[k]; QWidget *w = p.w; switch (p.type) { case SettingsItem::ParameterType::_int: { QSpinBox *sb = qobject_cast(w); if (!sb) continue; sb->setValue(sr->get_option_int(p.key)); } break; case SettingsItem::ParameterType::_bool: { QCheckBox *cb = qobject_cast(w); cb->setChecked(sr->get_option_bool(p.key)); } break; case SettingsItem::ParameterType::_double: { QDoubleSpinBox *sb = qobject_cast(w); sb->setValue(sr->get_option_double(p.key)); } break; case SettingsItem::ParameterType::_keyseq: break; default: break; } } this->hkim->clear(); this->hkim->setHorizontalHeaderLabels({"Menu Item", "Hotkey"}); for (auto &hkp : this->defmap) { std::string actn = hkp.first.substr(3); QKeySequence ks = sr->get_option_keyseq("hotkey/" + actn); if (this->actmap.find(actn) == this->actmap.end()) continue; QAction *act = this->actmap[actn]; QStandardItem *itma = new QStandardItem(act->text()); QStandardItem *itmk = new QStandardItem(act->shortcut().toString()); itma->setIcon(act->icon()); itma->setEditable(false); itma->setData(QString::fromStdString(actn), Qt::ItemDataRole::UserRole); itmk->setData(QVariant::fromValue(ks), Qt::ItemDataRole::UserRole); this->hkim->appendRow({itma, itmk}); } this->hktv->resizeColumnsToContents(); } void PreferenceDialog::save_widget_status() { for (auto &k : sr->klist) { auto &p = sr->smap[k]; QWidget *w = p.w; switch (p.type) { case SettingsItem::ParameterType::_int: { QSpinBox *sb = qobject_cast(w); if (!sb) continue; sr->set_option_int(p.key, sb->value()); } break; case SettingsItem::ParameterType::_bool: { QCheckBox *cb = qobject_cast(w); sr->set_option_bool(p.key, cb->isChecked()); } break; case SettingsItem::ParameterType::_double: { QDoubleSpinBox *sb = qobject_cast(w); sr->set_option_double(p.key, sb->value()); } break; case SettingsItem::ParameterType::_keyseq: break; default: break; } } for (int i = 0; i < hkim->rowCount(); ++i) { std::string actn = hkim->item(i, 0)->data(Qt::ItemDataRole::UserRole).toString().toStdString(); QKeySequence ks = hkim->item(i, 1)->data(Qt::ItemDataRole::UserRole).value(); sr->set_option_keyseq("hotkey/" + actn, ks); } } QWidget* ShortcutEditorDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { Q_UNUSED(option); Q_UNUSED(index); QKeySequenceEdit *kse = new QKeySequenceEdit(parent); QObject::connect(kse, &QKeySequenceEdit::editingFinished, [this, kse] { Q_EMIT const_cast(this)->commitData(kse); Q_EMIT const_cast(this)->closeEditor(kse); }); return kse; } void ShortcutEditorDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { QKeySequenceEdit *kse = qobject_cast(editor); kse->setKeySequence(index.data(Qt::ItemDataRole::UserRole).value()); } void ShortcutEditorDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { QKeySequenceEdit *kse = qobject_cast(editor); model->setData(index, QVariant::fromValue(kse->keySequence()), Qt::ItemDataRole::UserRole); model->setData(index, kse->keySequence().toString(), Qt::ItemDataRole::DisplayRole); }