diff --git a/src/Charts/OverviewItems.cpp b/src/Charts/OverviewItems.cpp index 1dcfbdd5c..86876b4b7 100644 --- a/src/Charts/OverviewItems.cpp +++ b/src/Charts/OverviewItems.cpp @@ -141,6 +141,8 @@ DataOverviewItem::DataOverviewItem(ChartSpace *parent, QString name, QString pro this->program = program; click = false; + lastsort = sortcolumn = -1; + lastorder = Qt::AscendingOrder; clickthru = NULL; configwidget = new OverviewItemConfig(this); @@ -1011,6 +1013,82 @@ DataOverviewItem::postProcess() } } +void +DataOverviewItem::sort(int column, Qt::SortOrder order) +{ + if (column >= names.count()) return; // out of bounds + + // step 1: infer the type for column + int isdate=0, istime=0, isnumber=0, isstring=0; + + int rows = values.count() / names.count(); + + QRegExp redate("^[0-9][0-9] [A-z][A-z][A-z] [0-9][0-9]*$"); + QRegExp retime("^[0-9:]*$"); + QRegExp renumber("^[0-9.]*$"); + + for(int i= rows * column; i argsortindex; + if (isstring) { + + QVector in; + for(int i= rows * column; i in; + for(int i= rows * column; i ordered = values; + for(int i=0; icontext->notifyRideSelected(clickthru); clickthru = NULL; } + + if (sortcolumn != -1) { + // sort !! + click=false; + if (lastsort == sortcolumn) sort(sortcolumn, lastorder == Qt::DescendingOrder ? Qt::AscendingOrder : Qt::DescendingOrder); + else sort(sortcolumn, Qt::DescendingOrder); + update(); + } + event->accept(); return true; @@ -2477,20 +2565,53 @@ DataOverviewItem::itemPaint(QPainter *painter, const QStyleOptionGraphicsItem *, // paint nothing if no values - or a mismatch if (values.count() < names.count()) return; + // step 1: calculate paint metrics, colors, fonts, margins etc etc ... + // we use the mid font, so lets get some font metrics QFontMetrics fm(multirow ? parent->smallfont : parent->midfont, parent->device()); double lineheight = fm.boundingRect("XXX").height() * 1.2f; + // default horizontal spacing, no flex here, is what it is + double hmargin=ROWHEIGHT; + // our bounding rectangle QRectF paintarea = QRectF(20,ROWHEIGHT*2, geometry().width()-40, geometry().height()-20-(ROWHEIGHT*2)); + // rows of data with column headings- will make paged and interactive in v3.7 + // + // layout like this: |hvvvsvvvsvvvsvvvsvvvh| + // where: + // h is hmargin + // vvv is metric value + // s is hspace + // + double content = 0; + foreach(double width, columnWidths) content += width; + double hspace = geometry().width() - (content + hmargin + hmargin); + hspace = (hspace > 0) ? hspace / (columnWidths.count()-1) : hmargin; // minimum space + + // fonts and colors for data + QFont normal = multirow ? parent->smallfont : parent->midfont; + QFont bold = normal; + bold.setBold(true); + + // normal just grey, we highlight with plot marker + QColor cnormal = (GCColor::luminance(GColor(CCARDBACKGROUND)) < 127) ? QColor(200,200,200) : QColor(70,70,70); + + + // step 2: where is the mouse hovering, paint a background etc .... + int hoverrow = -1; // remember if the mouse is over a particular row. - // paint the hover background - if (underMouse()) { + // paint the hover background, only matters when have multiple rows + if (multirow && underMouse()) { + QRectF dataarea = paintarea; dataarea.setY(dataarea.y() + (lineheight*2) + (lineheight*0.25f)); // 0.2 is the line spacing + QRectF headingarea = paintarea; + headingarea.setHeight(lineheight*2); + // single row just highlight the first data point if (!multirow) dataarea.setY(dataarea.y() - (lineheight*2)); @@ -2503,7 +2624,39 @@ DataOverviewItem::itemPaint(QPainter *painter, const QStyleOptionGraphicsItem *, int row = (cpos.y()-dataarea.topLeft().y())/lineheight; QRectF itemarea(dataarea.left(), dataarea.top()+(row*lineheight), dataarea.width(), lineheight); - if (itemarea.contains(cpos)) { + // in header or data area? + if (headingarea.contains(cpos)) { + + // column number and rectangle + int column = -1, cn=0; + double xoffset = 0; + QRectF crect; + foreach(double width, columnWidths) { + + // bound for column cn heading + QRectF prect = QRectF(headingarea.x()+xoffset, headingarea.y(), width+hspace, lineheight*2.25f); + if (prect.contains(cpos)) { + column = cn; + crect=prect; + } + + // and on to the next column + cn++; + xoffset += width + hspace; + } + + // lets paint the hover background for the column + if (column != -1) { + painter->setPen(Qt::NoPen); + QColor darkgray(120,120,120,120); + painter->setBrush(darkgray); + painter->drawRect(crect); + + if (click) sortcolumn = column; + } + + } else if (itemarea.contains(cpos)) { + if (files.count() && row < files.count()) { painter->setPen(Qt::NoPen); QColor darkgray(120,120,120,120); @@ -2521,41 +2674,38 @@ DataOverviewItem::itemPaint(QPainter *painter, const QStyleOptionGraphicsItem *, } } - // default horizontal spacing, no flex here, is what it is - double hmargin=ROWHEIGHT; - - // fonts and colors for data - QFont normal = multirow ? parent->smallfont : parent->midfont; - QFont bold = normal; - bold.setBold(true); + // step 3: paint the table from here .... painter->setFont(normal); - - // normal just grey, we highlight with plot marker - QColor cnormal = (GCColor::luminance(GColor(CCARDBACKGROUND)) < 127) ? QColor(200,200,200) : QColor(70,70,70); - painter->setPen(cnormal); + painter->setRenderHint(QPainter::Antialiasing); + painter->setPen(QPen(cnormal, 4, Qt::SolidLine, Qt::RoundCap)); if (multirow) { - - // rows of data with column headings- will make paged and interactive in v3.7 - // - // layout like this: |hvvvsvvvsvvvsvvvsvvvh| - // where: - // h is hmargin - // vvv is metric value - // s is hspace - // - double content = 0; - foreach(double width, columnWidths) content += width; - double hspace = geometry().width() - (content + hmargin + hmargin); - hspace = (hspace > 0) ? hspace / (columnWidths.count()-1) : hmargin; // minimum space - // heading row double xoffset = hmargin; double yoffset = paintarea.topLeft().y()+lineheight; for(int i=0; idrawText(xoffset, yoffset, names[i]); // todo: centering + + // if we are the sort column we need an indicator + if (lastsort == i) { + + QFontMetrics fm(normal); + QRectF tb = fm.boundingRect(names[i]); + QRectF cb = fm.boundingRect("X"); + + double direction = lastorder == Qt::AscendingOrder ? +1 : -1; + + // tick + QPointF start(xoffset+tb.width()+(cb.width()*1.8), yoffset-(cb.height()/5)); + painter->drawLine(start, start-QPointF(cb.width()/2, direction * cb.height()/5)); + painter->drawLine(start-QPointF(cb.width()/2, direction * cb.height()/5), start-QPointF(cb.width(), 0)); + + //painter->setPen(cnormal); + } xoffset += columnWidths[i] + hspace; } yoffset += lineheight; diff --git a/src/Charts/OverviewItems.h b/src/Charts/OverviewItems.h index 47208129d..7942a90ed 100644 --- a/src/Charts/OverviewItems.h +++ b/src/Charts/OverviewItems.h @@ -156,6 +156,9 @@ class DataOverviewItem : public ChartSpaceItem // the look and feel of the old ride summary static QString getLegacyProgram(int, DataFilterRuntime &); + // sort the datatable + void sort(int column, Qt::SortOrder order); + // settings QString program; Leaf *fnames, *funits, *fvalues, *ffiles; @@ -170,6 +173,10 @@ class DataOverviewItem : public ChartSpaceItem bool click; // for clickthru RideItem *clickthru; + int sortcolumn; // for sorting a column + + int lastsort; // the column we last sorted on + Qt::SortOrder lastorder; // the order we last sorted on }; class RPEOverviewItem : public ChartSpaceItem