~ubuntu-branches/ubuntu/saucy/goldencheetah/saucy

« back to all changes in this revision

Viewing changes to src/LTMSidebar.cpp

  • Committer: Package Import Robot
  • Author(s): KURASHIKI Satoru
  • Date: 2013-08-18 07:02:45 UTC
  • mfrom: (4.1.8 sid)
  • Revision ID: package-import@ubuntu.com-20130818070245-zgdvb47e1k3mtgil
Tags: 3.0-3
debian/control: remove needless dependency. (Closes: #719571)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2012 Mark Liversedge (liversedge@gmail.com)
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or modify it
 
5
 * under the terms of the GNU General Public License as published by the Free
 
6
 * Software Foundation; either version 2 of the License, or (at your option)
 
7
 * any later version.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful, but WITHOUT
 
10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 
12
 * more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License along
 
15
 * with this program; if not, write to the Free Software Foundation, Inc., 51
 
16
 * Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
17
 */
 
18
 
 
19
#include "LTMSidebar.h"
 
20
#include "MainWindow.h"
 
21
#include "Settings.h"
 
22
#include "Units.h"
 
23
#include <assert.h>
 
24
#include <QApplication>
 
25
#include <QWebView>
 
26
#include <QWebFrame>
 
27
#include <QtGui>
 
28
 
 
29
// seasons support
 
30
#include "Season.h"
 
31
#include "SeasonParser.h"
 
32
#include <QXmlInputSource>
 
33
#include <QXmlSimpleReader>
 
34
 
 
35
// metadata support
 
36
#include "RideMetadata.h"
 
37
#include "SpecialFields.h"
 
38
 
 
39
#include "MetricAggregator.h"
 
40
#include "SummaryMetrics.h"
 
41
 
 
42
LTMSidebar::LTMSidebar(MainWindow *parent, const QDir &home) : QWidget(parent), home(home), main(parent), active(false)
 
43
{
 
44
    QVBoxLayout *mainLayout = new QVBoxLayout(this);
 
45
    mainLayout->setContentsMargins(0,0,0,0);
 
46
    mainLayout->setSpacing(0);
 
47
    setContentsMargins(0,0,0,0);
 
48
 
 
49
    seasonsWidget = new GcSplitterItem(tr("Date Ranges"), iconFromPNG(":images/sidebar/calendar.png"), this);
 
50
    QAction *moreSeasonAct = new QAction(iconFromPNG(":images/sidebar/extra.png"), tr("Menu"), this);
 
51
    seasonsWidget->addAction(moreSeasonAct);
 
52
    connect(moreSeasonAct, SIGNAL(triggered(void)), this, SLOT(dateRangePopup(void)));
 
53
 
 
54
    dateRangeTree = new SeasonTreeView;
 
55
    allDateRanges=dateRangeTree->invisibleRootItem();
 
56
    // Drop for Seasons
 
57
    allDateRanges->setFlags(Qt::ItemIsEnabled | Qt::ItemIsDropEnabled);
 
58
    allDateRanges->setText(0, tr("Date Ranges"));
 
59
    dateRangeTree->setFrameStyle(QFrame::NoFrame);
 
60
    dateRangeTree->setColumnCount(1);
 
61
    dateRangeTree->setSelectionMode(QAbstractItemView::SingleSelection);
 
62
    dateRangeTree->header()->hide();
 
63
    dateRangeTree->setIndentation(5);
 
64
    dateRangeTree->expandItem(allDateRanges);
 
65
    dateRangeTree->setContextMenuPolicy(Qt::CustomContextMenu);
 
66
#ifdef Q_OS_MAC
 
67
    dateRangeTree->setAttribute(Qt::WA_MacShowFocusRect, 0);
 
68
#endif
 
69
    seasonsWidget->addWidget(dateRangeTree);
 
70
 
 
71
 
 
72
    eventsWidget = new GcSplitterItem(tr("Events"), iconFromPNG(":images/sidebar/bookmark.png"), this);
 
73
    QAction *moreEventAct = new QAction(iconFromPNG(":images/sidebar/extra.png"), tr("Menu"), this);
 
74
    eventsWidget->addAction(moreEventAct);
 
75
    connect(moreEventAct, SIGNAL(triggered(void)), this, SLOT(eventPopup(void)));
 
76
 
 
77
 
 
78
    eventTree = new QTreeWidget;
 
79
    eventTree->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
 
80
    allEvents = eventTree->invisibleRootItem();
 
81
    allEvents->setText(0, tr("Events"));
 
82
    eventTree->setFrameStyle(QFrame::NoFrame);
 
83
    eventTree->setColumnCount(2);
 
84
    eventTree->setSelectionMode(QAbstractItemView::SingleSelection);
 
85
    eventTree->header()->hide();
 
86
    eventTree->setIndentation(5);
 
87
    eventTree->expandItem(allEvents);
 
88
    eventTree->setContextMenuPolicy(Qt::CustomContextMenu);
 
89
    eventTree->horizontalScrollBar()->setDisabled(true);
 
90
    eventTree->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
 
91
#ifdef Q_OS_MAC
 
92
    eventTree->setAttribute(Qt::WA_MacShowFocusRect, 0);
 
93
#endif
 
94
    eventsWidget->addWidget(eventTree);
 
95
 
 
96
    seasons = parent->seasons;
 
97
    resetSeasons(); // reset the season list
 
98
 
 
99
    configChanged(); // will reset the metric tree
 
100
 
 
101
    splitter = new GcSplitter(Qt::Vertical);
 
102
    splitter->addWidget(seasonsWidget);
 
103
    splitter->addWidget(eventsWidget);
 
104
 
 
105
    GcSplitterItem *summaryWidget = new GcSplitterItem(tr("Summary"), iconFromPNG(":images/sidebar/dashboard.png"), this);
 
106
 
 
107
    summary = new QWebView(this);
 
108
    summary->setContentsMargins(0,0,0,0);
 
109
    summary->page()->view()->setContentsMargins(0,0,0,0);
 
110
    summary->page()->mainFrame()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff);
 
111
    summary->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
 
112
    summary->setAcceptDrops(false);
 
113
 
 
114
    summaryWidget->addWidget(summary);
 
115
 
 
116
    QFont defaultFont; // mainwindow sets up the defaults.. we need to apply
 
117
    summary->settings()->setFontSize(QWebSettings::DefaultFontSize, defaultFont.pointSize());
 
118
    summary->settings()->setFontFamily(QWebSettings::StandardFont, defaultFont.family());
 
119
    splitter->addWidget(summaryWidget);
 
120
 
 
121
    mainLayout->addWidget(splitter);
 
122
 
 
123
    splitter->prepare(main->cyclist, "LTM");
 
124
 
 
125
    // our date ranges
 
126
    connect(dateRangeTree,SIGNAL(itemSelectionChanged()), this, SLOT(dateRangeTreeWidgetSelectionChanged()));
 
127
    connect(dateRangeTree,SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(dateRangePopup(const QPoint &)));
 
128
    connect(dateRangeTree,SIGNAL(itemChanged(QTreeWidgetItem *,int)), this, SLOT(dateRangeChanged(QTreeWidgetItem*, int)));
 
129
    connect(dateRangeTree,SIGNAL(itemMoved(QTreeWidgetItem *,int, int)), this, SLOT(dateRangeMoved(QTreeWidgetItem*, int, int)));
 
130
    connect(eventTree,SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(eventPopup(const QPoint &)));
 
131
    // GC signal
 
132
    connect(main, SIGNAL(configChanged()), this, SLOT(configChanged()));
 
133
    connect(seasons, SIGNAL(seasonsChanged()), this, SLOT(resetSeasons()));
 
134
 
 
135
    connect(this, SIGNAL(dateRangeChanged(DateRange)), this, SLOT(setSummary(DateRange)));
 
136
 
 
137
    // let everyone know what date range we are starting with
 
138
    dateRangeTreeWidgetSelectionChanged();
 
139
 
 
140
}
 
