Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/lib/gui/gui/gui_update.cc @ 4083

Last change on this file since 4083 was 4083, checked in by bensch, 19 years ago

orxonox/trunk/gui: now one can only select the data-repos

File size: 14.8 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3   Copyright (C) 2004 orx
4
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 2, or (at your option)
8   any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14
15   You should have received a copy of the GNU General Public License
16   along with this program; if not, write to the Free Software Foundation,
17   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
18
19
20   ### File Specific:
21   main-programmer: Benjamin Grauer
22
23*/
24
25#include "gui_update.h"
26#include <string.h>
27
28#include "gui.h"
29#include <stdio.h>
30#include <stdlib.h>
31
32using namespace std;
33
34/**
35   \brief Creates an Update-Frame
36*/
37GuiUpdate::GuiUpdate(void)
38{
39  FileDialog* dataDirDialog;   //!< A FileDialog for the selection of the DataRepos
40  Button* dataDirButton;       //!< A Button for the selection of the DataRepos
41  OptionLabel* dataDirLabel;   //!< A Label fot the selection of the DataRepos
42 
43
44  this->tmpDir = NULL;
45  this->homeDir = NULL;
46  this->installSourceDir = NULL;
47  this->userName = NULL;
48
49  this->getSystemInfo();
50
51  this->updateFrame = new Frame("Update-Options:");
52  this->updateFrame->setGroupName("update");
53  this->updateBox = new Box('v');
54
55  dataDirButton = new Button("Data Directory");
56  dataDirLabel = new OptionLabel("DataDir", "unknown");
57  dataDirLabel->saveability();
58  dataDirDialog = new FileDialog("data-Repos-location");
59  dataDirDialog->setDefaultFileName("data");
60  dataDirDialog->setMask(DATA_IDENTIFIER);
61  this->checkDataDir("../data/" DATA_IDENTIFIER, dataDirLabel);
62  dataDirDialog->disableFileOpts();
63  dataDirDialog->setOpenUpButton(dataDirButton);
64  //dataDirDialog->setChangeOption(dataDirLabel);
65  dataDirDialog->setOKFunc(dataDirLabel, GuiUpdate::checkDataDir);
66  updateBox->fill(dataDirButton);
67  updateBox->fill(dataDirLabel);
68
69#ifdef HAVE_CURL
70
71  // the Button for autoUpdating
72  this->autoUpdate = new CheckButton("auto update");
73  this->updateBox->fill(this->autoUpdate);
74  this->autoUpdate->setFlagName("update", "u", 0);
75  this->autoUpdate->saveability();
76
77 
78
79
80  this->updateSourceWindowCreate();
81  this->updateBox->fill(this->updateSourceWindowGetButton());
82
83  this->updateDataWindowCreate();
84  this->updateBox->fill(this->updateDataWindowGetButton());
85
86#else /* HAVE_CURL */
87  Label* noCurlLabel = new Label("since you do not have cURL-support,\nupdate options are not availible");
88  this->updateBox->fill(noCurlLabel); 
89#endif /* HAVE_CURL */
90  this->updateFrame->fill(this->updateBox);
91  this->setMainWidget(this->updateFrame);
92
93
94}
95
96/**
97   \brief Destructs the Update-stuff
98*/
99GuiUpdate::~GuiUpdate(void)
100{
101
102}
103
104/**
105   \brief checks if the Folder containing selected File is data.oxd, and if so sets it.
106   \param
107*/
108bool GuiUpdate::checkDataDir(const char* fileName, void* object)
109{
110  if (!strcmp(fileName+(strlen(fileName)-strlen(DATA_IDENTIFIER)), DATA_IDENTIFIER))
111    {
112      char* tmpName = new char[strlen(fileName)-strlen(DATA_IDENTIFIER)+1];
113      strncpy(tmpName, fileName, strlen(fileName)-strlen(DATA_IDENTIFIER));
114      tmpName[strlen(fileName)-strlen(DATA_IDENTIFIER)] = '\0'; 
115      static_cast<OptionLabel*>(object)->setValue(tmpName);
116      delete tmpName;
117      return true;
118    }
119  else
120    return false;
121}
122
123
124/**
125    \brief Look what info we can get from this system
126*/
127bool GuiUpdate::getSystemInfo(void)
128{
129  PRINTF(3)("Grabbing system information\n");
130  this->tmpDir = getenv("TMPDIR");
131  if(!tmpDir)
132    this->tmpDir = "/tmp";
133  PRINTF(4)("Temporary directory is: %s\n", this->tmpDir);
134
135#ifdef __WIN32__
136  this->homeDir = getenv("USERPROFILE");
137#else
138  this->homeDir = getenv("HOME");
139#endif
140  PRINTF(4)("Home directory is %s\n", homeDir);
141
142  this->installDataDir = "/usr/share/games/orxonox";
143  PRINTF(4)("Installation of orxonox-data will go to this directory: %s\n", this->installDataDir);
144
145  this->installSourceDir = "/usr/games/bin";
146  PRINTF(4)("Installation of orxonox-source will go to this directory: %s\n", this->installSourceDir);
147
148  this->userName = getenv("USER");
149  PRINTF(4)("Logged in username is: %s\n", this->userName);
150}
151
152#ifdef HAVE_CURL
153bool* GuiUpdate::checkForUpdates(void)
154{
155  PRINTF(3)("checking for new version of orxonox\n");
156  FileInfo updateFileInfo;
157  updateFileInfo.fileName = "update_info";
158  updateFileInfo.webRoot = "http://www.orxonox.ethz.ch/files/data";
159  updateFileInfo.localRoot = this->tmpDir;
160 
161  download(&updateFileInfo);
162}
163
164/**
165   \brief Creates a window, and all it contains for the Data-update.
166*/
167void GuiUpdate::updateDataWindowCreate(void)
168{
169  this->updateDataWindow = new Window("update orxonox::Data");   
170  this->updateDataBox = new Box('v');
171
172  // the close-Button of the Update Window.
173  //  updateWindowClose = new Button("close");
174#ifdef HAVE_GTK2
175  //  updateWindowClose->connectSignal("button_press_event", updateWindow, Window::windowClose);
176#endif /* HAVE_GTK2 */
177  //  updateWindowBox->fill(updateWindowClose);
178
179  this->updateDataBar = new ProgressBar();
180  this->updateDataBox->fill(this->updateDataBar);
181
182  FileInfo* dataInfo = new FileInfo;
183  dataInfo->bar = this->updateDataBar;
184
185  this->updateDataBegin = new Button("begin.");
186  dataInfo->stateButton = this->updateDataBegin;
187#ifdef HAVE_GTK2
188  dataInfo->buttonSignal = updateDataBegin->connectSignal("button_press_event", dataInfo, updateDataFunc);
189#endif /* HAVE_GTK2 */
190  this->updateDataBox->fill(this->updateDataBegin);
191
192  this->updateDataWindow->fill(this->updateDataBox);
193
194  this->updateDataWindowButton = new Button("update orxonox::Data");
195#ifdef HAVE_GTK2
196  this->updateDataWindowButton->connectSignal("button_press_event", this->updateDataWindow, Window::windowOpen);
197  this->updateDataWindow->connectSignal("destroy", this->updateDataWindow, Window::windowClose);
198  this->updateDataWindow->connectSignal("delete_event", this->updateDataWindow, Window::windowClose);
199#endif /* HAVE_GTK2 */
200
201}
202
203/**
204   \returns A Pointer to the Button of the UpdaterDataWindow
205*/
206Button* GuiUpdate::updateDataWindowGetButton(void)
207{
208  return this->updateDataWindowButton;
209}
210
211/**
212   \brief Creates a window, and all it contains for the Source-update.
213*/
214void GuiUpdate::updateSourceWindowCreate(void)
215{
216  // the button, that opens this Window.
217  this->updateSourceWindowButton = new Button("update orxonox::Source");
218
219  // the Window itself
220  this->updateSourceWindow = new Window("update orxonox::Source");
221
222  this->updateSourceBox = new Box();
223
224  this->updateSourceBar = new ProgressBar();
225  this->updateSourceBox->fill(this->updateSourceBar);
226  test = new Button("increment");
227
228#ifdef HAVE_GTK2
229  test->connectSignal("button_press_event", updateSourceBar, updateSourceFunc);
230#endif /* HAVE_GTK2 */
231
232  this->updateSourceBox->fill(test);
233  this->updateSourceWindow->fill(updateSourceBox); 
234#ifdef HAVE_GTK2
235  this->updateSourceWindowButton->connectSignal("button_press_event", this->updateSourceWindow, Window::windowOpen);
236  this->updateSourceWindow->connectSignal("destroy", this->updateSourceWindow, Window::windowClose);
237  this->updateSourceWindow->connectSignal("delete_event", this->updateSourceWindow, Window::windowClose);
238#endif /* HAVE_GTK2 */
239
240}
241
242/**
243   \returns A Pointer to the Button of the UpdaterSourceWindow
244*/
245Button* GuiUpdate::updateSourceWindowGetButton(void)
246{
247  return this->updateSourceWindowButton;
248}
249
250
251#ifdef HAVE_GTK2
252/**
253   \brief updates the Data of orxonox.
254   \param w The widget, that executed this Function.
255   \param event The event that trigered this Function.
256   \param button The Button, that triggered this event.
257*/
258gint GuiUpdate::updateDataFunc(GtkWidget* w, GdkEventKey* event, void* info)
259{
260  FileInfo* dataInfo =(FileInfo*)info;
261
262  dataInfo->fileName = "02%20orxonox%203.mp3";
263  dataInfo->webRoot  = "http://www.orxonox.ethz.ch/files/";
264  dataInfo->localRoot = "./";
265  PRINTF(3)("Preparing to download file %s.\n", dataInfo->fileName);
266  downloadWithStyle(dataInfo);
267}
268
269/**
270   \brief updates the source of orxonox.
271   \param w The widget, that executed this Function.
272   \param event The event that trigered this Function.
273   \param button The Button, that triggered this event.
274*/
275gint GuiUpdate::updateSourceFunc(GtkWidget* w, GdkEventKey* event, void* bar)
276{
277  ProgressBar* tmpBar = static_cast<ProgressBar*>(bar);
278  tmpBar->setTotalSize(20);
279  tmpBar->setProgress(tmpBar->getProgress()+1);
280}
281#endif /* HAVE_GTK2 */
282
283/**
284   \brief The Function Curl calls to write out the File.
285   \param ptr A Pointer to the date to write.
286   \param size The size in bytes of one nmemb to write.
287   \param nmemb The Count of size to write.
288   \param stream Filehandler to write to.
289*/
290size_t GuiUpdate::curlWriteFunc(void* ptr, size_t size, size_t nmemb, FILE* stream)
291{
292  return fwrite(ptr, size, nmemb, stream);
293}
294
295/**
296   \brief The Function Curl calls to write out the File.
297   \param ptr A Pointer to the date to write to.
298   \param size The size in bytes of one nmemb to write.
299   \param nmemb The Count of size to write.
300   \param stream Filehandler to get data from.
301*/
302size_t GuiUpdate::curlReadFunc(void* ptr, size_t size, size_t nmemb, FILE* stream)
303{
304  return fread(ptr, size, nmemb, stream);
305}
306
307
308/**
309   \brief An update Function for the GUI, to show the progress.
310   \param Bar th ProgressBar to update
311   \param totalSize The total size of the download in bytes.
312   \param progress The current Progress of the download in bytes.
313   \param upTotal not needed
314   \param upProgress not needed
315*/
316int GuiUpdate::curlProgressFunc(ProgressBar* bar, double totalSize, double progress, double upTotal, double upProgress)
317{
318  bar->setProgress(progress);
319  bar->setTotalSize(totalSize);
320#ifdef HAVE_GTK2
321  while(gtk_events_pending()) gtk_main_iteration();
322#endif
323  return 0;
324}
325
326/**
327   \brief The Curl handle for only one CURL(static).
328*/
329CURL* GuiUpdate::curlHandle = NULL;
330
331//! A bool parameter that shows if we are downloading.
332bool GuiUpdate::isDownloading = false;
333
334//! A parameter to see, if downloading has been canceled
335bool GuiUpdate::downloadCanceled = false;
336
337/**
338   \brief Initializes a Download without displaying it.
339   \param fileInfo the FileInfo.
340
341   !! BE AWARE THIS WILL NOT BE THREADED. !!
342*/
343bool GuiUpdate::download(void* fileInfo)
344{
345  if(isDownloading)
346    {
347      PRINTF(2)("unable to Download. already getting some file\n");
348      return false;
349    }
350  PRINTF(3)("Downloading.\n");
351  FileInfo* info =(FileInfo*)fileInfo;
352  CURLcode res;
353  CURL* localCurl;
354  localCurl = curl_easy_init();
355  char* fileOnNet = new char [strlen(info->webRoot)+strlen(info->fileName)+2];
356  strcpy(fileOnNet, info->webRoot);
357  if(fileOnNet[strlen(fileOnNet)] != '/') //!< \todo windows-shit
358    strcat(fileOnNet, "/");
359  strcat(fileOnNet, info->fileName);
360  char* fileOnDisk = new char [strlen(info->localRoot)+strlen(info->fileName)+2];
361  strcpy(fileOnDisk, info->localRoot);
362  if(fileOnDisk[strlen(fileOnDisk)] != '/') //!< \todo windows-shit
363    strcat(fileOnDisk, "/");
364  strcat(fileOnDisk, info->fileName);
365 
366  if(localCurl)
367    {
368     
369      info->fileHandle = fopen(fileOnDisk, "w");
370     
371      curl_easy_setopt(localCurl, CURLOPT_URL, fileOnNet);
372      curl_easy_setopt(localCurl, CURLOPT_WRITEDATA, info->fileHandle);
373      curl_easy_setopt(localCurl, CURLOPT_WRITEFUNCTION, curlWriteFunc);
374      curl_easy_setopt(localCurl, CURLOPT_READFUNCTION, curlReadFunc);
375      curl_easy_setopt(localCurl, CURLOPT_NOPROGRESS, true);
376     
377      curl_easy_perform(localCurl);
378
379      curl_easy_cleanup(localCurl);
380      fclose(info->fileHandle);
381    }
382}
383
384/**
385   \brief Initializes a Download with some style.
386   \param fileInfo the FileInfo.
387   \todo release thread-lock.
388
389   Downloading with a Button that gets a different Name while downloading, and a Bar, that gets to be updated. More to be followed
390*/
391bool GuiUpdate::downloadWithStyle(void* fileInfo)
392{
393  if(isDownloading)
394    {
395      PRINTF(2)("unable to Download. already getting some file\n");
396      return false;
397    }
398  PRINTF(3)("Downloading.\n");
399  FileInfo* info =(FileInfo*)fileInfo;
400  CURLcode res;
401  curlHandle = curl_easy_init();
402  char* fileOnNet = new char [strlen(info->webRoot)+strlen(info->fileName)+1];
403  strcpy(fileOnNet, info->webRoot);
404  strcat(fileOnNet, info->fileName);
405  char* fileOnDisk = new char [strlen(info->localRoot)+strlen(info->fileName)+1];
406  strcpy(fileOnDisk, info->localRoot);
407  strcat(fileOnDisk, info->fileName);
408
409  if(curlHandle)
410    {
411     
412      info->fileHandle = fopen(fileOnDisk, "w");
413     
414      curl_easy_setopt(curlHandle, CURLOPT_URL, fileOnNet);
415      curl_easy_setopt(curlHandle, CURLOPT_WRITEDATA, info->fileHandle);
416      curl_easy_setopt(curlHandle, CURLOPT_WRITEFUNCTION, curlWriteFunc);
417      curl_easy_setopt(curlHandle, CURLOPT_READFUNCTION, curlReadFunc);
418      curl_easy_setopt(curlHandle, CURLOPT_NOPROGRESS, false);
419      curl_easy_setopt(curlHandle, CURLOPT_PROGRESSFUNCTION, curlProgressFunc);
420      curl_easy_setopt(curlHandle, CURLOPT_PROGRESSDATA, info->bar);
421
422      if(!isDownloading)
423        {
424#ifdef HAVE_GTK2
425          info->stateButton->disconnectSignal(info->buttonSignal);
426          info->buttonSignal = info->stateButton->connectSignal("button_press_event", info, cancelDownload);
427#endif /* HAVE_GTK2 */
428          info->stateButton->setTitle("please wait");
429         
430          downloadThread(info);
431          downloadThreadFinished(info);
432         
433          //      res = curl_easy_perform(curlHandle);
434         
435          //      fclose(outfile);
436        }
437      else 
438        PRINTF(1)("thread already in use\n");
439
440    }
441  return true;
442}
443
444/**
445   \brief The downloading process(either threaded or not).
446   \param fileInfo the FileInfo.
447
448   \todo Threads get locked, if the cancel button is pressed in to small intervals.
449*/
450void* GuiUpdate::downloadThread(void* fileInfo)
451{
452  isDownloading = true;
453  curl_easy_perform(curlHandle);
454}
455
456/**
457   \brief Finishes a downloading process.
458   \param fileInfo the FileInfo.
459*/
460void* GuiUpdate::downloadThreadFinished(void* fileInfo)
461{ 
462  FileInfo* info =(FileInfo*)fileInfo;
463  if(curlHandle)
464    curl_easy_cleanup(curlHandle);
465 
466  PRINTF(3)("Closing the downloaded file.\n");
467  fclose(info->fileHandle);
468
469  if(isDownloading)
470    info->stateButton->setTitle("go on");
471  //  else
472  //    info->stateButton->setTitle("done");
473#ifdef HAVE_GTK2
474  info->stateButton->disconnectSignal(info->buttonSignal);
475  info->buttonSignal = info->stateButton->connectSignal("button_press_event", info, updateDataFunc);
476#endif /* HAVE_GTK2 */
477  isDownloading = false;
478
479}
480
481#ifdef HAVE_GTK2
482/**
483   \brief canceles a downloading session.
484   \param w The widget, that executed this Function.
485   \param event The event that trigered this Function.
486   \param bar The Bar, that triggered this event.
487
488   \todo canceling a session in non-threaded mode.
489*/
490gint GuiUpdate::cancelDownload(GtkWidget* w, GdkEventKey* event, void* bar)
491{
492  PRINTF(4)("Cannot cancle the Downloading process until after this File\n");
493}
494#endif /* HAVE_GTK2 */
495
496#endif /* HAVE_CURL */
Note: See TracBrowser for help on using the repository browser.