Subversion Repositories public

Rev

Rev 132 | Rev 143 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
95 andreas 1
/***************************************************************************
119 andreas 2
 *   Copyright (C) 2007, 2008 by Andreas Theofilu                          *
95 andreas 3
 *   andreas@theosys.at                                                    *
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 version 3 of the License.                *
8
 *                                                                         *
9
 *   This program is distributed in the hope that it will be useful,       *
10
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12
 *   GNU General Public License for more details.                          *
13
 *                                                                         *
14
 *   You should have received a copy of the GNU General Public License     *
15
 *   along with this program; if not, write to the                         *
16
 *   Free Software Foundation, Inc.,                                       *
17
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
18
 ***************************************************************************/
19
 
20
 
21
#include "progresswidget.h"
132 andreas 22
#include <kapplication.h>
95 andreas 23
#include <kprogress.h>
24
#include <kmessagebox.h>
25
#include <ksimpleconfig.h>
26
#include <klocale.h>
27
#include <qlabel.h>
28
#include "garmin.h"
29
 
137 andreas 30
#include <iostream>
132 andreas 31
 
137 andreas 32
using std::cout;
33
using std::endl;
34
 
132 andreas 35
extern KApplication *mapp;
36
 
95 andreas 37
progressWidget::progressWidget ( QWidget* parent, const char* name, bool modal, WFlags fl )
38
		: progressWidgetBase ( parent,name, modal,fl )
39
{
40
}
41
 
42
progressWidget::~progressWidget()
43
{
44
}
45
 
137 andreas 46
void progressWidget::CallBack(char *str)
47
{
48
cout << "I'm here :-) <" << str << ">" << endl;
49
}
50
 