141
 
 
142
void
 
143
LTMSidebar::configChanged()
 
144
{
 
145
}
 
146
 
 
147
/*----------------------------------------------------------------------
 
148
 * Selections Made
 
149
 *----------------------------------------------------------------------*/
 
150
 
 
151
void
 
152
LTMSidebar::dateRangeTreeWidgetSelectionChanged()
 
153
{
 
154
    if (active == true) return;
 
155
 
 
156
    const Season *dateRange = NULL;
 
157
 
 
158
    if (dateRangeTree->selectedItems().isEmpty()) dateRange = NULL;
 
159
    else {
 
160
        QTreeWidgetItem *which = dateRangeTree->selectedItems().first();
 
161
        if (which != allDateRanges) {
 
162
            dateRange = &seasons->seasons.at(allDateRanges->indexOfChild(which));
 
163
        } else {
 
164
            dateRange = NULL;
 
165
        }
 
166
    }
 
167
 
 
168
    if (dateRange) {
 
169
        int i;
 
170
        // clear events - we need to add for currently selected season
 
171
        for (i=allEvents->childCount(); i > 0; i--) {
 
172
            delete allEvents->takeChild(0);
 
173
        }
 
174
 
 
175
        // add this seasons events
 
176
        for (i=0; i <dateRange->events.count(); i++) {
 
177
            SeasonEvent event = dateRange->events.at(i);
 
178
            QTreeWidgetItem *add = new QTreeWidgetItem(allEvents);
 
179
            add->setText(0, event.name);
 
180
            add->setText(1, event.date.toString("MMM d, yyyy"));
 
181
        }
 
182
 
 
183
        // make sure they fit
 
184
        eventTree->header()->resizeSections(QHeaderView::ResizeToContents);
 
185
        appsettings->setCValue(main->cyclist, GC_LTM_LAST_DATE_RANGE, dateRange->id().toString());
 
186
 
 
187
    }
 
188
 
 
189
    // Let the view know its changed....
 
190
    if (dateRange) emit dateRangeChanged(DateRange(dateRange->start, dateRange->end, dateRange->name));
 
191
    else emit dateRangeChanged(DateRange());
 
192
 
 
193
}
 
