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
RevLine 
[3250]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>
[3285]31#include <stdlib.h>
[3270]32
[3250]33using namespace std;
34
35/**
[3318]36   \brief Creates an Update-Frame
[3250]37*/
[3315]38OrxonoxGuiUpdate::OrxonoxGuiUpdate(void)
[3250]39{
[3285]40  this->getSystemInfo();
41
[3315]42  this->updateFrame = new Frame("Update-Options:");
43  this->updateFrame->setGroupName("update");
44  this->updateBox = new Box('v');
[3281]45#ifdef HAVE_CURL
[3250]46
[3261]47  // the Button for autoUpdating
[3315]48  this->autoUpdate = new CheckButton("auto update");
[3261]49  this->updateBox->fill(this->autoUpdate);
[3315]50  this->autoUpdate->setFlagName("update", "u", 0);
[3288]51  this->autoUpdate->saveability();
[3253]52
[3315]53  this->updateSourceWindowCreate();
[3261]54  this->updateBox->fill(this->updateSourceWindowGetButton());
55
[3315]56  this->updateDataWindowCreate();
[3261]57  this->updateBox->fill(this->updateDataWindowGetButton());
58
[3281]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 */
[3253]63  this->updateFrame->fill(this->updateBox);
[4024]64  this->setMainWidget(this->updateFrame);
[3318]65}
[3281]66
[3318]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
[3250]84}
85
[3285]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");
[3315]92  this->tmpDir = getenv("TMPDIR");
93  if(!tmpDir)
94    this->tmpDir = "/tmp";
95  PRINTF(4)("Temporary directory is: %s\n", this->tmpDir);
[3285]96
97#ifdef __WIN32__
[3315]98  this->homeDir = getenv("USERPROFILE");
[3285]99#else
[3315]100  this->homeDir = getenv("HOME");
[3285]101#endif
102  PRINTF(4)("Home directory is %s\n", homeDir);
103
[3315]104  this->installDataDir = "/usr/share/games/orxonox";
105  PRINTF(4)("Installation of orxonox-data will go to this directory: %s\n", this->installDataDir);
[3285]106
[3315]107  this->installSourceDir = "/usr/games/bin";
108  PRINTF(4)("Installation of orxonox-source will go to this directory: %s\n", this->installSourceDir);
[3285]109
[3315]110  this->userName = getenv("USER");
111  PRINTF(4)("Logged in username is: %s\n", this->userName);
[3285]112}
113
[3281]114#ifdef HAVE_CURL
[3286]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";
[3298]121  updateFileInfo.localRoot = this->tmpDir;
[3286]122 
123  download(&updateFileInfo);
124}
125#endif /* HAVE_CURL */
126#ifdef HAVE_CURL
[3275]127/**
128   \brief Creates a window, and all it contains for the Data-update.
129*/
[3315]130void OrxonoxGuiUpdate::updateDataWindowCreate(void)
[3253]131{
[3315]132  this->updateDataWindow = new Window("update orxonox::Data");   
133  this->updateDataBox = new Box('v');
[3253]134
[3257]135  // the close-Button of the Update Window.
[3315]136  //  updateWindowClose = new Button("close");
[3257]137#ifdef HAVE_GTK2
[3261]138  //  updateWindowClose->connectSignal("button_press_event", updateWindow, Window::windowClose);
[3257]139#endif /* HAVE_GTK2 */
[3261]140  //  updateWindowBox->fill(updateWindowClose);
[3253]141
[3315]142  this->updateDataBar = new ProgressBar();
143  this->updateDataBox->fill(this->updateDataBar);
[3263]144
[3274]145  FileInfo* dataInfo = new FileInfo;
[3315]146  dataInfo->bar = this->updateDataBar;
[3274]147
[3315]148  this->updateDataBegin = new Button("begin.");
149  dataInfo->stateButton = this->updateDataBegin;
[3291]150#ifdef HAVE_GTK2
[3315]151  dataInfo->buttonSignal = updateDataBegin->connectSignal("button_press_event", dataInfo, updateDataFunc);
[3291]152#endif /* HAVE_GTK2 */
[3315]153  this->updateDataBox->fill(this->updateDataBegin);
[3263]154
[3315]155  this->updateDataWindow->fill(this->updateDataBox);
[3253]156
[3315]157  this->updateDataWindowButton = new Button("update orxonox::Data");
[3254]158#ifdef HAVE_GTK2
[3315]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);
[3253]162#endif /* HAVE_GTK2 */
163
164}
165
[3258]166/**
[3275]167   \returns A Pointer to the Button of the UpdaterDataWindow
[3258]168*/
[3259]169Button* OrxonoxGuiUpdate::updateDataWindowGetButton(void)
170{
[3315]171  return this->updateDataWindowButton;
[3259]172}
173
[3275]174/**
175   \brief Creates a window, and all it contains for the Source-update.
176*/
[3315]177void OrxonoxGuiUpdate::updateSourceWindowCreate(void)
[3259]178{
179  // the button, that opens this Window.
[3315]180  this->updateSourceWindowButton = new Button("update orxonox::Source");
[3259]181
182  // the Window itself
[3315]183  this->updateSourceWindow = new Window("update orxonox::Source");
[3259]184
[3315]185  this->updateSourceBox = new Box();
[3259]186
[3315]187  this->updateSourceBar = new ProgressBar();
188  this->updateSourceBox->fill(this->updateSourceBar);
189  test = new Button("increment");
[3261]190
191#ifdef HAVE_GTK2
[3259]192  test->connectSignal("button_press_event", updateSourceBar, updateSourceFunc);
[3261]193#endif /* HAVE_GTK2 */
194
[3315]195  this->updateSourceBox->fill(test);
196  this->updateSourceWindow->fill(updateSourceBox); 
[3259]197#ifdef HAVE_GTK2
[3315]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);
[3259]201#endif /* HAVE_GTK2 */
202
203}
204
[3275]205/**
206   \returns A Pointer to the Button of the UpdaterSourceWindow
207*/
[3259]208Button* OrxonoxGuiUpdate::updateSourceWindowGetButton(void)
209{
[3315]210  return this->updateSourceWindowButton;
[3259]211}
212
213
214#ifdef HAVE_GTK2
[3258]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*/
[3274]221gint OrxonoxGuiUpdate::updateDataFunc(GtkWidget* w, GdkEventKey* event, void* info)
[3254]222{
[3315]223  FileInfo* dataInfo =(FileInfo*)info;
[3254]224
[3274]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);
[3286]229  downloadWithStyle(dataInfo);
[3254]230}
231
[3258]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*/
[3259]238gint OrxonoxGuiUpdate::updateSourceFunc(GtkWidget* w, GdkEventKey* event, void* bar)
[3254]239{
[3259]240  ProgressBar* tmpBar = static_cast<ProgressBar*>(bar);
241  tmpBar->setTotalSize(20);
242  tmpBar->setProgress(tmpBar->getProgress()+1);
[3254]243}
[3263]244#endif /* HAVE_GTK2 */
[3254]245
[3275]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*/
[3315]253size_t OrxonoxGuiUpdate::curlWriteFunc(void* ptr, size_t size, size_t nmemb, FILE* stream)
[3263]254{
255  return fwrite(ptr, size, nmemb, stream);
256}
257
[3275]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*/
[3315]265size_t OrxonoxGuiUpdate::curlReadFunc(void* ptr, size_t size, size_t nmemb, FILE* stream)
[3263]266{
267  return fread(ptr, size, nmemb, stream);
268}
269
270
[3275]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*/
[3315]279int OrxonoxGuiUpdate::curlProgressFunc(ProgressBar* bar, double totalSize, double progress, double upTotal, double upProgress)
[3263]280{
[3315]281  bar->setProgress(progress);
282  bar->setTotalSize(totalSize);
[3274]283#ifdef HAVE_GTK2
284#ifndef HAVE_PTHREAD_H
285  while(gtk_events_pending()) gtk_main_iteration();
286#endif
287#endif
[3263]288  return 0;
289}
290
[3275]291/**
[3315]292   \brief The Curl handle for only one CURL(static).
[3275]293*/
[3270]294CURL* OrxonoxGuiUpdate::curlHandle = NULL;
[3273]295
296#ifdef HAVE_PTHREAD_H
[3275]297/** \brief The download Thread ID */
[3272]298pthread_t* OrxonoxGuiUpdate::downloadThreadID = new pthread_t;
[3275]299/**   \brief The download Thread ID*/
300pthread_t* OrxonoxGuiUpdate::downloadThreadFinishID = new pthread_t;
[3273]301#endif /* HAVE_PTHREAD_H */
[3275]302/**
303   \brief A bool parameter that shows if we are downloading.
304*/
[3272]305bool OrxonoxGuiUpdate::isDownloading = false;
[3266]306
[3286]307
[3275]308/**
[3286]309   \brief Initializes a Download without displaying it.
[3275]310   \param fileInfo the FileInfo.
[3286]311
312   !! BE AWARE THIS WILL NOT BE THREADED. !!
[3275]313*/
[3286]314bool OrxonoxGuiUpdate::download(void* fileInfo)
[3263]315{
[3315]316  if(isDownloading)
[3274]317    {
318      PRINTF(2)("unable to Download. already getting some file\n");
319      return false;
320    }
[3263]321  PRINTF(3)("Downloading.\n");
[3315]322  FileInfo* info =(FileInfo*)fileInfo;
[3263]323  CURLcode res;
[3286]324  CURL* localCurl;
325  localCurl = curl_easy_init();
326  char* fileOnNet = new char [strlen(info->webRoot)+strlen(info->fileName)+2];
[3315]327  strcpy(fileOnNet, info->webRoot);
328  if(fileOnNet[strlen(fileOnNet)] != '/') //!< \todo windows-shit
329    strcat(fileOnNet, "/");
330  strcat(fileOnNet, info->fileName);
[3286]331  char* fileOnDisk = new char [strlen(info->localRoot)+strlen(info->fileName)+2];
[3315]332  strcpy(fileOnDisk, info->localRoot);
333  if(fileOnDisk[strlen(fileOnDisk)] != '/') //!< \todo windows-shit
334    strcat(fileOnDisk, "/");
335  strcat(fileOnDisk, info->fileName);
[3286]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);
[3291]346      curl_easy_setopt(localCurl, CURLOPT_NOPROGRESS, true);
[3286]347     
348      curl_easy_perform(localCurl);
349
350      curl_easy_cleanup(localCurl);
[3315]351      fclose(info->fileHandle);
[3286]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{
[3315]364  if(isDownloading)
[3286]365    {
366      PRINTF(2)("unable to Download. already getting some file\n");
367      return false;
368    }
369  PRINTF(3)("Downloading.\n");
[3315]370  FileInfo* info =(FileInfo*)fileInfo;
[3286]371  CURLcode res;
[3270]372  curlHandle = curl_easy_init();
[3267]373  char* fileOnNet = new char [strlen(info->webRoot)+strlen(info->fileName)+1];
[3315]374  strcpy(fileOnNet, info->webRoot);
375  strcat(fileOnNet, info->fileName);
[3267]376  char* fileOnDisk = new char [strlen(info->localRoot)+strlen(info->fileName)+1];
[3315]377  strcpy(fileOnDisk, info->localRoot);
378  strcat(fileOnDisk, info->fileName);
[3273]379
[3270]380  if(curlHandle)
[3263]381    {
[3271]382     
[3272]383      info->fileHandle = fopen(fileOnDisk, "w");
[3274]384     
[3270]385      curl_easy_setopt(curlHandle, CURLOPT_URL, fileOnNet);
[3272]386      curl_easy_setopt(curlHandle, CURLOPT_WRITEDATA, info->fileHandle);
[3270]387      curl_easy_setopt(curlHandle, CURLOPT_WRITEFUNCTION, curlWriteFunc);
388      curl_easy_setopt(curlHandle, CURLOPT_READFUNCTION, curlReadFunc);
[3291]389      curl_easy_setopt(curlHandle, CURLOPT_NOPROGRESS, false);
[3270]390      curl_easy_setopt(curlHandle, CURLOPT_PROGRESSFUNCTION, curlProgressFunc);
[3274]391      curl_easy_setopt(curlHandle, CURLOPT_PROGRESSDATA, info->bar);
[3271]392
[3315]393      if(!isDownloading)
[3271]394        {
[3303]395#ifdef HAVE_PTHREAD_H     
[3284]396          pthread_join(*downloadThreadFinishID, NULL);
[3303]397#endif /* HAVE_PTHREAD_H */
[3291]398#ifdef HAVE_GTK2
[3284]399          info->stateButton->disconnectSignal(info->buttonSignal);
400          info->buttonSignal = info->stateButton->connectSignal("button_press_event", info, cancelDownload);
[3291]401#endif /* HAVE_GTK2 */
[3284]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         
[3271]408          //! \todo check if threads really were created.
[3273]409#ifdef HAVE_PTHREAD_H
[3272]410          pthread_create(downloadThreadID, NULL, downloadThread, info);
[3275]411          pthread_create(downloadThreadFinishID, NULL, downloadThreadFinished, info); 
[3273]412#else
413          downloadThread(info);
[3274]414          downloadThreadFinished(info);
[3273]415#endif /* HAVE_PTHREAD_H */
416         
[3272]417          //      res = curl_easy_perform(curlHandle);
418         
419          //      fclose(outfile);
[3271]420        }
[3274]421      else 
422        PRINTF(1)("thread already in use\n");
423
[3263]424    }
[3274]425  return true;
[3263]426}
[3275]427
428/**
[3315]429   \brief The downloading process(either threaded or not).
[3275]430   \param fileInfo the FileInfo.
[3282]431
432   \todo Threads get locked, if the cancel button is pressed in to small intervals.
[3275]433*/
[3271]434void* OrxonoxGuiUpdate::downloadThread(void* fileInfo)
435{
[3284]436  isDownloading = true;
[3274]437  curl_easy_perform(curlHandle);
438}
439
[3275]440/**
441   \brief Finishes a downloading process.
442   \param fileInfo the FileInfo.
443*/
[3274]444void* OrxonoxGuiUpdate::downloadThreadFinished(void* fileInfo)
445{ 
[3315]446  FileInfo* info =(FileInfo*)fileInfo;
[3274]447#ifdef HAVE_PTHREAD_H
[3315]448  pthread_join(*downloadThreadID, NULL);
[3291]449#ifdef HAVE_GTK2
[3283]450  gdk_threads_enter();
[3291]451#endif /* HAVE_GTK2 */
[3274]452#endif /* HAVE_PTHREAD_H */
[3315]453  if(curlHandle)
[3271]454    curl_easy_cleanup(curlHandle);
[3274]455 
[3271]456  PRINTF(3)("Closing the downloaded file.\n");
[3272]457  fclose(info->fileHandle);
458
[3315]459  if(isDownloading)
[3274]460    info->stateButton->setTitle("go on");
461  //  else
462  //    info->stateButton->setTitle("done");
[3291]463#ifdef HAVE_GTK2
[3274]464  info->stateButton->disconnectSignal(info->buttonSignal);
465  info->buttonSignal = info->stateButton->connectSignal("button_press_event", info, updateDataFunc);
[3291]466#endif /* HAVE_GTK2 */
[3272]467  isDownloading = false;
[3283]468#ifdef HAVE_PTHREAD_H
[3291]469#ifdef HAVE_GTK2
[3274]470  gdk_threads_leave();
[3291]471#endif /* HAVE_GTK2 */
[3283]472#endif /* HAVE_PTHREAD_H */
[3274]473
[3271]474}
475
[3268]476#ifdef HAVE_GTK2
[3275]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*/
[3268]485gint OrxonoxGuiUpdate::cancelDownload(GtkWidget* w, GdkEventKey* event, void* bar)
486{
[3274]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*/
[3268]492}
493#endif /* HAVE_GTK2 */
494
[3263]495#endif /* HAVE_CURL */
Note: See TracBrowser for help on using the repository browser.