Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/qt_gui/src/lib/gui/gtk_gui/gui_update.cc @ 7601

Last change on this file since 7601 was 7601, checked in by bensch, 18 years ago

orxonox/qt_gui: QtGuiComboBox saveable

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