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