194
 
 
195
/*----------------------------------------------------------------------
 
196
 * Seasons stuff
 
197
 *--------------------------------------------------------------------*/
 
198
 
 
199
void
 
200
LTMSidebar::resetSeasons()
 
201
{
 
202
    if (active == true) return;
 
203
 
 
204
    active = true;
 
205
    int i;
 
206
    for (i=allDateRanges->childCount(); i > 0; i--) {
 
207
        delete allDateRanges->takeChild(0);
 
208
    }
 
209
    QString id = appsettings->cvalue(main->cyclist, GC_LTM_LAST_DATE_RANGE, seasons->seasons.at(0).id().toString()).toString();
 
210
    for (i=0; i <seasons->seasons.count(); i++) {
 
211
        Season season = seasons->seasons.at(i);
 
212
        QTreeWidgetItem *add = new QTreeWidgetItem(allDateRanges, season.getType());
 
213
        if (season.id().toString()==id)
 
214
            add->setSelected(true);
 
215
 
 
216
        // No Drag/Drop for temporary  Season
 
217
        if (season.getType() == Season::temporary)
 
218
            add->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
 
219
        else
 
220
            add->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled);
 
221
        add->setText(0, season.getName());
 
222
    }
 
223
 
 
224
    active = false;
 
225
}
 
226
 
 
227
int
 
228
LTMSidebar::newSeason(QString name, QDate start, QDate end, int type)
 
229
{
 
230
    seasons->newSeason(name, start, end, type);
 
231
 
 
232
    QTreeWidgetItem *item = new QTreeWidgetItem(Season::season);
 
233
    item->setText(0, name);
 
234
    allDateRanges->insertChild(0, item);
 
235
    return 0; // always add at the top
 
236
}
 
237
 
 
238
void
 
239
LTMSidebar::updateSeason(int index, QString name, QDate start, QDate end, int type)
 
