Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/md2_loader/src/lib/gui/gui/gui_update.cc @ 4063

Last change on this file since 4063 was 4063, checked in by patrick, 19 years ago

orxonox/branche/md2_loader: merged trunk into my branche

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