Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk/gui: new Widget for FileSelector

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