LTMSidebar::LTMSidebar(MainWindow *parent, const QDir &home) : QWidget(parent), home(home), main(parent), active(false) { QVBoxLayout *mainLayout = new QVBoxLayout(this); mainLayout->setContentsMargins(0,0,0,0); mainLayout->setSpacing(0); setContentsMargins(0,0,0,0); seasonsWidget = new GcSplitterItem(tr("Date Ranges"), iconFromPNG(":images/sidebar/calendar.png"), this); QAction *moreSeasonAct = new QAction(iconFromPNG(":images/sidebar/extra.png"), tr("Menu"), this); seasonsWidget->addAction(moreSeasonAct); connect(moreSeasonAct, SIGNAL(triggered(void)), this, SLOT(dateRangePopup(void))); dateRangeTree = new SeasonTreeView; //allDateRanges = new QTreeWidgetItem(dateRangeTree, ROOT_TYPE); allDateRanges=dateRangeTree->invisibleRootItem(); // Drop for Seasons allDateRanges->setFlags(Qt::ItemIsEnabled | Qt::ItemIsDropEnabled); allDateRanges->setText(0, tr("Date Ranges")); dateRangeTree->setFrameStyle(QFrame::NoFrame); dateRangeTree->setColumnCount(1); dateRangeTree->setSelectionMode(QAbstractItemView::SingleSelection); dateRangeTree->header()->hide(); dateRangeTree->setIndentation(5); dateRangeTree->expandItem(allDateRanges); dateRangeTree->setContextMenuPolicy(Qt::CustomContextMenu); #ifdef Q_OS_MAC dateRangeTree->setAttribute(Qt::WA_MacShowFocusRect, 0); #endif seasonsWidget->addWidget(dateRangeTree); eventsWidget = new GcSplitterItem(tr("Events"), iconFromPNG(":images/sidebar/bookmark.png"), this); QAction *moreEventAct = new QAction(iconFromPNG(":images/sidebar/extra.png"), tr("Menu"), this); eventsWidget->addAction(moreEventAct); connect(moreEventAct, SIGNAL(triggered(void)), this, SLOT(eventPopup(void))); eventTree = new QTreeWidget; eventTree->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); //allEvents = new QTreeWidgetItem(eventTree, ROOT_TYPE); allEvents = eventTree->invisibleRootItem(); allEvents->setText(0, tr("Events")); eventTree->setFrameStyle(QFrame::NoFrame); eventTree->setColumnCount(2); eventTree->setSelectionMode(QAbstractItemView::SingleSelection); eventTree->header()->hide(); eventTree->setIndentation(5); eventTree->expandItem(allEvents); eventTree->setContextMenuPolicy(Qt::CustomContextMenu); eventTree->horizontalScrollBar()->setDisabled(true); eventTree->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); #ifdef Q_OS_MAC eventTree->setAttribute(Qt::WA_MacShowFocusRect, 0); #endif eventsWidget->addWidget(eventTree); seasons = parent->seasons; resetSeasons(); // reset the season list configChanged(); // will reset the metric tree splitter = new GcSplitter(Qt::Vertical); splitter->addWidget(seasonsWidget); splitter->addWidget(eventsWidget); GcSplitterItem *summaryWidget = new GcSplitterItem(tr("Summary"), iconFromPNG(":images/sidebar/dashboard.png"), this); summary = new QWebView(this); summary->setContentsMargins(0,0,0,0); summary->page()->view()->setContentsMargins(0,0,0,0); summary->page()->mainFrame()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff); summary->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); summary->setAcceptDrops(false); summaryWidget->addWidget(summary); QFont defaultFont; // mainwindow sets up the defaults.. we need to apply summary->settings()->setFontSize(QWebSettings::DefaultFontSize, defaultFont.pointSize()); summary->settings()->setFontFamily(QWebSettings::StandardFont, defaultFont.family()); splitter->addWidget(summaryWidget); mainLayout->addWidget(splitter); splitter->prepare(main->cyclist, "LTM"); // our date ranges connect(dateRangeTree,SIGNAL(itemSelectionChanged()), this, SLOT(dateRangeTreeWidgetSelectionChanged())); connect(dateRangeTree,SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(dateRangePopup(const QPoint &))); connect(dateRangeTree,SIGNAL(itemChanged(QTreeWidgetItem *,int)), this, SLOT(dateRangeChanged(QTreeWidgetItem*, int))); connect(dateRangeTree,SIGNAL(itemMoved(QTreeWidgetItem *,int, int)), this, SLOT(dateRangeMoved(QTreeWidgetItem*, int, int))); connect(eventTree,SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(eventPopup(const QPoint &))); // GC signal connect(main, SIGNAL(configChanged()), this, SLOT(configChanged())); connect(seasons, SIGNAL(seasonsChanged()), this, SLOT(resetSeasons())); connect(this, SIGNAL(dateRangeChanged(DateRange)), this, SLOT(setSummary(DateRange))); // let everyone know what date range we are starting with dateRangeTreeWidgetSelectionChanged(); }
IntervalSidebar::IntervalSidebar(Context *context) : QWidget(context->mainWindow), context(context) { QVBoxLayout *mainLayout = new QVBoxLayout(this); mainLayout->setContentsMargins(0,0,0,0); mainLayout->setSpacing(0); setContentsMargins(0,0,0,0); splitter = new GcSplitter(Qt::Vertical); mainLayout->addWidget(splitter); // Route routeNavigator = new IntervalNavigator(context, "Route", true); routeNavigator->setProperty("nomenu", true); groupByMapper = NULL; // Bests bestNavigator = new IntervalNavigator(context, "Best", true); bestNavigator->setProperty("nomenu", true); // retrieve settings (properties are saved when we close the window) if (appsettings->cvalue(context->athlete->cyclist, GC_ROUTEHEADINGS, "").toString() != "") { routeNavigator->setSortByIndex(appsettings->cvalue(context->athlete->cyclist, GC_ROUTESORTBY).toInt()); routeNavigator->setSortByOrder(appsettings->cvalue(context->athlete->cyclist, GC_ROUTESORTBYORDER).toInt()); //routeNavigator->setGroupBy(appsettings->cvalue(context->athlete->cyclist, GC_ROUTEGROUPBY).toInt()); routeNavigator->setColumns(appsettings->cvalue(context->athlete->cyclist, GC_ROUTEHEADINGS).toString()); routeNavigator->setWidths(appsettings->cvalue(context->athlete->cyclist, GC_ROUTEHEADINGWIDTHS).toString()); } if (appsettings->cvalue(context->athlete->cyclist, GC_BESTHEADINGS, "").toString() != "") { bestNavigator->setSortByIndex(appsettings->cvalue(context->athlete->cyclist, GC_BESTSORTBY).toInt()); bestNavigator->setSortByOrder(appsettings->cvalue(context->athlete->cyclist, GC_BESTSORTBYORDER).toInt()); bestNavigator->setColumns(appsettings->cvalue(context->athlete->cyclist, GC_BESTHEADINGS).toString()); bestNavigator->setWidths(appsettings->cvalue(context->athlete->cyclist, GC_BESTHEADINGWIDTHS).toString()); } QWidget *routeWidget = new QWidget(this); routeWidget->setContentsMargins(0,0,0,0); #ifndef Q_OS_MAC // not on mac thanks routeWidget->setStyleSheet("padding: 0px; border: 0px; margin: 0px;"); #endif QVBoxLayout *routeLayout = new QVBoxLayout(routeWidget); routeLayout->setSpacing(0); routeLayout->setContentsMargins(0,0,0,0); routeLayout->addWidget(routeNavigator); routeItem = new GcSplitterItem(tr("Routes"), iconFromPNG(":images/sidebar/folder.png"), this); QAction *routeAction = new QAction(iconFromPNG(":images/sidebar/extra.png"), tr("Menu"), this); routeItem->addAction(routeAction); connect(routeAction, SIGNAL(triggered(void)), this, SLOT(routePopup())); routeItem->addWidget(routeWidget); QWidget *bestWidget = new QWidget(this); bestWidget->setContentsMargins(0,0,0,0); #ifndef Q_OS_MAC // not on mac thanks bestWidget->setStyleSheet("padding: 0px; border: 0px; margin: 0px;"); #endif QVBoxLayout *bestLayout = new QVBoxLayout(bestWidget); bestLayout->setSpacing(0); bestLayout->setContentsMargins(0,0,0,0); bestLayout->addWidget(bestNavigator); bestItem = new GcSplitterItem(tr("Bests"), iconFromPNG(":images/sidebar/folder.png"), this); QAction *bestAction = new QAction(iconFromPNG(":images/sidebar/extra.png"), tr("Menu"), this); bestItem->addAction(bestAction); connect(bestAction, SIGNAL(triggered(void)), this, SLOT(bestPopup())); bestItem->addWidget(bestWidget); splitter->addWidget(routeItem); splitter->addWidget(bestItem); splitter->prepare(context->athlete->cyclist, "interval"); // GC signal connect(context, SIGNAL(configChanged()), this, SLOT(configChanged())); // right click menus... connect(routeNavigator,SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(showRouteMenu(const QPoint &))); //connect(context->athlete->intervalWidget,SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(showIntervalMenu(const QPoint &))); connect(bestNavigator,SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(showBestMenu(const QPoint &))); connect (context, SIGNAL(filterChanged()), this, SLOT(filterChanged())); configChanged(); }
//******************************************************************************** // CALENDAR SIDEBAR (DiarySidebar) //******************************************************************************** DiarySidebar::DiarySidebar(Context *context) : context(context) { setContentsMargins(0,0,0,0); setAutoFillBackground(true); month = year = 0; _ride = NULL; QVBoxLayout *mainLayout = new QVBoxLayout(this); mainLayout->setContentsMargins(0,0,0,0); mainLayout->setSpacing(0); // Splitter - cal at top, summary at bottom splitter = new GcSplitter(Qt::Vertical); mainLayout->addWidget(splitter); // calendar calendarItem = new GcSplitterItem(tr("Calendar"), iconFromPNG(":images/sidebar/calendar.png"), this); summaryItem = new GcSplitterItem(tr("Summary"), iconFromPNG(":images/sidebar/dashboard.png"), this); QPalette pal; pal.setColor(QPalette::Window, Qt::white); setPalette(pal); // cal widget QWidget *cal = new QWidget(this); cal->setPalette(pal); cal->setContentsMargins(0,0,0,0); cal->setStyleSheet("QLabel { color: gray; }"); layout = new QVBoxLayout(cal); layout->setSpacing(0); layout->setContentsMargins(0,0,0,0); calendarItem->addWidget(cal); // summary widget QWidget *sum = new QWidget(this); sum->setPalette(pal); sum->setContentsMargins(0,0,0,0); QVBoxLayout *slayout = new QVBoxLayout(sum); slayout->setSpacing(0); summaryItem->addWidget(sum); splitter->addWidget(calendarItem); splitter->addWidget(summaryItem); splitter->prepare(context->athlete->cyclist, "diary"); black.setColor(QPalette::WindowText, Qt::gray); white.setColor(QPalette::WindowText, Qt::white); grey.setColor(QPalette::WindowText, Qt::gray); multiCalendar = new GcMultiCalendar(context); layout->addWidget(multiCalendar); // Summary level selector QHBoxLayout *h = new QHBoxLayout(); h->setSpacing(5); summarySelect = new QComboBox(this); summarySelect->setFixedWidth(150); // is it impossible to size constrain qcombos? summarySelect->addItem(tr("Day Summary")); summarySelect->addItem(tr("Weekly Summary")); summarySelect->addItem(tr("Monthly Summary")); summarySelect->setCurrentIndex(2); // default to monthly h->addStretch(); h->addWidget(summarySelect, Qt::AlignCenter); h->addStretch(); slayout->addLayout(h); summary = new QWebView(this); summary->setContentsMargins(0,0,0,0); summary->page()->view()->setContentsMargins(0,0,0,0); summary->page()->mainFrame()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff); summary->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); summary->setAcceptDrops(false); QFont defaultFont; // mainwindow sets up the defaults.. we need to apply summary->settings()->setFontSize(QWebSettings::DefaultFontSize, defaultFont.pointSize()); summary->settings()->setFontFamily(QWebSettings::StandardFont, defaultFont.family()); slayout->addWidget(summary); slayout->addStretch(); // summary mode changed connect(summarySelect, SIGNAL(currentIndexChanged(int)), this, SLOT(refresh())); // refresh on these events... connect(context, SIGNAL(rideAdded(RideItem*)), this, SLOT(refresh())); connect(context, SIGNAL(rideDeleted(RideItem*)), this, SLOT(refresh())); connect(context, SIGNAL(configChanged()), this, SLOT(refresh())); // set up for current selections refresh(); }
void GcLabel::paintEvent(QPaintEvent *) { static QIcon left = iconFromPNG(":images/mac/left.png"); static QIcon right = iconFromPNG(":images/mac/right.png"); QPainter painter(this); painter.save(); painter.setRenderHints(QPainter::Antialiasing|QPainter::TextAntialiasing, true); // grr. some want a rect others want a rectf QRectF norm(0,0,width(),height()); QRect all(0,0,width(),height()); if (bg) { // setup a painter and the area to paint if (!underMouse()) painter.fillRect(all, bgColor); else { if (filtered) painter.fillRect(all, GColor(CCALCURRENT)); else painter.fillRect(all, Qt::lightGray); } painter.setPen(Qt::gray); painter.drawRect(QRect(0,0,width(),height())); } if (selected) { painter.fillRect(all, GColor(CCALCURRENT)); } if (text() != "<" && text() != ">") { painter.setFont(this->font()); if (xoff || yoff) { // draw text in white behind... QRectF off(xoff,yoff,width(),height()); painter.setPen(QColor(255,255,255,200)); painter.drawText(off, alignment(), text()); } if (filtered && !selected && !underMouse()) painter.setPen(GColor(CCALCURRENT)); else painter.setPen(QColor(0,0,0,170)); painter.drawText(norm, alignment(), text()); if (highlighted) { QColor over = GColor(CCALCURRENT); over.setAlpha(180); painter.setPen(over); painter.drawText(norm, alignment(), text()); } } else { // use standard icons QIcon &icon = text() == "<" ? left : right; Qt::AlignmentFlag alignment = text() == "<" ? Qt::AlignLeft : Qt::AlignRight; icon.paint(&painter, all, alignment|Qt::AlignVCenter); } if (text() != "" && filtered) { QPen pen; pen.setColor(GColor(CCALCURRENT)); pen.setWidth(3); painter.setPen(pen); painter.drawRect(QRect(0,0,width(),height())); } painter.restore(); }
ChartBar::ChartBar(Context *context) : QWidget(context->mainWindow), context(context) { // left / right scroller icon static QIcon leftIcon = iconFromPNG(":images/mac/left.png"); static QIcon rightIcon = iconFromPNG(":images/mac/right.png"); setContentsMargins(0,0,0,0); // main layout QHBoxLayout *mlayout = new QHBoxLayout(this); mlayout->setSpacing(0); mlayout->setContentsMargins(0,0,0,0); // buttonBar Widget buttonBar = new ButtonBar(this); buttonBar->setFixedHeight(23); buttonBar->setContentsMargins(0,0,0,0); QHBoxLayout *vlayout = new QHBoxLayout(buttonBar); vlayout->setSpacing(0); vlayout->setContentsMargins(0,0,0,0); layout = new QHBoxLayout; layout->setSpacing(2); layout->setContentsMargins(0,0,0,0); vlayout->addLayout(layout); vlayout->addStretch(); // scrollarea scrollArea = new QScrollArea(this); scrollArea->setAutoFillBackground(false); scrollArea->setWidgetResizable(true); scrollArea->setFrameStyle(QFrame::NoFrame); scrollArea->setContentsMargins(0,0,0,0); scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); scrollArea->setWidget(buttonBar); // scroll area turns it on .. we turn it off! buttonBar->setAutoFillBackground(false); // scroller buttons left = new QToolButton(this); left->setStyleSheet("QToolButton { border: none; padding: 0px; }"); left->setAutoFillBackground(false); left->setFixedSize(20,20); left->setIcon(leftIcon); left->setIconSize(QSize(20,20)); left->setFocusPolicy(Qt::NoFocus); mlayout->addWidget(left); connect(left, SIGNAL(clicked()), this, SLOT(scrollLeft())); // menu bar in the middle of the buttons mlayout->addWidget(scrollArea); right = new QToolButton(this); right->setStyleSheet("QToolButton { border: none; padding: 0px; }"); right->setAutoFillBackground(false); right->setFixedSize(20,20); right->setIcon(rightIcon); right->setIconSize(QSize(20,20)); right->setFocusPolicy(Qt::NoFocus); mlayout->addWidget(right); connect(right, SIGNAL(clicked()), this, SLOT(scrollRight())); // spacer to make the menuButton on the right QLabel *spacer = new QLabel("", this); spacer->setAutoFillBackground(false); spacer->setFixedHeight(20); spacer->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); mlayout->addWidget(spacer); menuButton = new QToolButton(this); menuButton->setStyleSheet("QToolButton { border: none; padding: 0px; }"); menuButton->setAutoFillBackground(false); menuButton->setFixedSize(20,20); menuButton->setIcon(iconFromPNG(":images/sidebar/extra.png")); menuButton->setIconSize(QSize(10,10)); menuButton->setFocusPolicy(Qt::NoFocus); mlayout->addWidget(menuButton); //connect(p, SIGNAL(clicked()), action, SLOT(trigger())); QFontMetrics fs(buttonFont); #ifdef Q_OS_MAC setFixedHeight(fs.height()+7); scrollArea->setFixedHeight(fs.height()+7); buttonBar->setFixedHeight(fs.height()+7); #else setFixedHeight(fs.height()+4); scrollArea->setFixedHeight(fs.height()+4); buttonBar->setFixedHeight(fs.height()+4); #endif signalMapper = new QSignalMapper(this); // maps each option connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(clicked(int))); barMenu = new QMenu("Add"); chartMenu = barMenu->addMenu(tr("Add Chart")); // menu connect(menuButton, SIGNAL(clicked()), this, SLOT(menuPopup())); connect(chartMenu, SIGNAL(aboutToShow()), this, SLOT(setChartMenu())); connect(chartMenu, SIGNAL(triggered(QAction*)), context->mainWindow, SLOT(addChart(QAction*))); // trap resize / mouse events installEventFilter(this); // appearance update connect(context, SIGNAL(configChanged(qint32)), this, SLOT(configChanged(qint32))); }
MainWindow::MainWindow(const QDir &home) { /*---------------------------------------------------------------------- * Bootstrap *--------------------------------------------------------------------*/ setAttribute(Qt::WA_DeleteOnClose); mainwindows.append(this); // add us to the list of open windows context = new Context(this); context->athlete = new Athlete(context, home); setInstanceName(context->athlete->cyclist); setWindowIcon(QIcon(":images/gc.png")); setWindowTitle(context->athlete->home.dirName()); setContentsMargins(0,0,0,0); setAcceptDrops(true); GCColor *GCColorSet = new GCColor(context); // get/keep colorset GCColorSet->colorSet(); // shut up the compiler #ifdef Q_OS_MAC // get an autorelease pool setup static CocoaInitializer cocoaInitializer; #endif #ifdef GC_HAVE_WFAPI WFApi *w = WFApi::getInstance(); // ensure created on main thread w->apiVersion();//shutup compiler #endif Library::initialise(context->athlete->home); QNetworkProxyQuery npq(QUrl("http://www.google.com")); QList<QNetworkProxy> listOfProxies = QNetworkProxyFactory::systemProxyForQuery(npq); if (listOfProxies.count() > 0) { QNetworkProxy::setApplicationProxy(listOfProxies.first()); } if (desktop == NULL) desktop = QApplication::desktop(); static const QIcon hideIcon(":images/toolbar/main/hideside.png"); static const QIcon rhideIcon(":images/toolbar/main/hiderside.png"); static const QIcon showIcon(":images/toolbar/main/showside.png"); static const QIcon rshowIcon(":images/toolbar/main/showrside.png"); static const QIcon tabIcon(":images/toolbar/main/tab.png"); static const QIcon tileIcon(":images/toolbar/main/tile.png"); static const QIcon fullIcon(":images/toolbar/main/togglefull.png"); #if (defined Q_OS_MAC) && (defined GC_HAVE_LION) fullScreen = new LionFullScreen(context); #endif #ifndef Q_OS_MAC fullScreen = new QTFullScreen(context); #endif // if no workout directory is configured, default to the // top level GoldenCheetah directory if (appsettings->value(NULL, GC_WORKOUTDIR).toString() == "") appsettings->setValue(GC_WORKOUTDIR, QFileInfo(context->athlete->home.absolutePath() + "/../").absolutePath()); /*---------------------------------------------------------------------- * GUI setup *--------------------------------------------------------------------*/ // need to restore geometry before setUnifiedToolBar.. on Mac appsettings->setValue(GC_SETTINGS_LAST, context->athlete->home.dirName()); QVariant geom = appsettings->value(this, GC_SETTINGS_MAIN_GEOM); if (geom == QVariant()) { // first run -- lets set some sensible defaults... // lets put it in the middle of screen 1 QRect size = desktop->availableGeometry(); struct SizeSettings app = GCColor::defaultSizes(size.height(), size.width()); // center on the available screen (minus toolbar/sidebar) move((size.width()-size.x())/2 - app.width/2, (size.height()-size.y())/2 - app.height/2); // set to the right default resize(app.width, app.height); // set all the default font sizes appsettings->setValue(GC_FONT_DEFAULT_SIZE, app.defaultFont); appsettings->setValue(GC_FONT_TITLES_SIZE, app.titleFont); appsettings->setValue(GC_FONT_CHARTMARKERS_SIZE, app.markerFont); appsettings->setValue(GC_FONT_CHARTLABELS_SIZE, app.labelFont); appsettings->setValue(GC_FONT_CALENDAR_SIZE, app.calendarFont); appsettings->setValue(GC_FONT_POPUP_SIZE, app.popupFont); // set the default fontsize QFont font; font.setPointSize(app.defaultFont); QApplication::setFont(font); } else { QRect size = desktop->availableGeometry(); // ensure saved geometry isn't greater than current screen size if ((geom.toRect().height() >= size.height()) || (geom.toRect().width() >= size.width())) setGeometry(size.x()+30,size.y()+30,size.width()-60,size.height()-60); else setGeometry(geom.toRect()); } /*---------------------------------------------------------------------- * Mac Toolbar *--------------------------------------------------------------------*/ #ifdef Q_OS_MAC setUnifiedTitleAndToolBarOnMac(true); head = addToolBar(context->athlete->cyclist); head->setContentsMargins(0,0,0,0); // widgets QWidget *macAnalButtons = new QWidget(this); macAnalButtons->setContentsMargins(0,0,20,0); // lhs buttons QHBoxLayout *lb = new QHBoxLayout(macAnalButtons); lb->setContentsMargins(0,0,0,0); lb->setSpacing(0); import = new QtMacButton(this, QtMacButton::TexturedRounded); QPixmap *importImg = new QPixmap(":images/mac/download.png"); import->setImage(importImg); import->setToolTip("Download"); lb->addWidget(import); lb->addWidget(new Spacer(this)); compose = new QtMacButton(this, QtMacButton::TexturedRounded); QPixmap *composeImg = new QPixmap(":images/mac/compose.png"); compose->setImage(composeImg); compose->setToolTip("Create"); lb->addWidget(compose); // connect to actions connect(import, SIGNAL(clicked(bool)), this, SLOT(downloadRide())); connect(compose, SIGNAL(clicked(bool)), this, SLOT(manualRide())); lb->addWidget(new Spacer(this)); // activity actions .. peaks, split, delete QWidget *acts = new QWidget(this); acts->setContentsMargins(0,0,0,0); QHBoxLayout *pp = new QHBoxLayout(acts); pp->setContentsMargins(0,0,0,0); pp->setContentsMargins(0,0,0,0); pp->setSpacing(5); sidebar = new QtMacButton(this, QtMacButton::TexturedRounded); QPixmap *sidebarImg = new QPixmap(":images/mac/sidebar.png"); sidebar->setImage(sidebarImg); sidebar->setMinimumSize(25, 25); sidebar->setMaximumSize(25, 25); sidebar->setToolTip("Sidebar"); sidebar->setSelected(true); // assume always start up with sidebar selected actbuttons = new QtMacSegmentedButton(3, acts); actbuttons->setWidth(115); actbuttons->setNoSelect(); actbuttons->setImage(0, new QPixmap(":images/mac/stop.png")); actbuttons->setImage(1, new QPixmap(":images/mac/split.png")); actbuttons->setImage(2, new QPixmap(":images/mac/trash.png")); pp->addWidget(actbuttons); lb->addWidget(acts); lb->addStretch(); connect(actbuttons, SIGNAL(clicked(int,bool)), this, SLOT(actionClicked(int))); lb->addWidget(new Spacer(this)); QWidget *viewsel = new QWidget(this); viewsel->setContentsMargins(0,0,0,0); QHBoxLayout *pq = new QHBoxLayout(viewsel); pq->setContentsMargins(0,0,0,0); pq->setSpacing(5); pq->addWidget(sidebar); styleSelector = new QtMacSegmentedButton(2, viewsel); styleSelector->setWidth(80); // actually its 80 but we want a 30px space between is and the searchbox styleSelector->setImage(0, new QPixmap(":images/mac/tabbed.png"), 24); styleSelector->setImage(1, new QPixmap(":images/mac/tiled.png"), 24); pq->addWidget(styleSelector); connect(sidebar, SIGNAL(clicked(bool)), this, SLOT(toggleSidebar())); connect(styleSelector, SIGNAL(clicked(int,bool)), this, SLOT(toggleStyle())); // setup Mac thetoolbar head->addWidget(macAnalButtons); head->addWidget(new Spacer(this)); head->addWidget(new Spacer(this)); head->addWidget(viewsel); #ifdef GC_HAVE_LUCENE SearchFilterBox *searchBox = new SearchFilterBox(this,context,false); QCleanlooksStyle *toolStyle = new QCleanlooksStyle(); searchBox->setStyle(toolStyle); searchBox->setFixedWidth(200); head->addWidget(searchBox); connect(searchBox, SIGNAL(searchResults(QStringList)), this, SLOT(setFilter(QStringList))); connect(searchBox, SIGNAL(searchClear()), this, SLOT(clearFilter())); #endif #endif /*---------------------------------------------------------------------- * Windows and Linux Toolbar *--------------------------------------------------------------------*/ #ifndef Q_OS_MAC head = new GcToolBar(this); QCleanlooksStyle *toolStyle = new QCleanlooksStyle(); QPalette metal; metal.setColor(QPalette::Button, QColor(215,215,215)); // get those icons importIcon = iconFromPNG(":images/mac/download.png"); composeIcon = iconFromPNG(":images/mac/compose.png"); intervalIcon = iconFromPNG(":images/mac/stop.png"); splitIcon = iconFromPNG(":images/mac/split.png"); deleteIcon = iconFromPNG(":images/mac/trash.png"); sidebarIcon = iconFromPNG(":images/mac/sidebar.png"); tabbedIcon = iconFromPNG(":images/mac/tabbed.png"); tiledIcon = iconFromPNG(":images/mac/tiled.png"); QSize isize(19,19); Spacer *spacerl = new Spacer(this); spacerl->setFixedWidth(5); import = new QPushButton(this); import->setIcon(importIcon); import->setIconSize(isize); import->setFixedHeight(25); import->setStyle(toolStyle); import->setToolTip(tr("Download from Device")); import->setPalette(metal); connect(import, SIGNAL(clicked(bool)), this, SLOT(downloadRide())); compose = new QPushButton(this); compose->setIcon(composeIcon); compose->setIconSize(isize); compose->setFixedHeight(25); compose->setStyle(toolStyle); compose->setToolTip(tr("Create Manual Activity")); compose->setPalette(metal); connect(compose, SIGNAL(clicked(bool)), this, SLOT(manualRide())); sidebar = new QPushButton(this); sidebar->setIcon(sidebarIcon); sidebar->setIconSize(isize); sidebar->setFixedHeight(25); sidebar->setStyle(toolStyle); sidebar->setToolTip(tr("Toggle Sidebar")); sidebar->setPalette(metal); connect(sidebar, SIGNAL(clicked(bool)), this, SLOT(toggleSidebar())); actbuttons = new QtSegmentControl(this); actbuttons->setStyle(toolStyle); actbuttons->setIconSize(isize); actbuttons->setCount(3); actbuttons->setSegmentIcon(0, intervalIcon); actbuttons->setSegmentIcon(1, splitIcon); actbuttons->setSegmentIcon(2, deleteIcon); actbuttons->setSelectionBehavior(QtSegmentControl::SelectNone); //wince. spelling. ugh actbuttons->setFixedHeight(25); actbuttons->setSegmentToolTip(0, tr("Find Intervals...")); actbuttons->setSegmentToolTip(1, tr("Split Activity...")); actbuttons->setSegmentToolTip(2, tr("Delete Activity")); actbuttons->setPalette(metal); connect(actbuttons, SIGNAL(segmentSelected(int)), this, SLOT(actionClicked(int))); styleSelector = new QtSegmentControl(this); styleSelector->setStyle(toolStyle); styleSelector->setIconSize(isize); styleSelector->setCount(2); styleSelector->setSegmentIcon(0, tabbedIcon); styleSelector->setSegmentIcon(1, tiledIcon); styleSelector->setSegmentToolTip(0, tr("Tabbed View")); styleSelector->setSegmentToolTip(1, tr("Tiled View")); styleSelector->setSelectionBehavior(QtSegmentControl::SelectOne); //wince. spelling. ugh styleSelector->setFixedHeight(25); styleSelector->setPalette(metal); connect(styleSelector, SIGNAL(segmentSelected(int)), this, SLOT(setStyleFromSegment(int))); //avoid toggle infinitely head->addWidget(spacerl); head->addWidget(import); head->addWidget(compose); head->addWidget(actbuttons); head->addStretch(); head->addWidget(sidebar); head->addWidget(styleSelector); #ifdef GC_HAVE_LUCENE // add a search box on far right, but with a little space too SearchFilterBox *searchBox = new SearchFilterBox(this,context,false); searchBox->setStyle(toolStyle); searchBox->setFixedWidth(200); head->addWidget(searchBox); connect(searchBox, SIGNAL(searchResults(QStringList)), this, SLOT(setFilter(QStringList))); connect(searchBox, SIGNAL(searchClear()), this, SLOT(clearFilter())); #endif Spacer *spacer = new Spacer(this); spacer->setFixedWidth(5); head->addWidget(spacer); #endif /*---------------------------------------------------------------------- * ScopeBar *--------------------------------------------------------------------*/ scopebar = new GcScopeBar(context); connect(scopebar, SIGNAL(selectDiary()), this, SLOT(selectDiary())); connect(scopebar, SIGNAL(selectHome()), this, SLOT(selectHome())); connect(scopebar, SIGNAL(selectAnal()), this, SLOT(selectAnalysis())); connect(scopebar, SIGNAL(selectTrain()), this, SLOT(selectTrain())); // Add chart is on the scope bar chartMenu = new QMenu(this); QCleanlooksStyle *styler = new QCleanlooksStyle(); QPushButton *newchart = new QPushButton("+", this); scopebar->addWidget(newchart); newchart->setStyle(styler); newchart->setFixedHeight(20); newchart->setFixedWidth(24); newchart->setFlat(true); newchart->setFocusPolicy(Qt::NoFocus); newchart->setToolTip(tr("Add Chart")); newchart->setAutoFillBackground(false); newchart->setAutoDefault(false); newchart->setMenu(chartMenu); connect(chartMenu, SIGNAL(aboutToShow()), this, SLOT(setChartMenu())); connect(chartMenu, SIGNAL(triggered(QAction*)), this, SLOT(addChart(QAction*))); /*---------------------------------------------------------------------- * Central Widget *--------------------------------------------------------------------*/ tab = new Tab(context); /*---------------------------------------------------------------------- * Central Widget *--------------------------------------------------------------------*/ QWidget *central = new QWidget(this); setContentsMargins(0,0,0,0); central->setContentsMargins(0,0,0,0); QVBoxLayout *mainLayout = new QVBoxLayout(central); mainLayout->setSpacing(0); mainLayout->setContentsMargins(0,0,0,0); #ifndef Q_OS_MAC // nonmac toolbar on main view -- its not // unified with the title bar. mainLayout->addWidget(head); #endif mainLayout->addWidget(scopebar); mainLayout->addWidget(tab); setCentralWidget(central); /*---------------------------------------------------------------------- * Application Menus *--------------------------------------------------------------------*/ #ifdef WIN32 menuBar()->setStyleSheet("QMenuBar { background: rgba(225,225,225); }" "QMenuBar::item { background: rgba(225,225,225); }"); menuBar()->setContentsMargins(0,0,0,0); #endif QMenu *fileMenu = menuBar()->addMenu(tr("&Athlete")); fileMenu->addAction(tr("&New..."), this, SLOT(newCyclist()), tr("Ctrl+N")); fileMenu->addAction(tr("&Open..."), this, SLOT(openCyclist()), tr("Ctrl+O")); fileMenu->addAction(tr("&Close Window"), this, SLOT(close()), tr ("Ctrl+W")); fileMenu->addAction(tr("&Quit All Windows"), this, SLOT(closeAll()), tr("Ctrl+Q")); QMenu *rideMenu = menuBar()->addMenu(tr("A&ctivity")); rideMenu->addAction(tr("&Download from device..."), this, SLOT(downloadRide()), tr("Ctrl+D")); rideMenu->addAction(tr("&Import from file..."), this, SLOT (importFile()), tr ("Ctrl+I")); rideMenu->addAction(tr("&Manual activity entry..."), this, SLOT(manualRide()), tr("Ctrl+M")); rideMenu->addSeparator (); rideMenu->addAction(tr("&Export..."), this, SLOT(exportRide()), tr("Ctrl+E")); rideMenu->addAction(tr("&Batch export..."), this, SLOT(exportBatch()), tr("Ctrl+B")); rideMenu->addAction(tr("Export Metrics as CSV..."), this, SLOT(exportMetrics()), tr("")); #ifdef GC_HAVE_SOAP rideMenu->addSeparator (); rideMenu->addAction(tr("&Upload to TrainingPeaks"), this, SLOT(uploadTP()), tr("Ctrl+U")); rideMenu->addAction(tr("Down&load from TrainingPeaks..."), this, SLOT(downloadTP()), tr("Ctrl+L")); #endif #ifdef GC_HAVE_LIBOAUTH tweetAction = new QAction(tr("Tweet Activity"), this); connect(tweetAction, SIGNAL(triggered(bool)), this, SLOT(tweetRide())); rideMenu->addAction(tweetAction); shareAction = new QAction(tr("Share (Strava, RideWithGPS, CyclingAnalytics)..."), this); connect(shareAction, SIGNAL(triggered(bool)), this, SLOT(share())); rideMenu->addAction(shareAction); #endif ttbAction = new QAction(tr("Upload to Trainingstagebuch..."), this); connect(ttbAction, SIGNAL(triggered(bool)), this, SLOT(uploadTtb())); rideMenu->addAction(ttbAction); rideMenu->addSeparator (); rideMenu->addAction(tr("&Save activity"), this, SLOT(saveRide()), tr("Ctrl+S")); rideMenu->addAction(tr("D&elete activity..."), this, SLOT(deleteRide())); rideMenu->addAction(tr("Split &activity..."), this, SLOT(splitRide())); rideMenu->addAction(tr("Merge activities..."), this, SLOT(mergeRide())); rideMenu->addSeparator (); QMenu *optionsMenu = menuBar()->addMenu(tr("&Tools")); optionsMenu->addAction(tr("&Options..."), this, SLOT(showOptions())); optionsMenu->addAction(tr("Critical Power Estimator..."), this, SLOT(showTools())); optionsMenu->addAction(tr("Air Density (Rho) Estimator..."), this, SLOT(showRhoEstimator())); optionsMenu->addSeparator(); optionsMenu->addAction(tr("Get &Withings Data..."), this, SLOT (downloadMeasures())); optionsMenu->addAction(tr("Get &Zeo Data..."), this, SLOT (downloadMeasuresFromZeo())); optionsMenu->addSeparator(); optionsMenu->addAction(tr("Create a new workout..."), this, SLOT(showWorkoutWizard())); optionsMenu->addAction(tr("Download workouts from ErgDB..."), this, SLOT(downloadErgDB())); optionsMenu->addAction(tr("Import workouts or videos..."), this, SLOT(importWorkout())); optionsMenu->addAction(tr("Scan disk for videos and workouts..."), this, SLOT(manageLibrary())); #ifdef GC_HAVE_ICAL optionsMenu->addSeparator(); optionsMenu->addAction(tr("Upload Activity to Calendar"), this, SLOT(uploadCalendar()), tr ("")); //optionsMenu->addAction(tr("Import Calendar..."), this, SLOT(importCalendar()), tr ("")); // planned for v3.1 //optionsMenu->addAction(tr("Export Calendar..."), this, SLOT(exportCalendar()), tr ("")); // planned for v3.1 optionsMenu->addAction(tr("Refresh Calendar"), this, SLOT(refreshCalendar()), tr ("")); #endif optionsMenu->addSeparator(); optionsMenu->addAction(tr("Find intervals..."), this, SLOT(addIntervals()), tr ("")); // Add all the data processors to the tools menu const DataProcessorFactory &factory = DataProcessorFactory::instance(); QMap<QString, DataProcessor*> processors = factory.getProcessors(); if (processors.count()) { optionsMenu->addSeparator(); toolMapper = new QSignalMapper(this); // maps each option QMapIterator<QString, DataProcessor*> i(processors); connect(toolMapper, SIGNAL(mapped(const QString &)), this, SLOT(manualProcess(const QString &))); i.toFront(); while (i.hasNext()) { i.next(); // The localized processor name is shown in menu QAction *action = new QAction(QString("%1...").arg(i.value()->name()), this); optionsMenu->addAction(action); connect(action, SIGNAL(triggered()), toolMapper, SLOT(map())); toolMapper->setMapping(action, i.key()); } }
GcOverlayWidget::GcOverlayWidget(Context *context, QWidget *parent) : QWidget(parent), context(context) { // left / right scroller icon static QIcon leftIcon = iconFromPNG(":images/mac/left.png"); static QIcon rightIcon = iconFromPNG(":images/mac/right.png"); setContentsMargins(4,0,4,4); setAutoFillBackground(false); setAttribute(Qt::WA_TranslucentBackground); setMouseTracking(true); setFocusPolicy(Qt::ClickFocus); setMinimumSize(250,200); setFocus(); mode = none; initial = true; // main layout QVBoxLayout *mlayout = new QVBoxLayout(this); mlayout->setSpacing(0); mlayout->setContentsMargins(1,0,1,1); QHBoxLayout *titleLayout = new QHBoxLayout; titleLayout->setSpacing(0); titleLayout->setContentsMargins(0,0,0,0); mlayout->addLayout(titleLayout); // scroller buttons left = new QToolButton(this); left->setStyleSheet("QToolButton { border: none; padding: 0px; }"); left->setAutoFillBackground(false); left->setFixedSize(23,23); left->setIcon(leftIcon); left->setIconSize(QSize(23,23)); left->setFocusPolicy(Qt::NoFocus); left->hide(); // don't show until we have >1 widgets titleLayout->addWidget(left); connect(left, SIGNAL(clicked()), this, SLOT(scrollLeft())); titleLabel = new GcLabel("No Title Set"); titleLabel->setAutoFillBackground(false); titleLabel->setFixedHeight(23); // menu bar in the middle of the buttons titleLayout->addStretch(); titleLayout->addWidget(titleLabel); titleLayout->addStretch(); right = new QToolButton(this); right->setStyleSheet("QToolButton { border: none; padding: 0px; }"); right->setAutoFillBackground(false); right->setFixedSize(20,20); right->setIcon(rightIcon); right->setIconSize(QSize(20,20)); right->setFocusPolicy(Qt::NoFocus); right->hide(); titleLayout->addWidget(right); connect(right, SIGNAL(clicked()), this, SLOT(scrollRight())); stack = new QStackedWidget(this); stack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); mlayout->addWidget(stack); // trap resize / mouse events m_infocus = true; m_showMenu = false; m_isEditing = true; installEventFilter(parent); connect(context, SIGNAL(configChanged()), this, SLOT(configChanged())); // setup colors configChanged(); }