1 /*
2 * Copyright 2014, 2019 Kai Pastor
3 *
4 * This file is part of OpenOrienteering.
5 *
6 * OpenOrienteering is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * OpenOrienteering is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with OpenOrienteering. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "autosave.h"
21
22 #include <QtGlobal>
23 #include <QLatin1String>
24 #include <QString>
25 #include <QVariant>
26
27 #include "settings.h"
28
29
30 namespace OpenOrienteering {
31
AutosavePrivate(Autosave & autosave)32 AutosavePrivate::AutosavePrivate(Autosave& autosave)
33 : document(autosave)
34 {
35 #ifdef QT_TESTLIB_LIB
36 // The AutosaveTest uses a very short interval. By using a precise timer,
37 // we try to avoid occasional AutosaveTest failures on macOS.
38 autosave_timer.setTimerType(Qt::PreciseTimer);
39 #endif
40 autosave_timer.setSingleShot(true);
41 connect(&autosave_timer, &QTimer::timeout, this, &AutosavePrivate::autosave);
42 connect(&Settings::getInstance(), &Settings::settingsChanged, this, &AutosavePrivate::settingsChanged);
43 settingsChanged();
44 }
45
46 AutosavePrivate::~AutosavePrivate() = default;
47
settingsChanged()48 void AutosavePrivate::settingsChanged()
49 {
50 // Normally, the autosave interval can be stored as an integer.
51 // It is loaded as a double here to allow for faster unit testing.
52 autosave_interval = qRound(Settings::getInstance().getSetting(Settings::General_AutosaveInterval).toDouble() * 60000);
53 if (autosave_interval < 1000)
54 {
55 // stop autosave
56 autosave_interval = 0;
57 autosave_timer.stop();
58 }
59 else if (autosave_needed && !autosave_timer.isActive())
60 {
61 // start autosave
62 autosave_timer.setInterval(autosave_interval);
63 autosave_timer.start();
64 }
65 }
66
autosaveNeeded() const67 bool AutosavePrivate::autosaveNeeded() const
68 {
69 return autosave_needed;
70 }
71
setAutosaveNeeded(bool needed)72 void AutosavePrivate::setAutosaveNeeded(bool needed)
73 {
74 autosave_needed = needed;
75 if (autosave_interval)
76 {
77 // autosaving enabled
78 if (autosave_needed && !autosave_timer.isActive())
79 {
80 autosave_timer.setInterval(autosave_interval);
81 autosave_timer.start();
82 }
83 else if (!autosave_needed && autosave_timer.isActive())
84 {
85 autosave_timer.stop();
86 }
87 }
88 }
89
autosave()90 void AutosavePrivate::autosave()
91 {
92 Autosave::AutosaveResult result = document.autosave();
93 if (autosave_interval)
94 {
95 switch (result)
96 {
97 case Autosave::TemporaryFailure:
98 autosave_timer.setInterval(5000);
99 autosave_timer.start();
100 return;
101 case Autosave::Success:
102 case Autosave::PermanentFailure:
103 autosave_timer.setInterval(autosave_interval);
104 autosave_timer.start();
105 return;
106 }
107 Q_UNREACHABLE();
108 }
109 }
110
111
112
113 // ### Autosave ###
114
Autosave()115 Autosave::Autosave()
116 : autosave_controller(*this)
117 {
118 // nothing else
119 }
120
121 Autosave::~Autosave() = default;
122
autosavePath(const QString & path) const123 QString Autosave::autosavePath(const QString &path) const
124 {
125 return path + QLatin1String(".autosave");
126 }
127
setAutosaveNeeded(bool needed)128 void Autosave::setAutosaveNeeded(bool needed)
129 {
130 autosave_controller.setAutosaveNeeded(needed);
131 }
132
autosaveNeeded() const133 bool Autosave::autosaveNeeded() const
134 {
135 return autosave_controller.autosaveNeeded();
136 }
137
138
139 } // namespace OpenOrienteering
140
141 #include "moc_autosave.cpp"
142