1 // This file is part of Heimer.
2 // Copyright (C) 2020 Jussi Lind <jussi.lind@iki.fi>
3 //
4 // Heimer is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 // Heimer is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with Heimer. If not, see <http://www.gnu.org/licenses/>.
15 
16 #include "settings.hpp"
17 #include "constants.hpp"
18 
19 #include <QSettings>
20 #include <QStandardPaths>
21 #include <QTimer>
22 
23 #include <memory>
24 
25 namespace {
26 
27 const auto settingsGroupApplication = "Application";
28 
29 const auto settingsGroupDefaults = "Defaults";
30 
31 const auto settingsGroupEditing = "Editing";
32 
33 const auto settingsGroupMainWindow = "MainWindow";
34 
35 const auto recentImagePathKey = "recentImagePath";
36 
37 const auto autosaveKey = "autosave";
38 
39 const auto edgeArrowModeKey = "edgeArrowMode";
40 
41 const auto gridSizeKey = "gridSize";
42 
43 const auto gridVisibleStateKey = "gridVisibleState";
44 
45 const auto recentPathKey = "recentPath";
46 
47 const auto reversedEdgeDirectionKey = "reversedEdgeDirection";
48 
49 const auto selectNodeGroupByIntersectionKey = "selectNodeGroupByIntersection";
50 
51 const auto windowFullScreenKey = "fullScreen";
52 
53 const auto windowSizeKey = "size";
54 
55 } // namespace
56 
loadAutosave()57 bool Settings::loadAutosave()
58 {
59     QSettings settings;
60     settings.beginGroup(settingsGroupEditing);
61     const auto autosave = settings.value(autosaveKey, false).toBool();
62     settings.endGroup();
63     return autosave;
64 }
65 
saveAutosave(bool autosave)66 void Settings::saveAutosave(bool autosave)
67 {
68     QSettings settings;
69     settings.beginGroup(settingsGroupEditing);
70     settings.setValue(autosaveKey, autosave);
71     settings.endGroup();
72 }
73 
loadEdgeArrowMode(Edge::ArrowMode defaultMode)74 Edge::ArrowMode Settings::loadEdgeArrowMode(Edge::ArrowMode defaultMode)
75 {
76     QSettings settings;
77     settings.beginGroup(settingsGroupDefaults);
78     const auto mode = static_cast<Edge::ArrowMode>(settings.value(edgeArrowModeKey, static_cast<int>(defaultMode)).toInt());
79     settings.endGroup();
80     return mode;
81 }
82 
saveEdgeArrowMode(Edge::ArrowMode mode)83 void Settings::saveEdgeArrowMode(Edge::ArrowMode mode)
84 {
85     QSettings settings;
86     settings.beginGroup(settingsGroupDefaults);
87     settings.setValue(edgeArrowModeKey, static_cast<int>(mode));
88     settings.endGroup();
89 }
90 
loadReversedEdgeDirection(bool defaultDirection)91 bool Settings::loadReversedEdgeDirection(bool defaultDirection)
92 {
93     QSettings settings;
94     settings.beginGroup(settingsGroupDefaults);
95     const auto direction = settings.value(reversedEdgeDirectionKey, defaultDirection).toBool();
96     settings.endGroup();
97     return direction;
98 }
99 
saveReversedEdgeDirection(bool reversed)100 void Settings::saveReversedEdgeDirection(bool reversed)
101 {
102     QSettings settings;
103     settings.beginGroup(settingsGroupDefaults);
104     settings.setValue(reversedEdgeDirectionKey, reversed);
105     settings.endGroup();
106 }
107 
loadGridSize()108 int Settings::loadGridSize()
109 {
110     QSettings settings;
111     settings.beginGroup(settingsGroupMainWindow);
112     const auto gridSize = settings.value(gridSizeKey, 0).toInt();
113     settings.endGroup();
114     return gridSize;
115 }
116 
saveGridSize(int value)117 void Settings::saveGridSize(int value)
118 {
119     static std::unique_ptr<QTimer> gridSizeTimer;
120     static int sGridSizeValue;
121     sGridSizeValue = value;
122     if (!gridSizeTimer) {
123         gridSizeTimer = std::make_unique<QTimer>();
124         gridSizeTimer->setSingleShot(true);
125         gridSizeTimer->setInterval(Constants::View::TOO_QUICK_ACTION_DELAY_MS);
126         gridSizeTimer->connect(gridSizeTimer.get(), &QTimer::timeout, [&]() {
127             QSettings settings;
128             settings.beginGroup(settingsGroupMainWindow);
129             settings.setValue(gridSizeKey, sGridSizeValue);
130             settings.endGroup();
131         });
132     }
133     if (gridSizeTimer->isActive()) {
134         gridSizeTimer->stop();
135     }
136     gridSizeTimer->start();
137 }
138 
loadGridVisibleState()139 Qt::CheckState Settings::loadGridVisibleState()
140 {
141     QSettings settings;
142     settings.beginGroup(settingsGroupMainWindow);
143     const auto gridState = settings.value(gridVisibleStateKey, Qt::Unchecked).toInt();
144     settings.endGroup();
145     return static_cast<Qt::CheckState>(gridState);
146 }
147 
saveGridVisibleState(int state)148 void Settings::saveGridVisibleState(int state)
149 {
150     QSettings settings;
151     settings.beginGroup(settingsGroupMainWindow);
152     settings.setValue(gridVisibleStateKey, state);
153     settings.endGroup();
154 }
155 
loadRecentPath()156 QString Settings::loadRecentPath()
157 {
158     QSettings settings;
159     settings.beginGroup(settingsGroupApplication);
160     const auto path = settings.value(recentPathKey, QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).toString();
161     settings.endGroup();
162     return path;
163 }
164 
saveRecentPath(QString path)165 void Settings::saveRecentPath(QString path)
166 {
167     QSettings settings;
168     settings.beginGroup(settingsGroupApplication);
169     settings.setValue(recentPathKey, path);
170     settings.endGroup();
171 }
172 
loadRecentImagePath()173 QString Settings::loadRecentImagePath()
174 {
175     QSettings settings;
176     settings.beginGroup(settingsGroupApplication);
177     const QString path = settings.value(recentImagePathKey, QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).toString();
178     settings.endGroup();
179     return path;
180 }
181 
saveRecentImagePath(QString path)182 void Settings::saveRecentImagePath(QString path)
183 {
184     QSettings settings;
185     settings.beginGroup(settingsGroupApplication);
186     settings.setValue(recentImagePathKey, path);
187     settings.endGroup();
188 }
189 
loadWindowSize(QSize defaultSize)190 QSize Settings::loadWindowSize(QSize defaultSize)
191 {
192     QSettings settings;
193     settings.beginGroup(settingsGroupMainWindow);
194     const auto size = settings.value(windowSizeKey, defaultSize).toSize();
195     settings.endGroup();
196     return size;
197 }
198 
saveWindowSize(QSize size)199 void Settings::saveWindowSize(QSize size)
200 {
201     QSettings settings;
202     settings.beginGroup(settingsGroupMainWindow);
203     settings.setValue(windowSizeKey, size);
204     settings.endGroup();
205 }
206 
loadFullScreen()207 bool Settings::loadFullScreen()
208 {
209     QSettings settings;
210     settings.beginGroup(settingsGroupMainWindow);
211     const auto fullScreen = settings.value(windowFullScreenKey, false).toBool();
212     settings.endGroup();
213     return fullScreen;
214 }
215 
saveFullScreen(bool fullScreen)216 void Settings::saveFullScreen(bool fullScreen)
217 {
218     QSettings settings;
219     settings.beginGroup(settingsGroupMainWindow);
220     settings.setValue(windowFullScreenKey, fullScreen);
221     settings.endGroup();
222 }
223 
loadSelectNodeGroupByIntersection()224 bool Settings::loadSelectNodeGroupByIntersection()
225 {
226     QSettings settings;
227     settings.beginGroup(settingsGroupDefaults);
228     const auto fullScreen = settings.value(selectNodeGroupByIntersectionKey, false).toBool();
229     settings.endGroup();
230     return fullScreen;
231 }
232 
saveSelectNodeGroupByIntersection(bool selectNodeGroupByIntersection)233 void Settings::saveSelectNodeGroupByIntersection(bool selectNodeGroupByIntersection)
234 {
235     QSettings settings;
236     settings.beginGroup(settingsGroupDefaults);
237     settings.setValue(selectNodeGroupByIntersectionKey, selectNodeGroupByIntersection);
238     settings.endGroup();
239 }
240