Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/lib/gui/gui/orxonox_gui_update.cc @ 4024

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

orxonox/trunk: gui: more addaptive structure

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