Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/updater/src/gui/orxonox_gui_update.cc @ 3281

Last change on this file since 3281 was 3281, checked in by dave, 19 years ago

orxonox/branches/updater: works without CURL too. gives some nice info about you not having CURL

File size: 11.1 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program; if not, write to the Free Software Foundation,
18   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
19
20
21   ### File Specific:
22   main-programmer: Benjamin Grauer
23
24*/
25
26#include "orxonox_gui_update.h"
27#include <iostream>
28#include <string>
29
30#include "orxonox_gui.h"
31#include <stdio.h>
32
33using namespace std;
34
35/**
36   \brief Creates an Audio-Frame
37*/
38OrxonoxGuiUpdate::OrxonoxGuiUpdate ()
39{
40  this->updateFrame = new Frame ("Update-Options:");
41  this->updateFrame->setGroupName ("update");
42  this->updateBox = new Box ('v');
43#ifdef HAVE_CURL
44
45  // the Button for autoUpdating
46  this->autoUpdate = new CheckButton ("auto update");
47  this->updateBox->fill(this->autoUpdate);
48  this->autoUpdate->setFlagName ("update", "u", 0);
49  this->autoUpdate->saveable = true;
50
51  this->updateSourceWindowCreate ();
52  this->updateBox->fill(this->updateSourceWindowGetButton());
53
54  this->updateDataWindowCreate ();
55  this->updateBox->fill(this->updateDataWindowGetButton());
56
57#else /* HAVE_CURL */
58  Label* noCurlLabel = new Label("since you do not have cURL,\nthis option is not availible");
59  this->updateBox->fill(noCurlLabel); 
60#endif /* HAVE_CURL */
61  this->updateFrame->fill(this->updateBox);
62
63}
64
65/**
66   \brief Return the Frame
67   \return Returns the Audio-frame
68*/
69Widget* OrxonoxGuiUpdate::getWidget ()
70{
71  return updateFrame;
72}
73
74#ifdef HAVE_CURL
75/**
76   \brief Creates a window, and all it contains for the Data-update.
77*/
78void OrxonoxGuiUpdate::updateDataWindowCreate (void)
79{
80  updateDataWindow = new Window ("update orxonox::Data");   
81  updateDataBox = new Box ('v');
82
83  // the close-Button of the Update Window.
84  //  updateWindowClose = new Button ("close");
85#ifdef HAVE_GTK2
86  //  updateWindowClose->connectSignal("button_press_event", updateWindow, Window::windowClose);
87#endif /* HAVE_GTK2 */
88  //  updateWindowBox->fill(updateWindowClose);
89
90  updateDataBar = new ProgressBar ();
91  updateDataBox->fill(updateDataBar);
92
93  FileInfo* dataInfo = new FileInfo;
94  dataInfo->bar = updateDataBar;
95
96  updateDataBegin = new Button ("begin.");
97  dataInfo->stateButton = updateDataBegin;
98  dataInfo->buttonSignal = updateDataBegin->connectSignal ("button_press_event", dataInfo, updateDataFunc);
99  updateDataBox->fill(updateDataBegin);
100
101  updateDataWindow->fill (updateDataBox);
102
103  updateDataWindowButton = new Button ("update orxonox::Data");
104#ifdef HAVE_GTK2
105  updateDataWindowButton->connectSignal("button_press_event", updateDataWindow, Window::windowOpen);
106  updateDataWindow->connectSignal("destroy", updateDataWindow, Window::windowClose);
107  updateDataWindow->connectSignal("delete_event", updateDataWindow, Window::windowClose);
108#endif /* HAVE_GTK2 */
109
110}
111
112/**
113   \returns A Pointer to the Button of the UpdaterDataWindow
114*/
115Button* OrxonoxGuiUpdate::updateDataWindowGetButton(void)
116{
117  return updateDataWindowButton;
118}
119
120/**
121   \brief Creates a window, and all it contains for the Source-update.
122*/
123void OrxonoxGuiUpdate::updateSourceWindowCreate (void)
124{
125  // the button, that opens this Window.
126  updateSourceWindowButton = new Button ("update orxonox::Source");
127
128  // the Window itself
129  updateSourceWindow = new Window ("update orxonox::Source");
130
131  updateSourceBox = new Box ();
132
133  updateSourceBar = new ProgressBar ();
134  updateSourceBox->fill(updateSourceBar);
135  test = new Button ("increment");
136
137#ifdef HAVE_GTK2
138  test->connectSignal("button_press_event", updateSourceBar, updateSourceFunc);
139#endif /* HAVE_GTK2 */
140
141  updateSourceBox->fill(test);
142  updateSourceWindow->fill(updateSourceBox); 
143#ifdef HAVE_GTK2
144  updateSourceWindowButton->connectSignal("button_press_event", updateSourceWindow, Window::windowOpen);
145  updateSourceWindow->connectSignal("destroy", updateSourceWindow, Window::windowClose);
146  updateSourceWindow->connectSignal("delete_event", updateSourceWindow, Window::windowClose);
147#endif /* HAVE_GTK2 */
148
149}
150
151/**
152   \returns A Pointer to the Button of the UpdaterSourceWindow
153*/
154Button* OrxonoxGuiUpdate::updateSourceWindowGetButton(void)
155{
156  return updateSourceWindowButton;
157}
158
159
160#ifdef HAVE_GTK2
161/**
162   \brief updates the Data of orxonox.
163   \param w The widget, that executed this Function.
164   \param event The event that trigered this Function.
165   \param button The Button, that triggered this event.
166*/
167gint OrxonoxGuiUpdate::updateDataFunc(GtkWidget* w, GdkEventKey* event, void* info)
168{
169  FileInfo* dataInfo = (FileInfo*)info;
170
171  dataInfo->fileName = "02%20orxonox%203.mp3";
172  dataInfo->webRoot  = "http://www.orxonox.ethz.ch/files/";
173  dataInfo->localRoot = "./";
174  PRINTF(3)("Preparing to download file %s.\n", dataInfo->fileName);
175  download (dataInfo);
176}
177
178/**
179   \brief updates the source of orxonox.
180   \param w The widget, that executed this Function.
181   \param event The event that trigered this Function.
182   \param button The Button, that triggered this event.
183*/
184gint OrxonoxGuiUpdate::updateSourceFunc(GtkWidget* w, GdkEventKey* event, void* bar)
185{
186  ProgressBar* tmpBar = static_cast<ProgressBar*>(bar);
187  tmpBar->setTotalSize(20);
188  tmpBar->setProgress(tmpBar->getProgress()+1);
189}
190#endif /* HAVE_GTK2 */
191
192/**
193   \brief The Function Curl calls to write out the File.
194   \param ptr A Pointer to the date to write.
195   \param size The size in bytes of one nmemb to write.
196   \param nmemb The Count of size to write.
197   \param stream Filehandler to write to.
198*/
199size_t OrxonoxGuiUpdate::curlWriteFunc (void* ptr, size_t size, size_t nmemb, FILE* stream)
200{
201  return fwrite(ptr, size, nmemb, stream);
202}
203
204/**
205   \brief The Function Curl calls to write out the File.
206   \param ptr A Pointer to the date to write to.
207   \param size The size in bytes of one nmemb to write.
208   \param nmemb The Count of size to write.
209   \param stream Filehandler to get data from.
210*/
211size_t OrxonoxGuiUpdate::curlReadFunc (void* ptr, size_t size, size_t nmemb, FILE* stream)
212{
213  return fread(ptr, size, nmemb, stream);
214}
215
216
217/**
218   \brief An update Function for the GUI, to show the progress.
219   \param Bar th ProgressBar to update
220   \param totalSize The total size of the download in bytes.
221   \param progress The current Progress of the download in bytes.
222   \param upTotal not needed
223   \param upProgress not needed
224*/
225int OrxonoxGuiUpdate::curlProgressFunc (ProgressBar* Bar, double totalSize, double progress, double upTotal, double upProgress)
226{
227  Bar->setProgress(progress);
228  Bar->setTotalSize(totalSize);
229#ifdef HAVE_GTK2
230#ifndef HAVE_PTHREAD_H
231  while(gtk_events_pending()) gtk_main_iteration();
232#endif
233#endif
234  return 0;
235}
236
237/**
238   \brief The Curl handle for only one CURL (static).
239*/
240CURL* OrxonoxGuiUpdate::curlHandle = NULL;
241
242#ifdef HAVE_PTHREAD_H
243/** \brief The download Thread ID */
244pthread_t* OrxonoxGuiUpdate::downloadThreadID = new pthread_t;
245/**   \brief The download Thread ID*/
246pthread_t* OrxonoxGuiUpdate::downloadThreadFinishID = new pthread_t;
247#endif /* HAVE_PTHREAD_H */
248/**
249   \brief A bool parameter that shows if we are downloading.
250*/
251bool OrxonoxGuiUpdate::isDownloading = false;
252
253/**
254   \brief Initializes a Download
255   \param fileInfo the FileInfo.
256*/
257bool OrxonoxGuiUpdate::download (void* fileInfo)
258{
259  if (isDownloading)
260    {
261      PRINTF(2)("unable to Download. already getting some file\n");
262      return false;
263    }
264  PRINTF(3)("Downloading.\n");
265  FileInfo* info = (FileInfo*)fileInfo;
266  CURLcode res;
267  curlHandle = curl_easy_init();
268  char* fileOnNet = new char [strlen(info->webRoot)+strlen(info->fileName)+1];
269  strcpy (fileOnNet, info->webRoot);
270  strcat (fileOnNet, info->fileName);
271  char* fileOnDisk = new char [strlen(info->localRoot)+strlen(info->fileName)+1];
272  strcpy (fileOnDisk, info->localRoot);
273  strcat (fileOnDisk, info->fileName);
274
275  if(curlHandle)
276    {
277     
278      info->fileHandle = fopen(fileOnDisk, "w");
279     
280      curl_easy_setopt(curlHandle, CURLOPT_URL, fileOnNet);
281      curl_easy_setopt(curlHandle, CURLOPT_WRITEDATA, info->fileHandle);
282      curl_easy_setopt(curlHandle, CURLOPT_WRITEFUNCTION, curlWriteFunc);
283      curl_easy_setopt(curlHandle, CURLOPT_READFUNCTION, curlReadFunc);
284      curl_easy_setopt(curlHandle, CURLOPT_NOPROGRESS, FALSE);
285      curl_easy_setopt(curlHandle, CURLOPT_PROGRESSFUNCTION, curlProgressFunc);
286      curl_easy_setopt(curlHandle, CURLOPT_PROGRESSDATA, info->bar);
287
288      if (!isDownloading)
289        {
290          isDownloading = true;
291          //! \todo check if threads really were created.
292#ifdef HAVE_PTHREAD_H
293          pthread_join(*downloadThreadFinishID, NULL);
294          pthread_create(downloadThreadID, NULL, downloadThread, info);
295          pthread_create(downloadThreadFinishID, NULL, downloadThreadFinished, info); 
296#else
297          downloadThread(info);
298          downloadThreadFinished(info);
299#endif /* HAVE_PTHREAD_H */
300         
301          //      res = curl_easy_perform(curlHandle);
302         
303          //      fclose(outfile);
304        }
305      else 
306        PRINTF(1)("thread already in use\n");
307
308    }
309  return true;
310}
311
312/**
313   \brief The downloading process (either threaded or not).
314   \param fileInfo the FileInfo.
315*/
316void* OrxonoxGuiUpdate::downloadThread(void* fileInfo)
317{
318  pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
319  gdk_threads_enter();
320  FileInfo* info = (FileInfo*)fileInfo;
321  info->stateButton->disconnectSignal(info->buttonSignal);
322  info->buttonSignal = info->stateButton->connectSignal("button_press_event", info, cancelDownload);
323  info->stateButton->setTitle("cancel");
324  gdk_threads_leave();
325  pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
326
327  curl_easy_perform(curlHandle);
328 
329}
330
331/**
332   \brief Finishes a downloading process.
333   \param fileInfo the FileInfo.
334*/
335void* OrxonoxGuiUpdate::downloadThreadFinished(void* fileInfo)
336{ 
337  FileInfo* info = (FileInfo*)fileInfo;
338#ifdef HAVE_PTHREAD_H
339  pthread_join (*downloadThreadID, NULL);
340#endif /* HAVE_PTHREAD_H */
341  gdk_threads_enter();
342  if (curlHandle)
343    curl_easy_cleanup(curlHandle);
344 
345  PRINTF(3)("Closing the downloaded file.\n");
346  fclose(info->fileHandle);
347
348  if (isDownloading)
349    info->stateButton->setTitle("go on");
350  //  else
351  //    info->stateButton->setTitle("done");
352  info->stateButton->disconnectSignal(info->buttonSignal);
353  info->buttonSignal = info->stateButton->connectSignal("button_press_event", info, updateDataFunc);
354  isDownloading = false;
355  gdk_threads_leave();
356
357}
358
359#ifdef HAVE_GTK2
360/**
361   \brief canceles a downloading session.
362   \param w The widget, that executed this Function.
363   \param event The event that trigered this Function.
364   \param bar The Bar, that triggered this event.
365
366   \todo canceling a session in non-threaded mode.
367*/
368gint OrxonoxGuiUpdate::cancelDownload(GtkWidget* w, GdkEventKey* event, void* bar)
369{
370#ifdef HAVE_PTHREAD_H
371  pthread_cancel(*downloadThreadID);
372#else
373  PRINTF(2)("Cannot cancle the Downloading process until after this File, because no threading was enabled");
374#endif /* HAVE_PTHREAD_H*/
375}
376#endif /* HAVE_GTK2 */
377
378#endif /* HAVE_CURL */
Note: See TracBrowser for help on using the repository browser.