240
{
 
241
    seasons->updateSeason(index, name, start, end, type);
 
242
    allDateRanges->child(index)->setText(0, name);
 
243
}
 
244
 
 
245
void
 
246
LTMSidebar::dateRangePopup(QPoint pos)
 
247
{
 
248
    QTreeWidgetItem *item = dateRangeTree->itemAt(pos);
 
249
    if (item != NULL) {
 
250
 
 
251
        // out of bounds or not user defined
 
252
        int index = allDateRanges->indexOfChild(item);
 
253
        if (index == -1 || index >= seasons->seasons.count()
 
254
            || seasons->seasons[index].getType() == Season::temporary) {
 
255
            // on system date we just offer to add a Season, since its
 
256
            // the only way of doing it when no seasons are defined!!
 
257
 
 
258
            // create context menu
 
259
            QMenu menu(dateRangeTree);
 
260
            QAction *add = new QAction(tr("Add season"), dateRangeTree);
 
261
            menu.addAction(add);
 
262
 
 
263
            // connect menu to functions
 
264
            connect(add, SIGNAL(triggered(void)), this, SLOT(addRange(void)));
 
265
 
 
266
            // execute the menu
 
267
            menu.exec(dateRangeTree->mapToGlobal(pos));
 
268
 
 
269
        } else {
 
270
 
 
271
            // create context menu
 
272
            QMenu menu(dateRangeTree);
 
273
            QAction *add = new QAction(tr("Add season"), dateRangeTree);
 
274
            QAction *edit = new QAction(tr("Edit season"), dateRangeTree);
 
275
            QAction *del = new QAction(tr("Delete season"), dateRangeTree);
 
276
            QAction *event = new QAction(tr("Add Event"), dateRangeTree);
 
277
            menu.addAction(add);
 
278
            menu.addAction(edit);
 
279
            menu.addAction(del);
 
280
            menu.addAction(event);
 
281
 
 
282
            // connect menu to functions
 
283
            connect(add, SIGNAL(triggered(void)), this, SLOT(addRange(void)));
 
284
            connect(edit, SIGNAL(triggered(void)), this, SLOT(editRange(void)));
 
285
            connect(del, SIGNAL(triggered(void)), this, SLOT(deleteRange(void)));
 
286
            connect(event, SIGNAL(triggered(void)), this, SLOT(addEvent(void)));
 
287
 
 
288
            // execute the menu
 
289
            menu.exec(dateRangeTree->mapToGlobal(pos));
 
290
        }
 
291
    }
 
292
}
 
293
 
 
294
void
 
295
LTMSidebar::dateRangePopup()
 
296
{
 
297
    // no current season selected
 
298
    if (dateRangeTree->selectedItems().isEmpty()) return;
 
299
 
 
300
    QTreeWidgetItem *item = dateRangeTree->selectedItems().at(0);
 
301
 
 
302
    // OK - we are working with a specific event..
 
303
    QMenu menu(dateRangeTree);
 
304
    QAction *add = new QAction(tr("Add season"), dateRangeTree);
 
305
    menu.addAction(add);
 
306
    connect(add, SIGNAL(triggered(void)), this, SLOT(addRange(void)));
 
307
 
 
308
    if (item != NULL && allDateRanges->indexOfChild(item) != -1) {
 
309
        QAction *edit = new QAction(tr("Edit season"), dateRangeTree);
 
310
        QAction *del = new QAction(tr("Delete season"), dateRangeTree);
 
311
        QAction *event = new QAction(tr("Add Event"), dateRangeTree);
 
312
 
 
313
        menu.addAction(edit);
 
314
        menu.addAction(del);
 
315
        menu.addAction(event);
 
316
 
 
317
        // connect menu to functions
 
318
 
 
319
        connect(edit, SIGNAL(triggered(void)), this, SLOT(editRange(void)));
 
320
        connect(del, SIGNAL(triggered(void)), this, SLOT(deleteRange(void)));
 
321
        connect(event, SIGNAL(triggered(void)), this, SLOT(addEvent(void)));
 
322
    }
 
323
    // execute the menu
 
324
    menu.exec(splitter->mapToGlobal(QPoint(seasonsWidget->pos().x()+seasonsWidget->width()-20,
 
325
                                           seasonsWidget->pos().y())));
 
326
}
 