95 andreas 51
/*$SPECIALIZATION$*/
137 andreas 52
bool progressWidget::Download()
95 andreas 53
{
100 andreas 54
QString Data, filepath, device;
95 andreas 55
int step, psteps = 4;
56
garmin_unit         garmin;
57
garmin_data *       data;
58
garmin_data *       data0;
59
garmin_data *       data1;
60
garmin_data *       data2;
61
garmin_data *       rlaps;
62
garmin_data *       rtracks;
63
garmin_list *       runs   = NULL;
64
garmin_list *       laps   = NULL;
65
garmin_list *       tracks = NULL;
66
garmin_data *       rlist;
67
garmin_list_node *  n;
68
garmin_list_node *  m;
69
uint32              trk;
70
uint32              f_lap;
71
uint32              l_lap;
72
uint32              l_idx;
73
time_type           start;
74
time_t              start_time;
75
char                filename[BUFSIZ];
76
struct tm *         tbuf;
77
 
78
	// Find the data path in config file
79
	KSimpleConfig *cfg = new KSimpleConfig(QString("sportwatcher.rc"), true);
80
	cfg->setGroup(QString("SportWatcher"));
81
	Data = cfg->readEntry("Data");
100 andreas 82
	device = cfg->readEntry("Device");
95 andreas 83
	delete cfg;
84
 
85
	if (Data.isEmpty())
86
	{
87
	   KMessageBox::error(this, i18n("No data path was set in the settings!"));
137 andreas 88
//	   done(QDialog::Rejected);
89
	   return false;
95 andreas 90
	}
91
 
100 andreas 92
	if (!isVisible())
132 andreas 93
	   setShown(true);
100 andreas 94
 
95
	garmin_set_device(device.ascii());
137 andreas 96
	garmin_set_method(0);		// Setting to 1 doesn't work!!
97
	// Initialize a callback function to have a real progress
98
	garmin_set_hook(&progressWidget::CallBack);
100 andreas 99
 
95 andreas 100
	if (garmin_init(&garmin, 0) == 0)
101
	{
100 andreas 102
	   garmin_close(&garmin);
137 andreas 103
	   garmin_clear_hook();
104
//	   done(QDialog::Rejected);
105
	   return false;
95 andreas 106
	}
107
 
108
	barProgress->setTotalSteps(5);
109
	step = 0;
110
	barProgress->setProgress(step++);
132 andreas 111
	lblInfo->setText(i18n("Extracting data from Garmin <i>") + QString(garmin.product.product_description) + QString("</i>"));
112
	lblReading->setText(i18n("Please wait, this may take some time!"));
95 andreas 113
 
132 andreas 114
	mapp->processEvents();
115
 
95 andreas 116
	if ((data = garmin_get(&garmin, GET_RUNS)) != NULL )
117
	{
118
	   /*
119
	    * We should have a list with three elements:
120
	    *
121
	    * 1) The runs (which identify the track and lap indices)
122
	    * 2) The laps (which are related to the runs)
123
	    * 3) The tracks (which are related to the runs)
124
	    */
125
 
126
	   barProgress->setProgress(step++);
132 andreas 127
	   lblReading->setText(i18n("Sorting out runs ..."));
128
	   mapp->processEvents();
95 andreas 129
	   data0 = garmin_list_data(data, 0);
130
	   barProgress->setProgress(step++);
132 andreas 131
	   lblReading->setText(i18n("Sorting out laps ..."));
132
	   mapp->processEvents();
95 andreas 133
	   data1 = garmin_list_data(data, 1);
134
	   barProgress->setProgress(step++);
132 andreas 135
	   lblReading->setText(i18n("Sorting out tracks ..."));
136
	   mapp->processEvents();
95 andreas 137
	   data2 = garmin_list_data(data, 2);
138
	   barProgress->setProgress(step++);
132 andreas 139
	   lblReading->setText(i18n("Sorting out data blocks done."));
140
	   mapp->processEvents();
95 andreas 141
 
142
	   if ( data0 != NULL && (runs   = (garmin_list *)data0->data) != NULL &&
143
		data1 != NULL && (laps   = (garmin_list *)data1->data) != NULL &&
144
		data2 != NULL && (tracks = (garmin_list *)data2->data) != NULL )
145
	   {
146
 
147
	      /* For each run, get its laps and track points. */
148
	      /* But first see how much runs to set the progress bar */
149
	      for (n = runs->head; n != NULL; n = n->next)
150
		 psteps++;
151
 
152
	      barProgress->setTotalSteps(psteps);
132 andreas 153
	      mapp->processEvents();
95 andreas 154
 
155
	      for (n = runs->head; n != NULL; n = n->next)
156
	      {
157
		 barProgress->setProgress(step++);
132 andreas 158
		 mapp->processEvents();
95 andreas 159
 
160
		 if (get_run_track_lap_info(n->data, &trk, &f_lap, &l_lap) != 0)
161
		 {
162
		    lblReading->setText(i18n("Running: track ") + QString("%1, ").arg(trk) + i18n("laps ") + QString("%1:%1").arg(f_lap).arg(l_lap));
132 andreas 163
		    mapp->processEvents();
95 andreas 164
		    start = 0;
165
 
166
		    /* Get the laps. */
167
		    rlaps = garmin_alloc_data(data_Dlist);
168
 
169
		    for (m = laps->head; m != NULL; m = m->next)
170
		    {
171
		       if (get_lap_index(m->data, &l_idx) != 0)
172
		       {
173
			  if ( l_idx >= f_lap && l_idx <= l_lap )
174
			  {
175
/*		             if ( garmin->verbose != 0 )
176
			     {
177
			        printf("[garmin] lap [%d] falls within laps [%d:%d]\n",
178
			        l_idx,f_lap,l_lap);
179
			     }
180
*/
181
			     garmin_list_append((garmin_list *)rlaps->data, m->data);
182
 
183
			     if ( l_idx == f_lap )
184
			     {
185
			        get_lap_start_time(m->data, &start);
186
 
187
/*			        if (garmin->verbose != 0)
188
				{
189
				   printf("[garmin] first lap [%d] has start time [%d]\n",
190
				   l_idx,(int)start);
191
				} */
192
			     }
193
			  }
194
		       }
195
		    }
196
 
197
		    /* Get the track points. */
198
 
199
		    rtracks = get_track(tracks,trk);
200
 
201
		    /* Now make a three-element list for this run. */
202
		    rlist = garmin_alloc_data(data_Dlist);
203
		    garmin_list_append((garmin_list *)rlist->data,n->data);
204
		    garmin_list_append((garmin_list *)rlist->data,rlaps);
205
		    garmin_list_append((garmin_list *)rlist->data,rtracks);
206
 
207
		    /*
208
		     * Determine the filename based on the start time of the first lap
209
		     */
210
 
211
		    if ((start_time = start) != 0)
212
		    {
213
		       tbuf = localtime(&start_time);
214
		       filepath.sprintf("%s/%d/%02d",
215
			  Data.ascii(), tbuf->tm_year+1900, tbuf->tm_mon + 1);
216
		       strftime(filename, sizeof(filename), "%Y%m%dT%H%M%S.gmn", tbuf);
217
 
218
		       /* Save rlist to the file. */
219
		       garmin_save(rlist, filename, filepath.ascii());
132 andreas 220
		       lblReading->setText(i18n("Saved file ") + QString(filename));
221
		       mapp->processEvents();
95 andreas 222
		    }
223
/*	            else
224
		    {
225
		       printf("Start time of first lap not found!\n");
226
		    }
227
*/
228
		    /* Free the temporary lists we were using. */
229
 
230
		    if (rlaps != NULL)
231
		    {
232
		       garmin_free_list_only((garmin_list *)rlaps->data);
233
		       free(rlaps);
234
		    }
235
 
236
		    if (rtracks != NULL)
237
		    {
238
		       garmin_free_list_only((garmin_list *)rtracks->data);
239
		       free(rtracks);
240
		    }
241
 
242
		    if (rlist != NULL)
243
		    {
244
		       garmin_free_list_only((garmin_list *)rlist->data);
245
		       free(rlist);
246
		    }
247
		 }
248
	      }
249
	   }
250
	   else
251
	   {
252
              if (data0 == NULL)
253
		 KMessageBox::error(this, i18n("Toplevel data missing element 0 (runs)"));
254
	      else if (runs == NULL)
255
		 KMessageBox::error(this, i18n("No runs extracted!"));
256
 
257
	      if ( data1 == NULL )
258
		 KMessageBox::error(this, i18n("Toplevel data missing element 1 (laps)"));
259
	      else if (laps == NULL)
260
		 KMessageBox::error(this, i18n("No laps extracted!"));
261
 
262
	      if (data2 == NULL)
263
		 KMessageBox::error(this, i18n("Toplevel data missing element 2 (tracks)"));
264
	      else if (tracks == NULL)
265
		 KMessageBox::error(this, i18n("No tracks extracted!"));
266
	   }
267
 
268
	   garmin_free_data(data);
269
	}
270
	else
271
	   KMessageBox::error(this, i18n("Unable to extract any data!"));
272
 
132 andreas 273
	mapp->processEvents();
100 andreas 274
	garmin_close(&garmin);
137 andreas 275
	garmin_clear_hook();
276
//	done(QDialog::Accepted);
277
 
278
	if (garmin_count_error() > 0)
279
	   return false;
280
 
281
	return true;
95 andreas 282
}
283
 
