Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: merged the guiMerge-branche back into the trunk
merged with command:
svn merge -r 4043:HEAD guiMerge/ ../trunk/
no conflicts, only updates and moves :)

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