##// END OF EJS Templates
Added HTML support for various text items...
Added HTML support for various text items - HTML tags can now be used in chart titles, legends, and labels - '\n' does no longer cause line break in multi-line text items. HTML tag <br/> can be used for line break now. - Setting pen for axis titles and labels is deprecated - When setting brush for titles and labels, only the color is relevant - Logic for identifying label format specifiers was improved, so adding additional information to labels via label format string is now more viable. Task-number: QTRD-1912 Change-Id: I8fa56df56fd656e2a3e427eff4abf3481435eec7 Reviewed-by: Mika Salmela <mika.salmela@digia.com>

File last commit:

r2433:4d17a12f375e
r2539:74f3dbde7a75
Show More
mainwindow.cpp
423 lines | 13.5 KiB | text/x-c | CppLexer
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc
** All rights reserved.
** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the Qt Commercial Charts Add-on.
**
** $QT_BEGIN_LICENSE$
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.
**
** If you have questions regarding the use of this file, please use
** contact form at http://qt.digia.com
** $QT_END_LICENSE$
**
****************************************************************************/
#include "mainwindow.h"
#include "objectinspectorwidget.h"
#include "penwidget.h"
#include "brushwidget.h"
#include "engine.h"
#include <QSettings>
#include <QChartView>
#include <QDockWidget>
#include <QMenuBar>
#include <QTableWidget>
#include <QSplitter>
#include <QMetaEnum>
#include <QStandardItemModel>
#include <QHeaderView>
#include <QDebug>
#include <QMessageBox>
static const QString FILENAME_SETTING("filename");
static const QString GEOMETRY_SETTING("geometry");
MainWindow::MainWindow() :
m_engine(new Engine(this)),
m_view(new QChartView(m_engine->chart())),
m_scene(m_view->scene()),
m_table(new QTableView()),
m_addSeriesMenu(0),
m_seriesMenu(0),
m_chartMenu(0),
m_themeMenu(0),
m_animationMenu(0),
m_zoomMenu(0),
m_removeAllAction(0),
m_legendAction(0),
m_antialiasingAction(0)
{
createMenus();
createDockWidgets();
createTable();
createLayout();
QSettings settings;
restoreGeometry(settings.value(GEOMETRY_SETTING).toByteArray());
m_filename = settings.value(FILENAME_SETTING).toString();
if (m_filename.isEmpty())
m_filename = "untitled";
setWindowTitle(m_filename);
updateUI();
}
MainWindow::~MainWindow()
{
delete m_engine;
}
void MainWindow::createMenus()
{
QMenu *file = menuBar()->addMenu(tr("File"));
QMenu *edit = menuBar()->addMenu(tr("Edit"));
m_seriesMenu = menuBar()->addMenu(tr("Series"));
m_chartMenu = menuBar()->addMenu(tr("Chart"));
m_addSeriesMenu = new QMenu(tr("Add series"));
m_themeMenu = new QMenu(tr("Apply theme"));
m_animationMenu = new QMenu(tr("Animations"));
m_zoomMenu = new QMenu(tr("Zoom"));
file->addAction(tr("New"), this, SLOT(handleNewAction()));
file->addAction(tr("Load"), this, SLOT(handleLoadAction()));
file->addAction(tr("Save"), this, SLOT(handleSaveAction()));
file->addAction(tr("Save As"), this, SLOT(handleSaveAsAction()));
//seriesMenu
m_seriesMenu->addMenu(m_addSeriesMenu);
m_removeAllAction = new QAction(tr("Remove all series"), this);
QObject::connect(m_removeAllAction, SIGNAL(triggered()), this, SLOT(handleRemoveAllSeriesAction()));
m_seriesMenu->addAction(m_removeAllAction);
m_seriesMenu->addSeparator();
//seriesMenu /addSeriesMenu
{
int index = QAbstractSeries::staticMetaObject.indexOfEnumerator("SeriesType");
QMetaEnum metaEnum = QAbstractSeries::staticMetaObject.enumerator(index);
int count = metaEnum.keyCount();
for (int i = 0; i < count; ++i) {
QAction* action = new QAction(metaEnum.key(i), this);
action->setData(metaEnum.value(i));
m_addSeriesMenu->addAction(action);
QObject::connect(action, SIGNAL(triggered()), this, SLOT(handleAddSeriesMenu()));
}
}
//chartMenu / themeMenu
{
m_chartMenu->addMenu(m_themeMenu);
int index = QChart::staticMetaObject.indexOfEnumerator("ChartTheme");
QMetaEnum metaEnum = QChart::staticMetaObject.enumerator(index);
int count = metaEnum.keyCount();
for (int i = 0; i < count; ++i) {
QAction* action = new QAction(metaEnum.key(i), this);
action->setData(metaEnum.value(i));
action->setCheckable(true);
m_themeMenu->addAction(action);
QObject::connect(action, SIGNAL(triggered()), this, SLOT(handleThemeMenu()));
}
}
//chartMenu / animationMenu
{
m_chartMenu->addMenu(m_animationMenu);
int index = QChart::staticMetaObject.indexOfEnumerator("AnimationOption");
QMetaEnum metaEnum = QChart::staticMetaObject.enumerator(index);
int count = metaEnum.keyCount();
for (int i = 0; i < count; ++i) {
QAction* action = new QAction(metaEnum.key(i), this);
action->setData(metaEnum.value(i));
action->setCheckable(true);
m_animationMenu->addAction(action);
QObject::connect(action, SIGNAL(triggered()), this, SLOT(handleAnimationMenu()));
}
}
//chartMenu / zoomMenu
{
m_chartMenu->addMenu(m_zoomMenu);
int index = QChartView::staticMetaObject.indexOfEnumerator("RubberBand");
QMetaEnum metaEnum = QChartView::staticMetaObject.enumerator(index);
int count = metaEnum.keyCount();
for (int i = 0; i < count; ++i) {
QAction* action = new QAction(metaEnum.key(i), this);
action->setData(metaEnum.value(i));
action->setCheckable(true);
m_zoomMenu->addAction(action);
QObject::connect(action, SIGNAL(triggered()), this, SLOT(handleZoomMenu()));
}
}
//chartMenu / legend
m_legendAction = new QAction(tr("Legend"), this);
m_legendAction->setCheckable(true);
m_chartMenu->addAction(m_legendAction);
QObject::connect(m_legendAction, SIGNAL(triggered()), this, SLOT(handleLegendAction()));
//chartMenu / Anti-aliasing
m_antialiasingAction = new QAction(tr("Anti-aliasing"), this);
m_antialiasingAction->setCheckable(true);
m_chartMenu->addAction(m_antialiasingAction);
QObject::connect(m_antialiasingAction, SIGNAL(triggered()), this, SLOT(handleAntialiasingAction()));
}
void MainWindow::createDockWidgets()
{
m_brushWidget = new BrushWidget();
QDockWidget *brushDockWidget = new QDockWidget(tr("Brush"), this);
brushDockWidget->setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable);
brushDockWidget->setWidget(m_brushWidget);
addDockWidget(Qt::RightDockWidgetArea, brushDockWidget);
m_penWidget = new PenWidget();
QDockWidget *penDockWidget = new QDockWidget(tr("Pen"), this);
penDockWidget->setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable);
penDockWidget->setWidget(m_penWidget);
addDockWidget(Qt::RightDockWidgetArea, penDockWidget);
m_inspectorWidget = new InspectorWidget();
QDockWidget *inspectorDockWidget = new QDockWidget(tr("Object Inspector"), this);
inspectorDockWidget->setFeatures(
QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable);
inspectorDockWidget->setWidget(m_inspectorWidget);
addDockWidget(Qt::RightDockWidgetArea, inspectorDockWidget);
setDockOptions(QMainWindow::AnimatedDocks);
}
void MainWindow::createLayout()
{
m_table->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
int rowHeight = m_table->rowHeight(0);
int tableHeight = (m_engine->modelCount() * rowHeight) + m_table->horizontalHeader()->height() + 2 * m_table->frameWidth();
m_table->setMinimumHeight(tableHeight);
m_table->setMaximumHeight(tableHeight);
QSplitter *splitter = new QSplitter(this);
splitter->setOrientation(Qt::Vertical);
splitter->addWidget(m_table);
splitter->addWidget(m_view);
setCentralWidget(splitter);
m_view->hide();
}
void MainWindow::createTable()
{
m_table->setModel(m_engine->model());
m_table->setSelectionModel(m_engine->selectionModel());
QObject::connect(m_table->selectionModel(),SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this,SLOT(updateUI()));
}
void MainWindow::updateUI()
{
QItemSelectionModel* selection = m_table->selectionModel();
const QModelIndexList& list = selection->selectedIndexes();
QMap<int, QModelIndex> columns;
foreach (const QModelIndex& index, list) {
columns.insertMulti(index.column(), index);
}
QList<int> keys = columns.uniqueKeys();
bool seriesEnabled = false;
foreach (QAction* action, m_addSeriesMenu->actions()) {
switch (action->data().toInt()) {
case QAbstractSeries::SeriesTypeLine:
case QAbstractSeries::SeriesTypeSpline:
case QAbstractSeries::SeriesTypeScatter:
action->setEnabled(list.count() > 0 && keys.count() >= 2);
seriesEnabled |= action->isEnabled();
break;
case QAbstractSeries::SeriesTypeBar:
case QAbstractSeries::SeriesTypePercentBar:
case QAbstractSeries::SeriesTypeStackedBar:
action->setEnabled(list.count() > 0 && keys.count() >= 2);
seriesEnabled |= action->isEnabled();
break;
case QAbstractSeries::SeriesTypePie:
action->setEnabled(list.count() > 0 && keys.count() == 2);
seriesEnabled |= action->isEnabled();
break;
case QAbstractSeries::SeriesTypeArea:
action->setEnabled(list.count() > 0 && keys.count() == 3);
seriesEnabled |= action->isEnabled();
break;
}
}
m_chartMenu->setEnabled(m_engine->chart()->series().count() > 0);
m_seriesMenu->setEnabled(seriesEnabled || m_engine->chart()->series().count() > 0);
m_removeAllAction->setEnabled(m_engine->chart()->series().count() > 0);
int theme = m_engine->chart()->theme();
foreach (QAction* action, m_themeMenu->actions()) {
action->setChecked(action->data().toInt() == theme);
}
int animation = m_engine->chart()->animationOptions();
foreach (QAction* action, m_animationMenu->actions()) {
action->setChecked(action->data().toInt() == animation);
}
int zoom = m_view->rubberBand();
foreach (QAction* action, m_zoomMenu->actions()) {
action->setChecked(action->data().toInt() == zoom);
}
m_legendAction->setChecked(m_engine->chart()->legend()->isVisible());
m_antialiasingAction->setChecked(m_view->renderHints().testFlag(QPainter::Antialiasing));
foreach (QAction *action, m_seriesMenu->actions()) {
//TODO: visibility handling
//if (m_series.value(action->text()))
// ;
//action->setChecked(false);
}
}
void MainWindow::closeEvent(QCloseEvent *event)
{
QSettings settings;
settings.setValue(GEOMETRY_SETTING, saveGeometry());
settings.setValue(FILENAME_SETTING, m_filename);
QMainWindow::closeEvent(event);
}
//handlers
void MainWindow::handleNewAction()
{
m_engine->chart()->removeAllSeries();
m_view->hide();
m_engine->clearModels();
createTable();
m_filename = "untitled";
setWindowTitle(m_filename);
updateUI();
}
void MainWindow::handleAddSeriesMenu()
{
m_view->show();
QAction* action = qobject_cast<QAction*>(sender());
QList<QAbstractSeries*> series = m_engine->addSeries(QAbstractSeries::SeriesType(action->data().toInt()));
foreach (QAbstractSeries* s , series)
{
QAction *newAction = new QAction(s->name(),this);
//newAction->setCheckable(true);
m_series.insert(s->name(),s);
m_seriesMenu->addAction(newAction);
}
updateUI();
}
void MainWindow::handleRemoveAllSeriesAction()
{
foreach (QAction* action, m_seriesMenu->actions()){
if(m_series.contains(action->text())){
m_seriesMenu->removeAction(action);
m_engine->removeSeries(m_series.value(action->text()));
delete action;
}
}
m_series.clear();
m_view->hide();
updateUI();
}
void MainWindow::handleThemeMenu()
{
QAction* action = qobject_cast<QAction*>(sender());
m_engine->chart()->setTheme(QChart::ChartTheme(action->data().toInt()));
updateUI();
}
void MainWindow::handleAnimationMenu()
{
QAction* action = qobject_cast<QAction*>(sender());
m_engine->chart()->setAnimationOptions(QChart::AnimationOption(action->data().toInt()));
updateUI();
}
void MainWindow::handleZoomMenu()
{
QAction* action = qobject_cast<QAction*>(sender());
m_view->setRubberBand(QChartView::RubberBand(action->data().toInt()));
updateUI();
}
void MainWindow::handleAntialiasingAction()
{
QAction* action = qobject_cast<QAction*>(sender());
if (action->isChecked()) {
m_view->setRenderHint(QPainter::Antialiasing, true);
}
else {
m_view->setRenderHint(QPainter::Antialiasing, false);
}
}
void MainWindow::handleLegendAction()
{
QAction* action = qobject_cast<QAction*>(sender());
if (action->isChecked()) {
m_engine->chart()->legend()->setVisible(true);
}
else {
m_engine->chart()->legend()->setVisible(false);
}
}
void MainWindow::handleSaveAction()
{
if(!m_engine->save(m_filename)) {
QScopedPointer<QMessageBox> messageBox(new QMessageBox(this));
messageBox->setIcon(QMessageBox::Warning);
messageBox->setWindowModality(Qt::WindowModal);
messageBox->setWindowTitle(QString(tr("Error")));
messageBox->setText(tr("Could not write to ") + m_filename);
messageBox->exec();
}
}
void MainWindow::handleLoadAction()
{
if(!m_engine->load(m_filename)) {
QScopedPointer<QMessageBox> messageBox(new QMessageBox(this));
messageBox->setIcon(QMessageBox::Warning);
messageBox->setWindowModality(Qt::WindowModal);
messageBox->setWindowTitle(QString(tr("Error")));
messageBox->setText(tr("Could not open ") + m_filename);
messageBox->exec();
}else createTable();
}