From 5e4944660790c6837b13b5beabfd55d4942599d2 Mon Sep 17 00:00:00 2001 From: peri4 Date: Thu, 24 Nov 2022 15:26:38 +0300 Subject: [PATCH] version 2.9.0 Graphic DateTime axis release --- CMakeLists.txt | 4 +- libs/graphic/graphic.cpp | 139 ++++++++++++++++------------ libs/graphic/graphic.h | 26 ++++-- libs/graphic/lang/qad_graphic_en.ts | 90 ++++++++++++------ libs/graphic/lang/qad_graphic_ru.ts | 90 ++++++++++++------ 5 files changed, 218 insertions(+), 131 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 731a374..cf255af 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,8 +3,8 @@ cmake_policy(SET CMP0017 NEW) # need include() with .cmake cmake_policy(SET CMP0072 NEW) # FindOpenGL prefers GLVND by default project(QAD) set(QAD_MAJOR 2) -set(QAD_MINOR 8) -set(QAD_REVISION 4) +set(QAD_MINOR 9) +set(QAD_REVISION 0) set(QAD_SUFFIX ) set(QAD_COMPANY SHS) set(QAD_DOMAIN org.SHS) diff --git a/libs/graphic/graphic.cpp b/libs/graphic/graphic.cpp index 52075e4..f10b848 100644 --- a/libs/graphic/graphic.cpp +++ b/libs/graphic/graphic.cpp @@ -30,6 +30,17 @@ # endif #endif +enum DateComponent { + DateMSecs, + DateSecs, + DateMinutes, + DateHours, + DateDays, + DateMonths, + DateYears, + DateComponentCount +}; + const char _button_prop_name_[] = "_button_"; const double rad2deg_qpie = 45. / atan(1.); @@ -80,6 +91,7 @@ Graphic::Graphic(QWidget * parent): QFrame(parent), canvas(0), line_x_min(this), ui->setupUi(this); ui->scrollLegend->layout()->addWidget(new LegendScrollArea(ui->widgetLegend)); ui->scrollLegend->hide(); + fillDateFormats(); #ifdef NO_BUTTONS ui->widgetLeft->hide(); ui->widgetRight->hide(); @@ -211,6 +223,7 @@ void Graphic::changeEvent(QEvent * e) { QFrame::changeEvent(e); if (e->type() == QEvent::LanguageChange) { ui->retranslateUi(this); + fillDateFormats(); return; } } @@ -1285,12 +1298,13 @@ void Graphic::drawGrid() { painter->drawLine(cx, hei + 5, cx, 0); } } else { - int dt_add[7] = {0,0,0,0,0,0,0}; - int dt_add_lo[7] = {0,0,0,0,0,0,0}; - const char * formats[3]; + int dt_add[DateComponentCount]; + int dt_add_lo[DateComponentCount]; + for (int i = 0; i < DateComponentCount; ++i) dt_add_lo[i] = dt_add[i] = 0; + DateFormats formats; step = splitRangeDate(range, wid / gridx / font_sz.width() / 1.5, formats, dt_add); - for (int i = 0; i < 6; ++i) dt_add_lo[i + 1] = dt_add[i]; - bool is_years = QString(formats[1]).isEmpty(); + for (int i = 0; i < DateComponentCount - 1; ++i) dt_add_lo[i + 1] = dt_add[i]; + bool is_years = formats.center.isEmpty(); if (step > 0.) { int up_y = cy - font_sz.height() * 2; int ce_y = cy - font_sz.height(); @@ -1310,7 +1324,7 @@ void Graphic::drawGrid() { } //qDebug() << cd << cur_scl[0] << cur_scl[1] << cur_scl[2] << cur_scl[3] << cur_scl[4] << cur_scl[5] << cur_scl[6]; struct Anchor { - int pix_x[2]; + int x_start, x_end; QDateTime date; }; QVector areas_ce, areas_lo; @@ -1329,15 +1343,15 @@ void Graphic::drawGrid() { int cxc = real2canvasX(cdc.toMSecsSinceEpoch() / grid_numbers_x); //qDebug() << cx << cxc << ddx << pcx; if ((qAbs(cxc - cx) < ddx) && (cx != cxc)) need_text = false; - areas_ce << Anchor{{area_start, qMin(cxc, right)}, cdp}; - area_start = areas_ce.back().pix_x[1]; + areas_ce << Anchor{area_start, qMin(cxc, right), cdp}; + area_start = areas_ce.back().x_end; cd = cdl = cdp = cdc; cx = cxc; roundDateTime(cdl, dt_add_lo); if (cdlp != cdl) { - areas_lo << Anchor{{area_start_lo, qMin(cxc, right)}, cdlp}; + areas_lo << Anchor{area_start_lo, qMin(cxc, right), cdlp}; cdlp = cdl; - area_start_lo = areas_lo.back().pix_x[1]; + area_start_lo = areas_lo.back().x_end; } } else { ddx = (cx - pcx) * 0.95; @@ -1354,35 +1368,35 @@ void Graphic::drawGrid() { painter->setPen(text_color); int dx = -font_sz.height() / 4.; painter->setFont(nf); - painter->drawText(cx + dx, up_y, cd.toString(formats[0])); + painter->drawText(cx + dx, up_y, cd.toString(formats.upper)); } } if (!is_years) { if (area_start < right) - areas_ce << Anchor{{area_start, right}, cdc}; + areas_ce << Anchor{area_start, right, cdc}; if (area_start_lo < right) - areas_lo << Anchor{{area_start_lo, right}, cdl}; - //qDebug() << areas_lo.size() << formats[2] << areas_lo[0].date; + areas_lo << Anchor{area_start_lo, right, cdl}; + //qDebug() << areas_lo.size() << formats.upper << areas_lo[0].date; painter->setPen(grid_pen); for (const auto & a: areas_ce) { - painter->drawLine(a.pix_x[0], hei + 5, a.pix_x[0], ce_y); + painter->drawLine(a.x_start, hei + 5, a.x_start, ce_y); } for (const auto & a: areas_lo) { - painter->drawLine(a.pix_x[0], ce_y, a.pix_x[0], lo_y); + painter->drawLine(a.x_start, ce_y, a.x_start, lo_y); } painter->setPen(text_color); painter->setFont(nf); auto pfm = painter->fontMetrics(); for (const auto & a: areas_ce) { - ds = a.date.toString(formats[1]); + ds = a.date.toString(formats.center); auto str_rect = pfm.boundingRect(ds); - painter->drawText(a.pix_x[0] + (a.pix_x[1] - a.pix_x[0] - str_rect.width()) / 2, ce_y, ds); + painter->drawText(a.x_start + (a.x_end - a.x_start - str_rect.width()) / 2, ce_y, ds); } for (const auto & a: areas_lo) { - ds = a.date.toString(formats[2]); + ds = a.date.toString(formats.lower); auto str_rect = pfm.boundingRect(ds); - painter->drawText(a.pix_x[0] + (a.pix_x[1] - a.pix_x[0] - str_rect.width()) / 2, lo_y, ds); + painter->drawText(a.x_start + (a.x_end - a.x_start - str_rect.width()) / 2, lo_y, ds); } } } @@ -1420,6 +1434,26 @@ QPair Graphic::gridMark(double v) const { } +void Graphic::fillDateFormats() { + date_formats.clear(); + QString tr_ms = tr("ms"), tr_s = tr("s"), tr_m = tr("m"), tr_h = tr("h"); + auto trFunc = [&](const DateFormats & src)->DateFormats{ + DateFormats ret; + ret.upper = QString(src.upper ).replace("%1", tr_ms).replace("%2", tr_s).replace("%3", tr_m).replace("%4", tr_h); + ret.center = QString(src.center).replace("%1", tr_ms).replace("%2", tr_s).replace("%3", tr_m).replace("%4", tr_h); + ret.lower = QString(src.lower ).replace("%1", tr_ms).replace("%2", tr_s).replace("%3", tr_m).replace("%4", tr_h); + return ret; + }; + date_formats << trFunc(DateFormats{"zzz '%1'", "h '%4' mm '%3' ss '%2'", "yyyy MMM dd(ddd)"}); + date_formats << trFunc(DateFormats{"ss '%2'" , "h '%4' mm '%3'" , "yyyy MMM dd(ddd)"}); + date_formats << trFunc(DateFormats{"mm '%3'" , "h '%4'" , "yyyy MMM dd(ddd)"}); + date_formats << trFunc(DateFormats{"h '%4'" , "dd(ddd)" , "yyyy MMM" }); + date_formats << trFunc(DateFormats{"dd(ddd)" , "MMM" , "yyyy" }); + date_formats << trFunc(DateFormats{"MMM" , "yyyy" , "" }); + date_formats << trFunc(DateFormats{"yyyy" , "" , "" }); +} + + void Graphic::drawGraphics() { if (isHover) ui->status->setText(tr("Cursor: ") + pointCoords(canvas2real(QPointF(curpos)))); @@ -1698,7 +1732,7 @@ double Graphic::splitRange(double range, int count) { } -double Graphic::splitRangeDate(double range, int count, const char ** formats, int step[7]) { +double Graphic::splitRangeDate(double range, int count, DateFormats & formats, int step[7]) { static const qint64 to_sec = 1000LL, to_min = 1000LL * 60, @@ -1706,31 +1740,16 @@ double Graphic::splitRangeDate(double range, int count, const char ** formats, i to_day = 1000LL * 60 * 60 * 24, to_month = 1000LL * 60 * 60 * 24 * 30, to_year = 1000LL * 60 * 60 * 24 * 30 * 12; - static const struct { - const char * upper; - const char * center; - const char * lower; - } date_formats[] = { - {"ss.zzz 's'", "h 'h' mm 'm'", "yyyy MMM dd(ddd)"}, - {"ss 's'" , "h 'h' mm 'm'", "yyyy MMM dd(ddd)"}, - {"mm 'm'" , "h 'h'" , "yyyy MMM dd(ddd)"}, - {"h 'h'" , "dd(ddd)" , "yyyy MMM"}, - {"dd(ddd)" , "MMM" , "yyyy"}, - {"MMM" , "yyyy" , ""}, - {"yyyy" , "" , ""} - }; double ret = splitRange(range, count); - int format_index = 6; - if (ret < to_sec / 2 ) {format_index = 0; step[0] = qRound64(ret);} - else if (ret < to_min / 2 ) {format_index = 1; step[1] = roundToNearest(ret / to_sec , {1, 2, 5, 10, 15, 20, 30});} - else if (ret < to_hour ) {format_index = 2; step[2] = roundToNearest(ret / to_min , {1, 2, 5, 10, 15, 20, 30});} - else if (ret < to_day ) {format_index = 3; step[3] = roundToNearest(ret / to_hour , {1, 2, 3, 4, 6, 8, 12});} - else if (ret < to_month / 1.6) {format_index = 4; step[4] = roundToNearest(ret / to_day , {1, 2, 5, 10});} - else if (ret < to_year ) {format_index = 5; step[5] = roundToNearest(ret / to_month, {1, 2, 3, 4, 6});} - else {format_index = 6; step[6] = qRound64(ret / to_year);} - formats[0] = date_formats[format_index].upper; - formats[1] = date_formats[format_index].center; - formats[2] = date_formats[format_index].lower; + int format_index = DateYears; + if (ret < to_sec / 1 ) {format_index = DateMSecs ; step[DateMSecs ] = qRound64(ret);} + else if (ret < to_min / 2 ) {format_index = DateSecs ; step[DateSecs ] = roundToNearest(ret / to_sec , {1, 2, 5, 10, 15, 20, 30});} + else if (ret < to_hour ) {format_index = DateMinutes; step[DateMinutes] = roundToNearest(ret / to_min , {1, 2, 5, 10, 15, 20, 30});} + else if (ret < to_day ) {format_index = DateHours ; step[DateHours ] = roundToNearest(ret / to_hour , {1, 2, 3, 4, 6, 8, 12});} + else if (ret < to_month / 1.6) {format_index = DateDays ; step[DateDays ] = roundToNearest(ret / to_day , {1, 2, 5, 10});} + else if (ret < to_year ) {format_index = DateMonths ; step[DateMonths ] = roundToNearest(ret / to_month, {1, 2, 3, 4, 6});} + else {format_index = DateYears ; step[DateYears ] = qRound64(ret / to_year);} + formats = date_formats[format_index]; return ret; } @@ -1741,26 +1760,26 @@ double Graphic::roundTo(double value, double round_to) { } -void Graphic::roundDateTime(QDateTime & dt, int c[7]) { +void Graphic::roundDateTime(QDateTime & dt, int * c) { QDate d(dt.date()); QTime t(dt.time()); - if (c[0] != 0) t.setHMS(t.hour(), t.minute(), t.second()); - if (c[1] != 0) t.setHMS(t.hour(), t.minute(), 0); - if (c[2] != 0) t.setHMS(t.hour(), 0, 0); - if (c[3] != 0) {t.setHMS(0, 0, 0); d.setDate(d.year(), d.month(), d.day());} - if (c[4] != 0) {t.setHMS(0, 0, 0); d.setDate(d.year(), d.month(), 1);} - if (c[5] != 0 || c[6] != 0) {t.setHMS(0, 0, 0); d.setDate(d.year(), 1, 1);} + if (c[DateMSecs ] != 0) t.setHMS(t.hour(), t.minute(), t.second()); + if (c[DateSecs ] != 0) t.setHMS(t.hour(), t.minute(), 0); + if (c[DateMinutes] != 0) t.setHMS(t.hour(), 0, 0); + if (c[DateHours ] != 0) {t.setHMS(0, 0, 0); d.setDate(d.year(), d.month(), d.day());} + if (c[DateDays ] != 0) {t.setHMS(0, 0, 0); d.setDate(d.year(), d.month(), 1);} + if (c[DateMonths ] != 0 || c[DateYears] != 0) {t.setHMS(0, 0, 0); d.setDate(d.year(), 1, 1);} dt = QDateTime(d, t); } -void Graphic::addDateTime(QDateTime & dt, int c[7], qint64 mul) { - if (c[0] != 0) dt = dt.addMSecs(mul * c[0]); - if (c[1] != 0) dt = dt.addSecs(mul * c[1]); - if (c[2] != 0) dt = dt.addSecs(mul * c[2] * 60); - if (c[3] != 0) dt = dt.addSecs(mul * c[3] * 60 * 60); - if (c[4] != 0) dt = dt.addDays(mul * c[4]); - if (c[5] != 0) dt = dt.addMonths(mul * c[5]); - if (c[6] != 0) dt = dt.addYears(mul * c[6]); +void Graphic::addDateTime(QDateTime & dt, int * c, qint64 mul) { + if (c[DateMSecs ] != 0) dt = dt.addMSecs (mul * c[DateMSecs ]); + if (c[DateSecs ] != 0) dt = dt.addSecs (mul * c[DateSecs ]); + if (c[DateMinutes] != 0) dt = dt.addSecs (mul * c[DateMinutes] * 60); + if (c[DateHours ] != 0) dt = dt.addSecs (mul * c[DateHours ] * 60 * 60); + if (c[DateDays ] != 0) dt = dt.addDays (mul * c[DateDays ]); + if (c[DateMonths ] != 0) dt = dt.addMonths(mul * c[DateMonths ]); + if (c[DateYears ] != 0) dt = dt.addYears (mul * c[DateYears ]); } diff --git a/libs/graphic/graphic.h b/libs/graphic/graphic.h index f29e7a7..95c9a9d 100644 --- a/libs/graphic/graphic.h +++ b/libs/graphic/graphic.h @@ -358,12 +358,18 @@ public slots: protected: - virtual void changeEvent(QEvent * e); - virtual void resizeEvent(QResizeEvent * ); - virtual void showEvent(QShowEvent * ); - virtual QSize sizeHint() const {return QSize(400, 300);} - virtual void timerEvent(QTimerEvent * e); - virtual bool eventFilter(QObject * o, QEvent * e); + struct DateFormats { + QString upper; + QString center; + QString lower; + }; + + void changeEvent(QEvent * e) override; + void resizeEvent(QResizeEvent * ) override; + void showEvent(QShowEvent * ) override; + QSize sizeHint() const override {return QSize(400, 300);} + void timerEvent(QTimerEvent * e) override; + bool eventFilter(QObject * o, QEvent * e) override; void prepareCanvas(QWidget * w); void procGesture(QGesture * g); @@ -388,13 +394,14 @@ protected: void setRectToLines(); void checkLines(); double splitRange(double range, int count = 1); - double splitRangeDate(double range, int count, const char ** formats, int step[7]); + double splitRangeDate(double range, int count, DateFormats & formats, int step[7]); double roundTo(double value, double round_to); - void roundDateTime(QDateTime & dt, int c[7]); - void addDateTime(QDateTime & dt, int c[7], qint64 mul = 1); + void roundDateTime(QDateTime & dt, int * c); + void addDateTime(QDateTime & dt, int * c, qint64 mul = 1); QPointF absPoint(QPointF point) {return QPointF(qAbs(point.x()), qAbs(point.y()));} QString pointCoords(QPointF point, bool x = true, bool y = true); QPair gridMark(double v) const; + void fillDateFormats(); Ui::Graphic * ui; UGLWidget * canvas_gl; @@ -434,6 +441,7 @@ protected: bool aalias, aupdate, grid, guides, isFit, isOGL, isHover, bufferActive, cancel, pause_, gestures, m_LODOptimization, m_fakeGL, need_createGL; bool hasLblX, hasLblY, navigation, only_expand_y, only_expand_x, is_lines_update, leg_update, visible_update, fullscr, need_mouse_pan, was_trace; std::function func_gridMarkX, func_gridMarkY; + QVector date_formats; QList record_imgs; protected slots: diff --git a/libs/graphic/lang/qad_graphic_en.ts b/libs/graphic/lang/qad_graphic_en.ts index 67a1532..d046687 100644 --- a/libs/graphic/lang/qad_graphic_en.ts +++ b/libs/graphic/lang/qad_graphic_en.ts @@ -19,28 +19,28 @@ - + Free - + Trace X - + Trace Y - - + + Only expand Y - + Only expand X @@ -80,94 +80,124 @@ - + + Record graphic + + + + Clear - + Close - + Cursor: ( ; ) - - + + Snap trace - - + + Cursor: - + Selection - + Size - - + + Range - - + + Length - - + + Cursor - - + + Export graphics - + Can`t open file "%1"! - + + ms + + + + + s + + + + + m + + + + + h + + + + Save Image - - + + y(x) - + Select decimal point - + Decimal point: - + + Save GIF + + + + Check all diff --git a/libs/graphic/lang/qad_graphic_ru.ts b/libs/graphic/lang/qad_graphic_ru.ts index ffa3d80..231fa16 100644 --- a/libs/graphic/lang/qad_graphic_ru.ts +++ b/libs/graphic/lang/qad_graphic_ru.ts @@ -19,28 +19,28 @@ Плавающие оси - + Free Свободный - + Trace X Трассировка по X - + Trace Y Трассировка по Y - - + + Only expand Y Только расширять Y - + Only expand X Только расширять X @@ -80,23 +80,28 @@ Экспорт графиков ... - + + Record graphic + Запись графика + + + Clear Очистить - + Close Закрыть - + Cursor: ( ; ) Курсор: ( ; ) - - + + Snap trace Трассировка с привязкой @@ -105,73 +110,98 @@ Свободная трассировка - - + + Cursor: Курсор: - + Selection Выделение - + Size Размер - - + + Range Диапазон - - + + Length Длина - - + + Cursor Курсор - - + + Export graphics Экспорт графиков - + Can`t open file "%1"! Невозможно открыть файл "%1"! - + + ms + мс + + + + s + сек + + + + m + мин + + + + h + ч + + + Save Image Сохранить изображение - - + + y(x) - + Select decimal point Выберите десятичный разделитель - + Decimal point: Десятичный разделитель: - + + Save GIF + Сохранить GIF + + + Check all Выбрать все