327
 
 
328
void
 
329
LTMSidebar::eventPopup(QPoint pos)
 
330
{
 
331
    // no current season selected
 
332
    if (dateRangeTree->selectedItems().isEmpty()) return;
 
333
 
 
334
    QTreeWidgetItem *item = eventTree->itemAt(pos);
 
335
 
 
336
    // save context - which season and event are we working with?
 
337
    QTreeWidgetItem *which = dateRangeTree->selectedItems().first();
 
338
    if (!which || which == allDateRanges) return;
 
339
 
 
340
    // OK - we are working with a specific event..
 
341
    QMenu menu(eventTree);
 
342
    if (item != NULL && allEvents->indexOfChild(item) != -1) {
 
343
 
 
344
        QAction *edit = new QAction(tr("Edit details"), eventTree);
 
345
        QAction *del = new QAction(tr("Delete event"), eventTree);
 
346
        menu.addAction(edit);
 
347
        menu.addAction(del);
 
348
 
 
349
        // connect menu to functions
 
350
        connect(edit, SIGNAL(triggered(void)), this, SLOT(editEvent(void)));
 
351
        connect(del, SIGNAL(triggered(void)), this, SLOT(deleteEvent(void)));
 
352
    }
 
353
 
 
354
    // we can always add, regardless of any event being selected...
 
355
    QAction *addEvent = new QAction(tr("Add event"), eventTree);
 
356
    menu.addAction(addEvent);
 
357
    connect(addEvent, SIGNAL(triggered(void)), this, SLOT(addEvent(void)));
 
358
 
 
359
    // execute the menu
 
360
    menu.exec(eventTree->mapToGlobal(pos));
 
361
}
 
362
 
 
363
void
 
364
LTMSidebar::eventPopup()
 
365
{
 
366
    // events are against a selected season
 
367
    if (dateRangeTree->selectedItems().count() == 0) return; // need a season selected!
 
368
 
 
369
    // and the season must be user defined not temporary
 
370
    int seasonindex = allDateRanges->indexOfChild(dateRangeTree->selectedItems().first());
 
371
    if (seasons->seasons[seasonindex].getType() == Season::temporary) return;
 
372
 
 
373
    // have we selected an event?
 
374
    QTreeWidgetItem *item = NULL;
 
375
    if (!eventTree->selectedItems().isEmpty()) item = eventTree->selectedItems().at(0);
 
376
 
 
377
    QMenu menu(eventTree);
 
378
 
 
379
    // we can always add, regardless of any event being selected...
 
380
    QAction *addEvent = new QAction(tr("Add event"), eventTree);
 
381
    menu.addAction(addEvent);
 
382
    connect(addEvent, SIGNAL(triggered(void)), this, SLOT(addEvent(void)));
 
383
 
 
384
    if (item != NULL && allEvents->indexOfChild(item) != -1) {
 
385
 
 
386
        QAction *edit = new QAction(tr("Edit details"), eventTree);
 
387
        QAction *del = new QAction(tr("Delete event"), eventTree);
 
388
        menu.addAction(edit);
 
389
        menu.addAction(del);
 
390
 
 
391
        // connect menu to functions
 
392
        connect(edit, SIGNAL(triggered(void)), this, SLOT(editEvent(void)));
 
393
        connect(del, SIGNAL(triggered(void)), this, SLOT(deleteEvent(void)));
 
394
    }
 
395
 
 
396
    // execute the menu
 
397
    menu.exec(splitter->mapToGlobal(QPoint(eventsWidget->pos().x()+eventsWidget->width()-20, eventsWidget->pos().y())));
 
398
}
 
399
 
 
400
void
 
401
LTMSidebar::dateRangeChanged(QTreeWidgetItem*item, int)
 
