/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Charts module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:GPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3 or (at your option) any later version ** approved by the KDE Free Qt Foundation. The licenses are as published by ** the Free Software Foundation and appearing in the file LICENSE.GPL3 ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "window.h" #include "view.h" #include "grid.h" #include "charts.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include Window::Window(const QVariantHash ¶meters, QWidget *parent) : QMainWindow(parent), m_scene(new QGraphicsScene(this)), m_view(0), m_form(0), m_themeComboBox(0), m_antialiasCheckBox(0), m_animatedComboBox(0), m_legendComboBox(0), m_templateComboBox(0), m_viewComboBox(0), m_xTickSpinBox(0), m_yTickSpinBox(0), m_minorXTickSpinBox(0), m_minorYTickSpinBox(0), m_openGLCheckBox(0), m_zoomCheckBox(0), m_scrollCheckBox(0), m_gridCheckBox(0), m_baseLayout(new QGraphicsLinearLayout()), m_menu(createMenu()), m_template(0), m_grid(new Grid(-1)) { createProxyWidgets(); // create layout QGraphicsLinearLayout *settingsLayout = new QGraphicsLinearLayout(); settingsLayout->setOrientation(Qt::Vertical); settingsLayout->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); settingsLayout->addItem(m_widgetHash["openGLCheckBox"]); settingsLayout->addItem(m_widgetHash["antialiasCheckBox"]); settingsLayout->addItem(m_widgetHash["viewLabel"]); settingsLayout->addItem(m_widgetHash["viewComboBox"]); settingsLayout->addItem(m_widgetHash["themeLabel"]); settingsLayout->addItem(m_widgetHash["themeComboBox"]); settingsLayout->addItem(m_widgetHash["animationsLabel"]); settingsLayout->addItem(m_widgetHash["animatedComboBox"]); settingsLayout->addItem(m_widgetHash["legendLabel"]); settingsLayout->addItem(m_widgetHash["legendComboBox"]); settingsLayout->addItem(m_widgetHash["templateLabel"]); settingsLayout->addItem(m_widgetHash["templateComboBox"]); settingsLayout->addItem(m_widgetHash["scrollCheckBox"]); settingsLayout->addItem(m_widgetHash["zoomCheckBox"]); settingsLayout->addItem(m_widgetHash["gridCheckBox"]); settingsLayout->addItem(m_widgetHash["xTickLabel"]); settingsLayout->addItem(m_widgetHash["xTickSpinBox"]); settingsLayout->addItem(m_widgetHash["yTickLabel"]); settingsLayout->addItem(m_widgetHash["yTickSpinBox"]); settingsLayout->addItem(m_widgetHash["minorXTickLabel"]); settingsLayout->addItem(m_widgetHash["minorXTickSpinBox"]); settingsLayout->addItem(m_widgetHash["minorYTickLabel"]); settingsLayout->addItem(m_widgetHash["minorYTickSpinBox"]); settingsLayout->addStretch(); m_baseLayout->setOrientation(Qt::Horizontal); m_baseLayout->addItem(m_grid); m_baseLayout->addItem(settingsLayout); m_form = new QGraphicsWidget(); m_form->setLayout(m_baseLayout); m_scene->addItem(m_form); m_view = new View(m_scene, m_form); m_view->setMinimumSize(m_form->minimumSize().toSize()); // Set defaults m_antialiasCheckBox->setChecked(true); initializeFromParamaters(parameters); updateUI(); if(!m_category.isEmpty() && !m_subcategory.isEmpty() && !m_name.isEmpty()) m_grid->createCharts(m_category,m_subcategory,m_name); handleGeometryChanged(); setCentralWidget(m_view); connectSignals(); } Window::~Window() { } void Window::connectSignals() { QObject::connect(m_form, SIGNAL(geometryChanged()), this , SLOT(handleGeometryChanged())); QObject::connect(m_viewComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateUI())); QObject::connect(m_themeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateUI())); QObject::connect(m_xTickSpinBox, SIGNAL(valueChanged(int)), this, SLOT(updateUI())); QObject::connect(m_yTickSpinBox, SIGNAL(valueChanged(int)), this, SLOT(updateUI())); QObject::connect(m_minorXTickSpinBox, SIGNAL(valueChanged(int)), this, SLOT(updateUI())); QObject::connect(m_minorYTickSpinBox, SIGNAL(valueChanged(int)), this, SLOT(updateUI())); QObject::connect(m_antialiasCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateUI())); QObject::connect(m_openGLCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateUI())); QObject::connect(m_zoomCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateUI())); QObject::connect(m_scrollCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateUI())); QObject::connect(m_gridCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateUI())); QObject::connect(m_animatedComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateUI())); QObject::connect(m_legendComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateUI())); QObject::connect(m_templateComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateUI())); QObject::connect(m_grid, SIGNAL(chartSelected(QChart*)), this, SLOT(handleChartSelected(QChart*))); } void Window::createProxyWidgets() { m_themeComboBox = createThemeBox(); m_viewComboBox = createViewBox(); m_xTickSpinBox = new QSpinBox(); m_xTickSpinBox->setMinimum(2); m_xTickSpinBox->setValue(5); m_yTickSpinBox = new QSpinBox(); m_yTickSpinBox->setMinimum(2); m_yTickSpinBox->setValue(5); m_minorXTickSpinBox = new QSpinBox(); m_minorYTickSpinBox = new QSpinBox(); m_antialiasCheckBox = new QCheckBox(tr("Anti-aliasing")); m_animatedComboBox = createAnimationBox(); m_legendComboBox = createLegendBox(); m_openGLCheckBox = new QCheckBox(tr("OpenGL")); m_zoomCheckBox = new QCheckBox(tr("Zoom")); m_scrollCheckBox = new QCheckBox(tr("Scroll")); m_gridCheckBox = new QCheckBox(tr("Grid lines")); m_templateComboBox = createTempleteBox(); m_widgetHash["viewLabel"] = m_scene->addWidget(new QLabel("View")); m_widgetHash["viewComboBox"] = m_scene->addWidget(m_viewComboBox); m_widgetHash["themeComboBox"] = m_scene->addWidget(m_themeComboBox); m_widgetHash["antialiasCheckBox"] = m_scene->addWidget(m_antialiasCheckBox); m_widgetHash["animatedComboBox"] = m_scene->addWidget(m_animatedComboBox); m_widgetHash["legendComboBox"] = m_scene->addWidget(m_legendComboBox); m_widgetHash["xTickLabel"] = m_scene->addWidget(new QLabel("X Tick")); m_widgetHash["xTickSpinBox"] = m_scene->addWidget(m_xTickSpinBox); m_widgetHash["yTickLabel"] = m_scene->addWidget(new QLabel("Y Tick")); m_widgetHash["yTickSpinBox"] = m_scene->addWidget(m_yTickSpinBox); m_widgetHash["minorXTickLabel"] = m_scene->addWidget(new QLabel("Minor X Tick")); m_widgetHash["minorXTickSpinBox"] = m_scene->addWidget(m_minorXTickSpinBox); m_widgetHash["minorYTickLabel"] = m_scene->addWidget(new QLabel("Minor Y Tick")); m_widgetHash["minorYTickSpinBox"] = m_scene->addWidget(m_minorYTickSpinBox); m_widgetHash["openGLCheckBox"] = m_scene->addWidget(m_openGLCheckBox); m_widgetHash["themeLabel"] = m_scene->addWidget(new QLabel("Theme")); m_widgetHash["animationsLabel"] = m_scene->addWidget(new QLabel("Animations")); m_widgetHash["legendLabel"] = m_scene->addWidget(new QLabel("Legend")); m_widgetHash["templateLabel"] = m_scene->addWidget(new QLabel("Chart template")); m_widgetHash["templateComboBox"] = m_scene->addWidget(m_templateComboBox); m_widgetHash["zoomCheckBox"] = m_scene->addWidget(m_zoomCheckBox); m_widgetHash["scrollCheckBox"] = m_scene->addWidget(m_scrollCheckBox); m_widgetHash["gridCheckBox"] = m_scene->addWidget(m_gridCheckBox); } QComboBox *Window::createThemeBox() { QComboBox *themeComboBox = new ComboBox(this); themeComboBox->addItem("Light", QChart::ChartThemeLight); themeComboBox->addItem("Blue Cerulean", QChart::ChartThemeBlueCerulean); themeComboBox->addItem("Dark", QChart::ChartThemeDark); themeComboBox->addItem("Brown Sand", QChart::ChartThemeBrownSand); themeComboBox->addItem("Blue NCS", QChart::ChartThemeBlueNcs); themeComboBox->addItem("High Contrast", QChart::ChartThemeHighContrast); themeComboBox->addItem("Blue Icy", QChart::ChartThemeBlueIcy); themeComboBox->addItem("Qt", QChart::ChartThemeQt); return themeComboBox; } QComboBox *Window::createViewBox() { QComboBox *viewComboBox = new ComboBox(this); viewComboBox->addItem("1 chart", 1); viewComboBox->addItem("4 charts", 2); viewComboBox->addItem("9 charts", 3); viewComboBox->addItem("16 charts", 4); return viewComboBox; } QComboBox *Window::createAnimationBox() { QComboBox *animationComboBox = new ComboBox(this); animationComboBox->addItem("No Animations", QChart::NoAnimation); animationComboBox->addItem("GridAxis Animations", QChart::GridAxisAnimations); animationComboBox->addItem("Series Animations", QChart::SeriesAnimations); animationComboBox->addItem("All Animations", QChart::AllAnimations); return animationComboBox; } QComboBox *Window::createLegendBox() { QComboBox *legendComboBox = new ComboBox(this); legendComboBox->addItem("No Legend ", 0); legendComboBox->addItem("Legend Top", Qt::AlignTop); legendComboBox->addItem("Legend Bottom", Qt::AlignBottom); legendComboBox->addItem("Legend Left", Qt::AlignLeft); legendComboBox->addItem("Legend Right", Qt::AlignRight); return legendComboBox; } QComboBox *Window::createTempleteBox() { QComboBox *templateComboBox = new ComboBox(this); templateComboBox->addItem("No Template", 0); Charts::ChartList list = Charts::chartList(); QMultiMap categoryMap; foreach (Chart *chart, list) categoryMap.insertMulti(chart->category(), chart); foreach (const QString &category, categoryMap.uniqueKeys()) templateComboBox->addItem(category, category); return templateComboBox; } void Window::initializeFromParamaters(const QVariantHash ¶meters) { if (parameters.contains("view")) { int t = parameters["view"].toInt(); for (int i = 0; i < m_viewComboBox->count(); ++i) { if (m_viewComboBox->itemData(i).toInt() == t) { m_viewComboBox->setCurrentIndex(i); break; } } } if (parameters.contains("chart")) { QString t = parameters["chart"].toString(); QRegularExpression rx("([a-zA-Z0-9_]*)::([a-zA-Z0-9_]*)::([a-zA-Z0-9_]*)"); QRegularExpressionMatch rmatch; int pos = t.indexOf(rx, 0, &rmatch); if (pos > -1) { m_category = rmatch.captured(1); m_subcategory = rmatch.captured(2); m_name = rmatch.captured(3); m_templateComboBox->setCurrentIndex(0); } else { for (int i = 0; i < m_templateComboBox->count(); ++i) { if (m_templateComboBox->itemText(i) == t) { m_templateComboBox->setCurrentIndex(i); break; } } } } if (parameters.contains("opengl")) { bool checked = parameters["opengl"].toBool(); m_openGLCheckBox->setChecked(checked); } if (parameters.contains("theme")) { QString t = parameters["theme"].toString(); for (int i = 0; i < m_themeComboBox->count(); ++i) { if (m_themeComboBox->itemText(i) == t) { m_themeComboBox->setCurrentIndex(i); break; } } } if (parameters.contains("animation")) { QString t = parameters["animation"].toString(); for (int i = 0; i < m_animatedComboBox->count(); ++i) { if (m_animatedComboBox->itemText(i) == t) { m_animatedComboBox->setCurrentIndex(i); break; } } } if (parameters.contains("legend")) { QString t = parameters["legend"].toString(); for (int i = 0; i < m_legendComboBox->count(); ++i) { if (m_legendComboBox->itemText(i) == t) { m_legendComboBox->setCurrentIndex(i); break; } } } } void Window::updateUI() { checkView(); checkTemplate(); checkOpenGL(); checkTheme(); checkAnimationOptions(); checkLegend(); checkState(); checkXTick(); checkYTick(); checkMinorXTick(); checkMinorYTick(); } void Window::checkView() { int count(m_viewComboBox->itemData(m_viewComboBox->currentIndex()).toInt()); if(m_grid->size()!=count){ m_grid->setSize(count); m_template = 0; } } void Window::checkXTick() { foreach (QChart *chart, m_grid->charts()) { if (qobject_cast(chart->axisX())) { QValueAxis *valueAxis = qobject_cast(chart->axisX()); valueAxis->setGridLineVisible(m_gridCheckBox->isChecked()); valueAxis->setTickCount(m_xTickSpinBox->value()); } } } void Window::checkYTick() { foreach (QChart *chart, m_grid->charts()) { if (qobject_cast(chart->axisY())) { QValueAxis *valueAxis = qobject_cast(chart->axisY()); valueAxis->setGridLineVisible(m_gridCheckBox->isChecked()); valueAxis->setTickCount(m_yTickSpinBox->value()); } } } void Window::checkMinorXTick() { foreach (QChart *chart, m_grid->charts()) { if (qobject_cast(chart->axisX())) { QValueAxis *valueAxis = qobject_cast(chart->axisX()); valueAxis->setMinorGridLineVisible(m_gridCheckBox->isChecked()); valueAxis->setGridLineVisible(m_gridCheckBox->isChecked()); valueAxis->setMinorTickCount(m_minorXTickSpinBox->value()); } } } void Window::checkMinorYTick() { foreach (QChart *chart, m_grid->charts()) { if (qobject_cast(chart->axisY())) { QValueAxis *valueAxis = qobject_cast(chart->axisY()); valueAxis->setMinorGridLineVisible(m_gridCheckBox->isChecked()); valueAxis->setGridLineVisible(m_gridCheckBox->isChecked()); valueAxis->setMinorTickCount(m_minorYTickSpinBox->value()); } } } void Window::checkLegend() { Qt::Alignment alignment(m_legendComboBox->itemData(m_legendComboBox->currentIndex()).toInt()); if (!alignment) { foreach (QChart *chart, m_grid->charts()) chart->legend()->hide(); } else { foreach (QChart *chart, m_grid->charts()) { chart->legend()->setAlignment(alignment); chart->legend()->show(); } } } void Window::checkOpenGL() { bool opengl = m_openGLCheckBox->isChecked(); bool isOpengl = qobject_cast(m_view->viewport()); if ((isOpengl && !opengl) || (!isOpengl && opengl)) { m_view->deleteLater(); m_view = new View(m_scene, m_form); m_view->setViewport(!opengl ? new QWidget() : new QOpenGLWidget()); setCentralWidget(m_view); } bool antialias = m_antialiasCheckBox->isChecked(); m_view->setRenderHint(QPainter::Antialiasing, antialias); } void Window::checkAnimationOptions() { QChart::AnimationOptions options( m_animatedComboBox->itemData(m_animatedComboBox->currentIndex()).toInt()); QList charts = m_grid->charts(); if (!charts.isEmpty() && charts.at(0)->animationOptions() != options) { foreach (QChart *chart, charts) chart->setAnimationOptions(options); } } void Window::checkState() { bool scroll = m_scrollCheckBox->isChecked(); if (m_grid->state() != Grid::ScrollState && scroll) { m_grid->setState(Grid::ScrollState); m_zoomCheckBox->setChecked(false); } else if (!scroll && m_grid->state() == Grid::ScrollState) { m_grid->setState(Grid::NoState); } bool zoom = m_zoomCheckBox->isChecked(); if (m_grid->state() != Grid::ZoomState && zoom) { m_grid->setState(Grid::ZoomState); m_scrollCheckBox->setChecked(false); } else if (!zoom && m_grid->state() == Grid::ZoomState) { m_grid->setState(Grid::NoState); } } void Window::checkTemplate() { int index = m_templateComboBox->currentIndex(); if (m_template == index || index == 0) return; m_template = index; QString category = m_templateComboBox->itemData(index).toString(); m_grid->createCharts(category); } void Window::checkTheme() { QChart::ChartTheme theme = (QChart::ChartTheme) m_themeComboBox->itemData( m_themeComboBox->currentIndex()).toInt(); foreach (QChart *chart, m_grid->charts()) chart->setTheme(theme); QPalette pal = window()->palette(); if (theme == QChart::ChartThemeLight) { pal.setColor(QPalette::Window, QRgb(0xf0f0f0)); pal.setColor(QPalette::WindowText, QRgb(0x404044)); } else if (theme == QChart::ChartThemeDark) { pal.setColor(QPalette::Window, QRgb(0x121218)); pal.setColor(QPalette::WindowText, QRgb(0xd6d6d6)); } else if (theme == QChart::ChartThemeBlueCerulean) { pal.setColor(QPalette::Window, QRgb(0x40434a)); pal.setColor(QPalette::WindowText, QRgb(0xd6d6d6)); } else if (theme == QChart::ChartThemeBrownSand) { pal.setColor(QPalette::Window, QRgb(0x9e8965)); pal.setColor(QPalette::WindowText, QRgb(0x404044)); } else if (theme == QChart::ChartThemeBlueNcs) { pal.setColor(QPalette::Window, QRgb(0x018bba)); pal.setColor(QPalette::WindowText, QRgb(0x404044)); } else if (theme == QChart::ChartThemeHighContrast) { pal.setColor(QPalette::Window, QRgb(0xffab03)); pal.setColor(QPalette::WindowText, QRgb(0x181818)); } else if (theme == QChart::ChartThemeBlueIcy) { pal.setColor(QPalette::Window, QRgb(0xcee7f0)); pal.setColor(QPalette::WindowText, QRgb(0x404044)); } else if (theme == QChart::ChartThemeQt) { pal.setColor(QPalette::Window, QRgb(0xf0f0f0)); pal.setColor(QPalette::WindowText, QRgb(0x404044)); } else { pal.setColor(QPalette::Window, QRgb(0xf0f0f0)); pal.setColor(QPalette::WindowText, QRgb(0x404044)); } foreach (QGraphicsProxyWidget *widget, m_widgetHash) widget->setPalette(pal); m_view->setBackgroundBrush(pal.color((QPalette::Window))); m_grid->setRubberPen(pal.color((QPalette::WindowText))); } void Window::comboBoxFocused(QComboBox *combobox) { foreach (QGraphicsProxyWidget *widget , m_widgetHash) { if (widget->widget() == combobox) widget->setZValue(2.0); else widget->setZValue(0.0); } } void Window::handleChartSelected(QChart *qchart) { if (m_templateComboBox->currentIndex() != 0) return; QAction *chosen = m_menu->exec(QCursor::pos()); if (chosen) { Chart *chart = (Chart *) chosen->data().value(); m_grid->replaceChart(qchart, chart); updateUI(); } } QMenu *Window::createMenu() { Charts::ChartList list = Charts::chartList(); QMultiMap categoryMap; QMenu *result = new QMenu(this); foreach (Chart *chart, list) categoryMap.insertMulti(chart->category(), chart); foreach (const QString &category, categoryMap.uniqueKeys()) { QMenu *menu(0); QMultiMap subCategoryMap; if (category.isEmpty()) { menu = result; } else { menu = new QMenu(category, this); result->addMenu(menu); } foreach (Chart *chart, categoryMap.values(category)) subCategoryMap.insert(chart->subCategory(), chart); foreach (const QString &subCategory, subCategoryMap.uniqueKeys()) { QMenu *subMenu(0); if (subCategory.isEmpty()) { subMenu = menu; } else { subMenu = new QMenu(subCategory, this); menu->addMenu(subMenu); } foreach (Chart *chart, subCategoryMap.values(subCategory)) { createMenuAction(subMenu, QIcon(), chart->name(), QVariant::fromValue(static_cast(chart))); } } } return result; } QAction *Window::createMenuAction(QMenu *menu, const QIcon &icon, const QString &text, const QVariant &data) { QAction *action = menu->addAction(icon, text); action->setCheckable(false); action->setData(data); return action; } void Window::handleGeometryChanged() { QSizeF size = m_baseLayout->sizeHint(Qt::MinimumSize); m_view->scene()->setSceneRect(0, 0, this->width(), this->height()); m_view->setMinimumSize(size.toSize()); }