#!/usr/bin/env python3 # ============================================================ # The rekonq project # ============================================================ # SPDX-License-Identifier: GPL-3.0-only # Copyright (C) 2022 aqua # ============================================================ """ Generate SettingsWidgets from KDE kcfg files """ import argparse import sys from xml.etree import ElementTree def write_int_entry(obj, name, default): """Add a QSpinBox connected to an Int (obj, name, default)""" print(f' auto* { obj } = new QSpinBox(this);') print(f' { obj }->setValue(s->value("{ obj }", { default }).toInt());') print(f' connect({ obj }, &QSpinBox::valueChanged, this, [this]() {{ emit changed(); }});') print(f' formLayout->addRow(tr("{ name }"), { obj });') def write_bool_entry(obj, name, default): """Add a QCheckBox connected to a Bool (obj, name, default)""" print(f' auto* { obj } = new QCheckBox(tr("{ name }"), this);') print(f' { obj }->setChecked(s->value("{ obj }", { default }).toBool());') print(f' connect({ obj }, &QCheckBox::stateChanged, this, [this]() {{ emit changed(); }});') print(f' formLayout->addRow(QString(), { obj });') def write_string_entry(obj, name, default): """Add a QLineEdit connected to a String (obj, name, default)""" print(f' auto* {obj} = new QLineEdit(this);') print(f' { obj }->setText(s->value("{ obj }", "{ default }").toString());') print(f' connect({ obj }, &QLineEdit::textChanged, this, [this]() {{ emit changed(); }});') print(f' formLayout->addRow(tr("{ name }"), { obj });') def write_font_entry(obj, name, default): """Add a QFontComboBox connected to a Font (obj, name, default)""" print(f' auto* { obj } = new QFontComboBox(this);') print(f' { obj }->setCurrentFont(s->value("{ obj }", "{ default }").toString());') print(f' connect({ obj }, &QFontComboBox::currentFontChanged, this, [this]() {{ emit changed(); }});') print(f' formLayout->addRow(tr("{ name }"), { obj });') def write_shortcut_entry(obj, name, default): """Add a QKeySequenceEdit connected to a Shortcut (obj, name, default)""" print(f' auto* { obj } = new QKeySequenceEdit(this);') print(f' { obj }->setKeySequence(s->value("{ obj }", "{ default }").toString());') print(f' connect({ obj }, &QKeySequenceEdit::keySequenceChanged, this, [this]() {{ emit changed(); }});') print(f' formLayout->addRow(tr("{ name }"), { obj });') def generate_group_widget(root, group): """Generate a class based on the group name""" class_group = group.attrib["name"].replace(' ', '') class_name = group.attrib["name"].replace(' ', '') + 'SettingsWidget' write_entry_fn = { 'Int': write_int_entry, 'Bool': write_bool_entry, 'String': write_string_entry, 'Font': write_font_entry, 'Shortcut': write_shortcut_entry } # includes print('// Includes') print('#include "settingswidgets.hpp"') print('#include "helpers.hpp"') print('#include ') print('#include ') print('#include ') print('#include ') print('#include ') print('#include ') print('// kcfg Includes') for include in root.findall('{http://www.kde.org/standards/kcfg/1.0}include'): print(f'#include <{ include.text }>') print('') # ctor print(f'{ class_name }::{ class_name }(RekonqSettings *s, QWidget *parent) : SettingsWidget(s, parent) {{') print(f' setObjectName("{ class_group }");') if class_group != 'General': print(f' s->beginGroup("{ class_group }");') print(' auto *formLayout = new QFormLayout;') print(' setLayout(formLayout);') print('') print(' // Entries') for entry in group.findall('{http://www.kde.org/standards/kcfg/1.0}entry'): if entry.attrib.get("hidden") == "true": print(f' // hidden entry { entry.attrib.get("name") }') else: obj = entry.attrib['key'] name = entry.attrib["name"] default = entry.find('{*}default').text write_entry_fn.get(entry.attrib['type'])(obj, name, default) print(f' { obj }->setObjectName("{ obj }");') print(f' { obj }->setProperty("defaultValue", "{ default }");') print('') if class_group != 'General': print(' s->endGroup();') print('}\n') def generate_group_ini(group): """Generate settings in ini format for group""" group_name = group.attrib["name"].replace(' ', '') print(f'[{ group_name }]') for entry in group.findall('{http://www.kde.org/standards/kcfg/1.0}entry'): if entry.find('{*}default').get('code') == 'true': continue entry_key = entry.attrib['key'] entry_val = entry.find('{*}default').text print(f'{ entry_key }={ entry_val }') print('') def main(): """main function""" parser = argparse.ArgumentParser(description='Generate SettingsWidgets') parser.add_argument('file', type=str, help='kcfg file') parser.add_argument('--group', type=str, required=True, help='Group') parser.add_argument('--output', type=str, default=None, help='Redirect output to file') args = parser.parse_args() with open(args.output, 'w', encoding="utf-8") if args.output else sys.stdout as sys.stdout: tree = ElementTree.parse(args.file) root = tree.getroot() if args.group == 'all': for group in root.findall('{http://www.kde.org/standards/kcfg/1.0}group'): generate_group_ini(group) else: for group in root.findall('{http://www.kde.org/standards/kcfg/1.0}group'): if group.attrib["name"] == args.group: print('// This is an automatically generated file') generate_group_widget(root, group) break if __name__ == '__main__': main()