Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: opened and saved some files, and also rewritten some organizatory stuff

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