]> icculus.org git repositories - icculus/iodoom3.git/blob - neo/tools/guied/GEWorkspaceFile.cpp
hello world
[icculus/iodoom3.git] / neo / tools / guied / GEWorkspaceFile.cpp
1 /*
2 ===========================================================================
3
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. 
6
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).  
8
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code.  If not, see <http://www.gnu.org/licenses/>.
21
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code.  If not, please request a copy in writing from id Software at the address below.
23
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25
26 ===========================================================================
27 */
28
29 #include "../../idlib/precompiled.h"
30 #pragma hdrstop
31
32 #include "GEApp.h"
33
34 bool GECheckInDlg_DoModal ( HWND parent, const char* filename, idStr* comment );
35
36 /*
37 ================
38 rvGEWorkspace::SaveFile
39
40 Writes the contents of the open gui file to disk
41 ================
42 */
43 bool rvGEWorkspace::SaveFile ( const char* filename )
44 {
45         idFile*         file;
46         idWindow*       window;
47
48         SetCursor ( LoadCursor ( NULL, MAKEINTRESOURCE(IDC_WAIT ) ) );
49         
50         mFilename = filename;
51         
52         // Since quake can only write to its path we will write a temp file then copy it over   
53         idStr tempfile;
54         idStr ospath;
55         
56         tempfile = "guis/temp.guied";
57         ospath = fileSystem->RelativePathToOSPath ( tempfile, "fs_basepath" );
58         
59         // Open the output file for write
60         if ( !(file = fileSystem->OpenFileWrite ( tempfile ) ) )
61         {
62                 int error = GetLastError ( );
63                 SetCursor ( LoadCursor ( NULL, MAKEINTRESOURCE(IDC_ARROW ) ) );
64                 return false;
65         }
66         
67         window = mInterface->GetDesktop ( );
68         
69         WriteWindow ( file, 1, window );
70         
71         fileSystem->CloseFile ( file );
72         
73         if ( !CopyFile ( ospath, filename, FALSE ) )
74         {
75                 DeleteFile ( ospath );
76                 SetCursor ( LoadCursor ( NULL, MAKEINTRESOURCE(IDC_ARROW ) ) );
77                 return false;
78         }
79         
80         DeleteFile ( ospath );
81
82         mFilename = filename;
83         mModified = false;
84         mNew      = false;
85         UpdateTitle ( );        
86
87         SetCursor ( LoadCursor ( NULL, MAKEINTRESOURCE(IDC_ARROW ) ) );
88         
89         return true;
90 }
91
92 /*
93 ================
94 rvGEWorkspace::WriteTabs
95
96 Writes the given number of tabs to the given file
97 ================
98 */
99 void rvGEWorkspace::WriteTabs ( idFile* file, int depth  )
100 {
101         int i;
102         
103         for ( i = 0; i < depth; i ++ )
104         {
105                 file->Write ( "\t", 1 );
106         }
107 }
108
109 /*
110 ================
111 rvGEWorkspace::WriteWindow
112
113 Writes the contents of the given window to the file
114 ================
115 */
116 bool rvGEWorkspace::WriteWindow ( idFile* file, int depth, idWindow* window )
117 {
118         idStr                           out;
119         rvGEWindowWrapper*      wrapper;
120         int                                     i;
121
122         wrapper = rvGEWindowWrapper::GetWrapper ( window );
123         if ( !wrapper )
124         {
125                 return true;
126         }
127
128         if ( wrapper->IsDeleted ( ) )
129         {
130                 return true;
131         }
132
133         // Window def header    
134         WriteTabs ( file, depth - 1 );
135         
136         out = wrapper->WindowTypeToString ( wrapper->GetWindowType ( ) );                       
137         out.Append ( " " );
138         file->Write ( out, out.Length() );      
139
140         out = window->GetName ( );
141         file->Write ( out, out.Length() );
142         file->Write ( "\r\n", 2 );
143         
144         WriteTabs ( file, depth - 1 );
145         
146         out = "{\r\n";
147         file->Write ( out, out.Length() );
148         file->ForceFlush ( );
149
150         for ( i = 0; i < wrapper->GetStateDict().GetNumKeyVals(); i ++ )
151         {
152                 const idKeyValue* key = wrapper->GetStateDict().GetKeyVal ( i );                
153
154                 // Dont write name to the files
155                 if ( !key->GetKey().Icmp ( "name" ) )
156                 {
157                         continue;
158                 }
159                                         
160                 WriteTabs ( file, depth );
161                         
162                 out = key->GetKey();
163                 out.Append ( "\t" );
164                 file->Write ( out, out.Length() );
165
166                 const char* p;
167                 for ( p = key->GetValue().c_str(); *p; p ++ )
168                 {                       
169                         switch ( *p )
170                         {
171                                 case '\n':
172                                         file->Write ( "\\n", 2 );
173                                         break;
174                                 
175                                 default:
176                                         file->Write ( p, 1 );
177                                         break;
178                         }
179                 }
180                 
181                 file->Write ( "\r\n", 2 );
182         }
183
184         for ( i = 0; i < wrapper->GetVariableDict().GetNumKeyVals(); i ++ )
185         {
186                 const idKeyValue* key = wrapper->GetVariableDict().GetKeyVal ( i );
187
188                 WriteTabs ( file, depth );
189
190                 out = key->GetKey();
191                 out.Append ( "\t" );
192                 out.Append ( key->GetValue() );
193                 out.Append ( "\r\n" );
194                 
195                 file->Write ( out, out.Length() );
196         }
197
198         if ( wrapper->GetScriptDict().GetNumKeyVals() )
199         {
200                 file->Write ( "\r\n", 2 );
201         }
202
203         for ( i = 0; i < wrapper->GetScriptDict().GetNumKeyVals(); i ++ )
204         {
205                 const idKeyValue* key = wrapper->GetScriptDict().GetKeyVal ( i );
206
207                 WriteTabs ( file, depth );
208                                 
209                 file->Write ( key->GetKey(), key->GetKey().Length() );
210                 file->Write ( " ", 1 );
211
212                 idLexer src( key->GetValue(), key->GetValue().Length(), "", LEXFL_ALLOWMULTICHARLITERALS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWBACKSLASHSTRINGCONCAT );
213                 src.ParseBracedSectionExact ( out, depth + 1);          
214                 
215                 file->Write ( out, out.Length() );
216                 file->Write ( "\r\n", 2 );
217                 file->Write ( "\r\n", 2 );
218         }
219
220         for ( i = 0; i < wrapper->GetChildCount(); i ++ )
221         {
222                 idWindow* child = wrapper->GetChild ( i );
223         
224                 WriteWindow ( file, depth + 1, child ); 
225         }
226
227         // Window def footer
228         WriteTabs ( file, depth - 1 );
229         
230         out = "}\r\n";
231         file->Write ( out, out.Length() );
232         file->ForceFlush ( );
233         
234         return true;
235 }
236
237 /*
238 ================
239 rvGEWorkspace::NewFile
240
241 Opens a new file for editing
242 ================
243 */
244 bool rvGEWorkspace::NewFile ( void )
245 {
246         idStr   empty;
247         idStr   ospath; 
248         idFile* file;
249
250         // Make a temporary file with nothing in it so we can just use 
251         // load to do all the work
252         ospath = fileSystem->RelativePathToOSPath ( "guis/Untitled.guiednew", "fs_basepath" );
253         DeleteFile ( ospath );
254         
255         file = fileSystem->OpenFileWrite ( "guis/Untitled.guiednew" );
256         if ( NULL == file )
257         {
258                 return false;
259         }
260         
261         empty = "windowDef Desktop { rect 0,0,640,480 }";
262         file->Write ( empty, empty.Length() );
263         fileSystem->CloseFile ( file );
264
265         // Load the temporary file
266         if ( !LoadFile ( ospath, NULL ) )
267         {
268                 // Ensure the temp file doesnt hang around
269                 DeleteFile ( ospath );
270                 return false;
271         }
272         
273         mNew = true;
274         
275         // Ensure the temp file doesnt hang around
276         DeleteFile ( ospath );
277         
278         // Go back to using a .gui extensions
279         ospath.StripFileExtension ( );
280         ospath.Append ( ".gui" );
281         
282         mFilename = ospath;
283                         
284         return true;
285 }
286
287 /*
288 ================
289 rvGEWorkspace::LoadFile
290
291 Loads the given gui file.
292 ================
293 */
294 bool rvGEWorkspace::LoadFile ( const char* filename, idStr* error )
295 {
296         delete mInterface;
297
298         idStr tempfile;
299         idStr ospath;
300         bool  result;
301         
302         tempfile = "guis/temp.guied";
303         ospath = fileSystem->RelativePathToOSPath ( tempfile, "fs_basepath" );
304
305         // Make sure the gui directory exists
306         idStr createDir = ospath;
307         createDir.StripFilename ( );
308         CreateDirectory ( createDir, NULL );
309
310         SetFileAttributes ( ospath, FILE_ATTRIBUTE_NORMAL );
311         DeleteFile ( ospath );
312         if ( !CopyFile ( filename, ospath, FALSE ) )
313         {
314                 if ( error )
315                 {
316                         *error = "File not found";
317                 }
318                 return false;
319         }
320                 
321         SetFileAttributes ( ospath, FILE_ATTRIBUTE_NORMAL );
322
323         mFilename = filename;
324         UpdateTitle ( );
325         
326         // Let the real window system parse it first
327         mInterface = NULL;
328         result     = true;
329         try 
330         {       
331                 mInterface = reinterpret_cast< idUserInterfaceLocal* >( uiManager->FindGui( tempfile, true, true ) );
332                 if ( !mInterface && error )
333                 {
334                         *error = "File not found";
335                 }
336         }
337         catch ( idException& e )
338         {
339                 result = false;
340                 if ( error )
341                 {
342                         *error = e.error;
343                 }
344                 return false;
345         }
346
347         if ( result )
348         {
349                 rvGEWindowWrapper::GetWrapper ( mInterface->GetDesktop ( ) )->Expand ( );
350         }
351         else
352         {
353                 DeleteFile ( ospath );
354         }       
355
356         return result;
357 }
358
359 /*
360 ================
361 rvGEWorkspace::CheckIn
362
363 Checks in the current workspace file into source control
364 ================
365 */
366 bool rvGEWorkspace::CheckIn ( void )
367 {
368         return false;
369
370 }
371
372 /*
373 ================
374 rvGEWorkspace::CheckOut
375
376 Checks out the current workspace file from source control
377 ================
378 */
379 bool rvGEWorkspace::CheckOut ( void )
380 {
381                 return false;
382 }
383
384 /*
385 ================
386 rvGEWorkspace::UndoCheckout
387
388 Undoes the checkout of the current file
389 ================
390 */
391 bool rvGEWorkspace::UndoCheckout ( void )
392 {
393         return false;
394 }
395