284
int progressWidget::get_run_track_lap_info ( garmin_data * run,
285
			 uint32 *      track_index,
286
			 uint32 *      first_lap_index,
287
			 uint32 *      last_lap_index )
288
{
289
  D1000 * d1000;
290
  D1009 * d1009;
291
  D1010 * d1010;
292
 
293
  int ok = 1;
294
 
295
  switch ( run->type ) {
296
  case data_D1000:
297
    d1000            = (D1000 *)run->data;
298
    *track_index     = d1000->track_index;
299
    *first_lap_index = d1000->first_lap_index;
300
    *last_lap_index  = d1000->last_lap_index;
301
    break;
302
  case data_D1009:
303
    d1009            = (D1009 *)run->data;
304
    *track_index     = d1009->track_index;
305
    *first_lap_index = d1009->first_lap_index;
306
    *last_lap_index  = d1009->last_lap_index;
307
    break;
308
  case data_D1010:
309
    d1010            = (D1010 *)run->data;
310
    *track_index     = d1010->track_index;
311
    *first_lap_index = d1010->first_lap_index;
312
    *last_lap_index  = d1010->last_lap_index;
313
    break;
314
  default:
132 andreas 315
    fprintf(stderr, "get_run_track_lap_info: run type %d invalid!\n",run->type);
95 andreas 316
    ok = 0;
317
    break;
318
  }
319
 
320
  return ok;
321
}
322
 
