Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk/gui: new Widget for FileSelector

File size: 14.0 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  this->tmpDir = NULL;
44  this->homeDir = NULL;
45  this->installSourceDir = NULL;
46  this->userName = NULL;
47
48  this->getSystemInfo();
49
50  this->updateFrame = new Frame("Update-Options:");
51  this->updateFrame->setGroupName("update");
52  this->updateBox = new Box('v');
53#ifdef HAVE_CURL
54
55  // the Button for autoUpdating
56  this->autoUpdate = new CheckButton("auto update");
57  this->updateBox->fill(this->autoUpdate);
58  this->autoUpdate->setFlagName("update", "u", 0);
59  this->autoUpdate->saveability();
60
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
73  this->updateSourceWindowCreate();
74  this->updateBox->fill(this->updateSourceWindowGetButton());
75
76  this->updateDataWindowCreate();
77  this->updateBox->fill(this->updateDataWindowGetButton());
78
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 */
83  this->updateFrame->fill(this->updateBox);
84  this->setMainWidget(this->updateFrame);
85
86
87}
88
89/**
90   \brief Destructs the Update-stuff
91*/
92GuiUpdate::~GuiUpdate(void)
93{
94
95}
96
97/**
98    \brief Look what info we can get from this system
99*/
100bool GuiUpdate::getSystemInfo(void)
101{
102  PRINTF(3)("Grabbing system information\n");
103  this->tmpDir = getenv("TMPDIR");
104  if(!tmpDir)
105    this->tmpDir = "/tmp";
106  PRINTF(4)("Temporary directory is: %s\n", this->tmpDir);
107
108#ifdef __WIN32__
109  this->homeDir = getenv("USERPROFILE");
110#else
111  this->homeDir = getenv("HOME");
112#endif
113  PRINTF(4)("Home directory is %s\n", homeDir);
114
115  this->installDataDir = "/usr/share/games/orxonox";
116  PRINTF(4)("Installation of orxonox-data will go to this directory: %s\n", this->installDataDir);
117
118  this->installSourceDir = "/usr/games/bin";
119  PRINTF(4)("Installation of orxonox-source will go to this directory: %s\n", this->installSourceDir);
120
121  this->userName = getenv("USER");
122  PRINTF(4)("Logged in username is: %s\n", this->userName);
123}
124
125#ifdef HAVE_CURL
126bool* GuiUpdate::checkForUpdates(void)
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";
132  updateFileInfo.localRoot = this->tmpDir;
133 
134  download(&updateFileInfo);
135}
136
137/**
138   \brief Creates a window, and all it contains for the Data-update.
139*/
140void GuiUpdate::updateDataWindowCreate(void)
141{
142  this->updateDataWindow = new Window("update orxonox::Data");   
143  this->updateDataBox = new Box('v');
144
145  // the close-Button of the Update Window.
146  //  updateWindowClose = new Button("close");
147#ifdef HAVE_GTK2
148  //  updateWindowClose->connectSignal("button_press_event", updateWindow, Window::windowClose);
149#endif /* HAVE_GTK2 */
150  //  updateWindowBox->fill(updateWindowClose);
151
152  this->updateDataBar = new ProgressBar();
153  this->updateDataBox->fill(this->updateDataBar);
154
155  FileInfo* dataInfo = new FileInfo;
156  dataInfo->bar = this->updateDataBar;
157
158  this->updateDataBegin = new Button("begin.");
159  dataInfo->stateButton = this->updateDataBegin;
160#ifdef HAVE_GTK2
161  dataInfo->buttonSignal = updateDataBegin->connectSignal("button_press_event", dataInfo, updateDataFunc);
162#endif /* HAVE_GTK2 */
163  this->updateDataBox->fill(this->updateDataBegin);
164
165  this->updateDataWindow->fill(this->updateDataBox);
166
167  this->updateDataWindowButton = new Button("update orxonox::Data");
168#ifdef HAVE_GTK2
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);
172#endif /* HAVE_GTK2 */
173
174}
175
176/**
177   \returns A Pointer to the Button of the UpdaterDataWindow
178*/
179Button* GuiUpdate::updateDataWindowGetButton(void)
180{
181  return this->updateDataWindowButton;
182}
183
184/**
185   \brief Creates a window, and all it contains for the Source-update.
186*/
187void GuiUpdate::updateSourceWindowCreate(void)
188{
189  // the button, that opens this Window.
190  this->updateSourceWindowButton = new Button("update orxonox::Source");
191
192  // the Window itself
193  this->updateSourceWindow = new Window("update orxonox::Source");
194
195  this->updateSourceBox = new Box();
196
197  this->updateSourceBar = new ProgressBar();
198  this->updateSourceBox->fill(this->updateSourceBar);
199  test = new Button("increment");
200
201#ifdef HAVE_GTK2
202  test->connectSignal("button_press_event", updateSourceBar, updateSourceFunc);
203#endif /* HAVE_GTK2 */
204
205  this->updateSourceBox->fill(test);
206  this->updateSourceWindow->fill(updateSourceBox); 
207#ifdef HAVE_GTK2
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);
211#endif /* HAVE_GTK2 */
212
213}
214
215/**
216   \returns A Pointer to the Button of the UpdaterSourceWindow
217*/
218Button* GuiUpdate::updateSourceWindowGetButton(void)
219{
220  return this->updateSourceWindowButton;
221}
222
223
224#ifdef HAVE_GTK2
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*/
231gint GuiUpdate::updateDataFunc(GtkWidget* w, GdkEventKey* event, void* info)
232{
233  FileInfo* dataInfo =(FileInfo*)info;
234
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);
239  downloadWithStyle(dataInfo);
240}
241
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*/
248gint GuiUpdate::updateSourceFunc(GtkWidget* w, GdkEventKey* event, void* bar)
249{
250  ProgressBar* tmpBar = static_cast<ProgressBar*>(bar);
251  tmpBar->setTotalSize(20);
252  tmpBar->setProgress(tmpBar->getProgress()+1);
253}
254#endif /* HAVE_GTK2 */
255
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*/
263size_t GuiUpdate::curlWriteFunc(void* ptr, size_t size, size_t nmemb, FILE* stream)
264{
265  return fwrite(ptr, size, nmemb, stream);
266}
267
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*/
275size_t GuiUpdate::curlReadFunc(void* ptr, size_t size, size_t nmemb, FILE* stream)
276{
277  return fread(ptr, size, nmemb, stream);
278}
279
280
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*/
289int GuiUpdate::curlProgressFunc(ProgressBar* bar, double totalSize, double progress, double upTotal, double upProgress)
290{
291  bar->setProgress(progress);
292  bar->setTotalSize(totalSize);
293#ifdef HAVE_GTK2
294  while(gtk_events_pending()) gtk_main_iteration();
295#endif
296  return 0;
297}
298
299/**
300   \brief The Curl handle for only one CURL(static).
301*/
302CURL* GuiUpdate::curlHandle = NULL;
303
304//! A bool parameter that shows if we are downloading.
305bool GuiUpdate::isDownloading = false;
306
307//! A parameter to see, if downloading has been canceled
308bool GuiUpdate::downloadCanceled = false;
309
310/**
311   \brief Initializes a Download without displaying it.
312   \param fileInfo the FileInfo.
313
314   !! BE AWARE THIS WILL NOT BE THREADED. !!
315*/
316bool GuiUpdate::download(void* fileInfo)
317{
318  if(isDownloading)
319    {
320      PRINTF(2)("unable to Download. already getting some file\n");
321      return false;
322    }
323  PRINTF(3)("Downloading.\n");
324  FileInfo* info =(FileInfo*)fileInfo;
325  CURLcode res;
326  CURL* localCurl;
327  localCurl = curl_easy_init();
328  char* fileOnNet = new char [strlen(info->webRoot)+strlen(info->fileName)+2];
329  strcpy(fileOnNet, info->webRoot);
330  if(fileOnNet[strlen(fileOnNet)] != '/') //!< \todo windows-shit
331    strcat(fileOnNet, "/");
332  strcat(fileOnNet, info->fileName);
333  char* fileOnDisk = new char [strlen(info->localRoot)+strlen(info->fileName)+2];
334  strcpy(fileOnDisk, info->localRoot);
335  if(fileOnDisk[strlen(fileOnDisk)] != '/') //!< \todo windows-shit
336    strcat(fileOnDisk, "/");
337  strcat(fileOnDisk, info->fileName);
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);
348      curl_easy_setopt(localCurl, CURLOPT_NOPROGRESS, true);
349     
350      curl_easy_perform(localCurl);
351
352      curl_easy_cleanup(localCurl);
353      fclose(info->fileHandle);
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*/
364bool GuiUpdate::downloadWithStyle(void* fileInfo)
365{
366  if(isDownloading)
367    {
368      PRINTF(2)("unable to Download. already getting some file\n");
369      return false;
370    }
371  PRINTF(3)("Downloading.\n");
372  FileInfo* info =(FileInfo*)fileInfo;
373  CURLcode res;
374  curlHandle = curl_easy_init();
375  char* fileOnNet = new char [strlen(info->webRoot)+strlen(info->fileName)+1];
376  strcpy(fileOnNet, info->webRoot);
377  strcat(fileOnNet, info->fileName);
378  char* fileOnDisk = new char [strlen(info->localRoot)+strlen(info->fileName)+1];
379  strcpy(fileOnDisk, info->localRoot);
380  strcat(fileOnDisk, info->fileName);
381
382  if(curlHandle)
383    {
384     
385      info->fileHandle = fopen(fileOnDisk, "w");
386     
387      curl_easy_setopt(curlHandle, CURLOPT_URL, fileOnNet);
388      curl_easy_setopt(curlHandle, CURLOPT_WRITEDATA, info->fileHandle);
389      curl_easy_setopt(curlHandle, CURLOPT_WRITEFUNCTION, curlWriteFunc);
390      curl_easy_setopt(curlHandle, CURLOPT_READFUNCTION, curlReadFunc);
391      curl_easy_setopt(curlHandle, CURLOPT_NOPROGRESS, false);
392      curl_easy_setopt(curlHandle, CURLOPT_PROGRESSFUNCTION, curlProgressFunc);
393      curl_easy_setopt(curlHandle, CURLOPT_PROGRESSDATA, info->bar);
394
395      if(!isDownloading)
396        {
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          info->stateButton->setTitle("please wait");
402         
403          downloadThread(info);
404          downloadThreadFinished(info);
405         
406          //      res = curl_easy_perform(curlHandle);
407         
408          //      fclose(outfile);
409        }
410      else 
411        PRINTF(1)("thread already in use\n");
412
413    }
414  return true;
415}
416
417/**
418   \brief The downloading process(either threaded or not).
419   \param fileInfo the FileInfo.
420
421   \todo Threads get locked, if the cancel button is pressed in to small intervals.
422*/
423void* GuiUpdate::downloadThread(void* fileInfo)
424{
425  isDownloading = true;
426  curl_easy_perform(curlHandle);
427}
428
429/**
430   \brief Finishes a downloading process.
431   \param fileInfo the FileInfo.
432*/
433void* GuiUpdate::downloadThreadFinished(void* fileInfo)
434{ 
435  FileInfo* info =(FileInfo*)fileInfo;
436  if(curlHandle)
437    curl_easy_cleanup(curlHandle);
438 
439  PRINTF(3)("Closing the downloaded file.\n");
440  fclose(info->fileHandle);
441
442  if(isDownloading)
443    info->stateButton->setTitle("go on");
444  //  else
445  //    info->stateButton->setTitle("done");
446#ifdef HAVE_GTK2
447  info->stateButton->disconnectSignal(info->buttonSignal);
448  info->buttonSignal = info->stateButton->connectSignal("button_press_event", info, updateDataFunc);
449#endif /* HAVE_GTK2 */
450  isDownloading = false;
451
452}
453
454#ifdef HAVE_GTK2
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*/
463gint GuiUpdate::cancelDownload(GtkWidget* w, GdkEventKey* event, void* bar)
464{
465  PRINTF(4)("Cannot cancle the Downloading process until after this File\n");
466}
467#endif /* HAVE_GTK2 */
468
469#endif /* HAVE_CURL */
Note: See TracBrowser for help on using the repository browser.