~ubuntu-branches/ubuntu/precise/widelands/precise-backports

« back to all changes in this revision

Viewing changes to src/game_main_menu_save_game.cc

  • Committer: Bazaar Package Importer
  • Author(s): Martin Quinson
  • Date: 2005-02-14 10:41:12 UTC
  • Revision ID: james.westby@ubuntu.com-20050214104112-6v08iux9fptxpva9
Tags: upstream-build9
Import upstream version build9

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2002-4 by the Widelands Development Team
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU General Public License
 
6
 * as published by the Free Software Foundation; either version 2
 
7
 * of the License, or (at your option) any later version.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software
 
16
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
17
 *
 
18
 */
 
19
 
 
20
#include "game.h"
 
21
#include "game_loader.h"
 
22
#include "game_main_menu_save_game.h"
 
23
#include "game_preload_data_packet.h"
 
24
#include "game_saver.h"
 
25
#include "interactive_player.h"
 
26
#include "ui_button.h"
 
27
#include "ui_editbox.h"
 
28
#include "ui_listselect.h"
 
29
#include "ui_modal_messagebox.h"
 
30
#include "ui_textarea.h"
 
31
 
 
32
/*
 
33
===============
 
34
Game_Main_Menu_Save_Game::Game_Main_Menu_Save_Game
 
35
 
 
36
Create all the buttons etc...
 
37
===============
 
38
*/
 
39
Game_Main_Menu_Save_Game::Game_Main_Menu_Save_Game(Interactive_Player* parent, UIUniqueWindowRegistry* registry)
 
40
  : UIUniqueWindow(parent,registry,400,270,"Save Game") {
 
41
   m_parent=parent;
 
42
 
 
43
   // Caption
 
44
   UITextarea* tt=new UITextarea(this, 0, 0, "Save Game", Align_Left);
 
45
   tt->set_pos((get_inner_w()-tt->get_w())/2, 5);
 
46
 
 
47
   int spacing=5;
 
48
   int offsx=spacing;
 
49
   int offsy=30;
 
50
   int posx=offsx;
 
51
   int posy=offsy;
 
52
 
 
53
   // listselect
 
54
   m_ls=new UIListselect(this, posx, posy, get_inner_w()/2-spacing, get_inner_h()-spacing-offsy-60);
 
55
   m_ls->selected.set(this, &Game_Main_Menu_Save_Game::selected);
 
56
   m_ls->double_clicked.set(this, &Game_Main_Menu_Save_Game::double_clicked);
 
57
   // Filename editbox 
 
58
   m_editbox=new UIEdit_Box(this, posx, posy+get_inner_h()-spacing-offsy-60+3, get_inner_w()/2-spacing, 20, 1, 0);
 
59
   m_editbox->changed.set(this, &Game_Main_Menu_Save_Game::edit_box_changed);
 
60
 
 
61
   // the descriptive areas
 
62
   // Name
 
63
   posx=get_inner_w()/2+spacing;
 
64
   posy+=20;
 
65
   new UITextarea(this, posx, posy, 150, 20, "Map Name: ", Align_CenterLeft);
 
66
   m_name=new UITextarea(this, posx+90, posy, 200, 20, "---", Align_CenterLeft);
 
67
   posy+=20+spacing;
 
68
 
 
69
   // Author
 
70
   new UITextarea(this, posx, posy, 150, 20, "Game Time: ", Align_CenterLeft);
 
71
   m_gametime=new UITextarea(this, posx+90, posy, 200, 20, "---", Align_CenterLeft);
 
72
   posy+=20+spacing;
 
73
 
 
74
   // Buttons
 
75
   posx=5;
 
76
   posy=get_inner_h()-30;
 
77
   UIButton* but= new UIButton(this, get_inner_w()/2-spacing-80, posy, 80, 20, 0, 1);
 
78
   but->clickedid.set(this, &Game_Main_Menu_Save_Game::clicked);
 
79
   but->set_title("OK");
 
80
   but->set_enabled(false); 
 
81
   m_ok_btn=but;
 
82
   but= new UIButton(this, get_inner_w()/2+spacing, posy, 80, 20, 1, 0);
 
83
   but->clickedid.set(this, &Game_Main_Menu_Save_Game::clicked);
 
84
   but->set_title("Cancel");
 
85
 
 
86
   m_basedir="ssave";
 
87
   m_curdir="ssave";
 
88
 
 
89
   fill_list();
 
90
 
 
91
   center_to_parent();
 
92
   move_to_top();
 
93
}
 
