Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: orxonox —help now shows something more usefull… still cleaning up the GUI

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