]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - radiant/autosave.cpp
Reload textures in the currently selected directory when shaders are reloaded
[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 "autosave.h"
23
24 #include "os/file.h"
25 #include "os/path.h"
26 #include "cmdlib.h"
27 #include "stream/stringstream.h"
28 #include "gtkutil/messagebox.h"
29 #include "scenelib.h"
30 #include "mapfile.h"
31
32 #include "map.h"
33 #include "mainframe.h"
34 #include "qe3.h"
35 #include "preferences.h"
36
37
38 #if defined( WIN32 )
39 #define PATH_MAX 260
40 #endif
41
42
43 bool DoesFileExist( const char* name, std::size_t& size ){
44         if ( file_exists( name ) ) {
45                 size += file_size( name );
46                 return true;
47         }
48         return false;
49 }
50
51 void Map_Snapshot(){
52         // we need to do the following
53         // 1. make sure the snapshot directory exists (create it if it doesn't)
54         // 2. find out what the lastest save is based on number
55         // 3. inc that and save the map
56         const char* path = Map_Name( g_map );
57         const char* name = path_get_filename_start( path );
58
59         StringOutputStream snapshotsDir( 256 );
60         snapshotsDir << StringRange( path, name ) << "snapshots";
61
62         if ( file_exists( snapshotsDir.c_str() ) || Q_mkdir( snapshotsDir.c_str() ) ) {
63                 std::size_t lSize = 0;
64                 StringOutputStream strNewPath( 256 );
65                 strNewPath << snapshotsDir.c_str() << '/' << name;
66
67                 StringOutputStream snapshotFilename( 256 );
68
69                 for ( int nCount = 0; ; ++nCount )
70                 {
71                         // The original map's filename is "<path>/<name>.<ext>"
72                         // The snapshot's filename will be "<path>/snapshots/<name>.<count>.<ext>"
73                         const char* end = path_get_filename_base_end( strNewPath.c_str() );
74                         snapshotFilename << StringRange( strNewPath.c_str(), end ) << '.' << nCount << end;
75
76                         if ( !DoesFileExist( snapshotFilename.c_str(), lSize ) ) {
77                                 break;
78                         }
79
80                         snapshotFilename.clear();
81                 }
82
83                 // save in the next available slot
84                 Map_SaveFile( snapshotFilename.c_str() );
85
86                 if ( lSize > 50 * 1024 * 1024 ) { // total size of saves > 50 mb
87                         globalOutputStream() << "The snapshot files in " << snapshotsDir.c_str() << " total more than 50 megabytes. You might consider cleaning up.";
88                 }
89         }
90         else
91         {
92                 StringOutputStream strMsg( 256 );
93                 strMsg << "Snapshot save failed.. unabled to create directory\n" << snapshotsDir.c_str();
94                 gtk_MessageBox( GTK_WIDGET( MainFrame_getWindow() ), strMsg.c_str() );
95         }
96 }
97 /*
98    ===============
99    QE_CheckAutoSave
100
101    If five minutes have passed since making a change
102    and the map hasn't been saved, save it out.
103    ===============
104  */
105
106 bool g_AutoSave_Enabled = true;
107 int m_AutoSave_Frequency = 5;
108 bool g_SnapShots_Enabled = false;
109
110 namespace
111 {
112 time_t s_start = 0;
113 std::size_t s_changes = 0;
114 }
115
116 void AutoSave_clear(){
117         s_changes = 0;
118 }
119
120 scene::Node& Map_Node(){
121         return GlobalSceneGraph().root();
122 }
123
124 void QE_CheckAutoSave( void ){
125         if ( !Map_Valid( g_map ) || !ScreenUpdates_Enabled() ) {
126                 return;
127         }
128
129         time_t now;
130         time( &now );
131
132         if ( s_start == 0 || s_changes == Node_getMapFile( Map_Node() )->changes() ) {
133                 s_start = now;
134         }
135
136         if ( ( now - s_start ) > ( 60 * m_AutoSave_Frequency ) ) {
137                 s_start = now;
138                 s_changes = Node_getMapFile( Map_Node() )->changes();
139
140                 if ( g_AutoSave_Enabled ) {
141                         const char* strMsg = g_SnapShots_Enabled ? "Autosaving snapshot..." : "Autosaving...";
142                         globalOutputStream() << strMsg << "\n";
143                         //Sys_Status(strMsg);
144
145                         // only snapshot if not working on a default map
146                         if ( g_SnapShots_Enabled && !Map_Unnamed( g_map ) ) {
147                                 Map_Snapshot();
148                         }
149                         else
150                         {
151                                 if ( Map_Unnamed( g_map ) ) {
152                                         StringOutputStream autosave( 256 );
153                                         autosave << g_qeglobals.m_userGamePath.c_str() << "maps/";
154                                         Q_mkdir( autosave.c_str() );
155                                         autosave << "autosave.map";
156                                         Map_SaveFile( autosave.c_str() );
157                                 }
158                                 else
159                                 {
160                                         const char* name = Map_Name( g_map );
161                                         const char* extension = path_get_filename_base_end( name );
162                                         StringOutputStream autosave( 256 );
163                                         autosave << StringRange( name, extension ) << ".autosave" << extension;
164                                         Map_SaveFile( autosave.c_str() );
165                                 }
166                         }
167                 }
168                 else
169                 {
170                         globalOutputStream() << "Autosave skipped...\n";
171                         //Sys_Status ("Autosave skipped...");
172                 }
173         }
174 }
175
176 void Autosave_constructPreferences( PreferencesPage& page ){
177         GtkWidget* autosave_enabled = page.appendCheckBox( "Autosave", "Enable Autosave", g_AutoSave_Enabled );
178         GtkWidget* autosave_frequency = page.appendSpinner( "Autosave Frequency (minutes)", m_AutoSave_Frequency, 1, 1, 60 );
179         Widget_connectToggleDependency( autosave_frequency, autosave_enabled );
180         page.appendCheckBox( "", "Save Snapshots", g_SnapShots_Enabled );
181 }
182 void Autosave_constructPage( PreferenceGroup& group ){
183         PreferencesPage page( group.createPage( "Autosave", "Autosave Preferences" ) );
184         Autosave_constructPreferences( page );
185 }
186 void Autosave_registerPreferencesPage(){
187         PreferencesDialog_addSettingsPage( FreeCaller1<PreferenceGroup&, Autosave_constructPage>() );
188 }
189
190
191 #include "preferencesystem.h"
192 #include "stringio.h"
193
194 void Autosave_Construct(){
195         GlobalPreferenceSystem().registerPreference( "Autosave", BoolImportStringCaller( g_AutoSave_Enabled ), BoolExportStringCaller( g_AutoSave_Enabled ) );
196         GlobalPreferenceSystem().registerPreference( "AutosaveMinutes", IntImportStringCaller( m_AutoSave_Frequency ), IntExportStringCaller( m_AutoSave_Frequency ) );
197         GlobalPreferenceSystem().registerPreference( "Snapshots", BoolImportStringCaller( g_SnapShots_Enabled ), BoolExportStringCaller( g_SnapShots_Enabled ) );
198
199         Autosave_registerPreferencesPage();
200 }
201
202 void Autosave_Destroy(){
203 }