Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: changed (void) → ()

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