402
{
 
403
    if (active == true) return;
 
404
 
 
405
    int index = allDateRanges->indexOfChild(item);
 
406
    seasons->seasons[index].setName(item->text(0));
 
407
 
 
408
    // save changes away
 
409
    active = true;
 
410
    seasons->writeSeasons();
 
411
    active = false;
 
412
 
 
413
    // signal date selected changed
 
414
    //dateRangeSelected(&seasons->seasons[index]);
 
415
}
 
416
 
 
417
void
 
418
LTMSidebar::dateRangeMoved(QTreeWidgetItem*item, int oldposition, int newposition)
 
419
{
 
420
    // no drop in the temporary seasons
 
421
    if (newposition>allDateRanges->childCount()-12) {
 
422
        newposition = allDateRanges->childCount()-12;
 
423
        allDateRanges->removeChild(item);
 
424
        allDateRanges->insertChild(newposition, item);
 
425
    }
 
426
 
 
427
    // report the move in the seasons
 
428
    seasons->seasons.move(oldposition, newposition);
 
429
 
 
430
    // save changes away
 
431
    active = true;
 
432
    seasons->writeSeasons();
 
433
    active = false;
 
434
 
 
435
    // deselect actual selection
 
436
    dateRangeTree->selectedItems().first()->setSelected(false);
 
437
    // select the move/drop item
 
438
    item->setSelected(true);
 
439
}
 
440
 
 
441
void
 
442
LTMSidebar::addRange()
 
443
{
 
444
    Season newOne;
 
445
 
 
446
    EditSeasonDialog dialog(main, &newOne);
 
447
 
 
448
    if (dialog.exec()) {
 
449
 
 
450
        active = true;
 
451
 
 
452
        // save 
 
453
        seasons->seasons.insert(0, newOne);
 
454
        seasons->writeSeasons();
 
455
        active = false;
 
456
 
 
457
        // signal its changed!
 
458
        resetSeasons();
 
459
    }
 
460
}
 
461
 
 
462
void
 
463
LTMSidebar::editRange()
 
464
{
 
465
    // throw up modal dialog box to edit all the season
 
466
    if (dateRangeTree->selectedItems().count() != 1) return;
 
467
 
 
468
    int index = allDateRanges->indexOfChild(dateRangeTree->selectedItems().first());
 
469
    EditSeasonDialog dialog(main, &seasons->seasons[index]);
 
470
 
 
471
    if (dialog.exec()) {
 
472
 
 
473
        active = true;
 
474
 
 
475
        // update name
 
476
        dateRangeTree->selectedItems().first()->setText(0, seasons->seasons[index].getName());
 
477
 
 
478
        // save changes away
 
479
        seasons->writeSeasons();
 
480
        active = false;
 
481
 
 
482
    }
 
483
}
 
484
 
 
485
void
 
486
LTMSidebar::deleteRange()
 
487
{
 
488
    if (dateRangeTree->selectedItems().count() != 1) return;
 
489
    int index = allDateRanges->indexOfChild(dateRangeTree->selectedItems().first());
 
490
 
 
491
    // now delete!
 
492
    delete allDateRanges->takeChild(index);
 
493
    seasons->deleteSeason(index);
 
494
}
 
495
 
 
496
void
 
497
LTMSidebar::addEvent()
 
498
{
 
499
    if (dateRangeTree->selectedItems().count() == 0) {
 
500
        QMessageBox::warning(this, tr("Add Event"), tr("You can only add events to user defined seasons. Please select a season you have created before adding an event."));
 
501
        return; // need a season selected!
 
502
    }
 
503
 
 
504
    int seasonindex = allDateRanges->indexOfChild(dateRangeTree->selectedItems().first());
 
505
 
 
506
    if (seasons->seasons[seasonindex].getType() == Season::temporary) {
 
507
        QMessageBox::warning(this, tr("Add Event"), tr("You can only add events to user defined seasons. Please select a season you have created before adding an event."));
 
508
        return; // must be a user season
 
509
    }
 
510
 
 
511
    SeasonEvent myevent("", QDate());
 
512
    EditSeasonEventDialog dialog(main, &myevent);
 
513
 
 
514
    if (dialog.exec()) {
 
515
 
 
516
        active = true;
 
517
        seasons->seasons[seasonindex].events.append(myevent);
 
518
 
 
519
        QTreeWidgetItem *add = new QTreeWidgetItem(allEvents);
 
520
        add->setText(0, myevent.name);
 
521
        add->setText(1, myevent.date.toString("MMM d, yyyy"));
 
522
 
 
523
        // make sure they fit
 
524
        eventTree->header()->resizeSections(QHeaderView::ResizeToContents);
 
525
 
 
526
        // save changes away
 
527
        seasons->writeSeasons();
 
528
        active = false;
 
529
    }
 
530
}
 
