s/GtkRadiant/NetRadiant/
[xonotic/netradiant.git] / contrib / camera / funchandlers.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 /*
23 Camera plugin for GtkRadiant
24 Copyright (C) 2002 Splash Damage Ltd.
25 */
26
27 #include "camera.h"
28
29 extern GtkWidget *g_pEditModeAddRadioButton;
30
31 char* Q_realpath(const char *path, char *resolved_path, size_t size)
32 {
33 #if defined(POSIX)
34         return realpath(path, resolved_path);
35 #elif defined(WIN32)
36         return _fullpath(resolved_path, path, size);
37 #else
38 #error "unsupported platform"
39 #endif
40 }
41
42 static void DoNewCamera( idCameraPosition::positionType type )
43 {
44         CCamera *cam = AllocCam();
45
46         if( cam ) {
47                 char buf[128];
48                 sprintf( buf, "camera%i", cam->GetCamNum() );
49
50                 cam->GetCam()->startNewCamera( type );
51                 cam->GetCam()->setName( buf );
52                 cam->GetCam()->buildCamera();
53
54                 sprintf( buf, "Unsaved Camera %i", cam->GetCamNum() );
55                 cam->SetFileName( buf, false );
56
57                 SetCurrentCam( cam );
58                 RefreshCamListCombo();
59
60                 // Go to editmode Add
61                 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(g_pEditModeAddRadioButton), TRUE );
62
63                 // Show the camera inspector
64                 DoCameraInspector();
65
66                 // Start edit mode (if not initiated by DoCameraInspector)
67                 if( !g_bEditOn )
68                         DoStartEdit( GetCurrentCam() );
69         } else {
70       g_FuncTable.m_pfnMessageBox( (GtkWidget *)g_pRadiantWnd, "No free cameras available.", "Create Camera Error", eMB_OK );
71         }
72 }
73
74 void DoNewFixedCamera()
75 {
76         DoNewCamera( idCameraPosition::FIXED );
77 }
78
79 void DoNewInterpolatedCamera()
80 {
81         DoNewCamera( idCameraPosition::INTERPOLATED );
82 }
83
84 void DoNewSplineCamera()
85 {
86         DoNewCamera( idCameraPosition::SPLINE );
87 }
88
89 void DoCameraInspector()
90 {
91   gtk_widget_show( g_pCameraInspectorWnd );
92 }
93
94 void DoPreviewCamera()
95 {
96         if( GetCurrentCam() ) {
97                 g_iPreviewRunning = 1;
98                 g_FuncTable.m_pfnSysUpdateWindows( W_XY_OVERLAY | W_CAMERA );
99         }
100 }
101
102 void DoLoadCamera()
103 {
104   char basepath[PATH_MAX];
105
106         if( firstCam && firstCam->HasBeenSaved() )
107     ExtractFilePath( firstCam->GetFileName(), basepath );
108   else
109     strcpy( basepath, g_FuncTable.m_pfnGetGamePath() );
110
111   const gchar *filename = g_FuncTable.m_pfnFileDialog( (GtkWidget *)g_pRadiantWnd, TRUE, "Open Camera File", basepath, "camera");
112
113   if( filename )
114         {
115     CCamera *cam = AllocCam();
116     char fullpathtofile[PATH_MAX];
117
118     if( cam ) {
119                         Q_realpath(filename, fullpathtofile, PATH_MAX);
120
121       // see if this camera file was already loaded
122       CCamera *checkCam = firstCam->GetNext();  // not the first one as we just allocated it
123       while( checkCam ) {
124         if( !strcmp( fullpathtofile, checkCam->GetFileName() ) ) {
125           char error[PATH_MAX+64];
126           FreeCam( cam );
127           sprintf( error, "Camera file \'%s\' is already loaded", fullpathtofile );
128           g_FuncTable.m_pfnMessageBox( (GtkWidget *)g_pRadiantWnd, error, "Load error", eMB_OK );
129           //g_free( filename );
130           return;
131         }
132         checkCam = checkCam->GetNext();
133       }
134
135                         if( loadCamera( cam->GetCamNum(), fullpathtofile ) ) {
136                                 cam->GetCam()->buildCamera();
137         cam->SetFileName( filename, true );
138         SetCurrentCam( cam );
139         RefreshCamListCombo();
140         g_FuncTable.m_pfnSysUpdateWindows( W_XY_OVERLAY | W_CAMERA );
141       } else {
142         char error[PATH_MAX+64];
143         FreeCam( cam );
144         sprintf( error, "An error occured during the loading of \'%s\'", fullpathtofile );
145         g_FuncTable.m_pfnMessageBox( (GtkWidget *)g_pRadiantWnd, error, "Load error", eMB_OK );
146       }
147
148       //g_free( filename );
149     } else {
150       g_FuncTable.m_pfnMessageBox( (GtkWidget *)g_pRadiantWnd, "No free camera slots available", "Load error", eMB_OK );
151           }
152         }
153 }
154
155 void DoSaveCamera() {
156   char basepath[PATH_MAX];
157
158   if( !GetCurrentCam() )
159     return;
160
161   if( GetCurrentCam()->GetFileName()[0] )
162     ExtractFilePath( GetCurrentCam()->GetFileName(), basepath );
163   else
164     strcpy( basepath, g_FuncTable.m_pfnGetGamePath() );
165
166   const gchar *filename = g_FuncTable.m_pfnFileDialog( g_pRadiantWnd, FALSE, "Save Camera File", basepath, "camera");
167
168   if( filename ) {
169     char fullpathtofile[PATH_MAX + 8];
170
171     Q_realpath(filename, fullpathtofile, PATH_MAX);
172
173                 // File dialog from windows (and maybe the gtk one from radiant) doesn't handle default extensions properly.
174                 // Add extension and check again if file exists
175                 if( strcmp( fullpathtofile + (strlen(fullpathtofile) - 7), ".camera" ) ) {
176                         strcat( fullpathtofile, ".camera" );
177
178                         if( FileExists( fullpathtofile ) ) {
179                                 if( g_FuncTable.m_pfnMessageBox( (GtkWidget *)g_pRadiantWnd, "File already exists.\nOverwrite?", "Save Camera File", eMB_YESNO ) == eIDNO ) 
180                                         return;
181                         }
182                 }
183
184           // see if this camera file was already loaded
185     CCamera *checkCam = firstCam;
186     while( checkCam ) {
187       if( checkCam == GetCurrentCam() ) {
188         checkCam = checkCam->GetNext();
189                                 if( !checkCam ) // we only have one camera file opened so no need to check further
190                                         break;
191       } else if( !strcmp( fullpathtofile, checkCam->GetFileName() ) ) {
192         char error[PATH_MAX+64];
193         sprintf( error, "Camera file \'%s\' is currently loaded by NetRadiant.\nPlease select a different filename.", fullpathtofile );
194         g_FuncTable.m_pfnMessageBox( (GtkWidget *)g_pRadiantWnd, error, "Save error", eMB_OK );
195         return;
196       }
197       checkCam = checkCam->GetNext();
198     }
199
200     // FIXME: check for existing directory
201
202     GetCurrentCam()->GetCam()->save( fullpathtofile );
203                 GetCurrentCam()->SetFileName( fullpathtofile, true );
204                 RefreshCamListCombo();
205   }
206 }
207
208 void DoUnloadCamera() {
209   if( !GetCurrentCam() )
210     return;
211
212         if( !GetCurrentCam()->HasBeenSaved() ) {
213                 char buf[PATH_MAX+64];
214                 sprintf( buf, "Do you want to save the changes for camera '%s'?", GetCurrentCam()->GetCam()->getName() );
215                 if( g_FuncTable.m_pfnMessageBox( (GtkWidget *)g_pRadiantWnd, buf, "Warning", eMB_YESNO ) == eIDYES ) 
216                         DoSaveCamera();
217         } else if( GetCurrentCam()->HasBeenSaved() == 2 ) {
218                 char buf[PATH_MAX+64];
219                 sprintf( buf, "Do you want to save the changes made to camera file '%s'?", GetCurrentCam()->GetFileName() );
220                 if( g_FuncTable.m_pfnMessageBox( (GtkWidget *)g_pRadiantWnd, buf, "Warning", eMB_YESNO ) == eIDYES ) 
221                         DoSaveCamera();
222         }
223
224   if( g_pCurrentEditCam ) {
225     DoStopEdit();
226     g_pCurrentEditCam = NULL;
227   }
228
229         FreeCam( GetCurrentCam() );
230         SetCurrentCam( NULL );
231         RefreshCamListCombo();
232 }
233
234 CCamera *g_pCurrentEditCam = NULL;
235
236 void DoStartEdit( CCamera *cam ) {
237   if( g_pCurrentEditCam ) {
238     DoStopEdit();
239     g_pCurrentEditCam = NULL;
240   }
241
242   if( cam ) {
243     g_bEditOn = true;
244
245     if( !Listener )
246       Listener = new CListener;
247
248     cam->GetCam()->startEdit( g_iActiveTarget < 0 ? true : false );
249
250     g_pCurrentEditCam = cam;
251
252     g_FuncTable.m_pfnSysUpdateWindows( W_XY_OVERLAY | W_CAMERA );
253   }
254 }
255
256 void DoStopEdit( void ) {
257   g_bEditOn = false;
258
259   if( Listener ) {
260       delete Listener;
261       Listener = NULL;
262   }
263
264   if( g_pCurrentEditCam ) {
265     // stop editing on the current cam
266     g_pCurrentEditCam->GetCam()->stopEdit();
267     g_pCurrentEditCam = NULL;
268
269     g_FuncTable.m_pfnSysUpdateWindows( W_XY_OVERLAY | W_CAMERA );
270   }
271 }