Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: gui: minor niceness-patch

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