531
 
 
532
void
 
533
LTMSidebar::deleteEvent()
 
534
{
 
535
    active = true;
 
536
 
 
537
    if (dateRangeTree->selectedItems().count()) {
 
538
 
 
539
        int seasonindex = allDateRanges->indexOfChild(dateRangeTree->selectedItems().first());
 
540
 
 
541
        // only delete those that are selected
 
542
        if (eventTree->selectedItems().count() > 0) {
 
543
 
 
544
            // wipe them away
 
545
            foreach(QTreeWidgetItem *d, eventTree->selectedItems()) {
 
546
                int index = allEvents->indexOfChild(d);
 
547
 
 
548
                delete allEvents->takeChild(index);
 
549
                seasons->seasons[seasonindex].events.removeAt(index);
 
550
            }
 
551
        }
 
552
 
 
553
        // save changes away
 
554
        seasons->writeSeasons();
 
555
 
 
556
    }
 
557
    active = false;
 
558
}
 
559
 
 
560
void
 
561
LTMSidebar::editEvent()
 
562
{
 
563
    active = true;
 
564
 
 
565
    if (dateRangeTree->selectedItems().count()) {
 
566
 
 
567
        int seasonindex = allDateRanges->indexOfChild(dateRangeTree->selectedItems().first());
 
568
 
 
569
        // only delete those that are selected
 
570
        if (eventTree->selectedItems().count() == 1) {
 
571
 
 
572
            QTreeWidgetItem *ours = eventTree->selectedItems().first();
 
573
            int index = allEvents->indexOfChild(ours);
 
574
 
 
575
            EditSeasonEventDialog dialog(main, &seasons->seasons[seasonindex].events[index]);
 
576
 
 
577
            if (dialog.exec()) {
 
578
 
 
579
                // update name
 
580
                ours->setText(0, seasons->seasons[seasonindex].events[index].name);
 
581
                ours->setText(1, seasons->seasons[seasonindex].events[index].date.toString("MMM d, yyyy"));
 
582
 
 
583
                // save changes away
 
584
                seasons->writeSeasons();
 
585
            }
 
586
        }
 
587
    }
 
588
    active = false;
 
589
}
 
590
 
 
591
void
 
592
LTMSidebar::setSummary(DateRange dateRange)
 