94
 
 
95
/*
 
96
===============
 
97
Game_Main_Menu_Save_Game::~Game_Main_Menu_Save_Game
 
98
 
 
99
Unregister from the registry pointer
 
100
===============
 
101
*/
 
102
Game_Main_Menu_Save_Game::~Game_Main_Menu_Save_Game()
 
103
{
 
104
}
 
105
 
 
106
/*
 
107
===========
 
108
called when the ok button has been clicked
 
109
===========
 
110
*/
 
111
void Game_Main_Menu_Save_Game::clicked(int id) {
 
112
   if(id==1) {
 
113
      // Ok
 
114
      std::string filename=m_editbox->get_text();
 
115
      
 
116
      if(filename=="") {
 
117
         // Maybe a dir is selected
 
118
         filename=static_cast<const char*>(m_ls->get_selection());
 
119
      }
 
120
 
 
121
      if(g_fs->IsDirectory(filename.c_str())) {
 
122
         char buffer[256];
 
123
         FS_CanonicalizeName(buffer, sizeof(buffer), filename.c_str());
 
124
         m_curdir=buffer;
 
125
         m_ls->clear();
 
126
         m_gamefiles.clear();
 
127
         fill_list();
 
128
      } else {
 
129
         if(save_game(filename)) 
 
130
            die();
 
131
      }
 
132
   } else if(id==0) {
 
133
      // Cancel
 
134
      die();
 
135
   } 
 
136
}
 
137
 
 
138
/*
 
139
 * called when a item is selected
 
140
 */
 
141
void Game_Main_Menu_Save_Game::selected(int i) {
 
142
   const char* name=static_cast<const char*>(m_ls->get_selection());
 
143
 
 
144
   if(!g_fs->IsDirectory(name)) {
 
145
      Game_Loader gl(name, m_parent->get_game());
 
146
      Game_Preload_Data_Packet gpdp;
 
147
      gl.preload_game(&gpdp); // This has worked before, no problem
 
148
     
 
149
      char* fname = strdup(FS_Filename(name));
 
150
      FS_StripExtension(fname);
 
151
      m_editbox->set_text(fname);
 
152
      free(fname);
 
153
      m_ok_btn->set_enabled(true);
 
154
      
 
155
      m_name->set_text(gpdp.get_mapname());
 
156
      
 
157
      char buf[200];
 
158
      uint gametime = gpdp.get_gametime();
 
159
 
 
160
      int hours = gametime / 3600000;
 
161
      gametime -= hours * 3600000;
 
162
      int minutes = gametime / 60000;
 
163
      
 
164
      sprintf(buf, "%02i:%02i", hours, minutes);
 
165
      m_gametime->set_text(buf);
 
166
   } else {
 
167
      m_name->set_text("");
 
168
      m_gametime->set_text("");
 
169
   }
 
170
}
 
171
 
 
172
/*
 
173
 * An Item has been doubleclicked
 
174
 */
 
175
void Game_Main_Menu_Save_Game::double_clicked(int) {
 
176
   clicked(1);
 
177
}
 
178
 
 
179
/*
 
180
 * fill the file list
 
181
 */
 