323
int progressWidget::get_lap_index ( garmin_data * lap, uint32 * lap_index )
324
{
325
  D1001 * d1001;
326
  D1011 * d1011;
327
  D1015 * d1015;
328
 
329
  int ok = 1;
330
 
331
  switch ( lap->type ) {
332
  case data_D1001:
333
    d1001      = (D1001 *)lap->data;
334
    *lap_index = d1001->index;
335
    break;
336
  case data_D1011:
337
    d1011      = (D1011 *)lap->data;
338
    *lap_index = d1011->index;
339
    break;
340
  case data_D1015:
341
    d1015      = (D1015 *)lap->data;
342
    *lap_index = d1015->index;
343
    break;
344
  default:
345
    fprintf(stderr, "get_lap_index: lap type %d invalid!\n",lap->type);
346
    ok = 0;
347
    break;
348
  }
349
 
350
  return ok;
351
}
352
 
353
 
354
int progressWidget::get_lap_start_time (garmin_data *lap, time_type *start_time)
355
{
356
  D1001 * d1001;
357
  D1011 * d1011;
358
  D1015 * d1015;
359
 
360
  int ok = 1;
361
 
362
  switch ( lap->type ) {
363
  case data_D1001:
364
    d1001       = (D1001 *)lap->data;
365
    *start_time = d1001->start_time + TIME_OFFSET;
366
    break;
367
  case data_D1011:
368
    d1011       = (D1011 *)lap->data;
369
    *start_time = d1011->start_time + TIME_OFFSET;
370
    break;
371
  case data_D1015:
372
    d1015       = (D1015 *)lap->data;
373
    *start_time = d1015->start_time + TIME_OFFSET;
374
    break;
375
  default:
132 andreas 376
    fprintf(stderr, "get_lap_start_time: lap type %d invalid!\n",lap->type);
95 andreas 377
    ok = 0;
378
    break;
379
  }
380
 
381
  return ok;
382
}
383
 
384
 
385
garmin_data *progressWidget::get_track(garmin_list *points, uint32 trk_index)
386
{
387
  garmin_list_node * n;
388
  garmin_data *      track = NULL;
389
  D311 *             d311;
390
  int                done = 0;
391
 
392
  /* Look for a data_D311 with an index that matches. */
393
 
394
  for ( n = points->head; n != NULL; n = n->next ) {    
395
    if ( n->data != NULL ) {
396
      switch ( n->data->type ) {
397
      case data_D311:
398
	if ( track == NULL ) {
399
	  d311 = (D311 *)n->data->data;
400
	  if ( d311->index == trk_index ) {
401
	    track = garmin_alloc_data(data_Dlist);
402
	    garmin_list_append((garmin_list *)track->data,n->data);
403
	  }
404
	} else {
405
	  /* We've reached the end of the track */
406
	  done = 1;
407
	}
408
	break;
409
      case data_D300:
410
      case data_D301:
411
      case data_D302:
412
      case data_D303:
413
      case data_D304:
414
	if ( track != NULL ) {
415
	  garmin_list_append((garmin_list *)track->data,n->data);
416
	}
417
	break;
418
      default:
132 andreas 419
	fprintf(stderr, "get_track: point type %d invalid!\n",n->data->type);
95 andreas 420
	break;
421
      }
422
    }
423
 
424
    if ( done != 0 ) break;
425
  }
426
 
427
  return track;
428
}
429
 
430
 
431
#include "progresswidget.moc"
432