aboutsummaryrefslogtreecommitdiff
path: root/lib/configuration/configuration.cpp
blob: bd7700cc5e590ed698aaca31bd7e364cbf0809b8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
 * This file is part of smolbote. It's copyrighted by the contributors recorded
 * in the version control history of the file, available from its original
 * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote
 *
 * SPDX-License-Identifier: GPL-3.0
 */

#include "configuration.h"
#include <sstream>
#include <algorithm>
#include <stdexcept>
#include <iostream>
#include <QStandardPaths>

static std::unique_ptr<Configuration> s_conf;

inline void strip(std::string &value)
{
    value.erase(value.begin(), std::find_if(value.begin(), value.end(), std::bind1st(std::not_equal_to<char>(), ' ')));
    value.erase(std::find_if(value.rbegin(), value.rend(), std::bind1st(std::not_equal_to<char>(), ' ')).base(), value.end());
}


Configuration::Configuration()
    : use_global(true)
{
    if(!s_conf)
        throw new std::runtime_error("Trying to use default Configuration, but none has been set!");
}

Configuration::Configuration(std::initializer_list<std::pair<std::string, conf_value_t>> l) noexcept
    : m_homePath(QStandardPaths::writableLocation(QStandardPaths::HomeLocation).toStdString())
{
        for(const auto &i : l) {
            insert_or_assign(i.first, i.second);
        }
}

void Configuration::read(std::basic_istream<char> &input)
{
    std::string line, key, value;
    std::istringstream is_line;

    while(std::getline(input, line)) {
        if(line[0] == '#' || line.length() == 0)
            continue;

        is_line.clear();
        is_line.str(line);

        if(std::getline(is_line, key, '=')) {
            is_line >> value;

            strip(key);
            strip(value);

            if(this->count(key) == 0) {
                // no type has been specified for this key, assuming std::string
                insert(std::make_pair(key, value));
                continue;
            }

            auto v = at(key);
            if(std::holds_alternative<std::string>(v)) {
                at(key) = value;
            } else if(std::holds_alternative<int>(v)) {
                at(key) = std::stoi(value);
            } else if(std::holds_alternative<bool>(v)) {
                at(key) = (value == "true");
            }

        }
    }
}


void Configuration::move_global(std::unique_ptr<Configuration> &&conf)
{
    s_conf = std::move(conf);
}

Configuration* Configuration::instance()
{
    return s_conf.get();
}

void setShortcut(QAction *action, const char *name)
{
    if(!s_conf)
        throw new std::runtime_error("Trying to set a shortcut, but no configuration has been set!");

    if(const auto shortcutText = s_conf->value<QString>(name)) {
        const QString tooltip = action->toolTip();
        action->setShortcut(QKeySequence::fromString(shortcutText.value()));
        action->setToolTip(QString("%1 (%2)").arg(tooltip, shortcutText.value()));
    }
#ifdef QT_DEBUG
    else {
        std::cout << "fixme: setShortcut called for " << name << ", but no such value exists!" << std::endl;
    }
#endif
}