Subversion Repositories public

Rev

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