]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - radiant/autosave.cpp
Remove <gtk/gtk.h> from gtkutil/window.h
[xonotic/netradiant.git] / radiant / autosave.cpp
1 /*
2    Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3    For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5    This file is part of GtkRadiant.
6
7    GtkRadiant is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    GtkRadiant is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GtkRadiant; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21
22 #include <uilib/uilib.h>
23 #include "autosave.h"
24
25 #include "os/file.h"
26 #include "os/path.h"
27 #include "cmdlib.h"
28 #include "stream/stringstream.h"
29 #include "gtkutil/messagebox.h"
30 #include "scenelib.h"
31 #include "mapfile.h"
32
33 #include "map.h"
34 #include "mainframe.h"
35 #include "qe3.h"
36 #include "preferences.h"
37
38
39 #if defined( WIN32 )
40 #define PATH_MAX 260
41 #endif
42
43
44 bool DoesFileExist( const char* name, std::size_t& size ){
45         if ( file_exists( name ) ) {
46                 size += file_size( name );
47                 return true;
48         }
49         return false;
50 }
51
52 void Map_Snapshot(){
53         // we need to do the following
54         // 1. make sure the snapshot directory exists (create it if it doesn't)
55         // 2. find out what the lastest save is based on number
56         // 3. inc that and save the map
57         const char* path = Map_Name( g_map );
58         const char* name = path_get_filename_start( path );
59
60         StringOutputStream snapshotsDir( 256 );
61         snapshotsDir << StringRange( path, name ) << "snapshots";
62
63         if ( file_exists( snapshotsDir.c_str() ) || Q_mkdir( snapshotsDir.c_str() ) ) {
64                 std::size_t lSize = 0;
65                 StringOutputStream strNewPath( 256 );
66                 strNewPath << snapshotsDir.c_str() << '/' << name;
67
68                 StringOutputStream snapshotFilename( 256 );
69
70                 for ( int nCount = 0; ; ++nCount )
71                 {
72                         // The original map's filename is "<path>/<name>.<ext>"
73                         // The snapshot's filename will be "<path>/snapshots/<name>.<count>.<ext>"
74                         const char* end = path_get_filename_base_end( strNewPath.c_str() );
75                         snapshotFilename << StringRange( strNewPath.c_str(), end ) << '.' << nCount << end;
76
77                         if ( !DoesFileExist( snapshotFilename.c_str(), lSize ) ) {
78                                 break;
79                         }
80
81                         snapshotFilename.clear();
82                 }
83
84                 // save in the next available slot
85                 Map_SaveFile( snapshotFilename.c_str() );
86
87                 if ( lSize > 50 * 1024 * 1024 ) { // total size of saves > 50 mb
88                         globalOutputStream() << "The snapshot files in " << snapshotsDir.c_str() << " total more than 50 megabytes. You might consider cleaning up.";
89                 }
90         }
91         else
92         {
93                 StringOutputStream strMsg( 256 );
94                 strMsg << "Snapshot save failed.. unabled to create directory\n" << snapshotsDir.c_str();
95                 MainFrame_getWindow().alert( strMsg.c_str() );
96         }
97 }
98 /*
99    ===============
100    QE_CheckAutoSave
101
102    If five minutes have passed since making a change
103    and the map hasn't been saved, save it out.
104    ===============
105  */
106
107 bool g_AutoSave_Enabled = true;
108 int m_AutoSave_Frequency = 5;
109 bool g_SnapShots_Enabled = false;
110
111 namespace
112 {
113 time_t s_start = 0;
114 std::size_t s_changes = 0;
115 }
116
117 void AutoSave_clear(){
118         s_changes = 0;
119 }
120
121 scene::Node& Map_Node(){
122         return GlobalSceneGraph().root();
123 }
124
125 void QE_CheckAutoSave( void ){
126         if ( !Map_Valid( g_map ) || !ScreenUpdates_Enabled() ) {
127                 return;
128         }
129
130         time_t now;
131         time( &now );
132
133         if ( s_start == 0 || s_changes == Node_getMapFile( Map_Node() )->changes() ) {
134                 s_start = now;
135         }
136
137         if ( ( now - s_start ) > ( 60 * m_AutoSave_Frequency ) ) {
138                 s_start = now;
139                 s_changes = Node_getMapFile( Map_Node() )->changes();
140
141                 if ( g_AutoSave_Enabled ) {
142                         const char* strMsg = g_SnapShots_Enabled ? "Autosaving snapshot..." : "Autosaving...";
143                         globalOutputStream() << strMsg << "\n";
144                         //Sys_Status(strMsg);
145
146                         // only snapshot if not working on a default map
147                         if ( g_SnapShots_Enabled && !Map_Unnamed( g_map ) ) {
148                                 Map_Snapshot();
149                         }
150                         else
151                         {
152                                 if ( Map_Unnamed( g_map ) ) {
153                                         StringOutputStream autosave( 256 );
154                                         autosave << g_qeglobals.m_userGamePath.c_str() << "maps/";
155                                         Q_mkdir( autosave.c_str() );
156                                         autosave << "autosave.map";
157                                         Map_SaveFile( autosave.c_str() );
158                                 }
159                                 else
160                                 {
161                                         const char* name = Map_Name( g_map );
162                                         const char* extension = path_get_filename_base_end( name );
163                                         StringOutputStream autosave( 256 );
164                                         autosave << StringRange( name, extension ) << ".autosave" << extension;
165                                         Map_SaveFile( autosave.c_str() );
166                                 }
167                         }
168                 }
169                 else
170                 {
171                         globalOutputStream() << "Autosave skipped...\n";
172                         //Sys_Status ("Autosave skipped...");
173                 }
174         }
175 }
176
177 void Autosave_constructPreferences( PreferencesPage& page ){
178         ui::CheckButton autosave_enabled = page.appendCheckBox( "Autosave", "Enable Autosave", g_AutoSave_Enabled );
179         ui::SpinButton autosave_frequency = page.appendSpinner( "Autosave Frequency (minutes)", m_AutoSave_Frequency, 1, 1, 60 );
180         Widget_connectToggleDependency( autosave_frequency, autosave_enabled );
181         page.appendCheckBox( "", "Save Snapshots", g_SnapShots_Enabled );
182 }
183 void Autosave_constructPage( PreferenceGroup& group ){
184         PreferencesPage page( group.createPage( "Autosave", "Autosave Preferences" ) );
185         Autosave_constructPreferences( page );
186 }
187 void Autosave_registerPreferencesPage(){
188         PreferencesDialog_addSettingsPage( FreeCaller1<PreferenceGroup&, Autosave_constructPage>() );
189 }
190
191
192 #include "preferencesystem.h"
193 #include "stringio.h"
194
195 void Autosave_Construct(){
196         GlobalPreferenceSystem().registerPreference( "Autosave", BoolImportStringCaller( g_AutoSave_Enabled ), BoolExportStringCaller( g_AutoSave_Enabled ) );
197         GlobalPreferenceSystem().registerPreference( "AutosaveMinutes", IntImportStringCaller( m_AutoSave_Frequency ), IntExportStringCaller( m_AutoSave_Frequency ) );
198         GlobalPreferenceSystem().registerPreference( "Snapshots", BoolImportStringCaller( g_SnapShots_Enabled ), BoolExportStringCaller( g_SnapShots_Enabled ) );
199
200         Autosave_registerPreferencesPage();
201 }
202
203 void Autosave_Destroy(){
204 }