593
{
 
594
    // where we construct the text
 
595
    QString summaryText("");
 
596
 
 
597
    // main totals
 
598
    static const QStringList totalColumn = QStringList()
 
599
        << "workout_time"
 
600
        << "time_riding"
 
601
        << "total_distance"
 
602
        << "total_work"
 
603
        << "elevation_gain";
 
604
 
 
605
    static const QStringList averageColumn = QStringList()
 
606
        << "average_speed"
 
607
        << "average_power"
 
608
        << "average_hr"
 
609
        << "average_cad";
 
610
 
 
611
    static const QStringList maximumColumn = QStringList()
 
612
        << "max_speed"
 
613
        << "max_power"
 
614
        << "max_heartrate"
 
615
        << "max_cadence";
 
616
 
 
617
    // user defined
 
618
    QString s = appsettings->value(this, GC_SETTINGS_SUMMARY_METRICS, GC_SETTINGS_SUMMARY_METRICS_DEFAULT).toString();
 
619
 
 
620
    // in case they were set tand then unset
 
621
    if (s == "") s = GC_SETTINGS_SUMMARY_METRICS_DEFAULT;
 
622
    QStringList metricColumn = s.split(",");
 
623
 
 
624
    // what date range should we use?
 
625
    QDate newFrom = dateRange.from;
 
626
    QDate newTo = dateRange.to;
 
627
 
 
628
    if (newFrom == from && newTo == to) return;
 
629
    else {
 
630
 
 
631
        // date range changed lets refresh
 
632
        from = newFrom;
 
633
        to = newTo;
 
634
 
 
635
        // lets get the metrics
 
636
        QList<SummaryMetrics>results = main->metricDB->getAllMetricsFor(QDateTime(from,QTime(0,0,0)), QDateTime(to, QTime(24,59,59)));
 
637
 
 
638
        // foreach of the metrics get an aggregated value
 
639
        // header of summary
 
640
        summaryText = QString("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 3.2//EN\">"
 
641
                              "<html>"
 
642
                              "<head>"
 
643
                              "<title></title>"
 
644
                              "</head>"
 
645
                              "<body>"
 
646
                              "<center>");
 
647
 
 
648
        for (int i=0; i<4; i++) {
 
649
 
 
650
            QString aggname;
 
651
            QStringList list;
 
652
 
 
653
            switch(i) {
 
654
                case 0 : // Totals
 
655
                    aggname = tr("Totals");
 
656
                    list = totalColumn;
 
657
                    break;
 
658
 
 
659
                case 1 :  // Averages
 
660
                    aggname = tr("Averages");
 
661
                    list = averageColumn;
 
662
                    break;
 
663
 
 
664
                case 3 :  // Maximums
 
665
                    aggname = tr("Maximums");
 
666
                    list = maximumColumn;
 
667
                    break;
 
668
 
 
669
                case 2 :  // User defined.. 
 
670
                    aggname = tr("Metrics");
 
671
                    list = metricColumn;
 
672
                    break;
 
673
 
 
674
            }
 
675
 
 
676
            summaryText += QString("<p><table width=\"85%\">"
 
677
                                   "<tr>"
 
678
                                   "<td align=\"center\" colspan=\"2\">"
 
679
                                   "<b>%1</b>"
 
680
                                   "</td>"
 
681
                                   "</tr>").arg(aggname);
 
682
 
 
683
            foreach(QString metricname, list) {
 
684
 
 
685
                const RideMetric *metric = RideMetricFactory::instance().rideMetric(metricname);
 
686
 
 
687
                QStringList empty; // filter list not used at present
 
688
                QString value = SummaryMetrics::getAggregated(main, metricname, results, empty, false, main->useMetricUnits);
 
689
 
 
690
                // Maximum Max and Average Average looks nasty, remove from name for display
 
691
                QString s = metric ? metric->name().replace(QRegExp(tr("^(Average|Max) ")), "") : "unknown";
 
692
 
 
693
                // don't show units for time values
 
694
                if (metric && (metric->units(main->useMetricUnits) == "seconds" ||
 
695
                               metric->units(main->useMetricUnits) == tr("seconds") ||
 
696
                               metric->units(main->useMetricUnits) == "")) {
 
697
 
 
698
                    summaryText += QString("<tr><td>%1:</td><td align=\"right\"> %2</td>")
 
699
                                            .arg(s)
 
700
                                            .arg(value);
 
701
 
 
702
                } else {
 
703
                    summaryText += QString("<tr><td>%1(%2):</td><td align=\"right\"> %3</td>")
 
704
                                            .arg(s)
 
705
                                            .arg(metric ? metric->units(main->useMetricUnits) : "unknown")
 
706
                                            .arg(value);
 
707
                }
 
708
            }
 
709
            summaryText += QString("</tr>" "</table>");
 
710
 
 
711
        }
 
712
 
 
713
        // finish off the html document
 
714
        summaryText += QString("</center>"
 
715
                               "</body>"
 
716
                               "</html>");
 
717
 
 
718
        // set webview contents
 
719
        summary->page()->mainFrame()->setHtml(summaryText);
 
720
 
 
721
    }
 
722
}