182
void Game_Main_Menu_Save_Game::fill_list(void) {
 
183
   // Fill it with all files we find. 
 
184
   g_fs->FindFiles(m_curdir, "*", &m_gamefiles, 1);
 
185
  
 
186
   for(filenameset_t::iterator pname = m_gamefiles.begin(); pname != m_gamefiles.end(); pname++) {
 
187
      const char *name = pname->c_str();
 
188
      if(!strcmp(FS_Filename(name),".")) continue;
 
189
      if(!strcmp(FS_Filename(name),"..")) continue; // Upsy, appeared again. ignore
 
190
      if(!g_fs->IsDirectory(name)) continue;
 
191
 
 
192
      m_ls->add_entry(FS_Filename(name), reinterpret_cast<void*>(const_cast<char*>(name)), false, g_gr->get_picture(PicMod_Game, "pics/ls_dir.png", true));
 
193
   }
 
194
 
 
195
   Game_Preload_Data_Packet gpdp;
 
196
   
 
197
   for(filenameset_t::iterator pname = m_gamefiles.begin(); pname != m_gamefiles.end(); pname++) {
 
198
      const char *name = pname->c_str();
 
199
      
 
200
      Game_Loader* gl = new Game_Loader(name,m_parent->get_game());
 
201
 
 
202
      try {
 
203
         gl->preload_game(&gpdp);
 
204
         char* fname = strdup(FS_Filename(name));
 
205
         FS_StripExtension(fname);
 
206
         m_ls->add_entry(fname, reinterpret_cast<void*>(const_cast<char*>(name)));
 
207
         free(fname);
 
208
      } catch(wexception& ) {
 
209
         // we simply skip illegal entries
 
210
      }
 
211
      delete gl;
 
212
   }
 
213
   
 
214
   if(m_ls->get_nr_entries())
 
215
      m_ls->select(0);
 
216
}
 
217
 
 
218
/*
 
219
 * The editbox was changed. Enable ok button
 
220
 */
 
221
void Game_Main_Menu_Save_Game::edit_box_changed(void) {
 
222
   m_ok_btn->set_enabled(true);
 
223
}
 
224
 
 
225
/*
 
226
 * Save the game
 
227
 *
 
228
 * returns true if dialog should close, false if it
 
229
 * should stay open
 
230
 */
 
231
bool Game_Main_Menu_Save_Game::save_game(std::string filename) {
 
232
  
 
233
   // Make sure that the base directory exists
 
234
   g_fs->EnsureDirectoryExists(m_basedir);
 
235
 
 
236
   // ok, first check if the extension matches (ignoring case)
 
237
   bool assign_extension=true;
 
238
   if(filename.size() >= strlen(WLGF_SUFFIX)) {
 
239
      char buffer[10]; // enough for the extension
 
240
      filename.copy(buffer, sizeof(WLGF_SUFFIX), filename.size()-strlen(WLGF_SUFFIX));
 
241
      if(!strncasecmp(buffer, WLGF_SUFFIX, strlen(WLGF_SUFFIX)))
 
242
         assign_extension=false;
 
243
   }
 
244
   if(assign_extension)
 
245
      filename+=WLGF_SUFFIX;
 
246
   
 
247
   // Now append directory name
 
248
   std::string complete_filename=m_curdir;
 
249
   complete_filename+="/";
 
250
   complete_filename+=filename;
 
251
 
 
252
   // Check if file exists, if it does, show a warning
 
253
   if(g_fs->FileExists(complete_filename)) {
 
254
      std::string s="A File with the name ";
 
255
      s+=FS_Filename(filename.c_str());
 
256
      s+=" exists already. Overwrite?";
 
257
      UIModal_Message_Box* mbox= new UIModal_Message_Box(m_parent, "Save Game Error!!", s, UIModal_Message_Box::YESNO);
 
258
      bool retval=mbox->run();
 
259
      delete mbox;
 
260
      if(!retval) 
 
261
         return false;
 
262
   }
 
263
 
 
264
   Game_Saver* gs=new Game_Saver(complete_filename.c_str(), m_parent->get_game());
 
265
   try {
 
266
      gs->save();
 
267
   } catch(std::exception& exe) {
 
268
      std::string s="Game Saving Error!\nSaved Game-File may be corrupt!\n\nReason given:\n";
 
269
      s+=exe.what();
 
270
      UIModal_Message_Box* mbox= new UIModal_Message_Box(m_parent, "Save Game Error!!", s, UIModal_Message_Box::OK);
 
271
      mbox->run();
 
272
      delete mbox;
 
273
   }
 
274
   delete gs;
 
275
   die();
 
276
 
 
277
   return true;
 
278
}
 
279
 
 
280