diff --git a/examples/Axis/Labels/AdjustedCartesianAxis.h b/examples/Axis/Labels/AdjustedCartesianAxis.h index 8dd19bf..9bf4c7a 100644 --- a/examples/Axis/Labels/AdjustedCartesianAxis.h +++ b/examples/Axis/Labels/AdjustedCartesianAxis.h @@ -1,50 +1,50 @@ /** * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ADJUSTED_CARTESIAN_AXIS_H #define ADJUSTED_CARTESIAN_AXIS_H #include #include class AdjustedCartesianAxis: public KChart::CartesianAxis { Q_OBJECT Q_DISABLE_COPY( AdjustedCartesianAxis ) public: explicit AdjustedCartesianAxis( KChart::AbstractCartesianDiagram* diagram = nullptr ); - const QString customizedLabel( const QString& label ) const Q_DECL_OVERRIDE; + const QString customizedLabel( const QString& label ) const override; void setBounds( qreal lower, qreal upper ) { m_lowerBound = lower; m_upperBound = upper; } qreal lowerBound() const { return m_lowerBound; } qreal upperBound() const { return m_upperBound; } private: qreal m_lowerBound; qreal m_upperBound; }; #endif // ADJUSTED_CARTESIAN_AXIS_H diff --git a/examples/DrawIntoPainter/framewidget.h b/examples/DrawIntoPainter/framewidget.h index d6d2f73..e682e7d 100644 --- a/examples/DrawIntoPainter/framewidget.h +++ b/examples/DrawIntoPainter/framewidget.h @@ -1,47 +1,47 @@ /** * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef FRAMEWIDGET_H #define FRAMEWIDGET_H #include namespace KChart { class Chart; } class FrameWidget : public QWidget { Q_OBJECT public: explicit FrameWidget( QWidget * parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags() ); - void paintEvent( QPaintEvent* ) Q_DECL_OVERRIDE; + void paintEvent( QPaintEvent* ) override; void setChart( KChart::Chart* chart ); private: KChart::Chart* mChart; }; #endif /* FRAMEWIDGET_H */ diff --git a/examples/DrawIntoPainter/mainwindow.h b/examples/DrawIntoPainter/mainwindow.h index 72af5b5..03a34f3 100644 --- a/examples/DrawIntoPainter/mainwindow.h +++ b/examples/DrawIntoPainter/mainwindow.h @@ -1,83 +1,83 @@ /** * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef MAINWINDOW_H #define MAINWINDOW_H #include "ui_mainwindow.h" #include #include namespace KChart { class Chart; class DatasetProxyModel; class LineDiagram; class Legend; } QT_BEGIN_NAMESPACE class QLabel; QT_END_NAMESPACE class MainWindow : public QWidget, private Ui::MainWindow { Q_OBJECT public: MainWindow( QWidget* parent = nullptr ); protected: /** * Adjusts the two small charts when the window is resized. */ - /* reimp */ void resizeEvent ( QResizeEvent * ) Q_DECL_OVERRIDE; + /* reimp */ void resizeEvent ( QResizeEvent * ) override; private slots: void on_lineTypeCB_currentIndexChanged( const QString & text ); void on_paintLegendCB_toggled( bool checked ); void on_paintValuesCB_toggled( bool checked ); void on_paintMarkersCB_toggled( bool checked ); void on_markersStyleCB_currentIndexChanged( const QString & text ); void on_markersWidthSB_valueChanged( int i ); void on_markersHeightSB_valueChanged( int i); void on_displayAreasCB_toggled( bool checked ); void on_transparencySB_valueChanged( int i ); void on_zoomFactorSB_valueChanged( qreal factor ); void on_hSBar_valueChanged( int value ); void on_vSBar_valueChanged( int value ); void on_savePB_clicked(); void on_savePDF_clicked(); private: void paintMarkers( bool checked, const QSize& printSize ); private: KChart::Chart* m_chart; TableModel m_model; KChart::DatasetProxyModel* m_datasetProxy; KChart::LineDiagram* m_lines; KChart::Legend* m_legend; QPixmap m_pix1, m_pix2; QLabel* m_smallChart1; QLabel* m_smallChart2; }; #endif /* MAINWINDOW_H */ diff --git a/examples/Gantt/legend_example/entrydelegate.h b/examples/Gantt/legend_example/entrydelegate.h index 06877ff..d08bafe 100644 --- a/examples/Gantt/legend_example/entrydelegate.h +++ b/examples/Gantt/legend_example/entrydelegate.h @@ -1,42 +1,42 @@ /** * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KGantt library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ENTRYDELEGATE_H #define ENTRYDELEGATE_H #include namespace KGantt { class ConstraintModel; } class EntryDelegate : public QItemDelegate { public: explicit EntryDelegate( KGantt::ConstraintModel* constraintModel, QObject* parent = nullptr ); - bool editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ) Q_DECL_OVERRIDE; + bool editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ) override; private: void addConstraint(const QModelIndex & index1, const QModelIndex & index2); void setReadOnly(const QModelIndex & index, bool readOnly); KGantt::ConstraintModel* constraintModel; }; #endif /* ENTRYDELEGATE_H */ diff --git a/examples/Gantt/legend_example/mainwindow.h b/examples/Gantt/legend_example/mainwindow.h index 0e080c7..244ff98 100644 --- a/examples/Gantt/legend_example/mainwindow.h +++ b/examples/Gantt/legend_example/mainwindow.h @@ -1,86 +1,86 @@ /** * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KGantt library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef MAINWINDOW_H #define MAINWINDOW_H #include #include QT_BEGIN_NAMESPACE class QStandardItemModel; class QCloseEvent; namespace Ui { class MainWindow; } QT_END_NAMESPACE namespace KGantt { class ConstraintModel; class DateTimeGrid; class Legend; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow( QWidget * parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags() ); virtual ~MainWindow(); - void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE; + void closeEvent(QCloseEvent *event) override; private slots: void addNewEntry(); void removeEntry(); void showContextMenu( const QPoint& ); void enableActions( const QItemSelection& selected ); void zoomIn(); void zoomOut(); void zoomFit(); void scaleAuto(); void scaleHour(); void scaleDay(); void scaleWeek(); void scaleMonth(); private: void initModel(); void initActions(); void initItemDelegate(); void initGrid(); void setReadOnly( const QModelIndex& index, bool readOnly ); void addConstraint( const QModelIndex& index1, const QModelIndex& index2 ); QStandardItemModel* model; KGantt::ConstraintModel* constraintModel; KGantt::DateTimeGrid* grid; KGantt::Legend* smallLegend; KGantt::Legend* detailedLegend; QAction* newEntryAction; QAction* removeEntryAction; QAction* zoomInAction; QAction* zoomOutAction; QAction* zoomFitAction; Ui::MainWindow* ui; }; #endif /* MAINWINDOW_H */ diff --git a/examples/Gantt/project/mainwindow.cpp b/examples/Gantt/project/mainwindow.cpp index ebb9d25..bf080b3 100644 --- a/examples/Gantt/project/mainwindow.cpp +++ b/examples/Gantt/project/mainwindow.cpp @@ -1,485 +1,485 @@ /** * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KGantt library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "mainwindow.h" #include "projectmodel.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class ItemTypeComboBox : public QComboBox { Q_OBJECT Q_PROPERTY( KGantt::ItemType itemType READ itemType WRITE setItemType ) public: explicit ItemTypeComboBox( QWidget* parent = nullptr ); KGantt::ItemType itemType() const; public slots: void setItemType( KGantt::ItemType typ ); }; ItemTypeComboBox::ItemTypeComboBox( QWidget* parent ) : QComboBox( parent ) { addItem( tr( "Task" ), QVariant( KGantt::TypeTask ) ); addItem( tr( "Event" ), QVariant( KGantt::TypeEvent ) ); addItem( tr( "Summary" ), QVariant( KGantt::TypeSummary ) ); } KGantt::ItemType ItemTypeComboBox::itemType() const { return static_cast( itemData( currentIndex() ).toInt() ); } void ItemTypeComboBox::setItemType( KGantt::ItemType typ ) { setCurrentIndex( typ-1 ); } class MyItemDelegate : public KGantt::ItemDelegate { public: explicit MyItemDelegate( QObject* parent = nullptr ); /*reimp*/ QWidget* createEditor( QWidget* parent, const QStyleOptionViewItem& option, - const QModelIndex& idx ) const Q_DECL_OVERRIDE; - /*reimp*/ void setEditorData( QWidget* editor, const QModelIndex& index ) const Q_DECL_OVERRIDE; + const QModelIndex& idx ) const override; + /*reimp*/ void setEditorData( QWidget* editor, const QModelIndex& index ) const override; /*reimp*/ void setModelData( QWidget* editor, QAbstractItemModel* model, - const QModelIndex & index ) const Q_DECL_OVERRIDE; + const QModelIndex & index ) const override; protected: /*reimp*/void drawDisplay( QPainter* painter, const QStyleOptionViewItem & option, - const QRect& rect, const QString& text ) const Q_DECL_OVERRIDE; + const QRect& rect, const QString& text ) const override; }; MyItemDelegate::MyItemDelegate( QObject* parent ) : KGantt::ItemDelegate( parent ) { } QWidget* MyItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& idx ) const { qDebug() << "MyItemDelegate::createEditor("<(editor)) && index.isValid() ) { c->setItemType(static_cast(index.data(Qt::EditRole).toInt())); } else { ItemDelegate::setEditorData(editor,index); } } void MyItemDelegate::setModelData ( QWidget* editor, QAbstractItemModel* model, const QModelIndex & index ) const { ItemTypeComboBox* c; if ( (c = qobject_cast(editor)) && index.isValid() ) { model->setData(index,c->itemType()); } else { ItemDelegate::setModelData(editor,model,index); } } void MyItemDelegate::drawDisplay( QPainter* painter, const QStyleOptionViewItem& option, const QRect& rect, const QString& text ) const { //qDebug() << "MyItemDelegate::drawDisplay(" <(text.toInt()); QString str; switch (typ) { case KGantt::TypeTask: str = tr("Task"); break; case KGantt::TypeEvent: str = tr("Event"); break; case KGantt::TypeSummary: str = tr("Summary"); break; default: str = tr("None"); break; } ItemDelegate::drawDisplay(painter,option,rect,str); } /////////////////////////////////////////////////////////////////////////////// // Provide custom background and foreground /////////////////////////////////////////////////////////////////////////////// class DateTimeGrid : public KGantt::DateTimeGrid { public: DateTimeGrid(QObject* parent = nullptr) { setParent(parent); setFreeDays( QSet() ); setFreeDaysBrush( QBrush( Qt::NoBrush ) ); } ~DateTimeGrid() { } //virtual void paintUserDefinedHeader(QPainter* painter, const QRectF& headerRect, const QRectF& exposedRect, qreal offset, const KGantt::DateTimeScaleFormatter* formatter, QWidget* widget = 0); - void drawBackground(QPainter* painter, const QRectF& rect) Q_DECL_OVERRIDE; - void drawForeground(QPainter* painter, const QRectF& rect) Q_DECL_OVERRIDE; + void drawBackground(QPainter* painter, const QRectF& rect) override; + void drawForeground(QPainter* painter, const QRectF& rect) override; }; void DateTimeGrid::drawBackground(QPainter* painter, const QRectF& rect) { QLinearGradient grad; grad.setCoordinateMode( QGradient::ObjectBoundingMode ); grad.setStart( 0.5, 0.5 ); grad.setFinalStop( 0.5, 0.0 ); grad.setSpread( QGradient::ReflectSpread ); // grad.setCenter( 0.5, 0.5 ); // grad.setFocalPoint( 0.5, 0.5 ); // grad.setRadius( 0.5 ); QColor currentColor = Qt::blue; for ( qreal i = 0; i <= 1.0; i += 0.1 ) { currentColor = currentColor.lighter( 100 + 20 * i ); grad.setColorAt( i, currentColor ); } QBrush brush( grad); //brush.setColor(Qt::lightGray); QRectF r = computeRect(QDateTime::currentDateTime(), QDateTime::currentDateTime().addDays(2), rect); painter->fillRect(r, brush); KGantt::DateTimeGrid::drawBackground(painter, rect); } void DateTimeGrid::drawForeground(QPainter* painter, const QRectF& rect) { painter->save(); QRectF r = computeRect(QDateTime::currentDateTime(), QDateTime::currentDateTime().addDays(2), rect); static QString text("Holiday"); QFont font = painter->font(); font.setPixelSize(r.width()/5); QFontMetrics fm(font); int width = fm.boundingRect(text).width(); int height = fm.boundingRect(text).height(); painter->translate(r.center()); painter->translate(-width/2, height/2); painter->setFont(font); painter->drawText(0, 0, text); painter->restore(); KGantt::DateTimeGrid::drawForeground(painter, rect); } /* void DateTimeGrid::paintUserDefinedHeader( QPainter* painter, const QRectF& headerRect, const QRectF& exposedRect, qreal offset, const KGantt::DateTimeScaleFormatter* formatter, QWidget* widget) { const QStyle* const style = widget ? widget->style() : QApplication::style(); QDateTime dt = formatter->currentRangeBegin( mapToDateTime( offset + exposedRect.left() ) ).toUTC(); qreal x = mapFromDateTime( dt ); while ( x < exposedRect.right() + offset ) { const QDateTime next = formatter->nextRangeBegin( dt ); const qreal nextx = mapFromDateTime( next ); QStyleOptionHeader opt; if ( widget ) opt.init( widget ); opt.rect = QRectF( x - offset+1, headerRect.top(), qMax( 1., nextx-x-1 ), headerRect.height() ).toAlignedRect(); //opt.state = QStyle::State_Raised | QStyle::State_Enabled; opt.textAlignment = formatter->alignment(); opt.text = formatter->text( dt ); // use white text on black background opt.palette.setColor(QPalette::Window, QColor("black")); opt.palette.setColor(QPalette::ButtonText, QColor("white")); style->drawControl( QStyle::CE_Header, &opt, painter, widget ); dt = next; x = nextx; } } */ MainWindow::MainWindow( QWidget* parent ) : QMainWindow( parent ), m_model( new ProjectModel( this ) ), m_view( new KGantt::View ) { m_view->setModel( m_model ); m_view->setSelectionModel( new QItemSelectionModel(m_model)); // slotToolsNewItem(); m_view->leftView()->setItemDelegateForColumn( 1, new MyItemDelegate( this ) ); m_view->leftView()->setHorizontalScrollBarPolicy( Qt::ScrollBarAsNeeded ); m_view->graphicsView()->setHorizontalScrollBarPolicy( Qt::ScrollBarAsNeeded ); DateTimeGrid *grid = new DateTimeGrid(this); grid->timeLine()->setPen(QPen(Qt::red)); grid->timeLine()->setOptions(KGantt::DateTimeTimeLine::UseCustomPen); grid->timeLine()->setInterval(5000); m_view->setGrid(grid); //QItemEditorCreatorBase *creator = new QItemEditorCreator("itemType"); //QItemEditorFactory* factory = new QItemEditorFactory; //factory->registerEditor( QVariant( KGantt::TypeTask ).type(), creator ); //m_view->itemDelegate()->setItemEditorFactory( factory ); setCentralWidget( m_view ); QMenuBar* mb = menuBar(); QMenu* fileMenu = new QMenu( tr( "&File" ) ); #ifndef QT_NO_PRINTER fileMenu->addAction( tr( "&Save as PDF..." ), this, SLOT(slotFileSavePdf()) ); fileMenu->addAction( tr( "&Print..." ), this, SLOT(slotFilePrint()) ); #endif fileMenu->addSeparator(); fileMenu->addAction( tr( "&Quit" ), this, SLOT(slotFileQuit()) ); mb->addMenu( fileMenu ); QMenu* toolsMenu = new QMenu( tr( "&Tools" ) ); toolsMenu->addAction( tr( "&New Item" ), this, SLOT(slotToolsNewItem()) ); toolsMenu->addAction( tr( "&Add Item" ), this, SLOT(slotToolsAppendItem()) ); toolsMenu->addSeparator(); QMenu *alignMenu = toolsMenu->addMenu( tr( "Ali&gn" ) ); alignMenu->addAction( tr( "&Left" ), this, SLOT(slotAlignLeft()) ); alignMenu->addAction( tr( "&Center" ), this, SLOT(slotAlignCenter()) ); alignMenu->addAction( tr( "&Right" ), this, SLOT(slotAlignRight()) ); alignMenu->addAction( tr( "&Hidden" ), this, SLOT(slotAlignHidden()) ); toolsMenu->addSeparator(); toolsMenu->addAction( tr( "&Collapse All" ), this, SLOT(slotCollapseAll()) ); toolsMenu->addAction( tr( "&Expand All" ), this, SLOT(slotExpandAll()) ); mb->addMenu( toolsMenu ); /* slotToolsNewItem(); slotToolsNewItem(); slotToolsNewItem(); for (int i = 0; i < 3; ++i) { m_model->setData(m_model->index(i,2,QModelIndex()), QVariant::fromValue(QDateTime::currentDateTime().addDays(i)), KGantt::StartTimeRole); m_model->setData(m_model->index(i,3,QModelIndex()), QVariant::fromValue(QDateTime::currentDateTime().addDays(i+1)), KGantt::EndTimeRole); } m_view->setConstraintModel(new KGantt::ConstraintModel(m_view)); m_view->constraintModel()->addConstraint(KGantt::Constraint(m_model->index(0,0,QModelIndex()),m_model->index(1,0,QModelIndex()))); m_view->constraintModel()->addConstraint(KGantt::Constraint(m_model->index(1,0,QModelIndex()),m_model->index(2,0,QModelIndex()))); */ } SavePdfDialog::SavePdfDialog(QWidget *parent) : QDialog(parent) { setModal(true); setWindowTitle(tr("Save as PDF")); QVBoxLayout *l = new QVBoxLayout(this); setLayout(l); QHBoxLayout *fileLayout = new QHBoxLayout(this); l->addLayout(fileLayout); QLabel *fileLabel = new QLabel(tr("File:"), this); fileLayout->addWidget(fileLabel); m_fileEdit = new QLineEdit(this); fileLabel->setBuddy(m_fileEdit); m_fileEdit->setText(QFileInfo(QDir::homePath(), "gantt.pdf").absoluteFilePath()); fileLayout->addWidget(m_fileEdit); QPushButton *m_fileButton = new QPushButton("...", this); connect(m_fileButton, SIGNAL(clicked()), this, SLOT(fileButtonClicked())); fileLayout->addWidget(m_fileButton); m_rowLabels = new QCheckBox(tr("Row Header"), this); m_rowLabels->setChecked(true); l->addWidget(m_rowLabels); m_columnLabels = new QCheckBox(tr("Column Header"), this); m_columnLabels->setChecked(true); l->addWidget(m_columnLabels); QDialogButtonBox *btnBox = new QDialogButtonBox(this); btnBox->setStandardButtons(QDialogButtonBox::Save | QDialogButtonBox::Cancel); connect(btnBox, SIGNAL(accepted()), this, SLOT(accept())); connect(btnBox, SIGNAL(rejected()), this, SLOT(reject())); l->addWidget(btnBox); resize(QSize(400, 100).expandedTo(minimumSizeHint())); } void SavePdfDialog::fileButtonClicked() { const QString file = QFileDialog::getSaveFileName(this, tr("Choose PDF File..."), QString(), tr("PDF files (*.pdf)")); if (!file.isEmpty()) m_fileEdit->setText(file); } void MainWindow::slotFileSavePdf() { #ifndef QT_NO_PRINTER SavePdfDialog dialog(this); if (dialog.exec() != QDialog::Accepted) return; const QString file = dialog.m_fileEdit->text(); if (file.isEmpty()) return; const bool drawRowLabels = dialog.m_rowLabels->isChecked(); const bool drawColumnLabels = dialog.m_columnLabels->isChecked(); QPrinter printer(QPrinter::HighResolution); printer.setOrientation(QPrinter::Landscape); printer.setColorMode(QPrinter::Color); printer.setPageMargins(0.2, 0.2, 0.2, 0.2, QPrinter::Point); printer.setOutputFormat(QPrinter::PdfFormat); printer.setOutputFileName(file); m_view->print(&printer, drawRowLabels, drawColumnLabels); #endif } void MainWindow::slotFilePrint() { #ifndef QT_NO_PRINTER QPrinter printer(QPrinter::HighResolution); printer.setOrientation(QPrinter::Landscape); printer.setColorMode(QPrinter::Color); QPrintDialog dialog(&printer, this); if (dialog.exec() != QDialog::Accepted) return; m_view->print(&printer); #endif } void MainWindow::slotFileQuit() { // TODO QApplication::instance()->quit(); } void MainWindow::slotToolsNewItem() { QModelIndex idx = m_view->selectionModel()->currentIndex(); if ( idx.isValid() ) { qDebug() << "MainWindow::slotToolsNewItem" << idx; m_model->insertRows( 0, 1, m_model->index( idx.row(),0,idx.parent() ) ); } else { m_model->insertRows( 0, 1, m_view->rootIndex() ); } } void MainWindow::slotToolsAppendItem() { QModelIndex idx = m_view->selectionModel()->currentIndex(); if ( idx.isValid() ) { qDebug() << "MainWindow::slotToolsAppendItem" << idx; m_model->insertRows( m_model->rowCount( idx ), 1, m_model->index( idx.row(),0,idx.parent() ) ); } else { m_model->insertRows( m_model->rowCount( m_view->rootIndex() ), 1, m_view->rootIndex() ); } } void MainWindow::slotCollapseAll() { // don't use the treeview's collapseAll/expandAll methods but use the one provided by the // view cause that one will take care to update everyt6hing as needed. //QTreeView* view = qobject_cast( m_view->leftView() ); //view->collapseAll(); QModelIndex idx = m_view->selectionModel()->currentIndex(); if ( idx.isValid() ) m_view->collapseAll(); } void MainWindow::slotExpandAll() { // don't use the treeview's collapseAll/expandAll methods but use the one provided by the // view cause that one will take care to update everyt6hing as needed. //QTreeView* view = qobject_cast( m_view->leftView() ); //view->expandAll(); QModelIndex idx = m_view->selectionModel()->currentIndex(); if ( idx.isValid() ) m_view->expandAll(); } void MainWindow::slotAlignLeft() { QModelIndex idx = m_view->selectionModel()->currentIndex(); if ( idx.isValid() ) { m_model->setData( idx, KGantt::StyleOptionGanttItem::Left, KGantt::TextPositionRole ); } } void MainWindow::slotAlignCenter() { QModelIndex idx = m_view->selectionModel()->currentIndex(); if ( idx.isValid() ) { m_model->setData( idx, KGantt::StyleOptionGanttItem::Center, KGantt::TextPositionRole ); } } void MainWindow::slotAlignRight() { QModelIndex idx = m_view->selectionModel()->currentIndex(); if ( idx.isValid() ) { m_model->setData( idx, KGantt::StyleOptionGanttItem::Right, KGantt::TextPositionRole ); } } void MainWindow::slotAlignHidden() { QModelIndex idx = m_view->selectionModel()->currentIndex(); if ( idx.isValid() ) { m_model->setData( idx, KGantt::StyleOptionGanttItem::Hidden, KGantt::TextPositionRole ); } } #include "mainwindow.moc" diff --git a/examples/Gantt/project/projectmodel.h b/examples/Gantt/project/projectmodel.h index 3c5dd20..cd7f01a 100644 --- a/examples/Gantt/project/projectmodel.h +++ b/examples/Gantt/project/projectmodel.h @@ -1,56 +1,56 @@ /** * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KGantt library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef PROJECTMODEL_H #define PROJECTMODEL_H #include class ProjectModel : public QAbstractItemModel { Q_OBJECT public: explicit ProjectModel( QObject* parent = nullptr ); virtual ~ProjectModel(); - /*reimp*/ int rowCount( const QModelIndex& idx ) const Q_DECL_OVERRIDE; - /*reimp*/ int columnCount( const QModelIndex& idx ) const Q_DECL_OVERRIDE; + /*reimp*/ int rowCount( const QModelIndex& idx ) const override; + /*reimp*/ int columnCount( const QModelIndex& idx ) const override; - /*reimp*/ QModelIndex index( int row, int col, const QModelIndex& parent = QModelIndex() ) const Q_DECL_OVERRIDE; - /*reimp*/ QModelIndex parent( const QModelIndex& idx ) const Q_DECL_OVERRIDE; + /*reimp*/ QModelIndex index( int row, int col, const QModelIndex& parent = QModelIndex() ) const override; + /*reimp*/ QModelIndex parent( const QModelIndex& idx ) const override; - /*reimp*/QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const Q_DECL_OVERRIDE; - /*reimp*/ QVariant data( const QModelIndex& idx, int role = Qt::DisplayRole ) const Q_DECL_OVERRIDE; + /*reimp*/QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override; + /*reimp*/ QVariant data( const QModelIndex& idx, int role = Qt::DisplayRole ) const override; /*reimp*/ bool setData( const QModelIndex& idx, const QVariant& value, - int role = Qt::DisplayRole ) Q_DECL_OVERRIDE; + int role = Qt::DisplayRole ) override; - /*reimp*/ bool insertRows( int row, int count, const QModelIndex& parent = QModelIndex() ) Q_DECL_OVERRIDE; + /*reimp*/ bool insertRows( int row, int count, const QModelIndex& parent = QModelIndex() ) override; - /*reimp*/ Qt::ItemFlags flags( const QModelIndex& ) const Q_DECL_OVERRIDE; + /*reimp*/ Qt::ItemFlags flags( const QModelIndex& ) const override; bool load( const QString& filename ); bool save( const QString& filename ); private: class Node; Node* m_root; }; #endif /* PROJECTMODEL_H */ diff --git a/examples/Lines/Advanced/mainwindow.h b/examples/Lines/Advanced/mainwindow.h index a63a453..d28090f 100644 --- a/examples/Lines/Advanced/mainwindow.h +++ b/examples/Lines/Advanced/mainwindow.h @@ -1,71 +1,71 @@ /** * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef MAINWINDOW_H #define MAINWINDOW_H #include "ui_mainwindow.h" #include namespace KChart { class Chart; class LineDiagram; } class MainWindow : public QWidget, private Ui::MainWindow { Q_OBJECT public: MainWindow( QWidget* parent = nullptr ); private: - bool eventFilter(QObject* target, QEvent* event) Q_DECL_OVERRIDE; + bool eventFilter(QObject* target, QEvent* event) override; private slots: void on_lineTypeCB_currentIndexChanged( const QString & text ); void on_paintValuesCB_toggled( bool checked ); void on_centerDataPointsCB_toggled( bool checked ); void on_threeDModeCB_toggled( bool checked ); void on_depthSB_valueChanged( int i ); void on_animateAreasCB_toggled( bool checked ); void on_highlightAreaCB_toggled( bool checked ); void on_highlightAreaSB_valueChanged( int i ); void setHighlightArea( int row, int column, int opacity, bool checked, bool doUpdate ); void on_trackAreasCB_toggled( bool checked ); void on_trackAreasSB_valueChanged( int i ); void setTrackedArea( int column, bool checked, bool doUpdate ); void slot_timerFired(); void on_reverseHorizontalCB_toggled( bool checked ); void on_reverseVerticalCB_toggled( bool checked ); private: KChart::Chart* m_chart; KChart::LineDiagram* m_lines; TableModel m_model; int m_curRow; int m_curColumn; int m_curOpacity; }; #endif /* MAINWINDOW_H */ diff --git a/examples/NoValues/mainwindow.cpp b/examples/NoValues/mainwindow.cpp index 516778b..bc04e88 100644 --- a/examples/NoValues/mainwindow.cpp +++ b/examples/NoValues/mainwindow.cpp @@ -1,125 +1,125 @@ /** * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "mainwindow.h" #include #include #include #include #include #include #include #include #include using namespace KChart; class EmptyModel : public QAbstractItemModel { public: EmptyModel( QObject* parent = nullptr ) : QAbstractItemModel( parent ) { //qDebug() << "EmptyModel::EmptyModel()"; } ~EmptyModel() { //qDebug() << "EmptyModel::~EmptyModel()"; } - int columnCount( const QModelIndex& parent = QModelIndex() ) const Q_DECL_OVERRIDE + int columnCount( const QModelIndex& parent = QModelIndex() ) const override { Q_UNUSED( parent ); //qDebug() << "EmptyModel::columnCount(...)"; return 0; } - int rowCount( const QModelIndex& parent = QModelIndex() ) const Q_DECL_OVERRIDE + int rowCount( const QModelIndex& parent = QModelIndex() ) const override { Q_UNUSED( parent ); //qDebug() << "EmptyModel::rowCount(...)"; return 0; } // NOTE: The following method will not be called by KD Chart, // because the model is returning 0 for columnCount() / rowCount(). - QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const Q_DECL_OVERRIDE + QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const override { Q_UNUSED( role ); qDebug() << "EmptyModel::data(" << index.row() << index.column() << ")"; Q_ASSERT_X( false, "EmptyModel::data", "We should not end here..." ); return QVariant(); } - QModelIndex index( int row, int column, const QModelIndex& parent = QModelIndex() ) const Q_DECL_OVERRIDE + QModelIndex index( int row, int column, const QModelIndex& parent = QModelIndex() ) const override { Q_UNUSED( row ); Q_UNUSED( column ); Q_UNUSED( parent ); //qDebug() << "EmptyModel::index(" << row << column << ")"; return QModelIndex(); } - QModelIndex parent( const QModelIndex& parent ) const Q_DECL_OVERRIDE + QModelIndex parent( const QModelIndex& parent ) const override { Q_UNUSED( parent ); //qDebug() << "EmptyModel::parent(...)"; return QModelIndex(); } }; MainWindow::MainWindow( QWidget* parent ) : QWidget( parent ) { QHBoxLayout* chartLayout = new QHBoxLayout( this ); m_chart = new Chart(); m_chart->setGlobalLeading( 5, 5, 5, 5 ); chartLayout->addWidget( m_chart ); m_model = new EmptyModel( this ); // model contains no data at all // Set up the diagram m_bars = new LineDiagram(); m_bars->setModel( m_model ); CartesianAxis *xAxis = new CartesianAxis( m_bars ); CartesianAxis *yAxis = new CartesianAxis ( m_bars ); xAxis->setPosition ( KChart::CartesianAxis::Bottom ); yAxis->setPosition ( KChart::CartesianAxis::Left ); xAxis->setTitleText ( "Abscissa axis at the bottom" ); yAxis->setTitleText ( "Ordinate axis at the left side" ); m_bars->addAxis( xAxis ); m_bars->addAxis( yAxis ); m_chart->coordinatePlane()->replaceDiagram( m_bars ); Legend* legend = new Legend( m_bars, m_chart ); legend->setPosition( Position::South ); legend->setAlignment( Qt::AlignCenter ); legend->setShowLines( true ); legend->setTitleText("This is the legend - showing no data either"); legend->setOrientation( Qt::Horizontal ); legend->addDiagram( m_bars ); m_chart->addLegend( legend ); } diff --git a/examples/Plotter/BigDataset/Model.h b/examples/Plotter/BigDataset/Model.h index 92dfa3f..e1892c6 100644 --- a/examples/Plotter/BigDataset/Model.h +++ b/examples/Plotter/BigDataset/Model.h @@ -1,68 +1,68 @@ /** * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef MODEL_H #define MODEL_H #include #include #include class Model : public QAbstractItemModel { Q_OBJECT public: enum Function { SineFunction = 0, TriangleFunction, SquareFunction, NoiseFunction, OneDivSineFunction, SineOneDivFunction }; Model(); - int columnCount( const QModelIndex& parent ) const Q_DECL_OVERRIDE; - int rowCount( const QModelIndex& parent ) const Q_DECL_OVERRIDE; + int columnCount( const QModelIndex& parent ) const override; + int rowCount( const QModelIndex& parent ) const override; - QModelIndex index( int row, int column, const QModelIndex& parent ) const Q_DECL_OVERRIDE; - QModelIndex parent( const QModelIndex& index ) const Q_DECL_OVERRIDE; + QModelIndex index( int row, int column, const QModelIndex& parent ) const override; + QModelIndex parent( const QModelIndex& index ) const override; - QVariant data( const QModelIndex& index, int role ) const Q_DECL_OVERRIDE; + QVariant data( const QModelIndex& index, int role ) const override; void setFunction( Function f ); void appendPoints( int numPoints ); public slots: void setRunning( bool ); private slots: void appendPoint(); private: qreal nextFunctionValue(); qreal m_x; Function m_function; QVector< qreal > m_data; QTimer m_appendTimer; }; #endif diff --git a/examples/Plotter/Timeline/timeaxis.h b/examples/Plotter/Timeline/timeaxis.h index 2e6bda3..42f9061 100644 --- a/examples/Plotter/Timeline/timeaxis.h +++ b/examples/Plotter/Timeline/timeaxis.h @@ -1,34 +1,34 @@ /** * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef TIMEAXIS_H #define TIMEAXIS_H #include class TimeAxis : public KChart::CartesianAxis { Q_OBJECT public: explicit TimeAxis( KChart::AbstractCartesianDiagram* parent ); - const QString customizedLabel( const QString& label ) const Q_DECL_OVERRIDE; + const QString customizedLabel( const QString& label ) const override; }; #endif diff --git a/examples/Plotter/Timeline/timechartmodel.h b/examples/Plotter/Timeline/timechartmodel.h index 1999809..98425a6 100644 --- a/examples/Plotter/Timeline/timechartmodel.h +++ b/examples/Plotter/Timeline/timechartmodel.h @@ -1,49 +1,49 @@ /** * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef TIMECHARTMODEL_H #define TIMECHARTMODEL_H #include #include #include class TimeChartModel : public QSortFilterProxyModel { Q_OBJECT public: explicit TimeChartModel( QObject* parent = nullptr ); QPair< QDateTime, QDateTime > visibleRange() const; public Q_SLOTS: void setVisibleRange( const QDateTime& start, const QDateTime& end ); void setVisibleStart( const QDateTime& start ); void setVisibleEnd( const QDateTime& end ); - QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const Q_DECL_OVERRIDE; + QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const override; protected: - bool filterAcceptsRow( int source_row, const QModelIndex& source_parent ) const Q_DECL_OVERRIDE; + bool filterAcceptsRow( int source_row, const QModelIndex& source_parent ) const override; private: QPair< QDateTime, QDateTime > range; }; #endif diff --git a/examples/Sql/main.cpp b/examples/Sql/main.cpp index 0fbbfca..96a43f6 100644 --- a/examples/Sql/main.cpp +++ b/examples/Sql/main.cpp @@ -1,146 +1,146 @@ /** * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace KChart; /** * Proxymodel that transposes columns and rows. */ class TransposeProxyModel : public QAbstractProxyModel{ public: explicit TransposeProxyModel(QObject* parent = nullptr) : QAbstractProxyModel(parent) {} virtual ~TransposeProxyModel() {} - QModelIndex mapFromSource ( const QModelIndex & sourceIndex ) const Q_DECL_OVERRIDE { return index(sourceIndex.column(), sourceIndex.row()); } - QModelIndex mapToSource ( const QModelIndex & proxyIndex ) const Q_DECL_OVERRIDE { return sourceModel()->index(proxyIndex.column(), proxyIndex.row()); } - QModelIndex index(int r, int c, const QModelIndex &ind=QModelIndex()) const Q_DECL_OVERRIDE { Q_UNUSED(ind) return createIndex(r,c); } - QModelIndex parent(const QModelIndex&) const Q_DECL_OVERRIDE { return QModelIndex(); } - int rowCount(const QModelIndex &) const Q_DECL_OVERRIDE { return sourceModel()->columnCount(); } - int columnCount(const QModelIndex &) const Q_DECL_OVERRIDE { return sourceModel()->rowCount(); } - QVariant data(const QModelIndex &ind, int role) const Q_DECL_OVERRIDE { return sourceModel()->data(mapToSource(ind), role); } + QModelIndex mapFromSource ( const QModelIndex & sourceIndex ) const override { return index(sourceIndex.column(), sourceIndex.row()); } + QModelIndex mapToSource ( const QModelIndex & proxyIndex ) const override { return sourceModel()->index(proxyIndex.column(), proxyIndex.row()); } + QModelIndex index(int r, int c, const QModelIndex &ind=QModelIndex()) const override { Q_UNUSED(ind) return createIndex(r,c); } + QModelIndex parent(const QModelIndex&) const override { return QModelIndex(); } + int rowCount(const QModelIndex &) const override { return sourceModel()->columnCount(); } + int columnCount(const QModelIndex &) const override { return sourceModel()->rowCount(); } + QVariant data(const QModelIndex &ind, int role) const override { return sourceModel()->data(mapToSource(ind), role); } }; /** * The example that creates the SQL-model, adds data to it and display the data in a model. */ class ChartWidget : public QWidget { Q_OBJECT public: explicit ChartWidget(QWidget* parent = nullptr) : QWidget(parent) , m_model(nullptr) { QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); db.setHostName("localhost"); db.setDatabaseName(":memory:"); // in memory rather then in a file //db.setUserName(""); //db.setPassword(""); bool ok = db.open(); Q_ASSERT(ok); Q_UNUSED(ok) // release mode QSqlQuery createTableQuery = db.exec("CREATE TABLE IF NOT EXISTS MyTable (col1 INT NOT NULL PRIMARY KEY, col2 INT);"); Q_ASSERT(!createTableQuery.lastError().isValid()); m_model = new QSqlTableModel(this, db); m_model->setTable("MyTable"); m_model->setEditStrategy(QSqlTableModel::OnRowChange); m_model->setSort(0, Qt::AscendingOrder); ok = m_model->select(); Q_ASSERT(ok); m_model->setHeaderData(0, Qt::Horizontal, tr("Column 1")); m_model->setHeaderData(1, Qt::Horizontal, tr("Column 2")); for (int row = 0; row < 3; ++row) { QSqlRecord rec; for (int column = 0; column < 2; ++column) { QSqlField field(column==0?"col1":"col2",QVariant::Int); field.setValue(row+1 * column); rec.append(field); } ok = m_model->insertRecord(-1, rec); Q_ASSERT(ok); } BarDiagram* diagram = new BarDiagram; TransposeProxyModel* proxymodel = new TransposeProxyModel(this); proxymodel->setSourceModel(m_model); diagram->setModel(proxymodel); m_chart.coordinatePlane()->replaceDiagram(diagram); // Add at one Header and set it up HeaderFooter* header = new HeaderFooter( &m_chart ); header->setPosition( Position::North ); header->setText( "A Simple Bar Chart" ); m_chart.addHeaderFooter( header ); // Configure the plane Frame attributes FrameAttributes pfa; pfa.setPen( QPen ( QBrush( Qt::blue ), 2 ) ); pfa.setVisible( true ); diagram->coordinatePlane()->setFrameAttributes( pfa ); // Configure the header Frame attributes FrameAttributes hfa; hfa.setPen( QPen ( QBrush( Qt::darkGray ), 2 ) ); hfa.setPadding( 2 ); hfa.setVisible( true ); header->setFrameAttributes( hfa ); QVBoxLayout* l = new QVBoxLayout(this); l->addWidget(&m_chart); setLayout(l); } private: Chart m_chart; QSqlTableModel *m_model; }; int main( int argc, char** argv ) { QApplication app( argc, argv ); ChartWidget w; w.show(); return app.exec(); } #include "main.moc" diff --git a/examples/Zoom/Keyboard/zoomwidget.h b/examples/Zoom/Keyboard/zoomwidget.h index a8d751a..c42d112 100644 --- a/examples/Zoom/Keyboard/zoomwidget.h +++ b/examples/Zoom/Keyboard/zoomwidget.h @@ -1,41 +1,41 @@ /** * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ZOOMWIDGET_H #define ZOOMWIDGET_H #include class ZoomWidget : public KChart::Widget { Q_OBJECT public: explicit ZoomWidget( QWidget* parent ); protected: QPointF findNewZoomCenter( const QPoint & pos ); - void mousePressEvent( QMouseEvent * e ) Q_DECL_OVERRIDE; - void wheelEvent( QWheelEvent* e ) Q_DECL_OVERRIDE; - void keyPressEvent( QKeyEvent* e ) Q_DECL_OVERRIDE; + void mousePressEvent( QMouseEvent * e ) override; + void wheelEvent( QWheelEvent* e ) override; + void keyPressEvent( QKeyEvent* e ) override; }; #endif /* ZOOMWIDGET_H */ diff --git a/examples/demo/colorslider.h b/examples/demo/colorslider.h index a3b9d75..4654229 100644 --- a/examples/demo/colorslider.h +++ b/examples/demo/colorslider.h @@ -1,56 +1,56 @@ /** * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef COLORSLIDER_H #define COLORSLIDER_H #include class ColorSlider : public QAbstractSlider { Q_OBJECT Q_PROPERTY( QColor startColor READ startColor WRITE setStartColor NOTIFY startColorChanged ) Q_PROPERTY( QColor endColor READ endColor WRITE setStartColor NOTIFY endColorChanged ) public: explicit ColorSlider( QWidget *parent = nullptr ); ~ColorSlider(); QColor startColor() const; void setStartColor( const QColor &color ); QColor endColor() const; void setEndColor( const QColor &color ); - QSize sizeHint() const Q_DECL_OVERRIDE; + QSize sizeHint() const override; protected: - void paintEvent( QPaintEvent *event ) Q_DECL_OVERRIDE; - void mousePressEvent(QMouseEvent *event ) Q_DECL_OVERRIDE; - void mouseReleaseEvent(QMouseEvent *event ) Q_DECL_OVERRIDE; - void mouseMoveEvent( QMouseEvent *event ) Q_DECL_OVERRIDE; + void paintEvent( QPaintEvent *event ) override; + void mousePressEvent(QMouseEvent *event ) override; + void mouseReleaseEvent(QMouseEvent *event ) override; + void mouseMoveEvent( QMouseEvent *event ) override; Q_SIGNALS: void startColorChanged(); void endColorChanged(); public Q_SLOTS: private: class Private; Private *d; }; #endif // COLORSLIDER_H diff --git a/examples/tools/TableModel.h b/examples/tools/TableModel.h index 0811fbe..bb6d45e 100644 --- a/examples/tools/TableModel.h +++ b/examples/tools/TableModel.h @@ -1,149 +1,149 @@ /** * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef TABLEMODEL_H #define TABLEMODEL_H #include #include #include #include "testtools_export.h" #include /** TableModel uses a simple rectangular vector of vectors to represent a data table that can be displayed in regular Qt Interview views. Additionally, it provides a method to load CSV files exported by OpenOffice Calc in the default configuration. This allows to prepare test data using spreadsheet software. It expects the CSV files in the subfolder ./modeldata. If the application is started from another location, it will ask for the location of the model data files. */ class TESTTOOLS_EXPORT TableModel : public QAbstractTableModel { Q_OBJECT public: TableModel( QObject* parent = nullptr ); ~TableModel(); /** Return header data from the model. The model will use the first data row and the first data column of the physical data as source of column and row header data. This data is not exposed as model data, that means, the first model row and column will start at index (0, 0). */ QVariant headerData( int section, Qt::Orientation orientation, - int role = Qt::DisplayRole ) const Q_DECL_OVERRIDE; + int role = Qt::DisplayRole ) const override; - int rowCount( const QModelIndex& parent = QModelIndex() ) const Q_DECL_OVERRIDE; + int rowCount( const QModelIndex& parent = QModelIndex() ) const override; - int columnCount( const QModelIndex& parent = QModelIndex() ) const Q_DECL_OVERRIDE; + int columnCount( const QModelIndex& parent = QModelIndex() ) const override; - QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const Q_DECL_OVERRIDE; + QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const override; - bool setData( const QModelIndex& index, const QVariant& value, int role = Qt::EditRole ) Q_DECL_OVERRIDE; + bool setData( const QModelIndex& index, const QVariant& value, int role = Qt::EditRole ) override; /** Load the table from a comma separated file. * * The files are supposed to be Unicode (UTF8), have commas (',') as * delimiters, and quotes ('"') as text delimiters. All lines are expected * to provide the same number of fields. HINT: This is the default way * OO.o-Calc exports CSV files. * The cell data is expected to be floating point values, except for the * first row and the first column, where string values are exected (those * will be used as axis descriptors). If values cannot be converted to * qreals, their string representation will be used. * * @returns true if successful, false otherwise * * @sa titleText */ bool loadFromCSV( const QString& filename ); /** * If both DataHasHorizontalHeaders and DataHasVerticalHeaders is * set true (that's the default setting) then loadFromCSV will interpret * the first field in the first row as title-text. * If no such field is found the loadFromCSV will set the title text to * an empty string. * * The text is stored and can be retrieved via titleText(), but the model * itself does nothing else with it: The calling application may use this * method and e.g. display the text as header or as title of the Legend * or as caption of the window ... * * @sa loadFromCSV */ const QString titleText() const { return m_titleText; } /** * Setting the title text has no effect except that the text * can then be retrieved via titleText. * * TableModel is just storing this data but it does nothing * else with it, nor does Qt's IndeView model make use of it. */ void setTitleText( const QString& txt ) { m_titleText = txt; } /** Make the model invalid, that is, provide no data. */ void clear(); /** * Set to false if the data has no horizontal header */ void setDataHasHorizontalHeaders( bool value ) { m_dataHasHorizontalHeaders = value; } /** * Set to false if the data has no vertical header */ void setDataHasVerticalHeaders( bool value ) { m_dataHasVerticalHeaders = value; } /** * setSupplyHeaderData(false) allows to prevent the model from supplying header data, * even if parsing found any */ void setSupplyHeaderData( bool value ) { m_supplyHeaderData = value; } protected: // the vector of rows: QVector< QVector > m_rows; private: // the header data: QStringList m_horizontalHeaderData; QStringList m_verticalHeaderData; QString m_titleText; bool m_dataHasHorizontalHeaders; bool m_dataHasVerticalHeaders; bool m_supplyHeaderData; }; #endif diff --git a/qtests/DrawIntoPainter/framewidget.h b/qtests/DrawIntoPainter/framewidget.h index d6d2f73..e682e7d 100644 --- a/qtests/DrawIntoPainter/framewidget.h +++ b/qtests/DrawIntoPainter/framewidget.h @@ -1,47 +1,47 @@ /** * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef FRAMEWIDGET_H #define FRAMEWIDGET_H #include namespace KChart { class Chart; } class FrameWidget : public QWidget { Q_OBJECT public: explicit FrameWidget( QWidget * parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags() ); - void paintEvent( QPaintEvent* ) Q_DECL_OVERRIDE; + void paintEvent( QPaintEvent* ) override; void setChart( KChart::Chart* chart ); private: KChart::Chart* mChart; }; #endif /* FRAMEWIDGET_H */ diff --git a/qtests/DrawIntoPainter/mainwindow.h b/qtests/DrawIntoPainter/mainwindow.h index 4836853..9fe4644 100644 --- a/qtests/DrawIntoPainter/mainwindow.h +++ b/qtests/DrawIntoPainter/mainwindow.h @@ -1,81 +1,81 @@ /** * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef MAINWINDOW_H #define MAINWINDOW_H #include "ui_mainwindow.h" #include #include namespace KChart { class Chart; class DatasetProxyModel; class LineDiagram; class Legend; } class QLabel; class MainWindow : public QWidget, private Ui::MainWindow { Q_OBJECT public: MainWindow( QWidget* parent = nullptr ); void updateData(QString data); protected: /** * Adjusts the two small charts when the window is resized. */ - /* reimp */ void resizeEvent ( QResizeEvent * ) Q_DECL_OVERRIDE; + /* reimp */ void resizeEvent ( QResizeEvent * ) override; private slots: void setLineType( const QString & text ); void setLegendVisible( bool visible ); void setValuesVisible( bool visible ); void setMarkersVisible( bool visible ); void updateMarkers(); void updateMarkersHeight(); void updateMarkersWidth(); void updateAreas( bool visible ); void updateAreasTransparency(); void setZoomFactor( qreal factor ); void setHPos( int value ); void setVPos( int value ); void saveChart(); private: void paintMarkers( bool checked, const QSize& printSize ); private: KChart::Chart* m_chart; TableModel m_model; KChart::DatasetProxyModel* m_datasetProxy; KChart::LineDiagram* m_lines; KChart::Legend* m_legend; QPixmap m_pix1, m_pix2; QLabel* m_smallChart1; QLabel* m_smallChart2; }; #endif /* MAINWINDOW_H */ diff --git a/qtests/ParamVsParam/ModelParamVsParamPlot.h b/qtests/ParamVsParam/ModelParamVsParamPlot.h index 3f47f97..17024bd 100644 --- a/qtests/ParamVsParam/ModelParamVsParamPlot.h +++ b/qtests/ParamVsParam/ModelParamVsParamPlot.h @@ -1,54 +1,54 @@ /** * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef SUMGUI_MODELPARAMVSPARAMPLOT_H #define SUMGUI_MODELPARAMVSPARAMPLOT_H #include class ModelParamVsParamPlot: public QSortFilterProxyModel { public: ModelParamVsParamPlot( QAbstractItemModel *p_sourceModel, int p_column1, int p_column2, QObject *p_parent = nullptr); int columnCount( - const QModelIndex &p_parent = QModelIndex()) const Q_DECL_OVERRIDE; + const QModelIndex &p_parent = QModelIndex()) const override; protected: QVariant data( const QModelIndex &p_index, - int p_role = Qt::DisplayRole) const Q_DECL_OVERRIDE; + int p_role = Qt::DisplayRole) const override; bool filterAcceptsColumn( int p_source_column, - const QModelIndex &p_source_parent) const Q_DECL_OVERRIDE; + const QModelIndex &p_source_parent) const override; private: int m_column1; int m_column2; }; // class ModelParamVsParamPlot #endif // SUMGUI_MODELPARAMVSPARAMPLOT_H diff --git a/qtests/QLayout/main.cpp b/qtests/QLayout/main.cpp index e2f4102..380581a 100644 --- a/qtests/QLayout/main.cpp +++ b/qtests/QLayout/main.cpp @@ -1,154 +1,154 @@ /** * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include #include #include #define KDAB_REIMP class MyLegendWidget : public QWidget { Q_OBJECT public: explicit MyLegendWidget( QWidget* parent ) : QWidget( parent ) { } void makeSizeFixed() { setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ); // like Legend setFixedSize( 50, 50 ); // hmm Legend has a layout instead. //QGridLayout* layout = new QGridLayout( this ); // ... } protected: - KDAB_REIMP void resizeEvent( QResizeEvent* ) Q_DECL_OVERRIDE { + KDAB_REIMP void resizeEvent( QResizeEvent* ) override { // Note that this is never called unless the widget is shown. qDebug() << "resizeEvent " << size(); } }; class MyWidgetItem : public QWidgetItem { public: explicit MyWidgetItem(QWidget *w) : QWidgetItem(w) { } - KDAB_REIMP bool isEmpty() const Q_DECL_OVERRIDE { return false; } + KDAB_REIMP bool isEmpty() const override { return false; } }; class TestQLayout : public QObject { Q_OBJECT private slots: // This is very much like KChart::Chart does with legends void testBoxLayoutHiddenWidget() { QBoxLayout* vLayout = new QVBoxLayout; MyLegendWidget* widget1 = new MyLegendWidget( nullptr ); widget1->resize( 10, 10 ); // Adding a hidden widget doesn't work, the layout ignores it // This is why we created MyWidgetItem above, then the layout works //vLayout->addWidget( widget1 ); MyWidgetItem* widgetItem = new MyWidgetItem( widget1 ); vLayout->addItem( widgetItem ); QRect geom( 100, 100, 800, 800 ); vLayout->setGeometry( geom ); //vLayout->activate(); // not needed QCOMPARE( vLayout->geometry(), geom ); qDebug() << "widget1: " << widget1->geometry(); QCOMPARE( widget1->geometry(), geom ); delete widget1; delete vLayout; } void testBoxLayoutChildWidget() { QWidget* topLevelWidget = new QWidget( nullptr ); // This time the layout is associated with a widget, like d->layout in KChart::Chart. QBoxLayout* vLayout = new QVBoxLayout( topLevelWidget ); MyLegendWidget* widget1 = new MyLegendWidget( topLevelWidget ); MyWidgetItem* widgetItem = new MyWidgetItem( widget1 ); vLayout->addItem( widgetItem ); //vLayout->activate(); QRect geom( 100, 100, 800, 800 ); vLayout->setGeometry( geom ); qDebug() << "widget1: " << widget1->geometry(); // int marg = topLevelWidget->style()->pixelMetric( QStyle::PM_DefaultTopLevelMargin ); int marg = vLayout->margin(); QCOMPARE( widget1->geometry(), geom.adjusted(marg,marg,-marg,-marg) ); geom = QRect( 10, 10, 80, 80 ); vLayout->setGeometry( geom ); qDebug() << "widget1: " << widget1->geometry(); QCOMPARE( widget1->geometry(), geom.adjusted(marg,marg,-marg,-marg) ); // And now let's show the widget for real geom = QRect( 0, 0, 500, 100 ); topLevelWidget->resize( geom.size() ); topLevelWidget->show(); QApplication::sendPostedEvents(); QRect expected = geom.adjusted(marg,marg,-marg,-marg); qDebug() << "widget1: " << widget1->frameGeometry() << "expecting" << expected; // this test is quite useless... //QCOMPARE( widget1->frameGeometry(), expected ); QVERIFY( widget1->isVisible() ); delete topLevelWidget; } void testSubGridLayout() { QWidget* topLevelWidget = new QWidget( nullptr ); QBoxLayout* vLayout = new QVBoxLayout( topLevelWidget ); QGridLayout* gridLayout = new QGridLayout(); QLineEdit* lineEdit = new QLineEdit( topLevelWidget ); MyWidgetItem* lineEditWidgetItem = new MyWidgetItem( lineEdit ); gridLayout->addItem( lineEditWidgetItem, 0, 0 ); MyLegendWidget* widget1 = new MyLegendWidget( topLevelWidget ); widget1->makeSizeFixed(); MyWidgetItem* widgetItem = new MyWidgetItem( widget1 ); gridLayout->addItem( widgetItem, 1, 1 ); vLayout->addLayout( gridLayout ); QRect geom( 100, 100, 800, 800 ); vLayout->setGeometry( geom ); qDebug() << "widget1: " << widget1->geometry(); QVERIFY( widget1->width() > 0 ); delete topLevelWidget; } }; QTEST_MAIN(TestQLayout) #include "main.moc" diff --git a/src/KChart/Cartesian/DiagramFlavors/KChartNormalBarDiagram_p.h b/src/KChart/Cartesian/DiagramFlavors/KChartNormalBarDiagram_p.h index 3522748..3c9169f 100644 --- a/src/KChart/Cartesian/DiagramFlavors/KChartNormalBarDiagram_p.h +++ b/src/KChart/Cartesian/DiagramFlavors/KChartNormalBarDiagram_p.h @@ -1,49 +1,49 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTNORMALBARDIAGRAM_P_H #define KCHARTNORMALBARDIAGRAM_P_H // // W A R N I N G // ------------- // // This file is not part of the KD Chart API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include "KChartBarDiagram_p.h" namespace KChart { class NormalBarDiagram : public BarDiagram::BarDiagramType { public: explicit NormalBarDiagram( BarDiagram* ); virtual ~NormalBarDiagram() {} - BarDiagram::BarType type() const Q_DECL_OVERRIDE; - const QPair calculateDataBoundaries() const Q_DECL_OVERRIDE; - void paint( PaintContext* ctx ) Q_DECL_OVERRIDE; + BarDiagram::BarType type() const override; + const QPair calculateDataBoundaries() const override; + void paint( PaintContext* ctx ) override; }; } #endif diff --git a/src/KChart/Cartesian/DiagramFlavors/KChartNormalLineDiagram_p.h b/src/KChart/Cartesian/DiagramFlavors/KChartNormalLineDiagram_p.h index 5ba60b0..7edb3c5 100644 --- a/src/KChart/Cartesian/DiagramFlavors/KChartNormalLineDiagram_p.h +++ b/src/KChart/Cartesian/DiagramFlavors/KChartNormalLineDiagram_p.h @@ -1,49 +1,49 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTNORMALLINEDIAGRAM_P_H #define KCHARTNORMALLINEDIAGRAM_P_H // // W A R N I N G // ------------- // // This file is not part of the KD Chart API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include "KChartLineDiagram_p.h" namespace KChart { class NormalLineDiagram : public LineDiagram::LineDiagramType { public: explicit NormalLineDiagram( LineDiagram* ); virtual ~NormalLineDiagram() {} - LineDiagram::LineType type() const Q_DECL_OVERRIDE; - const QPair calculateDataBoundaries() const Q_DECL_OVERRIDE; - void paint( PaintContext* ctx ) Q_DECL_OVERRIDE; + LineDiagram::LineType type() const override; + const QPair calculateDataBoundaries() const override; + void paint( PaintContext* ctx ) override; }; } #endif diff --git a/src/KChart/Cartesian/DiagramFlavors/KChartNormalLyingBarDiagram_p.h b/src/KChart/Cartesian/DiagramFlavors/KChartNormalLyingBarDiagram_p.h index ebb971f..235f28d 100644 --- a/src/KChart/Cartesian/DiagramFlavors/KChartNormalLyingBarDiagram_p.h +++ b/src/KChart/Cartesian/DiagramFlavors/KChartNormalLyingBarDiagram_p.h @@ -1,49 +1,49 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTNORMALLYINGBARDIAGRAM_P_H #define KCHARTNORMALLYINGBARDIAGRAM_P_H // // W A R N I N G // ------------- // // This file is not part of the KD Chart API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include "KChartBarDiagram_p.h" namespace KChart { class NormalLyingBarDiagram : public BarDiagram::BarDiagramType { public: explicit NormalLyingBarDiagram( BarDiagram* ); virtual ~NormalLyingBarDiagram() {} - BarDiagram::BarType type() const Q_DECL_OVERRIDE; - const QPair calculateDataBoundaries() const Q_DECL_OVERRIDE; - void paint( PaintContext* ctx ) Q_DECL_OVERRIDE; + BarDiagram::BarType type() const override; + const QPair calculateDataBoundaries() const override; + void paint( PaintContext* ctx ) override; }; } #endif diff --git a/src/KChart/Cartesian/DiagramFlavors/KChartNormalPlotter_p.h b/src/KChart/Cartesian/DiagramFlavors/KChartNormalPlotter_p.h index 6b6e0c7..dd09b8a 100644 --- a/src/KChart/Cartesian/DiagramFlavors/KChartNormalPlotter_p.h +++ b/src/KChart/Cartesian/DiagramFlavors/KChartNormalPlotter_p.h @@ -1,49 +1,49 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTNORMALPLOTTER_P_H #define KCHARTNORMALPLOTTER_P_H // // W A R N I N G // ------------- // // This file is not part of the KD Chart API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include "KChartPlotter_p.h" namespace KChart { class NormalPlotter : public Plotter::PlotterType { public: explicit NormalPlotter( Plotter* ); virtual ~NormalPlotter() {} - Plotter::PlotType type() const Q_DECL_OVERRIDE; - const QPair< QPointF, QPointF > calculateDataBoundaries() const Q_DECL_OVERRIDE; - void paint( PaintContext* ctx ) Q_DECL_OVERRIDE; + Plotter::PlotType type() const override; + const QPair< QPointF, QPointF > calculateDataBoundaries() const override; + void paint( PaintContext* ctx ) override; }; } #endif diff --git a/src/KChart/Cartesian/DiagramFlavors/KChartPercentBarDiagram_p.h b/src/KChart/Cartesian/DiagramFlavors/KChartPercentBarDiagram_p.h index 1e3509a..7e39d3c 100644 --- a/src/KChart/Cartesian/DiagramFlavors/KChartPercentBarDiagram_p.h +++ b/src/KChart/Cartesian/DiagramFlavors/KChartPercentBarDiagram_p.h @@ -1,40 +1,40 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTPERCENTBARDIAGRAM_P_H #define KCHARTPERCENTBARDIAGRAM_P_H #include "KChartBarDiagram_p.h" namespace KChart { class PercentBarDiagram : public BarDiagram::BarDiagramType { public: explicit PercentBarDiagram( BarDiagram* ); virtual ~PercentBarDiagram() {} - BarDiagram::BarType type() const Q_DECL_OVERRIDE; - const QPair calculateDataBoundaries() const Q_DECL_OVERRIDE; - void paint( PaintContext* ctx ) Q_DECL_OVERRIDE; + BarDiagram::BarType type() const override; + const QPair calculateDataBoundaries() const override; + void paint( PaintContext* ctx ) override; }; } #endif diff --git a/src/KChart/Cartesian/DiagramFlavors/KChartPercentLineDiagram_p.h b/src/KChart/Cartesian/DiagramFlavors/KChartPercentLineDiagram_p.h index b05ed11..2b4fe6c 100644 --- a/src/KChart/Cartesian/DiagramFlavors/KChartPercentLineDiagram_p.h +++ b/src/KChart/Cartesian/DiagramFlavors/KChartPercentLineDiagram_p.h @@ -1,39 +1,39 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTPERCENTLINEDIAGRAM_P_H #define KCHARTPERCENTLINEDIAGRAM_P_H #include "KChartLineDiagram_p.h" namespace KChart { class PercentLineDiagram : public LineDiagram::LineDiagramType { public: explicit PercentLineDiagram( LineDiagram* ); virtual ~PercentLineDiagram() {} - LineDiagram::LineType type() const Q_DECL_OVERRIDE; - const QPair calculateDataBoundaries() const Q_DECL_OVERRIDE; - void paint( PaintContext* ctx ) Q_DECL_OVERRIDE; + LineDiagram::LineType type() const override; + const QPair calculateDataBoundaries() const override; + void paint( PaintContext* ctx ) override; }; } #endif diff --git a/src/KChart/Cartesian/DiagramFlavors/KChartPercentLyingBarDiagram_p.h b/src/KChart/Cartesian/DiagramFlavors/KChartPercentLyingBarDiagram_p.h index d563336..2d172fa 100644 --- a/src/KChart/Cartesian/DiagramFlavors/KChartPercentLyingBarDiagram_p.h +++ b/src/KChart/Cartesian/DiagramFlavors/KChartPercentLyingBarDiagram_p.h @@ -1,39 +1,39 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTPERCENTLYINGBARDIAGRAM_P_H #define KCHARTPERCENTLYINGBARDIAGRAM_P_H #include "KChartBarDiagram_p.h" namespace KChart { class PercentLyingBarDiagram : public BarDiagram::BarDiagramType { public: explicit PercentLyingBarDiagram( BarDiagram* ); virtual ~PercentLyingBarDiagram() {} - BarDiagram::BarType type() const Q_DECL_OVERRIDE; - const QPair calculateDataBoundaries() const Q_DECL_OVERRIDE; - void paint( PaintContext* ctx ) Q_DECL_OVERRIDE; + BarDiagram::BarType type() const override; + const QPair calculateDataBoundaries() const override; + void paint( PaintContext* ctx ) override; }; } #endif diff --git a/src/KChart/Cartesian/DiagramFlavors/KChartPercentPlotter_p.h b/src/KChart/Cartesian/DiagramFlavors/KChartPercentPlotter_p.h index 75c3437..335dc20 100644 --- a/src/KChart/Cartesian/DiagramFlavors/KChartPercentPlotter_p.h +++ b/src/KChart/Cartesian/DiagramFlavors/KChartPercentPlotter_p.h @@ -1,38 +1,38 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTPERCENTPLOTTER_P_H #define KCHARTPERCENTPLOTTER_P_H #include "KChartPlotter_p.h" namespace KChart { class PercentPlotter : public Plotter::PlotterType { public: explicit PercentPlotter( Plotter* ); virtual ~PercentPlotter() {} - Plotter::PlotType type() const Q_DECL_OVERRIDE; - const QPair< QPointF, QPointF > calculateDataBoundaries() const Q_DECL_OVERRIDE; - void paint( PaintContext* ctx ) Q_DECL_OVERRIDE; + Plotter::PlotType type() const override; + const QPair< QPointF, QPointF > calculateDataBoundaries() const override; + void paint( PaintContext* ctx ) override; }; } #endif diff --git a/src/KChart/Cartesian/DiagramFlavors/KChartStackedBarDiagram_p.h b/src/KChart/Cartesian/DiagramFlavors/KChartStackedBarDiagram_p.h index 658e8c9..3141b29 100644 --- a/src/KChart/Cartesian/DiagramFlavors/KChartStackedBarDiagram_p.h +++ b/src/KChart/Cartesian/DiagramFlavors/KChartStackedBarDiagram_p.h @@ -1,39 +1,39 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTSTACKEDBARDIAGRAM_P_H #define KCHARTSTACKEDBARDIAGRAM_P_H #include "KChartBarDiagram_p.h" namespace KChart { class StackedBarDiagram : public BarDiagram::BarDiagramType { public: explicit StackedBarDiagram( BarDiagram* ); virtual ~StackedBarDiagram() {} - BarDiagram::BarType type() const Q_DECL_OVERRIDE; - const QPair calculateDataBoundaries() const Q_DECL_OVERRIDE; - void paint( PaintContext* ctx ) Q_DECL_OVERRIDE; + BarDiagram::BarType type() const override; + const QPair calculateDataBoundaries() const override; + void paint( PaintContext* ctx ) override; }; } #endif diff --git a/src/KChart/Cartesian/DiagramFlavors/KChartStackedLineDiagram_p.h b/src/KChart/Cartesian/DiagramFlavors/KChartStackedLineDiagram_p.h index a172aef..93ec9dd 100644 --- a/src/KChart/Cartesian/DiagramFlavors/KChartStackedLineDiagram_p.h +++ b/src/KChart/Cartesian/DiagramFlavors/KChartStackedLineDiagram_p.h @@ -1,39 +1,39 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTSTACKEDLINEDIAGRAM_P_H #define KCHARTSTACKEDLINEDIAGRAM_P_H #include "KChartLineDiagram_p.h" namespace KChart { class StackedLineDiagram : public LineDiagram::LineDiagramType { public: explicit StackedLineDiagram( LineDiagram* ); virtual ~StackedLineDiagram() {} - LineDiagram::LineType type() const Q_DECL_OVERRIDE; - const QPair calculateDataBoundaries() const Q_DECL_OVERRIDE; - void paint( PaintContext* ctx ) Q_DECL_OVERRIDE; + LineDiagram::LineType type() const override; + const QPair calculateDataBoundaries() const override; + void paint( PaintContext* ctx ) override; }; } #endif diff --git a/src/KChart/Cartesian/DiagramFlavors/KChartStackedLyingBarDiagram_p.h b/src/KChart/Cartesian/DiagramFlavors/KChartStackedLyingBarDiagram_p.h index ffbeb43..639c9f1 100644 --- a/src/KChart/Cartesian/DiagramFlavors/KChartStackedLyingBarDiagram_p.h +++ b/src/KChart/Cartesian/DiagramFlavors/KChartStackedLyingBarDiagram_p.h @@ -1,39 +1,39 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTSTACKEDLYINGBARDIAGRAM_P_H #define KCHARTSTACKEDLYINGBARDIAGRAM_P_H #include "KChartBarDiagram_p.h" namespace KChart { class StackedLyingBarDiagram : public BarDiagram::BarDiagramType { public: explicit StackedLyingBarDiagram( BarDiagram* ); virtual ~StackedLyingBarDiagram() {} - BarDiagram::BarType type() const Q_DECL_OVERRIDE; - const QPair calculateDataBoundaries() const Q_DECL_OVERRIDE; - void paint( PaintContext* ctx ) Q_DECL_OVERRIDE; + BarDiagram::BarType type() const override; + const QPair calculateDataBoundaries() const override; + void paint( PaintContext* ctx ) override; }; } #endif diff --git a/src/KChart/Cartesian/DiagramFlavors/KChartStackedPlotter_p.h b/src/KChart/Cartesian/DiagramFlavors/KChartStackedPlotter_p.h index 1f11e58..7e0b81d 100644 --- a/src/KChart/Cartesian/DiagramFlavors/KChartStackedPlotter_p.h +++ b/src/KChart/Cartesian/DiagramFlavors/KChartStackedPlotter_p.h @@ -1,47 +1,47 @@ /* -*- Mode: C++ -*- KChart - a multi-platform charting engine */ /**************************************************************************** ** Copyright (C) 2005-2007 Klarälvdalens Datakonsult AB. All rights reserved. ** ** This file is part of the KD Chart library. ** ** This file may be used under the terms of the GNU General Public ** License versions 2.0 or 3.0 as published by the Free Software ** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3 ** included in the packaging of this file. Alternatively you may (at ** your option) use any later version of the GNU General Public ** License if such license has been publicly approved by ** Klarälvdalens Datakonsult AB (or its successors, if any). ** ** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, ** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE. Klarälvdalens Datakonsult AB reserves all rights ** not expressly granted herein. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** **********************************************************************/ #ifndef KCHARTSTACKEDPLOTTER_P_H #define KCHARTSTACKEDPLOTTER_P_H #include "KChartPlotter_p.h" namespace KChart { class StackedPlotter : public Plotter::PlotterType { public: explicit StackedPlotter( Plotter* ); virtual ~StackedPlotter() {} - Plotter::PlotType type() const Q_DECL_OVERRIDE; - const QPair< QPointF, QPointF > calculateDataBoundaries() const Q_DECL_OVERRIDE; - void paint( PaintContext* ctx ) Q_DECL_OVERRIDE; + Plotter::PlotType type() const override; + const QPair< QPointF, QPointF > calculateDataBoundaries() const override; + void paint( PaintContext* ctx ) override; double interpolateMissingValue( const CartesianDiagramDataCompressor::CachePosition& pos ) const; }; } #endif diff --git a/src/KChart/Cartesian/KChartAbstractCartesianDiagram.h b/src/KChart/Cartesian/KChartAbstractCartesianDiagram.h index 78f37a7..f999222 100644 --- a/src/KChart/Cartesian/KChartAbstractCartesianDiagram.h +++ b/src/KChart/Cartesian/KChartAbstractCartesianDiagram.h @@ -1,129 +1,129 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTABSTRACTCARTESIANDIAGRAM_H #define KCHARTABSTRACTCARTESIANDIAGRAM_H #include "KChartCartesianCoordinatePlane.h" #include "KChartAbstractDiagram.h" #include "KChartCartesianAxis.h" namespace KChart { class GridAttributes; /** * @brief Base class for diagrams based on a cartesian coordianate system. * * The AbstractCartesianDiagram interface adds those elements that are * specific to diagrams based on a cartesian coordinate system to the * basic AbstractDiagram interface. */ class KCHART_EXPORT AbstractCartesianDiagram : public AbstractDiagram { Q_OBJECT Q_DISABLE_COPY( AbstractCartesianDiagram ) KCHART_DECLARE_DERIVED_DIAGRAM( AbstractCartesianDiagram, CartesianCoordinatePlane ) public: explicit AbstractCartesianDiagram( QWidget* parent = nullptr, CartesianCoordinatePlane* plane = nullptr ); virtual ~AbstractCartesianDiagram(); /** * Returns true if both diagrams have the same settings. */ bool compare( const AbstractCartesianDiagram* other ) const; #if defined(Q_COMPILER_MANGLES_RETURN_TYPE) virtual const int numberOfAbscissaSegments() const = 0; virtual const int numberOfOrdinateSegments() const = 0; #else virtual int numberOfAbscissaSegments() const = 0; virtual int numberOfOrdinateSegments() const = 0; #endif /** * Add the axis to the diagram. The diagram takes ownership of the axis * and will delete it. * * To gain back ownership (e.g. for assigning the axis to another diagram) * use the takeAxis method, before calling addAxis on the other diagram. * * \sa takeAxis */ virtual void addAxis( CartesianAxis * axis ); /** * Removes the axis from the diagram, without deleting it. * * The diagram no longer owns the axis, so it is * the caller's responsibility to delete the axis. * * \sa addAxis */ virtual void takeAxis( CartesianAxis * axis ); /** * @return a list of all axes added to the diagram */ virtual KChart::CartesianAxisList axes() const; /** * Triggers layouting of all coordinate planes on the current chart. * Normally you don't need to call this method. It's handled automatically for you. */ virtual void layoutPlanes(); /** \reimpl */ - void setCoordinatePlane( AbstractCoordinatePlane* plane ) Q_DECL_OVERRIDE; + void setCoordinatePlane( AbstractCoordinatePlane* plane ) override; /** * Makes this diagram use another diagram \a diagram as reference diagram with relative offset * \a offset. * To share cartesian axes between different diagrams there might be cases when you need that. * Normally you don't. * \sa examples/SharedAbscissa */ virtual void setReferenceDiagram( AbstractCartesianDiagram* diagram, const QPointF& offset = QPointF() ); /** * @return this diagram's reference diagram * \sa setReferenceDiagram */ virtual AbstractCartesianDiagram* referenceDiagram() const; /** * @return the relative offset of this diagram's reference diagram * \sa setReferenceDiagram */ virtual QPointF referenceDiagramOffset() const; /* reimpl */ - void setModel( QAbstractItemModel* model ) Q_DECL_OVERRIDE; + void setModel( QAbstractItemModel* model ) override; /* reimpl */ - void setRootIndex( const QModelIndex& index ) Q_DECL_OVERRIDE; + void setRootIndex( const QModelIndex& index ) override; /* reimpl */ - void setAttributesModel( AttributesModel* model ) Q_DECL_OVERRIDE; + void setAttributesModel( AttributesModel* model ) override; protected Q_SLOTS: void connectAttributesModel( AttributesModel* ); protected: /** @return the 3D item depth of the model index \a index */ virtual qreal threeDItemDepth( const QModelIndex& index ) const = 0; /** @return the 3D item depth of the data set \a column */ virtual qreal threeDItemDepth( int column ) const = 0; }; } #endif diff --git a/src/KChart/Cartesian/KChartAbstractCartesianDiagram_p.h b/src/KChart/Cartesian/KChartAbstractCartesianDiagram_p.h index 7420c1f..44d7467 100644 --- a/src/KChart/Cartesian/KChartAbstractCartesianDiagram_p.h +++ b/src/KChart/Cartesian/KChartAbstractCartesianDiagram_p.h @@ -1,89 +1,89 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTABSTRACTCARTESIANDIAGRAM_P_H #define KCHARTABSTRACTCARTESIANDIAGRAM_P_H // // W A R N I N G // ------------- // // This file is not part of the KD Chart API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include "KChartAbstractCartesianDiagram.h" #include #include #include #include "KChartMath_p.h" namespace KChart { class CartesianCoordinatePlane; class AbstractCartesianDiagram; /** * \internal */ class Q_DECL_HIDDEN AbstractCartesianDiagram::Private : public AbstractDiagram::Private { friend class AbstractCartesianDiagram; public: Private(); virtual ~Private(); Private( const Private& rhs ) : AbstractDiagram::Private( rhs ), // Do not copy axes and reference diagrams. axesList(), referenceDiagram( nullptr ), referenceDiagramOffset() { } /** \reimpl */ CartesianDiagramDataCompressor::AggregatedDataValueAttributes aggregatedAttrs( const QModelIndex & index, - const CartesianDiagramDataCompressor::CachePosition * position ) const Q_DECL_OVERRIDE + const CartesianDiagramDataCompressor::CachePosition * position ) const override { if ( position ) return compressor.aggregatedAttrs( diagram, index, *position ); CartesianDiagramDataCompressor::AggregatedDataValueAttributes allAttrs; allAttrs[index] = diagram->dataValueAttributes( index ); return allAttrs; } CartesianAxisList axesList; AbstractCartesianDiagram* referenceDiagram; QPointF referenceDiagramOffset; mutable CartesianDiagramDataCompressor compressor; }; KCHART_IMPL_DERIVED_DIAGRAM( AbstractCartesianDiagram, AbstractDiagram, CartesianCoordinatePlane ) } #endif /* KCHARTABSTRACTCARTESIANDIAGRAM_P_H */ diff --git a/src/KChart/Cartesian/KChartBarDiagram.h b/src/KChart/Cartesian/KChartBarDiagram.h index dfb7ec7..78a641a 100644 --- a/src/KChart/Cartesian/KChartBarDiagram.h +++ b/src/KChart/Cartesian/KChartBarDiagram.h @@ -1,127 +1,127 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTBARDIAGRAM_H #define KCHARTBARDIAGRAM_H #include "KChartAbstractCartesianDiagram.h" #include "KChartBarAttributes.h" QT_BEGIN_NAMESPACE class QPainter; QT_END_NAMESPACE namespace KChart { class ThreeDBarAttributes; /** * @brief BarDiagram defines a common bar diagram. * * It provides different subtypes which are set using \a setType. */ class KCHART_EXPORT BarDiagram : public AbstractCartesianDiagram { Q_OBJECT Q_DISABLE_COPY( BarDiagram ) KCHART_DECLARE_DERIVED_DIAGRAM( BarDiagram, CartesianCoordinatePlane ) public: class BarDiagramType; friend class BarDiagramType; explicit BarDiagram( QWidget* parent = nullptr, CartesianCoordinatePlane* plane = nullptr ); virtual ~BarDiagram(); virtual BarDiagram * clone() const; /** * Returns true if both diagrams have the same settings. */ bool compare( const BarDiagram* other ) const; enum BarType { Normal, Stacked, Percent, Rows ///< @deprecated Use BarDiagram::setOrientation() instead }; void setType( const BarType type ); BarType type() const; void setOrientation( Qt::Orientation orientation ); Qt::Orientation orientation() const; void setBarAttributes( const BarAttributes & a ); void setBarAttributes( int column, const BarAttributes & a ); void setBarAttributes( const QModelIndex & index, const BarAttributes & a ); BarAttributes barAttributes() const; BarAttributes barAttributes( int column ) const; BarAttributes barAttributes( const QModelIndex & index ) const; void setThreeDBarAttributes( const ThreeDBarAttributes & a ); void setThreeDBarAttributes( int column, const ThreeDBarAttributes & a ); void setThreeDBarAttributes( const QModelIndex & index, const ThreeDBarAttributes & a ); ThreeDBarAttributes threeDBarAttributes() const; ThreeDBarAttributes threeDBarAttributes( int column ) const; ThreeDBarAttributes threeDBarAttributes( const QModelIndex & index ) const; #if defined(Q_COMPILER_MANGLES_RETURN_TYPE) // implement AbstractCartesianDiagram /** \reimpl */ const int numberOfAbscissaSegments () const; /** \reimpl */ const int numberOfOrdinateSegments () const; #else // implement AbstractCartesianDiagram /** \reimpl */ - int numberOfAbscissaSegments () const Q_DECL_OVERRIDE; + int numberOfAbscissaSegments () const override; /** \reimpl */ - int numberOfOrdinateSegments () const Q_DECL_OVERRIDE; + int numberOfOrdinateSegments () const override; #endif protected: - void paint ( PaintContext* paintContext ) Q_DECL_OVERRIDE; + void paint ( PaintContext* paintContext ) override; public: - void resize ( const QSizeF& area ) Q_DECL_OVERRIDE; + void resize ( const QSizeF& area ) override; protected: - qreal threeDItemDepth( const QModelIndex & index ) const Q_DECL_OVERRIDE; - qreal threeDItemDepth( int column ) const Q_DECL_OVERRIDE; + qreal threeDItemDepth( const QModelIndex & index ) const override; + qreal threeDItemDepth( int column ) const override; /** \reimpl */ - const QPair calculateDataBoundaries() const Q_DECL_OVERRIDE; - void paintEvent ( QPaintEvent* ) Q_DECL_OVERRIDE; - void resizeEvent ( QResizeEvent* ) Q_DECL_OVERRIDE; + const QPair calculateDataBoundaries() const override; + void paintEvent ( QPaintEvent* ) override; + void resizeEvent ( QResizeEvent* ) override; private: void calculateValueAndGapWidths( int rowCount, int colCount, qreal groupWidth, qreal& barWidth, qreal& spaceBetweenBars, qreal& spaceBetweenGroups ); }; // End of class BarDiagram } #endif // KCHARTBARDIAGRAM_H diff --git a/src/KChart/Cartesian/KChartCartesianAxis.h b/src/KChart/Cartesian/KChartCartesianAxis.h index a748c5f..9c7dddd 100644 --- a/src/KChart/Cartesian/KChartCartesianAxis.h +++ b/src/KChart/Cartesian/KChartCartesianAxis.h @@ -1,192 +1,192 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTCARTESIANAXIS_H #define KCHARTCARTESIANAXIS_H #include #include "KChartAbstractAxis.h" namespace KChart { class AbstractCartesianDiagram; /** * The class for cartesian axes. * * For being useful, axes need to be assigned to a diagram, see * AbstractCartesianDiagram::addAxis and AbstractCartesianDiagram::takeAxis. * * \sa PolarAxis, AbstractCartesianDiagram */ class KCHART_EXPORT CartesianAxis : public AbstractAxis { Q_OBJECT Q_DISABLE_COPY( CartesianAxis ) KCHART_DECLARE_PRIVATE_DERIVED_PARENT( CartesianAxis, AbstractDiagram* ) Q_ENUMS(Position) public: enum Position { Bottom, Top, Right, Left }; /** * C'tor of the class for cartesian axes. * * \note If you pass a null parent to the constructor, you need to call * your diagram's addAxis function to add your axis to the diagram. * Otherwise there is no need to call addAxis, since the constructor * does it already. * * \sa AbstractCartesianDiagram::addAxis */ explicit CartesianAxis ( AbstractCartesianDiagram* diagram = nullptr ); ~CartesianAxis(); /** * Returns true if both axes have the same settings. */ bool compare( const CartesianAxis* other ) const; /** reimpl */ - void paint( QPainter* ) Q_DECL_OVERRIDE; + void paint( QPainter* ) override; /** reimpl */ - void paintCtx( PaintContext* ) Q_DECL_OVERRIDE; + void paintCtx( PaintContext* ) override; /** * Sets the optional text displayed as chart title. */ void setTitleText( const QString& text ); QString titleText() const; /** * \deprecated * Sets the spacing between the title and the diagram. * Be aware that setting this value can lead to * collisions between axis labels and the title */ void setTitleSpace( qreal value ); /// \deprecated qreal titleSpace() const; /// \deprecated \brief use setTitleTextAttributes() instead void setTitleSize(qreal value); /// \deprecated qreal titleSize() const; void setTitleTextAttributes( const TextAttributes &a ); /** * Returns the text attributes that will be used for displaying the * title text. * This is either the text attributes as specified by setTitleTextAttributes, * or (if setTitleTextAttributes() was not called) the default text attributes. * \sa resetTitleTextAttributes, hasDefaultTitleTextAttributes */ TextAttributes titleTextAttributes() const; /** * Reset the title text attributes to the built-in default: * * Same font and pen as AbstractAxis::textAttributes() * and 1.5 times their size. */ void resetTitleTextAttributes(); bool hasDefaultTitleTextAttributes() const; virtual void setPosition ( Position p ); #if defined(Q_COMPILER_MANGLES_RETURN_TYPE) virtual const Position position () const; #else virtual Position position () const; #endif virtual void layoutPlanes(); virtual bool isAbscissa() const; virtual bool isOrdinate() const; /** * Sets the axis annotations to \a annotations. * Annotations are a QMap of qreals and QStrings defining special * markers and their position. * If you use annotations, the normal ticks and values will be invisible. * To unset the annotations, pass an empty QMap. */ void setAnnotations( const QMap< qreal, QString >& annotations ); /** * Returns the currently set axis annotations. */ QMap< qreal, QString > annotations() const; /** * Sets custom ticks on the axis. * Ticks are a QList of qreals defining their special position. */ void setCustomTicks( const QList< qreal >& ticksPostions ); /** * Returns the currently set custom ticks on the axis. */ QList< qreal > customTicks() const; /** * Sets the length of custom ticks on the axis. */ void setCustomTickLength(int value); /** * Returns the length of custom ticks on the axis. */ int customTickLength() const; /** pure virtual in QLayoutItem */ - bool isEmpty() const Q_DECL_OVERRIDE; + bool isEmpty() const override; /** pure virtual in QLayoutItem */ - Qt::Orientations expandingDirections() const Q_DECL_OVERRIDE; + Qt::Orientations expandingDirections() const override; /** pure virtual in QLayoutItem */ - QSize maximumSize() const Q_DECL_OVERRIDE; + QSize maximumSize() const override; /** pure virtual in QLayoutItem */ - QSize minimumSize() const Q_DECL_OVERRIDE; + QSize minimumSize() const override; /** pure virtual in QLayoutItem */ - QSize sizeHint() const Q_DECL_OVERRIDE; + QSize sizeHint() const override; /** pure virtual in QLayoutItem */ - void setGeometry( const QRect& r ) Q_DECL_OVERRIDE; + void setGeometry( const QRect& r ) override; /** pure virtual in QLayoutItem */ - QRect geometry() const Q_DECL_OVERRIDE; + QRect geometry() const override; public Q_SLOTS: void setCachedSizeDirty() const; virtual int tickLength( bool subUnitTicks = false ) const; private Q_SLOTS: void coordinateSystemChanged(); }; typedef QList CartesianAxisList; } #if !defined(QT_NO_DEBUG_STREAM) KCHART_EXPORT QDebug operator<<(QDebug dbg, KChart::CartesianAxis::Position pos); #endif #endif diff --git a/src/KChart/Cartesian/KChartCartesianCoordinatePlane.h b/src/KChart/Cartesian/KChartCartesianCoordinatePlane.h index 1055f90..cba910e 100644 --- a/src/KChart/Cartesian/KChartCartesianCoordinatePlane.h +++ b/src/KChart/Cartesian/KChartCartesianCoordinatePlane.h @@ -1,502 +1,502 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTCARTESIANCOORDINATEPLANE_H #define KCHARTCARTESIANCOORDINATEPLANE_H #include "KChartAbstractCoordinatePlane.h" namespace KChart { class Chart; class PaintContext; class AbstractDiagram; class CartesianAxis; class CartesianGrid; /** * @brief Cartesian coordinate plane */ class KCHART_EXPORT CartesianCoordinatePlane : public AbstractCoordinatePlane { Q_OBJECT Q_DISABLE_COPY( CartesianCoordinatePlane ) KCHART_DECLARE_PRIVATE_DERIVED_PARENT( CartesianCoordinatePlane, Chart* ) friend class CartesianAxis; friend class CartesianGrid; public: explicit CartesianCoordinatePlane ( Chart* parent = nullptr ); ~CartesianCoordinatePlane(); - void addDiagram ( AbstractDiagram* diagram ) Q_DECL_OVERRIDE; + void addDiagram ( AbstractDiagram* diagram ) override; /** * If @p onOff is true, enforce that X and Y distances are scaled by the same factor. * This makes the plane's height a function of its width, and hasHeightForWidth() * will return true. */ void setIsometricScaling ( bool onOff ); bool doesIsometricScaling() const; - const QPointF translate ( const QPointF& diagramPoint ) const Q_DECL_OVERRIDE; + const QPointF translate ( const QPointF& diagramPoint ) const override; /** * \sa setZoomFactorX, setZoomCenter */ - qreal zoomFactorX() const Q_DECL_OVERRIDE; + qreal zoomFactorX() const override; /** * \sa setZoomFactorY, setZoomCenter */ - qreal zoomFactorY() const Q_DECL_OVERRIDE; + qreal zoomFactorY() const override; /** * \sa setZoomFactorX,setZoomFactorY */ - void setZoomFactors( qreal factorX, qreal factorY ) Q_DECL_OVERRIDE; + void setZoomFactors( qreal factorX, qreal factorY ) override; /** * \sa zoomFactorX, setZoomCenter */ - void setZoomFactorX( qreal factor ) Q_DECL_OVERRIDE; + void setZoomFactorX( qreal factor ) override; /** * \sa zoomFactorY, setZoomCenter */ - void setZoomFactorY( qreal factor ) Q_DECL_OVERRIDE; + void setZoomFactorY( qreal factor ) override; /** * \sa setZoomCenter, setZoomFactorX, setZoomFactorY */ - QPointF zoomCenter() const Q_DECL_OVERRIDE; + QPointF zoomCenter() const override; /** * \sa zoomCenter, setZoomFactorX, setZoomFactorY */ - void setZoomCenter( const QPointF& center ) Q_DECL_OVERRIDE; + void setZoomCenter( const QPointF& center ) override; /** * Allows to specify a fixed data-space / coordinate-space relation. If set * to true then fixed bar widths are used, so you see more bars as the window * is made wider. * * This allows to completely restrict the size of bars in a graph such that, * upon resizing a window, the graphs coordinate plane will grow (add more * ticks to x- and y-coordinates) rather than have the image grow. */ void setFixedDataCoordinateSpaceRelation( bool fixed ); bool hasFixedDataCoordinateSpaceRelation() const; /** * Allows to fix the lower bound of X axis to zero when diagram is in first quadrant. * * The default behavior is to lower x or y bound to be 0. If this behaviour is not wanted, * either \a CartesianCoordinatePlane::setHorizontalRange could be used instead of letting * KChart auto-adjust the ranges, or this method can be used to disable this behavior. */ void setXAxisStartAtZero(bool fixedStart); bool xAxisStartAtZero() const; /** * \brief Set the boundaries of the visible value space displayed in horizontal direction. * * This is also known as the horizontal viewport. * * By default the horizontal range is adjusted to the range covered by the model's data, * see setAutoAdjustHorizontalRangeToData for details. * Calling setHorizontalRange with a valid range disables this default automatic adjusting, * while on the other hand automatic adjusting will set these ranges. * * To disable use of this range you can either pass an empty pair by using the default * constructor QPair() or you can set both values to the same which constitutes * a null range. * * \note By default the visible data range often is larger than the * range calculated from the data model (or set by setHoriz.|Vert.Range(), resp.). * This is due to the built-in grid calculation feature: The visible start/end * values get adjusted so that they match a main-grid line. * You can turn this feature off for any of the four bounds by calling * GridAttributes::setAdjustBoundsToGrid() for either the global grid-attributes * or for the horizontal/vertical attrs separately. * * \note To set only one of the ends of the range to a fixed value while keeping * the other dynamically adjusted, use std::numeric_limits< qreal >::quiet_NaN() * for the dynamic value. * * \note If you use user defined vertical ranges together with logarithmic scale, only * positive values are supported. If you set it to negative values, the result is undefined. * * \param range a pair of values representing the smalles and the largest * horizontal value space coordinate displayed. * * \sa setAutoAdjustHorizontalRangeToData, setVerticalRange * \sa GridAttributes::setAdjustBoundsToGrid() */ void setHorizontalRange( const QPair & range ); /** * \brief Set the boundaries of the visible value space displayed in vertical direction. * * This is also known as the vertical viewport. * * By default the vertical range is adjusted to the range covered by the model's data, * see setAutoAdjustVerticalRangeToData for details. * Calling setVerticalRange with a valid range disables this default automatic adjusting, * while on the other hand automatic adjusting will set these ranges. * * To disable use of this range you can either pass an empty pair by using the default * constructor QPair() or you can set setting both values to the same which constitutes * a null range. * * \note By default the visible data range often is larger than the * range calculated from the data model (or set by setHoriz.|Vert.Range(), resp.). * This is due to the built-in grid calculation feature: The visible start/end * values get adjusted so that they match a main-grid line. * You can turn this feature off for any of the four bounds by calling * GridAttributes::setAdjustBoundsToGrid() for either the global grid-attributes * or for the horizontal/vertical attrs separately. * * \note To set only one of the ends of the range to a fixed value while keeping * the other dynamically adjusted, use std::numeric_limits< qreal >::quiet_NaN() * for the dynamic value. * * \note If you use user defined vertical ranges together with logarithmic scale, only * positive values are supported. If you set it to negative values, the result is undefined. * * \param range a pair of values representing the smalles and the largest * vertical value space coordinate displayed. * * \sa setAutoAdjustVerticalRangeToData, setHorizontalRange * \sa GridAttributes::setAdjustBoundsToGrid() */ void setVerticalRange( const QPair & range ); /** * @return The largest and smallest visible horizontal value space * value. If this is not explicitly set,or if both values are the same, * the plane will use the union of the dataBoundaries of all * associated diagrams. * \see KChart::AbstractDiagram::dataBoundaries */ QPair horizontalRange() const; /** * @return The largest and smallest visible horizontal value space * value. If this is not explicitly set, or if both values are the same, * the plane will use the union of the dataBoundaries of all * associated diagrams. * \see KChart::AbstractDiagram::dataBoundaries */ QPair verticalRange() const; /** * \brief Automatically adjust horizontal range settings to the ranges covered by * the model's values, when ever the data have changed, and then emit horizontalRangeAutomaticallyAdjusted. * * By default the horizontal range is adjusted automatically, if more than 67 percent of * the available horizontal space would be empty otherwise. * * Range setting is adjusted if more than \c percentEmpty percent of the horizontal * space covered by the coordinate plane would otherwise be empty. * Automatic range adjusting can happen, when either all of the data are positive or all are negative. * * Set percentEmpty to 100 to disable automatic range adjusting. * * \param percentEmpty The maximal percentage of horizontal space that may be empty. * * \sa horizontalRangeAutomaticallyAdjusted * \sa autoAdjustHorizontalRangeToData, adjustRangesToData * \sa setHorizontalRange, setVerticalRange * \sa setAutoAdjustVerticalRangeToData */ void setAutoAdjustHorizontalRangeToData( unsigned int percentEmpty = 67 ); /** * \brief Automatically adjust vertical range settings to the ranges covered by * the model's values, when ever the data have changed, and then emit verticalRangeAutomaticallyAdjusted. * * By default the vertical range is adjusted automatically, if more than 67 percent of * the available vertical space would be empty otherwise. * * Range setting is adjusted if more than \c percentEmpty percent of the horizontal * space covered by the coordinate plane would otherwise be empty. * Automatic range adjusting can happen, when either all of the data are positive or all are negative. * * Set percentEmpty to 100 to disable automatic range adjusting. * * \param percentEmpty The maximal percentage of horizontal space that may be empty. * * \sa verticalRangeAutomaticallyAdjusted * \sa autoAdjustVerticalRangeToData, adjustRangesToData * \sa setHorizontalRange, setVerticalRange * \sa setAutoAdjustHorizontalRangeToData */ void setAutoAdjustVerticalRangeToData( unsigned int percentEmpty = 67 ); /** * \brief Returns the maximal allowed percent of the horizontal * space covered by the coordinate plane that may be empty. * * \return A percent value indicating how much of the horizontal space may be empty. * If more than this is empty, automatic range adjusting is applied. * A return value of 100 indicates that no such automatic adjusting is done at all. * * \sa setAutoAdjustHorizontalRangeToData, adjustRangesToData */ unsigned int autoAdjustHorizontalRangeToData() const; /** * \brief Returns the maximal allowed percent of the vertical * space covered by the coordinate plane that may be empty. * * \return A percent value indicating how much of the vertical space may be empty. * If more than this is empty, automatic range adjusting is applied. * A return value of 100 indicates that no such automatic adjusting is done at all. * * \sa setAutoAdjustVerticalRangeToData, adjustRangesToData */ unsigned int autoAdjustVerticalRangeToData() const; /** * Set the attributes to be used for grid lines drawn in horizontal * direction (or in vertical direction, resp.). * * To disable horizontal grid painting, for example, your code should like this: * \code * GridAttributes ga = plane->gridAttributes( Qt::Horizontal ); * ga.setGridVisible( false ); * plane-setGridAttributes( Qt::Horizontal, ga ); * \endcode * * \note setGridAttributes overwrites the global attributes that * were set by AbstractCoordinatePlane::setGlobalGridAttributes. * To re-activate these global attributes you can call * resetGridAttributes. * * \sa resetGridAttributes, gridAttributes * \sa setAutoAdjustGridToZoom * \sa AbstractCoordinatePlane::setGlobalGridAttributes * \sa hasOwnGridAttributes */ void setGridAttributes( Qt::Orientation orientation, const GridAttributes & ); /** * Reset the attributes to be used for grid lines drawn in horizontal * direction (or in vertical direction, resp.). * By calling this method you specify that the global attributes set by * AbstractCoordinatePlane::setGlobalGridAttributes be used. * * \sa setGridAttributes, gridAttributes * \sa setAutoAdjustGridToZoom * \sa AbstractCoordinatePlane::globalGridAttributes * \sa hasOwnGridAttributes */ void resetGridAttributes( Qt::Orientation orientation ); /** * \return The attributes used for grid lines drawn in horizontal * direction (or in vertical direction, resp.). * * \note This function always returns a valid set of grid attributes: * If no special grid attributes were set foe this orientation * the global attributes are returned, as returned by * AbstractCoordinatePlane::globalGridAttributes. * * \sa setGridAttributes * \sa resetGridAttributes * \sa AbstractCoordinatePlane::globalGridAttributes * \sa hasOwnGridAttributes */ const GridAttributes gridAttributes( Qt::Orientation orientation ) const; /** * \return Returns whether the grid attributes have been set for the * respective direction via setGridAttributes( orientation ). * * If false, the grid will use the global attributes set * by AbstractCoordinatePlane::globalGridAttributes (or the default * attributes, resp.) * * \sa setGridAttributes * \sa resetGridAttributes * \sa AbstractCoordinatePlane::globalGridAttributes */ bool hasOwnGridAttributes( Qt::Orientation orientation ) const; /** * Disable / re-enable the built-in grid adjusting feature. * * By default additional lines will be drawn in a Linear grid when zooming in. * * \sa autoAdjustGridToZoom, setGridAttributes */ void setAutoAdjustGridToZoom( bool autoAdjust ); /** * Return the status of the built-in grid adjusting feature. * * \sa setAutoAdjustGridToZoom */ #if defined(Q_COMPILER_MANGLES_RETURN_TYPE) const bool autoAdjustGridToZoom() const; #else bool autoAdjustGridToZoom() const; #endif AxesCalcMode axesCalcModeY() const; AxesCalcMode axesCalcModeX() const; /** Specifies the calculation modes for all axes */ void setAxesCalcModes( AxesCalcMode mode ); /** Specifies the calculation mode for all Ordinate axes */ void setAxesCalcModeY( AxesCalcMode mode ); /** Specifies the calculation mode for all Abscissa axes */ void setAxesCalcModeX( AxesCalcMode mode ); /** reimpl */ - void paint( QPainter* ) Q_DECL_OVERRIDE; + void paint( QPainter* ) override; /** reimpl */ - AbstractCoordinatePlane* sharedAxisMasterPlane( QPainter* p = nullptr ) Q_DECL_OVERRIDE; + AbstractCoordinatePlane* sharedAxisMasterPlane( QPainter* p = nullptr ) override; /** * Returns the currently visible data range. Might be greater than the * range of the grid. */ QRectF visibleDataRange() const; /** * Returns the logical area, i.e., the rectangle defined by the very top * left and very bottom right coordinate. */ QRectF logicalArea() const; /** * Returns the (physical) area occupied by the diagram. Unless zoom is applied * (which is also true when a fixed data coordinate / space relation is used), * \code diagramArea() == drawingArea() \endcode . * \sa setFixedDataCoordinateSpaceRelation * \sa drawingArea */ QRectF diagramArea() const; /** * Returns the visible part of the diagram area, i.e. * \code diagramArea().intersected( drawingArea() ) \endcode * \sa diagramArea */ QRectF visibleDiagramArea() const; /** * Sets whether the horizontal range should be reversed or not, i.e. * small values to the left and large values to the right (the default) * or vice versa. * \param reverse Whether the horizontal range should be reversed or not */ void setHorizontalRangeReversed( bool reverse ); /** * \return Whether the horizontal range is reversed or not */ bool isHorizontalRangeReversed() const; /** * Sets whether the vertical range should be reversed or not, i.e. * small values at the bottom and large values at the top (the default) * or vice versa. * \param reverse Whether the vertical range should be reversed or not */ void setVerticalRangeReversed( bool reverse ); /** * \return Whether the vertical range is reversed or not */ bool isVerticalRangeReversed() const; /** * reimplemented from AbstractCoordinatePlane */ - void setGeometry( const QRect& r ) Q_DECL_OVERRIDE; + void setGeometry( const QRect& r ) override; // reimplemented - Qt::Orientations expandingDirections() const Q_DECL_OVERRIDE; + Qt::Orientations expandingDirections() const override; public Q_SLOTS: /** * \brief Adjust both, horizontal and vertical range settings to the * ranges covered by the model's data values. * * \sa setHorizontalRange, setVerticalRange * \sa adjustHorizontalRangeToData, adjustVerticalRangeToData * \sa setAutoAdjustHorizontalRangeToData, setAutoAdjustVerticalRangeToData */ void adjustRangesToData(); /** * Adjust horizontal range settings to the ranges covered by the model's data values. * \sa adjustRangesToData */ void adjustHorizontalRangeToData(); /** * Adjust vertical range settings to the ranges covered by the model's data values. * \sa adjustRangesToData */ void adjustVerticalRangeToData(); protected: QRectF getRawDataBoundingRectFromDiagrams() const; QRectF adjustedToMaxEmptyInnerPercentage( const QRectF& r, unsigned int percentX, unsigned int percentY ) const; virtual QRectF calculateRawDataBoundingRect() const; - DataDimensionsList getDataDimensionsList() const Q_DECL_OVERRIDE; + DataDimensionsList getDataDimensionsList() const override; // the whole drawing area, includes diagrams and axes, but maybe smaller // than (width, height): virtual QRectF drawingArea() const; public: const QPointF translateBack( const QPointF& screenPoint ) const; protected: void paintEvent ( QPaintEvent* ); - void layoutDiagrams() Q_DECL_OVERRIDE; + void layoutDiagrams() override; // the following three return true if the new value is different from the old bool doneSetZoomFactorX( qreal factor ); bool doneSetZoomFactorY( qreal factor ); bool doneSetZoomCenter( const QPointF& center ); void handleFixedDataCoordinateSpaceRelation( const QRectF& geometry ); // reimplemented from QLayoutItem, via AbstractLayoutItem, AbstractArea, AbstractCoordinatePlane - bool hasHeightForWidth() const Q_DECL_OVERRIDE; - int heightForWidth( int w ) const Q_DECL_OVERRIDE; - QSize sizeHint() const Q_DECL_OVERRIDE; + bool hasHeightForWidth() const override; + int heightForWidth( int w ) const override; + QSize sizeHint() const override; protected Q_SLOTS: void slotLayoutChanged( AbstractDiagram* ); private: void setHasOwnGridAttributes( Qt::Orientation orientation, bool on ); }; } #endif diff --git a/src/KChart/Cartesian/KChartCartesianCoordinatePlane_p.h b/src/KChart/Cartesian/KChartCartesianCoordinatePlane_p.h index 43a16bf..4e7f14b 100644 --- a/src/KChart/Cartesian/KChartCartesianCoordinatePlane_p.h +++ b/src/KChart/Cartesian/KChartCartesianCoordinatePlane_p.h @@ -1,141 +1,141 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTCARTESIANCOORDINATEPLANE_P_H #define KCHARTCARTESIANCOORDINATEPLANE_P_H // // W A R N I N G // ------------- // // This file is not part of the KD Chart API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include "KChartAbstractCoordinatePlane_p.h" #include "CartesianCoordinateTransformation.h" #include "KChartCartesianGrid.h" #include "KChartZoomParameters.h" #include "KChartMath_p.h" namespace KChart { /** * \internal */ class Q_DECL_HIDDEN CartesianCoordinatePlane::Private : public AbstractCoordinatePlane::Private { friend class CartesianCoordinatePlane; public: explicit Private(); virtual ~Private() { } - void initialize() Q_DECL_OVERRIDE + void initialize() override { bPaintIsRunning = false; coordinateTransformation.axesCalcModeX = Linear; coordinateTransformation.axesCalcModeY = Linear; grid = new CartesianGrid(); } static Private *get( CartesianCoordinatePlane *plane ) { return static_cast< Private * >( plane->d_func() ); } - bool isVisiblePoint( const AbstractCoordinatePlane * plane, const QPointF& point ) const Q_DECL_OVERRIDE + bool isVisiblePoint( const AbstractCoordinatePlane * plane, const QPointF& point ) const override { QPointF p = point; const CartesianCoordinatePlane* const ref = qobject_cast< const CartesianCoordinatePlane* >( const_cast< AbstractCoordinatePlane* >( plane )->sharedAxisMasterPlane() ); const CartesianCoordinatePlane* const cartPlane = dynamic_cast< const CartesianCoordinatePlane* >( plane ); if ( ref != nullptr && ref != cartPlane ) { const QPointF logical = ref->translateBack( point ) - cartPlane->visibleDataRange().topLeft() + ref->visibleDataRange().topLeft(); p = ref->translate( logical ); } const QRectF geo( plane->geometry() ); return geo.contains( p ); } // the coordinate plane will calculate the coordinate transformation: CoordinateTransformation coordinateTransformation; bool bPaintIsRunning; // true after setGridAttributes( Qt::Orientation ) was used, // false if resetGridAttributes( Qt::Orientation ) was called bool hasOwnGridAttributesHorizontal; bool hasOwnGridAttributesVertical; // true after the first resize event came in // bool initialResizeEventReceived; // true if the coordinate plane scales isometrically // (same scaling ratio from data to screen space for both axes) bool isometricScaling; GridAttributes gridAttributesHorizontal; GridAttributes gridAttributesVertical; qreal horizontalMin; qreal horizontalMax; qreal verticalMin; qreal verticalMax; // autoAdjustHorizontalRangeToData determines if and how much the horizontal range is adjusted. // A value of 100 means that the fixed horizontal range will be used (e.g. set by the user), // otherwise the value will be the percentage of the diagram's horizontal range that is to be // left empty (i.e., it resembles the 'gap' between the horizontal extrema and the border of the // diagram). unsigned int autoAdjustHorizontalRangeToData; // autoAdjustVerticalRangeToData determines if and how much the vertical range is adjusted. // A value of 100 means that the fixed vertical range will be used (e.g. set by the user), // otherwise the value will be the percentage of the diagram's vertical range that is to be // left empty (i.e., it resembles the 'gap' between the vertical extrema and the border of the // diagram). unsigned int autoAdjustVerticalRangeToData; bool autoAdjustGridToZoom; bool fixedDataCoordinateSpaceRelation; bool xAxisStartAtZero; QSizeF fixedDataCoordinateSpaceRelationPinnedSize; ZoomParameters fixedDataCoordinateSpaceRelationPinnedZoom; DataDimensionsList dimensions; bool reverseVerticalPlane; bool reverseHorizontalPlane; }; KCHART_IMPL_DERIVED_PLANE(CartesianCoordinatePlane, AbstractCoordinatePlane) } #endif /* KCHARTBARDIAGRAM_P_H */ diff --git a/src/KChart/Cartesian/KChartCartesianGrid.h b/src/KChart/Cartesian/KChartCartesianGrid.h index b94f499..0e8e486 100644 --- a/src/KChart/Cartesian/KChartCartesianGrid.h +++ b/src/KChart/Cartesian/KChartCartesianGrid.h @@ -1,117 +1,117 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTCARTESIANGRID_H #define KCHARTCARTESIANGRID_H #include "KChartCartesianCoordinatePlane.h" #include "KChartAbstractGrid.h" namespace KChart { class PaintContext; class CartesianCoordinatePlane; /** * \internal * * \brief Class for the grid in a cartesian plane. * * The CartesianGrid interface is used * for calculating and for drawing * the horizonal grid lines, and the vertical grid lines * of a cartesian coordinate plane. */ class CartesianGrid : public AbstractGrid { public: CartesianGrid(); virtual ~CartesianGrid(); int minimalSteps() const; void setMinimalSteps(int minsteps); int maximalSteps() const; void setMaximalSteps(int maxsteps); - void drawGrid( PaintContext* context ) Q_DECL_OVERRIDE; + void drawGrid( PaintContext* context ) override; private: int m_minsteps; int m_maxsteps; DataDimensionsList calculateGrid( - const DataDimensionsList& rawDataDimensions ) const Q_DECL_OVERRIDE; + const DataDimensionsList& rawDataDimensions ) const override; /** * Helper function called by calculateGrid() to calculate the grid of one dimension. * * Classes derived from CartesianGrid can overwrite calculateGridXY() if they need * a special way of calculating the start or end or step width of their grid lines. * * \param adjustLower If true, the function adjusts the start value * so it matches the position of a grid line, if false the start value is * the raw data dimension start value. * \param adjustUpper If true, the function adjusts the end value * so it matches the position of a grid line, if false the end value is * the raw data dimension end value. */ virtual DataDimension calculateGridXY( const DataDimension& rawDataDimension, Qt::Orientation orientation, bool adjustLower, bool adjustUpper ) const; /** * Helper function called by calculateGridXY(). * * Classes derived from CartesianGrid can overwrite calculateStepWidth() if they need * a way of calculating the step width, based upon given start/end values * for their horizontal or vertical grid lines which is different from the default * implementation. * * \note The CartesianGrid class tries to keep the displayed range as close to * the raw data range as possible, so in most cases there should be no reason * to change the default implementation: Using * KChart::GridAttributes::setGridGranularitySequence() should be sufficient. * * \param start The raw start value of the data range. * \param end The raw end value of the data range. * \param granularities The list of allowed granularities. * \param adjustLower If true, the function adjusts the start value * so it matches the position of a grid line, if false the start value is * left as it is, in any case the value is adjusted for internal calculation only. * \param adjustUpper If true, the function adjusts the end value * so it matches the position of a grid line, if false the end value is * left as it is, in any case the value is adjusted for internal calculation only. * * \returns stepWidth: One of the values from the granularities * list, optionally multiplied by a positive (or negative, resp.) * power of ten. subStepWidth: The matching width for sub-grid lines. */ virtual void calculateStepWidth( qreal start, qreal end, const QList& granularities, Qt::Orientation orientation, qreal& stepWidth, qreal& subStepWidth, bool adjustLower, bool adjustUpper ) const; }; } #endif diff --git a/src/KChart/Cartesian/KChartLeveyJenningsAxis.h b/src/KChart/Cartesian/KChartLeveyJenningsAxis.h index 961663e..7c0b642 100644 --- a/src/KChart/Cartesian/KChartLeveyJenningsAxis.h +++ b/src/KChart/Cartesian/KChartLeveyJenningsAxis.h @@ -1,85 +1,85 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTLEVEYJENNINGSAXIS_H #define KCHARTLEVEYJENNINGSAXIS_H #include #include "KChartCartesianAxis.h" #include "KChartLeveyJenningsGridAttributes.h" namespace KChart { class LeveyJenningsDiagram; /** * The class for levey jennings axes. * * For being useful, axes need to be assigned to a diagram, see * LeveyJenningsDiagram::addAxis and LeveyJenningsDiagram::takeAxis. * * \sa PolarAxis, AbstractCartesianDiagram */ class KCHART_EXPORT LeveyJenningsAxis : public CartesianAxis { Q_OBJECT Q_DISABLE_COPY( LeveyJenningsAxis ) KCHART_DECLARE_PRIVATE_DERIVED_PARENT( LeveyJenningsAxis, AbstractDiagram* ) public: /** * C'tor of the class for levey jennings axes. * * \note If using a zero parent for the constructor, you need to call * your diagram's addAxis function to add your axis to the diagram. * Otherwise, there is no need to call addAxis, since the constructor * does that automatically for you, if you pass a diagram as parameter. * * \sa AbstractCartesianDiagram::addAxis */ explicit LeveyJenningsAxis ( LeveyJenningsDiagram* diagram = nullptr ); ~LeveyJenningsAxis(); LeveyJenningsGridAttributes::GridType type() const; void setType( LeveyJenningsGridAttributes::GridType type ); Qt::DateFormat dateFormat() const; void setDateFormat( Qt::DateFormat format ); /** * Returns true if both axes have the same settings. */ bool compare( const LeveyJenningsAxis* other ) const; /** reimpl */ - void paintCtx( PaintContext* ) Q_DECL_OVERRIDE; + void paintCtx( PaintContext* ) override; protected: virtual void paintAsOrdinate( PaintContext* ); virtual void paintAsAbscissa( PaintContext* ); }; typedef QList LeveyJenningsAxisList; } #endif diff --git a/src/KChart/Cartesian/KChartLeveyJenningsCoordinatePlane.h b/src/KChart/Cartesian/KChartLeveyJenningsCoordinatePlane.h index 83df944..24b8c4e 100644 --- a/src/KChart/Cartesian/KChartLeveyJenningsCoordinatePlane.h +++ b/src/KChart/Cartesian/KChartLeveyJenningsCoordinatePlane.h @@ -1,64 +1,64 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTLEVEYJENNINGSCOORDINATEPLANE_H #define KCHARTLEVEYJENNINGSCOORDINATEPLANE_H #include "KChartCartesianCoordinatePlane.h" #include "KChartLeveyJenningsGridAttributes.h" namespace KChart { class LeveyJenningsGrid; /** * @brief Levey Jennings coordinate plane * This is actually nothing real more than a plain cartesian * coordinate plane. The difference is, that only Levey Jennings * Diagrams can be added to it. */ class KCHART_EXPORT LeveyJenningsCoordinatePlane : public CartesianCoordinatePlane { Q_OBJECT Q_DISABLE_COPY( LeveyJenningsCoordinatePlane ) KCHART_DECLARE_PRIVATE_DERIVED_PARENT( LeveyJenningsCoordinatePlane, Chart* ) friend class LeveyJenningsGrid; public: explicit LeveyJenningsCoordinatePlane( Chart* parent = nullptr ); ~LeveyJenningsCoordinatePlane(); - void addDiagram( AbstractDiagram* diagram ) Q_DECL_OVERRIDE; + void addDiagram( AbstractDiagram* diagram ) override; LeveyJenningsGridAttributes gridAttributes() const; void setGridAttributes( const LeveyJenningsGridAttributes& attr ); protected: const QPointF translateBack( const QPointF& screenPoint ) const; private: LeveyJenningsGrid* grid() const; }; } #endif diff --git a/src/KChart/Cartesian/KChartLeveyJenningsCoordinatePlane_p.h b/src/KChart/Cartesian/KChartLeveyJenningsCoordinatePlane_p.h index 32ff9c8..2310100 100644 --- a/src/KChart/Cartesian/KChartLeveyJenningsCoordinatePlane_p.h +++ b/src/KChart/Cartesian/KChartLeveyJenningsCoordinatePlane_p.h @@ -1,71 +1,71 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTLEVEYJENNINGSCOORDINATEPLANE_P_H #define KCHARTLEVEYJENNINGSCOORDINATEPLANE_P_H // // W A R N I N G // ------------- // // This file is not part of the KD Chart API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include #include "KChartLeveyJenningsCoordinatePlane.h" #include "KChartLeveyJenningsGrid.h" #include "KChartCartesianCoordinatePlane_p.h" #include "KChartMath_p.h" namespace KChart { class CartesianAxis; /** * \internal */ class Q_DECL_HIDDEN LeveyJenningsCoordinatePlane::Private : public CartesianCoordinatePlane::Private { friend class LeveyJenningsCoordinatePlane; public: explicit Private(); virtual ~Private() { // grid is delete in base class dtor } - void initialize() Q_DECL_OVERRIDE + void initialize() override { grid = new LeveyJenningsGrid(); } LeveyJenningsGridAttributes gridAttributes; }; KCHART_IMPL_DERIVED_PLANE(LeveyJenningsCoordinatePlane, CartesianCoordinatePlane) } #endif /* KCHARTTERNARYCOORDINATEPLANE_P_H */ diff --git a/src/KChart/Cartesian/KChartLeveyJenningsDiagram.h b/src/KChart/Cartesian/KChartLeveyJenningsDiagram.h index 94baa15..4fa3e80 100644 --- a/src/KChart/Cartesian/KChartLeveyJenningsDiagram.h +++ b/src/KChart/Cartesian/KChartLeveyJenningsDiagram.h @@ -1,129 +1,129 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTLEVEYJENNINGSDIAGRAM_H #define KCHARTLEVEYJENNINGSDIAGRAM_H #include "KChartLineDiagram.h" #include "KChartLeveyJenningsCoordinatePlane.h" QT_BEGIN_NAMESPACE class QPainter; class QPolygonF; class QSvgRenderer; QT_END_NAMESPACE namespace KChart { class ThreeDLineAttributes; /** * @brief LeveyDiagram defines a Levey Jennings chart. * * It provides different subtypes which are set using \a setType. */ class KCHART_EXPORT LeveyJenningsDiagram : public LineDiagram { Q_OBJECT Q_DISABLE_COPY( LeveyJenningsDiagram ) // KCHART_DECLARE_PRIVATE_DERIVED_PARENT( LineDiagram, CartesianCoordinatePlane * ) KCHART_DECLARE_DERIVED_DIAGRAM( LeveyJenningsDiagram, LeveyJenningsCoordinatePlane ) public: explicit LeveyJenningsDiagram( QWidget* parent = nullptr, LeveyJenningsCoordinatePlane* plane = nullptr ); virtual ~LeveyJenningsDiagram(); - LineDiagram * clone() const Q_DECL_OVERRIDE; + LineDiagram * clone() const override; enum Symbol { OkDataPoint, NotOkDataPoint, LotChanged, SensorChanged, FluidicsPackChanged }; /** * Returns true if both diagrams have the same settings. */ bool compare( const LeveyJenningsDiagram* other ) const; void setLotChangedSymbolPosition( Qt::Alignment pos ); Qt::Alignment lotChangedSymbolPosition() const; void setFluidicsPackChangedSymbolPosition( Qt::Alignment pos ); Qt::Alignment fluidicsPackChangedSymbolPosition() const; void setSensorChangedSymbolPosition( Qt::Alignment pos ); Qt::Alignment sensorChangedSymbolPosition() const; void setExpectedMeanValue( float meanValue ); float expectedMeanValue() const; void setExpectedStandardDeviation( float sd ); float expectedStandardDeviation() const; float calculatedMeanValue() const; float calculatedStandardDeviation() const; void setFluidicsPackChanges( const QVector< QDateTime >& changes ); QVector< QDateTime > fluidicsPackChanges() const; void setSensorChanges( const QVector< QDateTime >& changes ); QVector< QDateTime > sensorChanges() const; void setScanLinePen( const QPen& pen ); QPen scanLinePen() const; void setSymbol( Symbol symbol, const QString& filename ); QString symbol( Symbol symbol ) const; /* \reimpl */ - void setModel( QAbstractItemModel* model ) Q_DECL_OVERRIDE; + void setModel( QAbstractItemModel* model ) override; QPair< QDateTime, QDateTime > timeRange() const; void setTimeRange( const QPair< QDateTime, QDateTime >& timeRange ); protected: - void paint( PaintContext* paintContext ) Q_DECL_OVERRIDE; + void paint( PaintContext* paintContext ) override; void drawChanges( PaintContext* paintContext ); virtual void drawDataPointSymbol( PaintContext* paintContext, const QPointF& pos, bool ok ); virtual void drawLotChangeSymbol( PaintContext* paintContext, const QPointF& pos ); virtual void drawSensorChangedSymbol( PaintContext* paintContext, const QPointF& pos ); virtual void drawFluidicsPackChangedSymbol( PaintContext* paintContext, const QPointF& pos ); virtual QRectF iconRect() const; QSvgRenderer* iconRenderer( Symbol symbol ); /** \reimpl */ - const QPair calculateDataBoundaries() const Q_DECL_OVERRIDE; + const QPair calculateDataBoundaries() const override; protected Q_SLOTS: void calculateMeanAndStandardDeviation() const; }; // End of class KChartLineDiagram } #endif // KCHARTLINEDIAGRAM_H diff --git a/src/KChart/Cartesian/KChartLeveyJenningsGrid.h b/src/KChart/Cartesian/KChartLeveyJenningsGrid.h index 8c75a69..10bb7df 100644 --- a/src/KChart/Cartesian/KChartLeveyJenningsGrid.h +++ b/src/KChart/Cartesian/KChartLeveyJenningsGrid.h @@ -1,57 +1,57 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTLEVEYJENNINGSGRID_H #define KCHARTLEVEYJENNINGSGRID_H #include "KChartCartesianGrid.h" namespace KChart { class PaintContext; /** * \internal * * \brief Class for the grid in a Levey Jennings plane. * * The LeveyJenningsGrid interface is used * for calculating and for drawing * the horizonal grid lines, and the vertical grid lines * of a Levey Jennings coordinate plane. */ class LeveyJenningsGrid : public CartesianGrid { public: LeveyJenningsGrid() : CartesianGrid() {} virtual ~LeveyJenningsGrid() {} - void drawGrid( PaintContext* context ) Q_DECL_OVERRIDE; + void drawGrid( PaintContext* context ) override; private: - DataDimensionsList calculateGrid( const DataDimensionsList& rawDataDimensions ) const Q_DECL_OVERRIDE; + DataDimensionsList calculateGrid( const DataDimensionsList& rawDataDimensions ) const override; DataDimension calculateGridXY( const DataDimension& rawDataDimension, - Qt::Orientation orientation, bool adjustLower, bool adjustUpper ) const Q_DECL_OVERRIDE; + Qt::Orientation orientation, bool adjustLower, bool adjustUpper ) const override; void calculateStepWidth( qreal start_, qreal end_, const QList& granularities, Qt::Orientation orientation, - qreal& stepWidth, qreal& subStepWidth, bool adjustLower, bool adjustUpper ) const Q_DECL_OVERRIDE; + qreal& stepWidth, qreal& subStepWidth, bool adjustLower, bool adjustUpper ) const override; }; } #endif diff --git a/src/KChart/Cartesian/KChartLineDiagram.h b/src/KChart/Cartesian/KChartLineDiagram.h index 6e5b979..92b9d68 100644 --- a/src/KChart/Cartesian/KChartLineDiagram.h +++ b/src/KChart/Cartesian/KChartLineDiagram.h @@ -1,148 +1,148 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTLINEDIAGRAM_H #define KCHARTLINEDIAGRAM_H #include "KChartAbstractCartesianDiagram.h" #include "KChartLineAttributes.h" #include "KChartValueTrackerAttributes.h" QT_BEGIN_NAMESPACE class QPainter; class QPolygonF; QT_END_NAMESPACE namespace KChart { class ThreeDLineAttributes; /** * @brief LineDiagram defines a common line diagram. * * It provides different subtypes which are set using \a setType. */ class KCHART_EXPORT LineDiagram : public AbstractCartesianDiagram { Q_OBJECT Q_DISABLE_COPY( LineDiagram ) // KCHART_DECLARE_PRIVATE_DERIVED_PARENT( LineDiagram, CartesianCoordinatePlane * ) KCHART_DECLARE_DERIVED_DIAGRAM( LineDiagram, CartesianCoordinatePlane ) public: class LineDiagramType; friend class LineDiagramType; explicit LineDiagram( QWidget* parent = nullptr, CartesianCoordinatePlane* plane = nullptr ); virtual ~LineDiagram(); virtual LineDiagram * clone() const; /** * Returns true if both diagrams have the same settings. */ bool compare( const LineDiagram* other ) const; enum LineType { Normal = 0, Stacked = 1, Percent = 2 }; void setType( const LineType type ); LineType type() const; /** If centerDataPoints() is true, all data points are moved by an * offset of 0.5 to the right. This is useful in conjunction with * bar diagrams, since data points are then centered just like bars. * * \sa centerDataPoints() */ void setCenterDataPoints( bool center ); /** @return option set by setCenterDataPoints() */ bool centerDataPoints() const; /** With this property set to true, data sets in a normal line diagram * are drawn in reversed order. More clearly, the first (top-most) data set * in the source model will then appear in front. This is mostly due to * historical reasons. */ void setReverseDatasetOrder( bool reverse ); /** \see setReverseDatasetOrder */ bool reverseDatasetOrder() const; void setLineAttributes( const LineAttributes & a ); void setLineAttributes( int column, const LineAttributes & a ); void setLineAttributes( const QModelIndex & index, const LineAttributes & a ); void resetLineAttributes( int column ); void resetLineAttributes( const QModelIndex & index ); LineAttributes lineAttributes() const; LineAttributes lineAttributes( int column ) const; LineAttributes lineAttributes( const QModelIndex & index ) const; void setThreeDLineAttributes( const ThreeDLineAttributes & a ); void setThreeDLineAttributes( int column, const ThreeDLineAttributes & a ); void setThreeDLineAttributes( const QModelIndex & index, const ThreeDLineAttributes & a ); ThreeDLineAttributes threeDLineAttributes() const; ThreeDLineAttributes threeDLineAttributes( int column ) const; ThreeDLineAttributes threeDLineAttributes( const QModelIndex & index ) const; void setValueTrackerAttributes( const QModelIndex & index, const ValueTrackerAttributes & a ); ValueTrackerAttributes valueTrackerAttributes( const QModelIndex & index ) const; #if defined(Q_COMPILER_MANGLES_RETURN_TYPE) // implement AbstractCartesianDiagram /* reimpl */ const int numberOfAbscissaSegments () const; /* reimpl */ const int numberOfOrdinateSegments () const; #else // implement AbstractCartesianDiagram /* reimpl */ - int numberOfAbscissaSegments () const Q_DECL_OVERRIDE; + int numberOfAbscissaSegments () const override; /* reimpl */ - int numberOfOrdinateSegments () const Q_DECL_OVERRIDE; + int numberOfOrdinateSegments () const override; #endif protected: - void paint ( PaintContext* paintContext ) Q_DECL_OVERRIDE; + void paint ( PaintContext* paintContext ) override; public: - void resize ( const QSizeF& area ) Q_DECL_OVERRIDE; + void resize ( const QSizeF& area ) override; protected: - qreal threeDItemDepth( const QModelIndex & index ) const Q_DECL_OVERRIDE; - qreal threeDItemDepth( int column ) const Q_DECL_OVERRIDE; + qreal threeDItemDepth( const QModelIndex & index ) const override; + qreal threeDItemDepth( int column ) const override; /** \reimpl */ - const QPair calculateDataBoundaries() const Q_DECL_OVERRIDE; - void paintEvent ( QPaintEvent* ) Q_DECL_OVERRIDE; - void resizeEvent ( QResizeEvent* ) Q_DECL_OVERRIDE; + const QPair calculateDataBoundaries() const override; + void paintEvent ( QPaintEvent* ) override; + void resizeEvent ( QResizeEvent* ) override; }; // End of class KChartLineDiagram } #endif // KCHARTLINEDIAGRAM_H diff --git a/src/KChart/Cartesian/KChartPlotter.h b/src/KChart/Cartesian/KChartPlotter.h index 0278660..65054c0 100644 --- a/src/KChart/Cartesian/KChartPlotter.h +++ b/src/KChart/Cartesian/KChartPlotter.h @@ -1,141 +1,141 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTPLOTTER_H #define KCHARTPLOTTER_H #include "KChartAbstractCartesianDiagram.h" #include "KChartLineAttributes.h" #include "KChartValueTrackerAttributes.h" namespace KChart { class ThreeDLineAttributes; /** * @brief Plotter defines a diagram type plotting two-dimensional data. */ class KCHART_EXPORT Plotter : public AbstractCartesianDiagram { Q_OBJECT Q_DISABLE_COPY( Plotter ) Q_ENUMS( CompressionMode ) KCHART_DECLARE_DERIVED_DIAGRAM( Plotter, CartesianCoordinatePlane ) Q_PROPERTY( CompressionMode useDataCompression READ useDataCompression WRITE setUseDataCompression ) Q_PROPERTY( qreal mergeRadiusPercentage READ mergeRadiusPercentage WRITE setMergeRadiusPercentage ) public: // SLOPE enables a compression based on minmal slope changes // DISTANCE is still buggy and can fail, same for BOTH, NONE is the default mode enum CompressionMode{ SLOPE, DISTANCE, BOTH, NONE }; class PlotterType; friend class PlotterType; explicit Plotter( QWidget* parent = nullptr, CartesianCoordinatePlane* plane = nullptr ); virtual ~Plotter(); virtual Plotter* clone() const; /** * Returns true if both diagrams have the same settings. */ bool compare( const Plotter* other ) const; enum PlotType { Normal = 0, Percent, Stacked }; void setType( const PlotType type ); PlotType type() const; void setLineAttributes( const LineAttributes & a ); void setLineAttributes( int column, const LineAttributes & a ); void setLineAttributes( const QModelIndex & index, const LineAttributes & a ); void resetLineAttributes( int column ); void resetLineAttributes( const QModelIndex & index ); LineAttributes lineAttributes() const; LineAttributes lineAttributes( int column ) const; LineAttributes lineAttributes( const QModelIndex & index ) const; void setThreeDLineAttributes( const ThreeDLineAttributes & a ); void setThreeDLineAttributes( int column, const ThreeDLineAttributes & a ); void setThreeDLineAttributes( const QModelIndex & index, const ThreeDLineAttributes & a ); ThreeDLineAttributes threeDLineAttributes() const; ThreeDLineAttributes threeDLineAttributes( int column ) const; ThreeDLineAttributes threeDLineAttributes( const QModelIndex & index ) const; void setValueTrackerAttributes( const QModelIndex & index, const ValueTrackerAttributes & a ); ValueTrackerAttributes valueTrackerAttributes( const QModelIndex & index ) const; CompressionMode useDataCompression() const; void setUseDataCompression( CompressionMode value ); qreal maxSlopeChange() const; void setMaxSlopeChange( qreal value ); qreal mergeRadiusPercentage() const; void setMergeRadiusPercentage( qreal value ); #if defined(Q_COMPILER_MANGLES_RETURN_TYPE) // implement AbstractCartesianDiagram /* reimpl */ const int numberOfAbscissaSegments () const; /* reimpl */ const int numberOfOrdinateSegments () const; #else // implement AbstractCartesianDiagram /* reimpl */ - int numberOfAbscissaSegments () const Q_DECL_OVERRIDE; + int numberOfAbscissaSegments () const override; /* reimpl */ - int numberOfOrdinateSegments () const Q_DECL_OVERRIDE; + int numberOfOrdinateSegments () const override; #endif protected Q_SLOTS: void connectAttributesModel( AttributesModel* ); protected: - void paint ( PaintContext* paintContext ) Q_DECL_OVERRIDE; + void paint ( PaintContext* paintContext ) override; public: - void resize ( const QSizeF& area ) Q_DECL_OVERRIDE; + void resize ( const QSizeF& area ) override; protected: - qreal threeDItemDepth( const QModelIndex & index ) const Q_DECL_OVERRIDE; - qreal threeDItemDepth( int column ) const Q_DECL_OVERRIDE; + qreal threeDItemDepth( const QModelIndex & index ) const override; + qreal threeDItemDepth( int column ) const override; /** \reimpl */ - const QPair calculateDataBoundaries() const Q_DECL_OVERRIDE; - void paintEvent ( QPaintEvent* ) Q_DECL_OVERRIDE; - void resizeEvent ( QResizeEvent* ) Q_DECL_OVERRIDE; + const QPair calculateDataBoundaries() const override; + void paintEvent ( QPaintEvent* ) override; + void resizeEvent ( QResizeEvent* ) override; protected Q_SLOTS: void setDataBoundariesDirty(); void calcMergeRadius(); }; // End of class KChart::Plotter } #endif // KCHARTLINEDIAGRAM_H diff --git a/src/KChart/Cartesian/KChartStockDiagram.h b/src/KChart/Cartesian/KChartStockDiagram.h index a80179c..238d045 100644 --- a/src/KChart/Cartesian/KChartStockDiagram.h +++ b/src/KChart/Cartesian/KChartStockDiagram.h @@ -1,116 +1,116 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHART_STOCK_DIAGRAM_H #define KCHART_STOCK_DIAGRAM_H #include "KChartAbstractCartesianDiagram.h" #include "KChartCartesianCoordinatePlane.h" #include "KChartStockBarAttributes.h" #include "KChartThreeDBarAttributes.h" namespace KChart { class PaintContext; class KCHART_EXPORT StockDiagram : public AbstractCartesianDiagram { Q_OBJECT Q_DISABLE_COPY( StockDiagram ) KCHART_DECLARE_DERIVED_DIAGRAM( StockDiagram, CartesianCoordinatePlane ) public: enum Type { HighLowClose, OpenHighLowClose, Candlestick }; explicit StockDiagram( QWidget *parent = nullptr, CartesianCoordinatePlane *plane = nullptr ); ~StockDiagram(); void setType( Type type ); Type type() const; void setStockBarAttributes( const StockBarAttributes &attr ); StockBarAttributes stockBarAttributes() const; void setStockBarAttributes( int column, const StockBarAttributes &attr ); StockBarAttributes stockBarAttributes( int column ) const; void setThreeDBarAttributes( const ThreeDBarAttributes &attr ); ThreeDBarAttributes threeDBarAttributes() const; void setThreeDBarAttributes( int column, const ThreeDBarAttributes &attr ); ThreeDBarAttributes threeDBarAttributes( int column ) const; void setLowHighLinePen( const QPen &pen ); QPen lowHighLinePen() const; void setLowHighLinePen( int column, const QPen &pen ); QPen lowHighLinePen( int column ) const; void setUpTrendCandlestickBrush( const QBrush &brush ); QBrush upTrendCandlestickBrush() const; void setDownTrendCandlestickBrush( const QBrush &brush ); QBrush downTrendCandlestickBrush() const; void setUpTrendCandlestickBrush( int column, const QBrush &brush ); QBrush upTrendCandlestickBrush( int column ) const; void setDownTrendCandlestickBrush( int column, const QBrush &brush ); QBrush downTrendCandlestickBrush( int column ) const; void setUpTrendCandlestickPen( const QPen &pen ); QPen upTrendCandlestickPen() const; void setDownTrendCandlestickPen( const QPen &pen ); QPen downTrendCandlestickPen() const; void setUpTrendCandlestickPen( int column, const QPen &pen ); QPen upTrendCandlestickPen( int column ) const; void setDownTrendCandlestickPen( int column, const QPen &pen ); QPen downTrendCandlestickPen( int column ) const; #if defined(Q_COMPILER_MANGLES_RETURN_TYPE) virtual const int numberOfAbscissaSegments() const; virtual const int numberOfOrdinateSegments() const; #else - int numberOfAbscissaSegments() const Q_DECL_OVERRIDE; - int numberOfOrdinateSegments() const Q_DECL_OVERRIDE; + int numberOfAbscissaSegments() const override; + int numberOfOrdinateSegments() const override; #endif - void paint( PaintContext *paintContext ) Q_DECL_OVERRIDE; + void paint( PaintContext *paintContext ) override; - void resize( const QSizeF &size ) Q_DECL_OVERRIDE; + void resize( const QSizeF &size ) override; - qreal threeDItemDepth( int column ) const Q_DECL_OVERRIDE; - qreal threeDItemDepth( const QModelIndex &index ) const Q_DECL_OVERRIDE; + qreal threeDItemDepth( int column ) const override; + qreal threeDItemDepth( const QModelIndex &index ) const override; protected: - const QPair calculateDataBoundaries() const Q_DECL_OVERRIDE; + const QPair calculateDataBoundaries() const override; }; } // namespace KChart #endif // KCHART_STOCK_DIAGRAM_H diff --git a/src/KChart/ChartGraphicsItem.h b/src/KChart/ChartGraphicsItem.h index 2e64827..b141ca0 100644 --- a/src/KChart/ChartGraphicsItem.h +++ b/src/KChart/ChartGraphicsItem.h @@ -1,51 +1,51 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef CHARTGRAPHICSITEM_H #define CHARTGRAPHICSITEM_H #include namespace KChart { /** * @brief Graphics item used inside of the ReverseMapper * \internal */ class ChartGraphicsItem : public QGraphicsPolygonItem { public: enum { Type = UserType + 1 }; ChartGraphicsItem(); ChartGraphicsItem( int row, int column ); int row() const { return m_row; } int column() const { return m_column; } - int type() const Q_DECL_OVERRIDE { return Type; } + int type() const override { return Type; } private: int m_row; int m_column; }; } #endif diff --git a/src/KChart/KChartAbstractArea.h b/src/KChart/KChartAbstractArea.h index 9bfb95e..7e0a6fb 100644 --- a/src/KChart/KChartAbstractArea.h +++ b/src/KChart/KChartAbstractArea.h @@ -1,133 +1,133 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTABSTRACTAREA_H #define KCHARTABSTRACTAREA_H #include #include "KChartGlobal.h" #include "KChartAbstractAreaBase.h" #include "KChartLayoutItems.h" namespace KChart { /** * @class AbstractArea KChartAbstractArea.h * @brief An area in the chart with a background, a frame, etc. * * AbstractArea is the base class for all non-widget chart elements that have * a set of background attributes and frame attributes, such as * coordinate planes or axes. * * @note This class inherits from AbstractAreaBase, AbstractLayoutItem, QObject. * The reason for this triple inheritance is that neither AbstractAreaBase nor * AbstractLayoutItem are QObject. */ class KCHART_EXPORT AbstractArea : public QObject, public AbstractAreaBase, public AbstractLayoutItem { Q_OBJECT Q_DISABLE_COPY( AbstractArea ) KCHART_DECLARE_PRIVATE_DERIVED( AbstractArea ) public: virtual ~AbstractArea() ; /** * @brief Draws the background and frame, then calls paint(). * * In most cases there is no need to overwrite this method in a derived * class, but you would overwrite AbstractLayoutItem::paint() instead. */ virtual void paintIntoRect( QPainter& painter, const QRect& rect ); /** * Call paintAll, if you want the background and the frame to be drawn * before the normal paint() is invoked automatically. */ - void paintAll( QPainter& painter ) Q_DECL_OVERRIDE; + void paintAll( QPainter& painter ) override; /** * This is called at layout time by KChart::AutoSpacerLayoutItem::sizeHint(). * * The method triggers AbstractArea::sizeHint() to find out the * amount of overlap at the left edge of the area. * * \note The default implementation is not using any caching, * it might make sense to implement a more sophisticated solution * for derived classes that have complex work to do in sizeHint(). * All we have here is a primitive flag to be set by the caller * if it is sure that no sizeHint() needs to be called. */ virtual int leftOverlap( bool doNotRecalculate=false ) const; /** * This is called at layout time by KChart::AutoSpacerLayoutItem::sizeHint(). * * The method triggers AbstractArea::sizeHint() to find out the * amount of overlap at the right edge of the area. * * \note The default implementation is not using any caching, * it might make sense to implement a more sophisticated solution * for derived classes that have complex work to do in sizeHint(). * All we have here is a primitive flag to be set by the caller * if it is sure that no sizeHint() needs to be called. */ virtual int rightOverlap( bool doNotRecalculate=false ) const; /** * This is called at layout time by KChart::AutoSpacerLayoutItem::sizeHint(). * * The method triggers AbstractArea::sizeHint() to find out the * amount of overlap at the top edge of the area. * * \note The default implementation is not using any caching, * it might make sense to implement a more sophisticated solution * for derived classes that have complex work to do in sizeHint(). * All we have here is a primitive flag to be set by the caller * if it is sure that no sizeHint() needs to be called. */ virtual int topOverlap( bool doNotRecalculate=false ) const; /** * This is called at layout time by KChart:AutoSpacerLayoutItem::sizeHint(). * * The method triggers AbstractArea::sizeHint() to find out the * amount of overlap at the bottom edge of the area. * * \note The default implementation is not using any caching, * it might make sense to implement a more sophisticated solution * for derived classes that have complex work to do in sizeHint(). * All we have here is a primitive flag to be set by the caller * if it is sure that no sizeHint() needs to be called. */ virtual int bottomOverlap( bool doNotRecalculate=false ) const; protected: AbstractArea(); - QRect areaGeometry() const Q_DECL_OVERRIDE; - void positionHasChanged() Q_DECL_OVERRIDE; + QRect areaGeometry() const override; + void positionHasChanged() override; Q_SIGNALS: void positionChanged( AbstractArea * ); }; // End of class AbstractArea } #endif // KCHARTABSTRACTAREA_H diff --git a/src/KChart/KChartAbstractAreaWidget.h b/src/KChart/KChartAbstractAreaWidget.h index 691d04e..310af1c 100644 --- a/src/KChart/KChartAbstractAreaWidget.h +++ b/src/KChart/KChartAbstractAreaWidget.h @@ -1,110 +1,110 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTABSTRACTAREAWIDGET_H #define KCHARTABSTRACTAREAWIDGET_H #include #include #include #include #include "KChartAbstractAreaBase.h" namespace KChart { /** * @class AbstractAreaWidget KChartAbstractArea.h * @brief An area in the chart with a background, a frame, etc. * * AbstractAreaWidget is the base for all widget classes that have * a set of background attributes and frame attributes, such as * KChart::Chart and KChart::Legend. */ class KCHART_EXPORT AbstractAreaWidget : public QWidget, public AbstractAreaBase { Q_OBJECT Q_DISABLE_COPY( AbstractAreaWidget ) KCHART_DECLARE_PRIVATE_DERIVED_QWIDGET( AbstractAreaWidget ) public: explicit AbstractAreaWidget( QWidget* parent = nullptr ); /** * @brief Draws the background and frame, then calls paint(). * * In most cases there is no need to overwrite this method in a derived * class, but you would overwrite paint() instead. * @sa paint */ - void paintEvent( QPaintEvent* event ) Q_DECL_OVERRIDE; + void paintEvent( QPaintEvent* event ) override; /** * @brief Draws the background and frame, then calls paint(). * * In most cases there is no need to overwrite this method in a derived * class, but you would overwrite paint() instead. */ virtual void paintIntoRect( QPainter& painter, const QRect& rect ); /** * Overwrite this to paint the inner contents of your widget. * * @note When overriding this method, please let your widget draw * itself at the top/left corner of the painter. You should call rect() * (or width(), height(), resp.) to find the drawable area's size: * While the paint() method is being executed the frame of the widget * is outside of its rect(), so you can use all of rect() for * your custom drawing! * @sa paint, paintIntoRect */ virtual void paint( QPainter* painter ) = 0; /** * Call paintAll, if you want the background and the frame to be drawn * before the normal paint() is invoked automatically. */ void paintAll( QPainter& painter ); /** * Call this to trigger an unconditional re-building of the widget's internals. */ virtual void forceRebuild(); /** * Call this to trigger an conditional re-building of the widget's internals. * * e.g. AbstractAreaWidget call this, before calling layout()->setGeometry() */ virtual void needSizeHint(); virtual void resizeLayout( const QSize& ); Q_SIGNALS: void positionChanged( AbstractAreaWidget * ); protected: virtual ~AbstractAreaWidget() ; - QRect areaGeometry() const Q_DECL_OVERRIDE; - void positionHasChanged() Q_DECL_OVERRIDE; + QRect areaGeometry() const override; + void positionHasChanged() override; }; } #endif // KCHARTABSTRACTAREAWIDGET_H diff --git a/src/KChart/KChartAbstractAxis.h b/src/KChart/KChartAbstractAxis.h index b9c63a1..f0086cd 100644 --- a/src/KChart/KChartAbstractAxis.h +++ b/src/KChart/KChartAbstractAxis.h @@ -1,252 +1,252 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTABSTRACTAXIS_H #define KCHARTABSTRACTAXIS_H // #include // #include // #include #include "kchart_export.h" #include "KChartGlobal.h" #include "KChartAbstractArea.h" #include "KChartTextAttributes.h" #include "KChartRulerAttributes.h" QT_BEGIN_NAMESPACE class QPainter; class QSizeF; QT_END_NAMESPACE namespace KChart { class Area; class AbstractCoordinatePlane; class PaintContext; class AbstractDiagram; /** * The base class for axes. * * For being useful, axes need to be assigned to a diagram, see * AbstractCartesianDiagram::addAxis and AbstractCartesianDiagram::takeAxis. * * \sa PolarAxis, AbstractCartesianDiagram */ class KCHART_EXPORT AbstractAxis : public AbstractArea { Q_OBJECT Q_DISABLE_COPY( AbstractAxis ) KCHART_DECLARE_PRIVATE_DERIVED_PARENT( AbstractAxis, AbstractDiagram* ) public: explicit AbstractAxis( AbstractDiagram* diagram = nullptr ); virtual ~AbstractAxis(); // FIXME implement when code os ready for it: // virtual Area* clone() const = 0; // FIXME (Mirko) readd when needed // void copyRelevantDetailsFrom( const KChartAxis* axis ); /* virtual void paint( PaintContext* ) const = 0; virtual QSize sizeHint() const = 0;*/ //virtual void paintEvent( QPaintEvent* event) = 0; /** * \brief Reimplement this method if you want to adjust axis labels * before they are printed. * * KChart is calling this method immediately before drawing the * text, this means: What you return here will be drawn without * further modifications. * * \param label The text of the label as KChart has calculated it * automatically (or as it was taken from a QStringList provided * by you, resp.) * * \note If you reimplement this method in a subclass of KChart::CartesianAxis, * and your reimplementation's return value depends on data other than @p label * (so KChart will not know when it changes), you must manually ensure that * layouts are adapted to any changed sizes of the axis labels. To do that, * call KChart::CartesianAxis::layoutPlanes() from your reimplementation when * you know that the external data changed and it will change label sizes - * or when you cannot exclude that. * * \return The text to be drawn. By default this is the same as \c label. */ virtual const QString customizedLabel( const QString& label ) const; /** * Returns true if both axes have the same settings. */ bool compare( const AbstractAxis* other ) const; /** * \internal * * Method invoked by AbstractCartesianDiagram::addAxis(). * * You should not call this function, unless you know exactly, * what you are doing. * * \sa connectSignals(), AbstractCartesianDiagram::addAxis() */ void createObserver( AbstractDiagram* diagram ); /** * \internal * * Method invoked by AbstractCartesianDiagram::takeAxis(). * * You should not call this function, unless you know exactly, * what you are doing. * * \sa AbstractCartesianDiagram::takeAxis() */ void deleteObserver( AbstractDiagram* diagram ); const AbstractDiagram* diagram() const; bool observedBy( AbstractDiagram* diagram ) const; /** * Wireing the signal/slot connections. * * This method gets called automatically, each time, when you assign * the axis to a diagram, either by passing a diagram* to the c'tor, * or by calling the diagram's setAxis method, resp. * * If overwriting this method in derived classes, make sure to call * this base method AbstractAxis::connectSignals(), so your axis * gets connected to the diagram's built-in signals. * * \sa AbstractCartesianDiagram::addAxis() */ virtual void connectSignals(); /** \brief Use this to specify the text attributes to be used for axis labels. By default, the reference area will be set at painting time. It will be the then-valid coordinate plane's parent widget, so normally, it will be the KChart::Chart. Thus the labels of all of your axes in all of your diagrams within that Chart will be drawn in same font size, by default. \sa textAttributes, setLabels */ void setTextAttributes( const TextAttributes &a ); /** \brief Returns the text attributes to be used for axis labels. \sa setTextAttributes */ TextAttributes textAttributes() const; /** \brief Use this to specify the attributes used to paint the axis ruler Every axis has a default set of ruler attributes that is exactly the same among them. Use this method to specify your own attributes. \sa rulerAttributes */ void setRulerAttributes( const RulerAttributes &a ); /** \brief Returns the attributes to be used for painting the rulers \sa setRulerAttributes */ RulerAttributes rulerAttributes() const; /** \brief Use this to specify your own set of strings, to be used as axis labels. Labels specified via setLabels take precedence: If a non-empty list is passed, KChart will use these strings as axis labels, instead of calculating them. If you pass a smaller number of strings than the number of labels drawn at this axis, KChart will repeat the strings until all labels are drawn. As an example you could specify the seven days of the week as abscissa labels, which would be repeatedly used then. By passing an empty QStringList you can reset the default behaviour. \sa labels, setShortLabels */ void setLabels( const QStringList& list ); /** Returns a list of strings, that are used as axis labels, as set via setLabels. \sa setLabels */ QStringList labels() const; /** \brief Use this to specify your own set of strings, to be used as axis labels, in case the normal labels are too long. \note Setting done via setShortLabels will be ignored, if you did not pass a non-empty string list via setLabels too! By passing an empty QStringList you can reset the default behaviour. \sa shortLabels, setLabels */ void setShortLabels( const QStringList& list ); /** Returns a list of strings, that are used as axis labels, as set via setShortLabels. \note Setting done via setShortLabels will be ignored, if you did not pass a non-empty string list via setLabels too! \sa setShortLabels */ QStringList shortLabels() const; - void setGeometry( const QRect& rect ) Q_DECL_OVERRIDE = 0; - QRect geometry() const Q_DECL_OVERRIDE = 0; + void setGeometry( const QRect& rect ) override = 0; + QRect geometry() const override = 0; /** \brief Convenience function, returns the coordinate plane, in which this axis is used. If the axis is not used in a coordinate plane, the return value is Zero. */ const AbstractCoordinatePlane* coordinatePlane() const; protected Q_SLOTS: /** called for initializing after the c'tor has completed */ virtual void delayedInit(); public Q_SLOTS: void update(); Q_SIGNALS: void coordinateSystemChanged(); }; } #endif // KCHARTABSTRACTAXIS_H diff --git a/src/KChart/KChartAbstractCoordinatePlane.h b/src/KChart/KChartAbstractCoordinatePlane.h index 6e92b69..9c5c481 100644 --- a/src/KChart/KChartAbstractCoordinatePlane.h +++ b/src/KChart/KChartAbstractCoordinatePlane.h @@ -1,443 +1,443 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTABSTRACTCOORDINATEPLANE_H #define KCHARTABSTRACTCOORDINATEPLANE_H #include #include #include "KChartAbstractArea.h" #include "KChartAbstractDiagram.h" #include "KChartEnums.h" namespace KChart { class Chart; class GridAttributes; class DataDimension; typedef QList DataDimensionsList; /** * @brief Base class common for all coordinate planes, CartesianCoordinatePlane, PolarCoordinatePlane, TernaryCoordinatePlane */ class KCHART_EXPORT AbstractCoordinatePlane : public AbstractArea { Q_OBJECT KCHART_DECLARE_PRIVATE_DERIVED_PARENT( AbstractCoordinatePlane, Chart* ) friend class AbstractGrid; public: enum AxesCalcMode { Linear, Logarithmic }; protected: explicit AbstractCoordinatePlane( Chart* parent = nullptr ); public: virtual ~AbstractCoordinatePlane(); /** * Adds a diagram to this coordinate plane. * @param diagram The diagram to add. * * \sa replaceDiagram, takeDiagram */ virtual void addDiagram( AbstractDiagram* diagram ); /** * Replaces the old diagram, or appends the * diagram, it there is none yet. * * @param diagram The diagram to be used instead of the old diagram. * This parameter must not be zero, or the method will do nothing. * * @param oldDiagram The diagram to be removed by the new diagram. This * diagram will be deleted automatically. If the parameter is omitted, * the very first diagram will be replaced. In case, there was no * diagram yet, the new diagram will just be added. * * \note If you want to re-use the old diagram, call takeDiagram and * addDiagram, instead of using replaceDiagram. * * \sa addDiagram, takeDiagram */ virtual void replaceDiagram( AbstractDiagram* diagram, AbstractDiagram* oldDiagram = nullptr ); /** * Removes the diagram from the plane, without deleting it. * * The plane no longer owns the diagram, so it is * the caller's responsibility to delete the diagram. * * \sa addDiagram, replaceDiagram */ virtual void takeDiagram( AbstractDiagram* diagram ); /** * @return The first diagram associated with this coordinate plane. */ AbstractDiagram* diagram(); /** * @return The list of diagrams associated with this coordinate plane. */ AbstractDiagramList diagrams(); /** * @return The list of diagrams associated with this coordinate plane. */ ConstAbstractDiagramList diagrams() const; /** * Distribute the available space among the diagrams and axes. */ virtual void layoutDiagrams() = 0; /** * Translate the given point in value space coordinates to a position * in pixel space. * @param diagramPoint The point in value coordinates. * @returns The translated point. */ virtual const QPointF translate( const QPointF& diagramPoint ) const = 0; /** * @return Whether zooming with a rubber band using the mouse is enabled. */ bool isRubberBandZoomingEnabled() const; /** * Enables or disables zooming with a rubber band using the mouse. */ void setRubberBandZoomingEnabled( bool enable ); /** * @return The zoom factor in horizontal direction, that is applied * to all coordinate transformations. */ virtual qreal zoomFactorX() const { return 1.0; } /** * @return The zoom factor in vertical direction, that is applied * to all coordinate transformations. */ virtual qreal zoomFactorY() const { return 1.0; } /** * Sets both zoom factors in one go. * \sa setZoomFactorX,setZoomFactorY */ virtual void setZoomFactors( qreal factorX, qreal factorY ) { Q_UNUSED( factorX ); Q_UNUSED( factorY ); } /** * Sets the zoom factor in horizontal direction, that is applied * to all coordinate transformations. * @param factor The new zoom factor */ virtual void setZoomFactorX( qreal factor ) { Q_UNUSED( factor ); } /** * Sets the zoom factor in vertical direction, that is applied * to all coordinate transformations. * @param factor The new zoom factor */ virtual void setZoomFactorY( qreal factor ) { Q_UNUSED( factor ); } /** * @return The center point (in value coordinates) of the * coordinate plane, that is used for zoom operations. */ virtual QPointF zoomCenter() const { return QPointF(0.0, 0.0); } /** * Set the point (in value coordinates) to be used as the * center point in zoom operations. * @param center The point to use. */ virtual void setZoomCenter( const QPointF& center ) { Q_UNUSED( center ); } /** * Set the grid attributes to be used by this coordinate plane. * To disable grid painting, for example, your code should like this: * \code * GridAttributes ga = plane->globalGridAttributes(); * ga.setGlobalGridVisible( false ); * plane->setGlobalGridAttributes( ga ); * \endcode * \sa globalGridAttributes * \sa CartesianCoordinatePlane::setGridAttributes */ void setGlobalGridAttributes( const GridAttributes & ); /** * @return The grid attributes used by this coordinate plane. * \sa setGlobalGridAttributes * \sa CartesianCoordinatePlane::gridAttributes */ GridAttributes globalGridAttributes() const; /** * Returns the dimensions used for drawing the grid lines. * * Returned data is the result of (cached) grid calculations, * so - if you need that information for your own tasks - make sure to * call again this function after every data modification that has changed * the data range, since grid calculation is based upon the data range, * thus the grid start/end might have changed if the data was changed. * * @note Returned list will contain different numbers of DataDimension, * depending on the kind of coordinate plane used. * For CartesianCoordinatePlane two DataDimension are returned: the first * representing grid lines in X direction (matching the Abscissa axes) * and the second indicating vertical grid lines (or Ordinate axes, resp.). * * @return The dimensions used for drawing the grid lines. * @sa DataDimension */ DataDimensionsList gridDimensionsList(); /** * Set another coordinate plane to be used as the reference plane * for this one. * @param plane The coordinate plane to be used the reference plane * for this one. * @see referenceCoordinatePlane */ void setReferenceCoordinatePlane( AbstractCoordinatePlane * plane ); /** * There are two ways, in which planes can be caused to interact, in * where they are put layouting wise: The first is the reference plane. If * such a reference plane is set, on a plane, it will use the same cell in the * layout as that one. In addition to this, planes can share an axis. In that case * they will be laid out in relation to each other as suggested by the position * of the axis. If, for example Plane1 and Plane2 share an axis at position Left, * that will result in the layout: Axis Plane1 Plane 2, vertically. If Plane1 * also happens to be Plane2's reference plane, both planes are drawn over each * other. The reference plane concept allows two planes to share the same space * even if neither has any axis, and in case there are shared axis, it is used * to decided, whether the planes should be painted on top of each other or * laid out vertically or horizontally next to each other. * @return The reference coordinate plane associated with this one. */ AbstractCoordinatePlane * referenceCoordinatePlane() const; /** * @return Whether this plane should have spacers in the corners * formed by the presence of axes. */ bool isCornerSpacersEnabled() const; /** * Enables or disables the use of spacers in the plane corners. */ void setCornerSpacersEnabled( bool enable ); virtual AbstractCoordinatePlane* sharedAxisMasterPlane( QPainter* p = nullptr ); // KChart 3: const method? /** pure virtual in QLayoutItem */ - bool isEmpty() const Q_DECL_OVERRIDE; + bool isEmpty() const override; /** pure virtual in QLayoutItem */ - Qt::Orientations expandingDirections() const Q_DECL_OVERRIDE; + Qt::Orientations expandingDirections() const override; /** pure virtual in QLayoutItem */ - QSize maximumSize() const Q_DECL_OVERRIDE; + QSize maximumSize() const override; /** pure virtual in QLayoutItem */ - QSize minimumSize() const Q_DECL_OVERRIDE; + QSize minimumSize() const override; /** pure virtual in QLayoutItem */ - QSize sizeHint() const Q_DECL_OVERRIDE; + QSize sizeHint() const override; /** pure virtual in QLayoutItem * * \note Do not call this function directly, unless you know * exactly what you are doing. Geometry management is done * by KChart's internal layouting measures. */ - void setGeometry( const QRect& r ) Q_DECL_OVERRIDE; + void setGeometry( const QRect& r ) override; /** pure virtual in QLayoutItem */ - QRect geometry() const Q_DECL_OVERRIDE; + QRect geometry() const override; virtual void mousePressEvent( QMouseEvent* event ); virtual void mouseDoubleClickEvent( QMouseEvent* event ); virtual void mouseMoveEvent( QMouseEvent* event ); virtual void mouseReleaseEvent( QMouseEvent* event ); /** * Called internally by KChart::Chart */ void setParent( Chart* parent ); Chart* parent(); const Chart* parent() const; /** * Tests, if a point is visible on the coordinate plane. * * \note Before calling this function the point must have been translated into coordinate plane space. */ #if defined(Q_COMPILER_MANGLES_RETURN_TYPE) const bool isVisiblePoint( const QPointF& point ) const; #else bool isVisiblePoint( const QPointF& point ) const; #endif public Q_SLOTS: /** * Calling update() on the plane triggers the global KChart::Chart::update() */ void update(); /** * Calling relayout() on the plane triggers the global KChart::Chart::slotRelayout() */ void relayout(); /** * Calling layoutPlanes() on the plane triggers the global KChart::Chart::slotLayoutPlanes() */ void layoutPlanes(); /** * Used by the chart to clear the cached grid data. */ void setGridNeedsRecalculate(); Q_SIGNALS: /** Emitted when this coordinate plane is destroyed. */ void destroyedCoordinatePlane( AbstractCoordinatePlane* ); /** Emitted when plane needs to update its drawings. */ void needUpdate(); /** Emitted when plane needs to trigger the Chart's layouting. */ void needRelayout(); /** Emitted when plane needs to trigger the Chart's layouting of the coord. planes. */ void needLayoutPlanes(); /** Emitted upon change of a property of the Coordinate Plane or any of its components. */ void propertiesChanged(); void boundariesChanged(); /** Emitted after the geometry of the Coordinate Plane has been changed. * and control has returned to the event loop. * * Parameters are the old geometry, the new geometry. */ void geometryChanged( QRect, QRect ); private: Q_SIGNALS: // Emitted from inside the setGeometry() // This is connected via QueuedConnection to the geometryChanged() Signal // that users can connect to safely then. void internal_geometryChanged( QRect, QRect ); /** Emitted upon change of the view coordinate system */ void viewportCoordinateSystemChanged(); protected: virtual DataDimensionsList getDataDimensionsList() const = 0; //KCHART_DECLARE_PRIVATE_DERIVED( AbstractCoordinatePlane ) }; /** * \brief Helper class for one dimension of data, e.g. for the rows in a data model, * or for the labels of an axis, or for the vertical lines in a grid. * * isCalculated specifies whether this dimension's values are calculated or counted. * (counted == "Item 1", "Item 2", "Item 3" ...) * * sequence is the GranularitySequence, as specified at for the respective * coordinate plane. * * Step width is an optional parameter, to be omitted (or set to Zero, resp.) * if the step width is unknown. * * The default c'tor just gets you counted values from 1..10, using step width 1, * used by the CartesianGrid, when showing an empty plane without any diagrams. */ class DataDimension{ public: DataDimension() : start( 1.0 ) , end( 10.0 ) , isCalculated( false ) , calcMode( AbstractCoordinatePlane::Linear ) , sequence( KChartEnums::GranularitySequence_10_20 ) , stepWidth( 1.0 ) , subStepWidth( 0.0 ) {} DataDimension( qreal start_, qreal end_, bool isCalculated_, AbstractCoordinatePlane::AxesCalcMode calcMode_, KChartEnums::GranularitySequence sequence_, qreal stepWidth_=0.0, qreal subStepWidth_=0.0 ) : start( start_ ) , end( end_ ) , isCalculated( isCalculated_ ) , calcMode( calcMode_ ) , sequence( sequence_ ) , stepWidth( stepWidth_ ) , subStepWidth( subStepWidth_ ) {} /** * Returns the size of the distance, * equivalent to the width() (or height(), resp.) of a QRectF. * * Note that this value can be negative, e.g. indicating axis labels * going in reversed direction. */ qreal distance() const { return end-start; } bool operator==( const DataDimension& r ) const { return (start == r.start) && (end == r.end) && (sequence == r.sequence) && (isCalculated == r.isCalculated) && (calcMode == r.calcMode) && (stepWidth == r.stepWidth) && (subStepWidth == r.subStepWidth); } bool operator!=( const DataDimension& other ) const { return !operator==( other ); } qreal start; qreal end; bool isCalculated; AbstractCoordinatePlane::AxesCalcMode calcMode; KChartEnums::GranularitySequence sequence; qreal stepWidth; qreal subStepWidth; }; #if !defined(QT_NO_DEBUG_STREAM) QDebug operator<<( QDebug stream, const DataDimension& r ); #endif } #endif diff --git a/src/KChart/KChartAbstractDiagram.h b/src/KChart/KChartAbstractDiagram.h index bf8aa21..e2a9162 100644 --- a/src/KChart/KChartAbstractDiagram.h +++ b/src/KChart/KChartAbstractDiagram.h @@ -1,735 +1,735 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTABSTRACTDIAGRAM_H #define KCHARTABSTRACTDIAGRAM_H #include #include #include #include "KChartGlobal.h" #include "KChartMarkerAttributes.h" #include "KChartAttributesModel.h" namespace KChart { class AbstractCoordinatePlane; class AttributesModel; class DataValueAttributes; class PaintContext; /** * @brief AbstractDiagram defines the interface for diagram classes * * AbstractDiagram is the base class for diagram classes ("chart types"). * * It defines the interface, that needs to be implemented for the diagram, * to function within the KChart framework. It extends Interview's * QAbstractItemView. */ class KCHART_EXPORT AbstractDiagram : public QAbstractItemView { Q_OBJECT Q_DISABLE_COPY( AbstractDiagram ) KCHART_DECLARE_PRIVATE_BASE_POLYMORPHIC( AbstractDiagram ) friend class AbstractCoordinatePlane; friend class CartesianCoordinatePlane; friend class PolarCoordinatePlane; protected: explicit inline AbstractDiagram( Private *p, QWidget* parent, AbstractCoordinatePlane* plane ); explicit AbstractDiagram ( QWidget* parent = nullptr, AbstractCoordinatePlane* plane = nullptr ); public: virtual ~AbstractDiagram(); /** * Returns true if both diagrams have the same settings. */ bool compare( const AbstractDiagram* other ) const; /** * @brief Return the bottom left and top right data point, that the * diagram will display (unless the grid adjusts these values). * * This method returns a cached result of calculations done by * calculateDataBoundaries. * Classes derived from AbstractDiagram must implement the * calculateDataBoundaries function, to specify their own * way of calculating the data boundaries. * If derived classes want to force recalculation of the * data boundaries, they can call setDataBoundariesDirty() * * Returned value is in diagram coordinates. */ const QPair dataBoundaries() const; // protected: // FIXME: why should that be private? (Mirko) /** * Draw the diagram contents to the rectangle and painter, that are * passed in as part of the paint context. * * @param paintContext All information needed for painting. */ virtual void paint ( PaintContext* paintContext ) = 0; /** * Called by the widget's sizeEvent. Adjust all internal structures, * that are calculated, dependending on the size of the widget. * * @param area */ virtual void resize ( const QSizeF& area ); /** Associate a model with the diagram. */ - void setModel ( QAbstractItemModel * model ) Q_DECL_OVERRIDE; + void setModel ( QAbstractItemModel * model ) override; /** Associate a seleection model with the diagrom. */ - void setSelectionModel( QItemSelectionModel* selectionModel ) Q_DECL_OVERRIDE; + void setSelectionModel( QItemSelectionModel* selectionModel ) override; /** * Associate an AttributesModel with this diagram. Note that * the diagram does _not_ take ownership of the AttributesModel. * This should thus only be used with AttributesModels that * have been explicitly created by the user, and are owned * by her. Setting an AttributesModel that is internal to * another diagram is an error. * * Correct: * * \code * AttributesModel *am = new AttributesModel( model, 0 ); * diagram1->setAttributesModel( am ); * diagram2->setAttributesModel( am ); * * \endcode * * Wrong: * * \code * * diagram1->setAttributesModel( diagram2->attributesModel() ); * * \endcode * * @param model The AttributesModel to use for this diagram. * @see AttributesModel, usesExternalAttributesModel */ virtual void setAttributesModel( AttributesModel* model ); /** * Returns whether the diagram is using its own built-in attributes model * or an attributes model that was set via setAttributesModel. * * @see setAttributesModel */ virtual bool usesExternalAttributesModel() const; /** * Returns the AttributesModel, that is used by this diagram. * By default each diagram owns its own AttributesModel, which * should never be deleted. Only if a user-supplied AttributesModel * has been set does the pointer returned here not belong to the * diagram. * * @return The AttributesModel associated with the diagram. * @see setAttributesModel */ virtual AttributesModel* attributesModel() const; /** Set the root index in the model, where the diagram starts * referencing data for display. */ - void setRootIndex ( const QModelIndex& idx ) Q_DECL_OVERRIDE; + void setRootIndex ( const QModelIndex& idx ) override; /** \reimpl */ - QRect visualRect(const QModelIndex &index) const Q_DECL_OVERRIDE; + QRect visualRect(const QModelIndex &index) const override; /** \reimpl */ - void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible) Q_DECL_OVERRIDE; + void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible) override; /** \reimpl */ - QModelIndex indexAt(const QPoint &point) const Q_DECL_OVERRIDE; + QModelIndex indexAt(const QPoint &point) const override; /** \reimpl */ - QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers) Q_DECL_OVERRIDE; + QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers) override; /** \reimpl */ - int horizontalOffset() const Q_DECL_OVERRIDE; + int horizontalOffset() const override; /** \reimpl */ - int verticalOffset() const Q_DECL_OVERRIDE; + int verticalOffset() const override; /** \reimpl */ - bool isIndexHidden(const QModelIndex &index) const Q_DECL_OVERRIDE; + bool isIndexHidden(const QModelIndex &index) const override; /** \reimpl */ - void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command) Q_DECL_OVERRIDE; + void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command) override; /** \reimpl */ - QRegion visualRegionForSelection(const QItemSelection &selection) const Q_DECL_OVERRIDE; + QRegion visualRegionForSelection(const QItemSelection &selection) const override; virtual QRegion visualRegion(const QModelIndex &index) const; /** \reimpl */ - void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles = QVector()) Q_DECL_OVERRIDE; + void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles = QVector()) override; /** \reimpl */ - void doItemsLayout() Q_DECL_OVERRIDE; + void doItemsLayout() override; /** * The coordinate plane associated with the diagram. This determines * how coordinates in value space are mapped into pixel space. By default * this is a CartesianCoordinatePlane. * @return The coordinate plane associated with the diagram. */ AbstractCoordinatePlane* coordinatePlane() const; /** * Set the coordinate plane associated with the diagram. This determines * how coordinates in value space are mapped into pixel space. The chart * takes ownership. * @return The coordinate plane associated with the diagram. */ virtual void setCoordinatePlane( AbstractCoordinatePlane* plane ); /** * Hide (or unhide, resp.) a data cell. * * \note Hidden data are still taken into account by the coordinate plane, * so neither the grid nor your axes' ranges will change, when you hide data. * For totally removing data from KChart's view you can use another approach: * e.g. you could define a proxy model on top of your data model, and register * the proxy model calling setModel() instead of registering your real data model. * * @param index The datapoint to set the hidden status for. With a dataset dimension * of two, this is the index of the key of each key/value pair. * @param hidden The hidden status to set. */ void setHidden( const QModelIndex & index, bool hidden ); /** * Hide (or unhide, resp.) a dataset. * * \note Hidden data are still taken into account by the coordinate plane, * so neither the grid nor your axes' ranges will change, when you hide data. * For totally removing data from KChart's view you can use another approach: * e.g. you could define a proxy model on top of your data model, and register * the proxy model calling setModel() instead of registering your real data model. * * @param dataset The dataset to set the hidden status for. * @param hidden The hidden status to set. */ void setHidden( int dataset, bool hidden ); /** * Hide (or unhide, resp.) all datapoints in the model. * * \note Hidden data are still taken into account by the coordinate plane, * so neither the grid nor your axes' ranges will change, when you hide data. * For totally removing data from KChart's view you can use another approach: * e.g. you could define a proxy model on top of your data model, and register * the proxy model calling setModel() instead of registering your real data model. * * @param hidden The hidden status to set. */ void setHidden( bool hidden ); /** * Retrieve the hidden status specified globally. This will fall * back automatically to the default settings ( = not hidden), if there * are no specific settings. * @return The global hidden status. */ bool isHidden() const; /** * Retrieve the hidden status for the given dataset. This will fall * back automatically to what was set at diagram level, if there * are no dataset specific settings. * @param dataset The dataset to retrieve the hidden status for. * @return The hidden status for the given dataset. */ bool isHidden( int dataset ) const; /** * Retrieve the hidden status for the given index. This will fall * back automatically to what was set at dataset or diagram level, if there * are no datapoint specific settings. * @param index The datapoint to retrieve the hidden status for. * @return The hidden status for the given index. */ bool isHidden( const QModelIndex & index ) const; /** * Set the DataValueAttributes for the given index. * @param index The datapoint to set the attributes for. With a dataset dimension * of two, this is the index of the key of each key/value pair. * @param a The attributes to set. */ void setDataValueAttributes( const QModelIndex & index, const DataValueAttributes & a ); /** * Set the DataValueAttributes for the given dataset. * @param dataset The dataset to set the attributes for. * @param a The attributes to set. */ void setDataValueAttributes( int dataset, const DataValueAttributes & a ); /** * Set the DataValueAttributes for all datapoints in the model. * @param a The attributes to set. */ void setDataValueAttributes( const DataValueAttributes & a ); /** * Retrieve the DataValueAttributes specified globally. This will fall * back automatically to the default settings, if there * are no specific settings. * @return The global DataValueAttributes. */ DataValueAttributes dataValueAttributes() const; /** * Retrieve the DataValueAttributes for the given dataset. This will fall * back automatically to what was set at model level, if there * are no dataset specific settings. * @param dataset The dataset to retrieve the attributes for. * @return The DataValueAttributes for the given dataset. */ DataValueAttributes dataValueAttributes( int dataset ) const; /** * Retrieve the DataValueAttributes for the given index. This will fall * back automatically to what was set at dataset or model level, if there * are no datapoint specific settings. * @param index The datapoint to retrieve the attributes for. With a dataset dimension * of two, this is the index of the key of each key/value pair. * @return The DataValueAttributes for the given index. */ DataValueAttributes dataValueAttributes( const QModelIndex & index ) const; /** * Set the pen to be used, for painting the datapoint at the given index. * @param index The datapoint's index in the model. With a dataset dimension * of two, this is the index of the key of each key/value pair. * @param pen The pen to use. */ void setPen( const QModelIndex& index, const QPen& pen ); /** * Set the pen to be used, for painting the given dataset. * @param dataset The dataset to set the pen for. * @param pen The pen to use. */ void setPen( int dataset, const QPen& pen ); /** * Set the pen to be used, for painting all datasets in the model. * @param pen The pen to use. */ void setPen( const QPen& pen ); /** * Retrieve the pen to be used for painting datapoints globally. This will fall * back automatically to the default settings, if there * are no specific settings. * @return The pen to use for painting. */ QPen pen() const; /** * Retrieve the pen to be used for the given dataset. This will fall * back automatically to what was set at model level, if there * are no dataset specific settings. * @param dataset The dataset to retrieve the pen for. * @return The pen to use for painting. */ QPen pen( int dataset ) const; /** * Retrieve the pen to be used, for painting the datapoint at the given * index in the model. * @param index The index of the datapoint in the model. With a dataset dimension * of two, this is the index of the key of each key/value pair. * @return The pen to use for painting. */ QPen pen( const QModelIndex& index ) const; /** * Set the brush to be used, for painting the datapoint at the given index. * @param index The datapoint's index in the model. With a dataset dimension * of two, this is the index of the key of each key/value pair. * @param brush The brush to use. */ void setBrush( const QModelIndex& index, const QBrush& brush); /** * Set the brush to be used, for painting the given dataset. * @param dataset The dataset to set the brush for. * @param brush The brush to use. */ void setBrush( int dataset, const QBrush& brush ); /** * Set the brush to be used, for painting all datasets in the model. * @param brush The brush to use. */ void setBrush( const QBrush& brush); /** * Retrieve the brush to be used for painting datapoints globally. This will fall * back automatically to the default settings, if there * are no specific settings. * @return The brush to use for painting. */ QBrush brush() const; /** * Retrieve the brush to be used for the given dataset. This will fall * back automatically to what was set at model level, if there * are no dataset specific settings. * @param dataset The dataset to retrieve the brush for. * @return The brush to use for painting. */ QBrush brush( int dataset ) const; /** * Retrieve the brush to be used, for painting the datapoint at the given * index in the model. * @param index The index of the datapoint in the model. With a dataset dimension * of two, this is the index of the key of each key/value pair. * @return The brush to use for painting. */ QBrush brush( const QModelIndex& index ) const; /** * Set the unit prefix to be used on axes for one specific column. * @param prefix The prefix to be used. * @param column The column which should be set. * @param orientation The orientation of the axis to use. */ void setUnitPrefix( const QString& prefix, int column, Qt::Orientation orientation ); /** * Set the unit prefix to be used on axes for all columns. * @param prefix The prefix to be used. * @param orientation The orientation of the axis to use. */ void setUnitPrefix( const QString& prefix, Qt::Orientation orientation ); /** * Set the unit prefix to be used on axes for one specific column. * @param suffix The suffix to be used. * @param column The column which should be set. * @param orientation The orientation of the axis to use. */ void setUnitSuffix( const QString& suffix, int column, Qt::Orientation orientation ); /** * Set the unit prefix to be used on axes for all columns. * @param suffix The suffix to be used. * @param orientation The orientation of the axis to use. */ void setUnitSuffix( const QString& suffix, Qt::Orientation orientation ); /** * Retrieves the axis unit prefix for a specific column. * @param column The column whose prefix should be retrieved. * @param orientation The orientation of the axis. * @param fallback If true, the prefix for all columns is returned, when * none is set for the selected column. * @return The axis unit prefix. */ QString unitPrefix( int column, Qt::Orientation orientation, bool fallback = false ) const; /** * Retrieves the axis unit prefix. * @param orientation The orientation of the axis. * @return The axis unit prefix. */ QString unitPrefix( Qt::Orientation orientation ) const; /** * Retrieves the axis unit suffix for a specific column. * @param column The column whose prefix should be retrieved. * @param orientation The orientation of the axis. * @param fallback If true, the suffix for all columns is returned, when * none is set for the selected column. * @return The axis unit suffix. */ QString unitSuffix( int column, Qt::Orientation orientation, bool fallback = false ) const; /** * Retrieves the axis unit suffix. * @param orientation The orientation of the axis. * @return The axis unit suffix. */ QString unitSuffix( Qt::Orientation orientation ) const; /** * Set whether data value labels are allowed to overlap. * @param allow True means that overlapping labels are allowed. */ void setAllowOverlappingDataValueTexts( bool allow ); /** * @return Whether data value labels are allowed to overlap. */ bool allowOverlappingDataValueTexts() const; /** * Set whether anti-aliasing is to be used while rendering * this diagram. * @param enabled True means that AA is enabled. */ void setAntiAliasing( bool enabled ); /** * @return Whether anti-aliasing is to be used for rendering * this diagram. */ bool antiAliasing() const; /** * Set the palette to be used, for painting datasets to the default * palette. * @see KChart::Palette. * FIXME: fold into one usePalette (KChart::Palette&) method */ void useDefaultColors(); /** * Set the palette to be used, for painting datasets to the rainbow * palette. * @see KChart::Palette. */ void useRainbowColors(); /** * Set the palette to be used, for painting datasets to the subdued * palette. * @see KChart::Palette. */ void useSubduedColors(); /** * The set of item row labels currently displayed, for use in Abscissa axes, etc. * @return The set of item row labels currently displayed. */ QStringList itemRowLabels() const; /** * The set of dataset labels currently displayed, for use in legends, etc. * @return The set of dataset labels currently displayed. */ QStringList datasetLabels() const; /** * The set of dataset brushes currently used, for use in legends, etc. * * @note Cell-level override brushes, if set, take precedence over the * dataset values, so you might need to check these too, in order to find * the brush, that is used for a single cell. * * @return The current set of dataset brushes. */ QList datasetBrushes() const; /** * The set of dataset pens currently used, for use in legends, etc. * * @note Cell-level override pens, if set, take precedence over the * dataset values, so you might need to check these too, in order to find * the pens, that is used for a single cell. * * @return The current set of dataset pens. */ QList datasetPens() const; /** * The set of dataset markers currently used, for use in legends, etc. * * @note Cell-level override markers, if set, take precedence over the * dataset values, so you might need to check these too, in order to find * the marker, that is shown for a single cell. * * @return The current set of dataset brushes. */ QList datasetMarkers() const; /** * \deprecated * * \brief Deprecated method that turns the percent mode of this diagram on or off. * * This method is deprecated. Use the setType() method of a supporting diagram implementation * instead, e.g. BarDiagram::setType(). * * \see percentMode */ void setPercentMode( bool percent ); /** * \brief Returns whether this diagram is drawn in percent mode. * * If true, all data points in the same column of a diagram will * be be drawn at the same X coordinate and stacked up so that the distance from the * last data point (or the zero line) to a data point P is always the ratio of (Y-Value of P)/ * (sum of all Y-Values in same column as P) relative to the diagrams height * (or width, if abscissa and ordinate are swapped). * * Note that this property is not applicable to all diagram types. */ bool percentMode() const; virtual void paintMarker( QPainter* painter, const MarkerAttributes& markerAttributes, const QBrush& brush, const QPen&, const QPointF& point, const QSizeF& size ); /** * The dataset dimension of a diagram determines how many value dimensions * it expects each datapoint to have. * For each dimension and data series it will expect one column of values in the model. * If the dimension is 1, automatic values will be used for X. * * For example, a diagram with the default dimension of 1 will have one column * per data series (the Y values) and will use automatic values for X * (1, 2, 3, ... n). * If the dimension is 2, the diagram will use the first, (and the third, * fifth, etc) columns as X values, and the second, (and the fourth, sixth, * etc) column as Y values. * @return The dataset dimension of the diagram. */ int datasetDimension() const; /** * \deprecated * * Sets the dataset dimension of the diagram. Using this method * is deprecated. Use the specific diagram types instead. */ void setDatasetDimension( int dimension ); protected: void setDatasetDimensionInternal( int dimension ); public: void update() const; void paintMarker( QPainter* painter, const DataValueAttributes& a, const QModelIndex& index, const QPointF& pos ); void paintMarker( QPainter* painter, const QModelIndex& index, const QPointF& pos ); void paintDataValueText( QPainter* painter, const QModelIndex& index, const QPointF& pos, qreal value ); // reverse mapping: /** This method is added alongside with indexAt from QAIM, since in KChart multiple indexes can be displayed at the same spot. */ QModelIndexList indexesAt( const QPoint& point ) const; QModelIndexList indexesIn( const QRect& rect ) const; protected: virtual bool checkInvariants( bool justReturnTheStatus=false ) const; virtual const QPair calculateDataBoundaries() const = 0; protected Q_SLOTS: void setDataBoundariesDirty() const; protected: /** * \deprecated * This method is deprecated and provided for backward-compatibility only. * Your own diagram classes should call * d->paintDataValueTextsAndMarkers() instead * which also is taking care for showing your cell-specific comments, if any, */ virtual void paintDataValueTexts( QPainter* painter ); /** * \deprecated * This method is deprecated and provided for backward-compatibility only. * Your own diagram classes should call * d->paintDataValueTextsAndMarkers() instead * which also is taking care for showing your cell-specific comments, if any, */ virtual void paintMarkers( QPainter* painter ); void setAttributesModelRootIndex( const QModelIndex& ); QModelIndex attributesModelRootIndex() const; /** * Helper method, retrieving the data value (DisplayRole) for a given row and column * @param row The row to query. * @param column The column to query. * @return The value of the display role at the given row and column as a qreal. * @deprecated */ qreal valueForCell( int row, int column ) const; Q_SIGNALS: /** Diagrams are supposed to emit this signal, when the layout of one of their element changes. Layouts can change, for example, when axes are added or removed, or when the configuration was changed in a way that the axes or the diagram itself are displayed in a different geometry. Changes in the diagrams coordinate system also result in the layoutChanged() signal being emitted. */ void layoutChanged( AbstractDiagram* ); /** * This signal is emitted when this diagram is being destroyed, but before all the * data, i.e. the attributes model, is invalidated. */ void aboutToBeDestroyed(); /** This signal is emitted when either the model or the AttributesModel is replaced. */ void modelsChanged(); /** This signal is emitted just before the new attributes model is connected internally. It gives you a chance to connect to its signals first or perform other setup work. */ void attributesModelAboutToChange( AttributesModel* newModel, AttributesModel* oldModel ); /** This signal is emitted, when the model data is changed. */ void modelDataChanged(); /** This signal is emitted, when the hidden status of at least one data cell was (un)set. */ void dataHidden(); /** Emitted upon change of a property of the Diagram. */ void propertiesChanged(); /** Emitted upon change of a data boundary */ void boundariesChanged(); /** Emitted upon change of the view coordinate system */ void viewportCoordinateSystemChanged(); private: QModelIndex conditionallyMapFromSource( const QModelIndex & sourceIndex ) const; }; typedef QList AbstractDiagramList; typedef QList ConstAbstractDiagramList; /** * @brief Internally used class just adding a special constructor used by AbstractDiagram */ class PrivateAttributesModel : public AttributesModel { Q_OBJECT public: explicit PrivateAttributesModel( QAbstractItemModel* model, QObject * parent = nullptr ) : AttributesModel(model,parent) {} }; } #endif diff --git a/src/KChart/KChartAbstractProxyModel.h b/src/KChart/KChartAbstractProxyModel.h index adc5fa8..496d25c 100644 --- a/src/KChart/KChartAbstractProxyModel.h +++ b/src/KChart/KChartAbstractProxyModel.h @@ -1,51 +1,51 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTABSTRACTPROXYMODEL_H #define KCHARTABSTRACTPROXYMODEL_H #include #include "KChartGlobal.h" namespace KChart { /** * @brief Base class for all proxy models used inside KChart * \internal */ class KCHART_EXPORT AbstractProxyModel : public QAbstractProxyModel { Q_OBJECT public: explicit AbstractProxyModel( QObject* parent = nullptr ); /*! \reimpl */ - QModelIndex mapFromSource( const QModelIndex & sourceIndex ) const Q_DECL_OVERRIDE; + QModelIndex mapFromSource( const QModelIndex & sourceIndex ) const override; /*! \reimpl */ - QModelIndex mapToSource( const QModelIndex &proxyIndex ) const Q_DECL_OVERRIDE; + QModelIndex mapToSource( const QModelIndex &proxyIndex ) const override; /*! \reimpl */ - QModelIndex index( int row, int col, const QModelIndex& index ) const Q_DECL_OVERRIDE; + QModelIndex index( int row, int col, const QModelIndex& index ) const override; /*! \reimpl */ - QModelIndex parent( const QModelIndex& index ) const Q_DECL_OVERRIDE; + QModelIndex parent( const QModelIndex& index ) const override; }; } #endif /* KCHARTABSTRACTPROXYMODEL_H */ diff --git a/src/KChart/KChartAttributesModel.h b/src/KChart/KChartAttributesModel.h index 3de4f7b..1854118 100644 --- a/src/KChart/KChartAttributesModel.h +++ b/src/KChart/KChartAttributesModel.h @@ -1,149 +1,149 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef __KCHART_ATTRIBUTES_MODEL_H__ #define __KCHART_ATTRIBUTES_MODEL_H__ #include "KChartAbstractProxyModel.h" #include #include #include "KChartGlobal.h" namespace KChart { /** * @brief A proxy model used for decorating data with attributes. * * An AttributesModel forwards data from and to the source model and adds attributes, * data that influences the graphical rendering of the source model data. * The attributes are distinguished from the source model's data by their @p role values. * Therefore this class does not need to, and does not, change the data layout from the * source model's; indexes that refer to the same data have the same row and column * values in both models. * Attribute changes, that is changes to data with the attribute role, via the interface * of this class (including setData()) are stored internally and not forwarded to the source model. */ class KCHART_EXPORT AttributesModel : public AbstractProxyModel { Q_OBJECT KCHART_DECLARE_PRIVATE_BASE_POLYMORPHIC( AttributesModel ) public: enum PaletteType { PaletteTypeDefault = 0, PaletteTypeRainbow = 1, PaletteTypeSubdued = 2 }; explicit AttributesModel( QAbstractItemModel* model, QObject * parent = nullptr ); ~AttributesModel(); /** Copies the internal data (maps and palette) of another * AttributesModel* into this one. */ void initFrom( const AttributesModel* other ); /** Returns true if both, all of the attributes set, and * the palette set is equal in both of the AttributeModels. */ bool compare( const AttributesModel* other ) const; bool compareAttributes( int role, const QVariant& a, const QVariant& b ) const; /* Attributes Model specific API */ bool setModelData( const QVariant value, int role ); QVariant modelData( int role ) const; /** Returns whether the given role corresponds to one of the known * internally used ones. */ bool isKnownAttributesRole( int role ) const; /** Sets the palettetype used by this attributesmodel */ void setPaletteType( PaletteType type ); PaletteType paletteType() const; /** Returns the data that were specified at global level, * or the default data, or QVariant(). */ QVariant data(int role) const; /** Returns the data that were specified at per column level, * or the globally set data, or the default data, or QVariant(). */ QVariant data(int column, int role) const; /** \reimpl */ - QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const Q_DECL_OVERRIDE; + QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override; /** \reimpl */ - int rowCount(const QModelIndex& ) const Q_DECL_OVERRIDE; + int rowCount(const QModelIndex& ) const override; /** \reimpl */ - int columnCount(const QModelIndex& ) const Q_DECL_OVERRIDE; + int columnCount(const QModelIndex& ) const override; /** \reimpl */ - QVariant data(const QModelIndex&, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; + QVariant data(const QModelIndex&, int role = Qt::DisplayRole) const override; /** \reimpl */ - bool setData ( const QModelIndex & index, const QVariant & value, int role = Qt::DisplayRole) Q_DECL_OVERRIDE; + bool setData ( const QModelIndex & index, const QVariant & value, int role = Qt::DisplayRole) override; /** Remove any explicit attributes settings that might have been specified before. */ bool resetData ( const QModelIndex & index, int role = Qt::DisplayRole); /** \reimpl */ bool setHeaderData ( int section, Qt::Orientation orientation, const QVariant & value, - int role = Qt::DisplayRole) Q_DECL_OVERRIDE; + int role = Qt::DisplayRole) override; /** Returns default values for the header data. */ virtual QVariant defaultHeaderData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const; /** Remove any explicit attributes settings that might have been specified before. */ bool resetHeaderData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole); /** \reimpl */ - void setSourceModel ( QAbstractItemModel* sourceModel ) Q_DECL_OVERRIDE; + void setSourceModel ( QAbstractItemModel* sourceModel ) override; /** Define the default value for a certain role. Passing a default-constructed QVariant is equivalent to removing the default. */ void setDefaultForRole( int role, const QVariant& value ); /** Set the dimension of the dataset in the source model. \sa AbstractDiagram::setDatasetDimension */ void setDatasetDimension( int dimension ); int datasetDimension() const; Q_SIGNALS: void attributesChanged( const QModelIndex&, const QModelIndex& ); private Q_SLOTS: void slotRowsAboutToBeInserted( const QModelIndex& parent, int start, int end ); void slotColumnsAboutToBeInserted( const QModelIndex& parent, int start, int end ); void slotRowsInserted( const QModelIndex& parent, int start, int end ); void slotColumnsInserted( const QModelIndex& parent, int start, int end ); void slotRowsAboutToBeRemoved( const QModelIndex& parent, int start, int end ); void slotColumnsAboutToBeRemoved( const QModelIndex& parent, int start, int end ); void slotRowsRemoved( const QModelIndex& parent, int start, int end ); void slotColumnsRemoved( const QModelIndex& parent, int start, int end ); void slotDataChanged( const QModelIndex& topLeft, const QModelIndex& bottomRight ); private: // helper QVariant defaultsForRole( int role ) const; bool compareHeaderDataMaps( const QMap< int, QMap< int, QVariant > >& mapA, const QMap< int, QMap< int, QVariant > >& mapB ) const; void removeEntriesFromDataMap( int start, int end ); void removeEntriesFromDirectionDataMaps( Qt::Orientation dir, int start, int end ); }; } #endif diff --git a/src/KChart/KChartChart.cpp b/src/KChart/KChartChart.cpp index 3d0f4f5..fe3babc 100644 --- a/src/KChart/KChartChart.cpp +++ b/src/KChart/KChartChart.cpp @@ -1,1773 +1,1773 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "KChartChart.h" #include "KChartChart_p.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "KChartCartesianCoordinatePlane.h" #include "KChartAbstractCartesianDiagram.h" #include "KChartHeaderFooter.h" #include "KChartEnums.h" #include "KChartLegend.h" #include "KChartLayoutItems.h" #include #include #include "KChartPainterSaver_p.h" #include "KChartPrintingParameters.h" #include #if defined KDAB_EVAL #include "../evaldialog/evaldialog.h" #endif #if 0 // dumpLayoutTree dumps a QLayout tree in a hopefully easy to read format to stderr - feel free to // use, improve and extend; it is very useful for looking at any layout problem. #include // this is this different from both QRect::isEmpty() and QRect::isNull() for "wrong" QRects, // i.e. those where topLeft() is actually below and / or right of bottomRight(). static bool isZeroArea(const QRect &r) { return !r.width() || !r.height(); } static QString lineProlog(int nestingDepth, int lineno) { QString numbering(QString::number(lineno).rightJustified(5).append(QChar::fromAscii(':'))); QString indent(nestingDepth * 4, QLatin1Char(' ')); return numbering + indent; } static void dumpLayoutTreeRecurse(QLayout *l, int *counter, int depth) { const QLatin1String colorOn(isZeroArea(l->geometry()) ? "\033[0m" : "\033[32m"); const QLatin1String colorOff("\033[0m"); QString prolog = lineProlog(depth, *counter); (*counter)++; qDebug() << colorOn + prolog << l->metaObject()->className() << l->geometry() << "hint" << l->sizeHint() << l->hasHeightForWidth() << "min" << l->minimumSize() << "max" << l->maximumSize() << l->expandingDirections() << l->alignment() << colorOff; for (int i = 0; i < l->count(); i++) { QLayoutItem *child = l->itemAt(i); if (QLayout *childL = child->layout()) { dumpLayoutTreeRecurse(childL, counter, depth + 1); } else { // The isZeroArea check culls usually largely useless output - you might want to remove it in // some debugging situations. Add a boolean parameter to this and dumpLayoutTree() if you do. if (!isZeroArea(child->geometry())) { prolog = lineProlog(depth + 1, *counter); (*counter)++; qDebug() << colorOn + prolog << typeid(*child).name() << child->geometry() << "hint" << child->sizeHint() << child->hasHeightForWidth() << "min" << child->minimumSize() << "max" << child->maximumSize() << child->expandingDirections() << child->alignment() << colorOff; } } } } static void dumpLayoutTree(QLayout *l) { int counter = 0; dumpLayoutTreeRecurse(l, &counter, 0); } #endif static const Qt::Alignment s_gridAlignments[ 3 ][ 3 ] = { // [ row ][ column ] { Qt::AlignTop | Qt::AlignLeft, Qt::AlignTop | Qt::AlignHCenter, Qt::AlignTop | Qt::AlignRight }, { Qt::AlignVCenter | Qt::AlignLeft, Qt::AlignVCenter | Qt::AlignHCenter, Qt::AlignVCenter | Qt::AlignRight }, { Qt::AlignBottom | Qt::AlignLeft, Qt::AlignBottom | Qt::AlignHCenter, Qt::AlignBottom | Qt::AlignRight } }; static void getRowAndColumnForPosition(KChartEnums::PositionValue pos, int* row, int* column) { switch ( pos ) { case KChartEnums::PositionNorthWest: *row = 0; *column = 0; break; case KChartEnums::PositionNorth: *row = 0; *column = 1; break; case KChartEnums::PositionNorthEast: *row = 0; *column = 2; break; case KChartEnums::PositionEast: *row = 1; *column = 2; break; case KChartEnums::PositionSouthEast: *row = 2; *column = 2; break; case KChartEnums::PositionSouth: *row = 2; *column = 1; break; case KChartEnums::PositionSouthWest: *row = 2; *column = 0; break; case KChartEnums::PositionWest: *row = 1; *column = 0; break; case KChartEnums::PositionCenter: *row = 1; *column = 1; break; default: *row = -1; *column = -1; break; } } using namespace KChart; // Layout widgets even if they are not visible (that's why isEmpty() is overridden) - at least that // was the original reason... class MyWidgetItem : public QWidgetItem { public: explicit MyWidgetItem(QWidget *w, Qt::Alignment alignment = Qt::Alignment()) : QWidgetItem( w ) { setAlignment( alignment ); } // All of the methods are reimplemented from QWidgetItem, and work around some oddity in QLayout and / or // KD Chart - I forgot the details between writing this code as an experiment and committing it, very // sorry about that! // Feel free to comment out any of them and then try the line-breaking feature in horizontal legends in // the Legends/Advanced example. It will not work well in various ways - won't get enough space and look // very broken, will inhibit resizing the window etc. - QSize sizeHint() const Q_DECL_OVERRIDE + QSize sizeHint() const override { QWidget* w = const_cast< MyWidgetItem * >( this )->widget(); return w->sizeHint(); } - QSize minimumSize() const Q_DECL_OVERRIDE + QSize minimumSize() const override { QWidget* w = const_cast< MyWidgetItem * >( this )->widget(); return w->minimumSize(); } - QSize maximumSize() const Q_DECL_OVERRIDE + QSize maximumSize() const override { // Not just passing on w->maximumSize() fixes that the size policy of Legend is disregarded, making // Legend take all available space, which makes both the Legend internal layout and the overall // layout of chart + legend look bad. QWidget::maximumSize() is not a virtual method, it's a // property, so "overriding" that one would be even uglier, and prevent user-set property // values from doing anything. QWidget* w = const_cast< MyWidgetItem * >( this )->widget(); QSize ret = w->maximumSize(); const QSize hint = w->sizeHint(); const QSizePolicy::Policy hPolicy = w->sizePolicy().horizontalPolicy(); if (hPolicy == QSizePolicy::Fixed || hPolicy == QSizePolicy::Maximum) { ret.rwidth() = hint.width(); } const QSizePolicy::Policy vPolicy = w->sizePolicy().verticalPolicy(); if (vPolicy == QSizePolicy::Fixed || vPolicy == QSizePolicy::Maximum) { ret.rheight() = hint.height(); } return ret; } - Qt::Orientations expandingDirections() const Q_DECL_OVERRIDE + Qt::Orientations expandingDirections() const override { QWidget* w = const_cast< MyWidgetItem * >( this )->widget(); if ( isEmpty() ) { return Qt::Orientations(); } Qt::Orientations e = w->sizePolicy().expandingDirections(); return e; } - void setGeometry(const QRect &g) Q_DECL_OVERRIDE + void setGeometry(const QRect &g) override { QWidget* w = const_cast< MyWidgetItem * >( this )->widget(); w->setGeometry(g); } - QRect geometry() const Q_DECL_OVERRIDE + QRect geometry() const override { QWidget* w = const_cast< MyWidgetItem * >( this )->widget(); return w->geometry(); } - bool hasHeightForWidth() const Q_DECL_OVERRIDE + bool hasHeightForWidth() const override { QWidget* w = const_cast< MyWidgetItem * >( this )->widget(); bool ret = !isEmpty() && qobject_cast< Legend* >( w )->hasHeightForWidth(); return ret; } - int heightForWidth( int width ) const Q_DECL_OVERRIDE + int heightForWidth( int width ) const override { QWidget* w = const_cast< MyWidgetItem * >( this )->widget(); int ret = w->heightForWidth( width ); return ret; } - bool isEmpty() const Q_DECL_OVERRIDE { + bool isEmpty() const override { QWidget* w = const_cast< MyWidgetItem * >( this )->widget(); // legend->hide() should indeed hide the legend, // but a legend in a chart that hasn't been shown yet isn't hidden // (as can happen when using Chart::paint() without showing the chart) return w->isHidden() && w->testAttribute( Qt::WA_WState_ExplicitShowHide ); } }; // When "abusing" QLayouts to lay out items with different geometry from the backing QWidgets, // some manual work is required to correctly update all the sublayouts. // This is because all the convenient ways to deal with QLayouts assume QWidgets somewhere. // What this does is somewhat similar to QLayout::activate(), but it never refers to the parent // QWidget which has the wrong geometry. static void invalidateLayoutTree( QLayoutItem *item ) { QLayout *layout = item->layout(); if ( layout ) { const int count = layout->count(); for ( int i = 0; i < count; i++ ) { invalidateLayoutTree( layout->itemAt( i ) ); } } item->invalidate(); } void Chart::Private::slotUnregisterDestroyedLegend( Legend *l ) { chart->takeLegend( l ); } void Chart::Private::slotUnregisterDestroyedHeaderFooter( HeaderFooter* hf ) { chart->takeHeaderFooter( hf ); } void Chart::Private::slotUnregisterDestroyedPlane( AbstractCoordinatePlane* plane ) { coordinatePlanes.removeAll( plane ); Q_FOREACH ( AbstractCoordinatePlane* p, coordinatePlanes ) { if ( p->referenceCoordinatePlane() == plane) { p->setReferenceCoordinatePlane( nullptr ); } } plane->layoutPlanes(); } Chart::Private::Private( Chart* chart_ ) : chart( chart_ ) , useNewLayoutSystem( false ) , layout(nullptr) , vLayout(nullptr) , planesLayout(nullptr) , headerLayout(nullptr) , footerLayout(nullptr) , dataAndLegendLayout(nullptr) , leftOuterSpacer(nullptr) , rightOuterSpacer(nullptr) , topOuterSpacer(nullptr) , bottomOuterSpacer(nullptr) , isFloatingLegendsLayoutDirty( true ) , isPlanesLayoutDirty( true ) , globalLeadingLeft(0) , globalLeadingRight(0) , globalLeadingTop(0) , globalLeadingBottom(0) { for ( int row = 0; row < 3; ++row ) { for ( int column = 0; column < 3; ++column ) { for ( int i = 0; i < 2; i++ ) { innerHdFtLayouts[ i ][ row ][ column ] = nullptr; } } } } Chart::Private::~Private() { } enum VisitorState{ Visited, Unknown }; struct ConnectedComponentsComparator{ bool operator()( const LayoutGraphNode *lhs, const LayoutGraphNode *rhs ) const { return lhs->priority < rhs->priority; } }; static QVector< LayoutGraphNode* > getPrioritySortedConnectedComponents( QVector< LayoutGraphNode* > &nodeList ) { QVector< LayoutGraphNode* >connectedComponents; QHash< LayoutGraphNode*, VisitorState > visitedComponents; Q_FOREACH ( LayoutGraphNode* node, nodeList ) visitedComponents[ node ] = Unknown; for ( int i = 0; i < nodeList.size(); ++i ) { LayoutGraphNode *curNode = nodeList[ i ]; LayoutGraphNode *representativeNode = curNode; if ( visitedComponents[ curNode ] != Visited ) { QStack< LayoutGraphNode* > stack; stack.push( curNode ); while ( !stack.isEmpty() ) { curNode = stack.pop(); Q_ASSERT( visitedComponents[ curNode ] != Visited ); visitedComponents[ curNode ] = Visited; if ( curNode->bottomSuccesor && visitedComponents[ curNode->bottomSuccesor ] != Visited ) stack.push( curNode->bottomSuccesor ); if ( curNode->leftSuccesor && visitedComponents[ curNode->leftSuccesor ] != Visited ) stack.push( curNode->leftSuccesor ); if ( curNode->sharedSuccesor && visitedComponents[ curNode->sharedSuccesor ] != Visited ) stack.push( curNode->sharedSuccesor ); if ( curNode->priority < representativeNode->priority ) representativeNode = curNode; } connectedComponents.append( representativeNode ); } } std::sort( connectedComponents.begin(), connectedComponents.end(), ConnectedComponentsComparator() ); return connectedComponents; } struct PriorityComparator{ public: PriorityComparator( QHash< AbstractCoordinatePlane*, LayoutGraphNode* > mapping ) : m_mapping( mapping ) {} bool operator() ( AbstractCoordinatePlane *lhs, AbstractCoordinatePlane *rhs ) const { const LayoutGraphNode *lhsNode = m_mapping[ lhs ]; Q_ASSERT( lhsNode ); const LayoutGraphNode *rhsNode = m_mapping[ rhs ]; Q_ASSERT( rhsNode ); return lhsNode->priority < rhsNode->priority; } const QHash< AbstractCoordinatePlane*, LayoutGraphNode* > m_mapping; }; void checkExistingAxes( LayoutGraphNode* node ) { if ( node && node->diagramPlane && node->diagramPlane->diagram() ) { AbstractCartesianDiagram *diag = qobject_cast< AbstractCartesianDiagram* >( node->diagramPlane->diagram() ); if ( diag ) { Q_FOREACH( const CartesianAxis* axis, diag->axes() ) { switch ( axis->position() ) { case( CartesianAxis::Top ): node->topAxesLayout = true; break; case( CartesianAxis::Bottom ): node->bottomAxesLayout = true; break; case( CartesianAxis::Left ): node->leftAxesLayout = true; break; case( CartesianAxis::Right ): node->rightAxesLayout = true; break; } } } } } static void mergeNodeAxisInformation( LayoutGraphNode* lhs, LayoutGraphNode* rhs ) { lhs->topAxesLayout |= rhs->topAxesLayout; rhs->topAxesLayout = lhs->topAxesLayout; lhs->bottomAxesLayout |= rhs->bottomAxesLayout; rhs->bottomAxesLayout = lhs->bottomAxesLayout; lhs->leftAxesLayout |= rhs->leftAxesLayout; rhs->leftAxesLayout = lhs->leftAxesLayout; lhs->rightAxesLayout |= rhs->rightAxesLayout; rhs->rightAxesLayout = lhs->rightAxesLayout; } static CoordinatePlaneList findSharingAxisDiagrams( AbstractCoordinatePlane* plane, const CoordinatePlaneList& list, Chart::Private::AxisType type, QVector< CartesianAxis* >* sharedAxes ) { if ( !plane || !plane->diagram() ) return CoordinatePlaneList(); Q_ASSERT( plane ); Q_ASSERT( plane->diagram() ); CoordinatePlaneList result; AbstractCartesianDiagram* diagram = qobject_cast< AbstractCartesianDiagram* >( plane->diagram() ); if ( !diagram ) return CoordinatePlaneList(); QList< CartesianAxis* > axes; Q_FOREACH( CartesianAxis* axis, diagram->axes() ) { if ( ( type == Chart::Private::Ordinate && ( axis->position() == CartesianAxis::Left || axis->position() == CartesianAxis::Right ) ) || ( type == Chart::Private::Abscissa && ( axis->position() == CartesianAxis::Top || axis->position() == CartesianAxis::Bottom ) ) ) { axes.append( axis ); } } Q_FOREACH( AbstractCoordinatePlane *curPlane, list ) { AbstractCartesianDiagram* diagram = qobject_cast< AbstractCartesianDiagram* > ( curPlane->diagram() ); if ( !diagram ) continue; Q_FOREACH( CartesianAxis* curSearchedAxis, axes ) { Q_FOREACH( CartesianAxis* curAxis, diagram->axes() ) { if ( curSearchedAxis == curAxis ) { result.append( curPlane ); if ( !sharedAxes->contains( curSearchedAxis ) ) sharedAxes->append( curSearchedAxis ); } } } } return result; } /** * this method determines the needed layout of the graph * taking care of the sharing problematic * its NOT allowed to have a diagram that shares * more than one axis in the same direction */ QVector< LayoutGraphNode* > Chart::Private::buildPlaneLayoutGraph() { QHash< AbstractCoordinatePlane*, LayoutGraphNode* > planeNodeMapping; QVector< LayoutGraphNode* > allNodes; // create all nodes and a mapping between plane and nodes Q_FOREACH( AbstractCoordinatePlane* curPlane, coordinatePlanes ) { if ( curPlane->diagram() ) { allNodes.append( new LayoutGraphNode ); allNodes[ allNodes.size() - 1 ]->diagramPlane = curPlane; allNodes[ allNodes.size() - 1 ]->priority = allNodes.size(); checkExistingAxes( allNodes[ allNodes.size() - 1 ] ); planeNodeMapping[ curPlane ] = allNodes[ allNodes.size() - 1 ]; } } // build the graph connections Q_FOREACH( LayoutGraphNode* curNode, allNodes ) { QVector< CartesianAxis* > sharedAxes; CoordinatePlaneList xSharedPlanes = findSharingAxisDiagrams( curNode->diagramPlane, coordinatePlanes, Abscissa, &sharedAxes ); Q_ASSERT( sharedAxes.size() < 2 ); // TODO duplicated code make a method out of it if ( sharedAxes.size() == 1 && xSharedPlanes.size() > 1 ) { //xSharedPlanes.removeAll( sharedAxes.first()->diagram()->coordinatePlane() ); //std::sort( xSharedPlanes.begin(), xSharedPlanes.end(), PriorityComparator( planeNodeMapping ) ); for ( int i = 0; i < xSharedPlanes.size() - 1; ++i ) { LayoutGraphNode *tmpNode = planeNodeMapping[ xSharedPlanes[ i ] ]; Q_ASSERT( tmpNode ); LayoutGraphNode *tmpNode2 = planeNodeMapping[ xSharedPlanes[ i + 1 ] ]; Q_ASSERT( tmpNode2 ); tmpNode->bottomSuccesor = tmpNode2; } // if ( sharedAxes.first()->diagram() && sharedAxes.first()->diagram()->coordinatePlane() ) // { // LayoutGraphNode *lastNode = planeNodeMapping[ xSharedPlanes.last() ]; // Q_ASSERT( lastNode ); // Q_ASSERT( sharedAxes.first()->diagram()->coordinatePlane() ); // LayoutGraphNode *ownerNode = planeNodeMapping[ sharedAxes.first()->diagram()->coordinatePlane() ]; // Q_ASSERT( ownerNode ); // lastNode->bottomSuccesor = ownerNode; // } //merge AxisInformation, needs a two pass run LayoutGraphNode axisInfoNode; for ( int count = 0; count < 2; ++count ) { for ( int i = 0; i < xSharedPlanes.size(); ++i ) { mergeNodeAxisInformation( &axisInfoNode, planeNodeMapping[ xSharedPlanes[ i ] ] ); } } } sharedAxes.clear(); CoordinatePlaneList ySharedPlanes = findSharingAxisDiagrams( curNode->diagramPlane, coordinatePlanes, Ordinate, &sharedAxes ); Q_ASSERT( sharedAxes.size() < 2 ); if ( sharedAxes.size() == 1 && ySharedPlanes.size() > 1 ) { //ySharedPlanes.removeAll( sharedAxes.first()->diagram()->coordinatePlane() ); //std::sort( ySharedPlanes.begin(), ySharedPlanes.end(), PriorityComparator( planeNodeMapping ) ); for ( int i = 0; i < ySharedPlanes.size() - 1; ++i ) { LayoutGraphNode *tmpNode = planeNodeMapping[ ySharedPlanes[ i ] ]; Q_ASSERT( tmpNode ); LayoutGraphNode *tmpNode2 = planeNodeMapping[ ySharedPlanes[ i + 1 ] ]; Q_ASSERT( tmpNode2 ); tmpNode->leftSuccesor = tmpNode2; } // if ( sharedAxes.first()->diagram() && sharedAxes.first()->diagram()->coordinatePlane() ) // { // LayoutGraphNode *lastNode = planeNodeMapping[ ySharedPlanes.last() ]; // Q_ASSERT( lastNode ); // Q_ASSERT( sharedAxes.first()->diagram()->coordinatePlane() ); // LayoutGraphNode *ownerNode = planeNodeMapping[ sharedAxes.first()->diagram()->coordinatePlane() ]; // Q_ASSERT( ownerNode ); // lastNode->bottomSuccesor = ownerNode; // } //merge AxisInformation, needs a two pass run LayoutGraphNode axisInfoNode; for ( int count = 0; count < 2; ++count ) { for ( int i = 0; i < ySharedPlanes.size(); ++i ) { mergeNodeAxisInformation( &axisInfoNode, planeNodeMapping[ ySharedPlanes[ i ] ] ); } } } sharedAxes.clear(); if ( curNode->diagramPlane->referenceCoordinatePlane() ) curNode->sharedSuccesor = planeNodeMapping[ curNode->diagramPlane->referenceCoordinatePlane() ]; } return allNodes; } QHash Chart::Private::buildPlaneLayoutInfos() { /* There are two ways in which planes can be caused to interact in * where they are put layouting wise: The first is the reference plane. If * such a reference plane is set, on a plane, it will use the same cell in the * layout as that one. In addition to this, planes can share an axis. In that case * they will be laid out in relation to each other as suggested by the position * of the axis. If, for example Plane1 and Plane2 share an axis at position Left, * that will result in the layout: Axis Plane1 Plane 2, vertically. If Plane1 * also happens to be Plane2's referece plane, both planes are drawn over each * other. The reference plane concept allows two planes to share the same space * even if neither has any axis, and in case there are shared axis, it is used * to decided, whether the planes should be painted on top of each other or * laid out vertically or horizontally next to each other. */ QHash axisInfos; QHash planeInfos; Q_FOREACH(AbstractCoordinatePlane* plane, coordinatePlanes ) { PlaneInfo p; // first check if we share space with another plane p.referencePlane = plane->referenceCoordinatePlane(); planeInfos.insert( plane, p ); Q_FOREACH( AbstractDiagram* abstractDiagram, plane->diagrams() ) { AbstractCartesianDiagram* diagram = qobject_cast ( abstractDiagram ); if ( !diagram ) { continue; } Q_FOREACH( CartesianAxis* axis, diagram->axes() ) { if ( !axisInfos.contains( axis ) ) { /* If this is the first time we see this axis, add it, with the * current plane. The first plane added to the chart that has * the axis associated with it thus "owns" it, and decides about * layout. */ AxisInfo i; i.plane = plane; axisInfos.insert( axis, i ); } else { AxisInfo i = axisInfos[axis]; if ( i.plane == plane ) { continue; // we don't want duplicates, only shared } /* The user expects diagrams to be added on top, and to the right * so that horizontally we need to move the new diagram, vertically * the reference one. */ PlaneInfo pi = planeInfos[plane]; // plane-to-plane linking overrides linking via axes if ( !pi.referencePlane ) { // we're not the first plane to see this axis, mark us as a slave pi.referencePlane = i.plane; if ( axis->position() == CartesianAxis::Left || axis->position() == CartesianAxis::Right ) { pi.horizontalOffset += 1; } planeInfos[plane] = pi; pi = planeInfos[i.plane]; if ( axis->position() == CartesianAxis::Top || axis->position() == CartesianAxis::Bottom ) { pi.verticalOffset += 1; } planeInfos[i.plane] = pi; } } } } // Create a new grid layout for each plane that has no reference. p = planeInfos[plane]; if ( p.referencePlane == nullptr ) { p.gridLayout = new QGridLayout(); p.gridLayout->setContentsMargins( 0, 0, 0, 0 ); planeInfos[plane] = p; } } return planeInfos; } void Chart::Private::slotLayoutPlanes() { /*TODO make sure this is really needed */ const QBoxLayout::Direction oldPlanesDirection = planesLayout ? planesLayout->direction() : QBoxLayout::TopToBottom; if ( planesLayout && dataAndLegendLayout ) dataAndLegendLayout->removeItem( planesLayout ); const bool hadPlanesLayout = planesLayout != nullptr; int left, top, right, bottom; if ( hadPlanesLayout ) planesLayout->getContentsMargins(&left, &top, &right, &bottom); Q_FOREACH( AbstractLayoutItem* plane, planeLayoutItems ) { plane->removeFromParentLayout(); } //TODO they should get a correct parent, but for now it works Q_FOREACH( AbstractLayoutItem* plane, planeLayoutItems ) { if ( dynamic_cast< AutoSpacerLayoutItem* >( plane ) ) delete plane; } planeLayoutItems.clear(); delete planesLayout; //hint: The direction is configurable by the user now, as // we are using a QBoxLayout rather than a QVBoxLayout. (khz, 2007/04/25) planesLayout = new QBoxLayout( oldPlanesDirection ); isPlanesLayoutDirty = true; // here we create the layouts; we need to "run" them before painting if ( useNewLayoutSystem ) { gridPlaneLayout = new QGridLayout; planesLayout->addLayout( gridPlaneLayout ); if (hadPlanesLayout) planesLayout->setContentsMargins(left, top, right, bottom); planesLayout->setObjectName( QString::fromLatin1( "planesLayout" ) ); /* First go through all planes and all axes and figure out whether the planes * need to coordinate. If they do, they share a grid layout, if not, each * get their own. See buildPlaneLayoutInfos() for more details. */ QVector< LayoutGraphNode* > vals = buildPlaneLayoutGraph(); //qDebug() << Q_FUNC_INFO << "GraphNodes" << vals.size(); QVector< LayoutGraphNode* > connectedComponents = getPrioritySortedConnectedComponents( vals ); //qDebug() << Q_FUNC_INFO << "SubGraphs" << connectedComponents.size(); int row = 0; int col = 0; QSet< CartesianAxis* > laidOutAxes; for ( int i = 0; i < connectedComponents.size(); ++i ) { LayoutGraphNode *curComponent = connectedComponents[ i ]; for ( LayoutGraphNode *curRowComponent = curComponent; curRowComponent; curRowComponent = curRowComponent->bottomSuccesor ) { col = 0; for ( LayoutGraphNode *curColComponent = curRowComponent; curColComponent; curColComponent = curColComponent->leftSuccesor ) { Q_ASSERT( curColComponent->diagramPlane->diagrams().size() == 1 ); Q_FOREACH( AbstractDiagram* diagram, curColComponent->diagramPlane->diagrams() ) { const int planeRowOffset = 1;//curColComponent->topAxesLayout ? 1 : 0; const int planeColOffset = 1;//curColComponent->leftAxesLayout ? 1 : 0; //qDebug() << Q_FUNC_INFO << row << col << planeRowOffset << planeColOffset; //qDebug() << Q_FUNC_INFO << row + planeRowOffset << col + planeColOffset; planeLayoutItems << curColComponent->diagramPlane; AbstractCartesianDiagram *cartDiag = qobject_cast< AbstractCartesianDiagram* >( diagram ); if ( cartDiag ) { gridPlaneLayout->addItem( curColComponent->diagramPlane, row + planeRowOffset, col + planeColOffset, 2, 2 ); curColComponent->diagramPlane->setParentLayout( gridPlaneLayout ); QHBoxLayout *leftLayout = nullptr; QHBoxLayout *rightLayout = nullptr; QVBoxLayout *topLayout = nullptr; QVBoxLayout *bottomLayout = nullptr; if ( curComponent->sharedSuccesor ) { gridPlaneLayout->addItem( curColComponent->sharedSuccesor->diagramPlane, row + planeRowOffset, col + planeColOffset, 2, 2 ); curColComponent->sharedSuccesor->diagramPlane->setParentLayout( gridPlaneLayout ); planeLayoutItems << curColComponent->sharedSuccesor->diagramPlane; } Q_FOREACH( CartesianAxis* axis, cartDiag->axes() ) { if ( axis->isAbscissa() ) { if ( curColComponent->bottomSuccesor ) continue; } if ( laidOutAxes.contains( axis ) ) continue; // if ( axis->diagram() != diagram ) // continue; switch ( axis->position() ) { case( CartesianAxis::Top ): if ( !topLayout ) topLayout = new QVBoxLayout; topLayout->addItem( axis ); axis->setParentLayout( topLayout ); break; case( CartesianAxis::Bottom ): if ( !bottomLayout ) bottomLayout = new QVBoxLayout; bottomLayout->addItem( axis ); axis->setParentLayout( bottomLayout ); break; case( CartesianAxis::Left ): if ( !leftLayout ) leftLayout = new QHBoxLayout; leftLayout->addItem( axis ); axis->setParentLayout( leftLayout ); break; case( CartesianAxis::Right ): if ( !rightLayout ) { rightLayout = new QHBoxLayout; } rightLayout->addItem( axis ); axis->setParentLayout( rightLayout ); break; } planeLayoutItems << axis; laidOutAxes.insert( axis ); } if ( leftLayout ) gridPlaneLayout->addLayout( leftLayout, row + planeRowOffset, col, 2, 1, Qt::AlignRight | Qt::AlignVCenter ); if ( rightLayout ) gridPlaneLayout->addLayout( rightLayout, row, col + planeColOffset + 2, 2, 1, Qt::AlignLeft | Qt::AlignVCenter ); if ( topLayout ) gridPlaneLayout->addLayout( topLayout, row, col + planeColOffset, 1, 2, Qt::AlignBottom | Qt::AlignHCenter ); if ( bottomLayout ) gridPlaneLayout->addLayout( bottomLayout, row + planeRowOffset + 2, col + planeColOffset, 1, 2, Qt::AlignTop | Qt::AlignHCenter ); } else { gridPlaneLayout->addItem( curColComponent->diagramPlane, row, col, 4, 4 ); curColComponent->diagramPlane->setParentLayout( gridPlaneLayout ); } col += planeColOffset + 2 + ( 1 ); } } int axisOffset = 2;//curRowComponent->topAxesLayout ? 1 : 0; //axisOffset += curRowComponent->bottomAxesLayout ? 1 : 0; const int rowOffset = axisOffset + 2; row += rowOffset; } // if ( planesLayout->direction() == QBoxLayout::TopToBottom ) // ++row; // else // ++col; } qDeleteAll( vals ); // re-add our grid(s) to the chart's layout if ( dataAndLegendLayout ) { dataAndLegendLayout->addLayout( planesLayout, 1, 1 ); dataAndLegendLayout->setRowStretch( 1, 1000 ); dataAndLegendLayout->setColumnStretch( 1, 1000 ); } slotResizePlanes(); #ifdef NEW_LAYOUT_DEBUG for ( int i = 0; i < gridPlaneLayout->rowCount(); ++i ) { for ( int j = 0; j < gridPlaneLayout->columnCount(); ++j ) { if ( gridPlaneLayout->itemAtPosition( i, j ) ) qDebug() << Q_FUNC_INFO << "item at" << i << j << gridPlaneLayout->itemAtPosition( i, j )->geometry(); else qDebug() << Q_FUNC_INFO << "item at" << i << j << "no item present"; } } //qDebug() << Q_FUNC_INFO << "Relayout ended"; #endif } else { if ( hadPlanesLayout ) { planesLayout->setContentsMargins( left, top, right, bottom ); } planesLayout->setContentsMargins( 0, 0, 0, 0 ); planesLayout->setSpacing( 0 ); planesLayout->setObjectName( QString::fromLatin1( "planesLayout" ) ); /* First go through all planes and all axes and figure out whether the planes * need to coordinate. If they do, they share a grid layout, if not, each * gets their own. See buildPlaneLayoutInfos() for more details. */ QHash planeInfos = buildPlaneLayoutInfos(); QHash axisInfos; Q_FOREACH( AbstractCoordinatePlane* plane, coordinatePlanes ) { Q_ASSERT( planeInfos.contains(plane) ); PlaneInfo& pi = planeInfos[ plane ]; const int column = pi.horizontalOffset; const int row = pi.verticalOffset; //qDebug() << "processing plane at column" << column << "and row" << row; QGridLayout *planeLayout = pi.gridLayout; if ( !planeLayout ) { PlaneInfo& refPi = pi; // if this plane is sharing an axis with another one, recursively check for the original plane and use // the grid of that as planeLayout. while ( !planeLayout && refPi.referencePlane ) { refPi = planeInfos[refPi.referencePlane]; planeLayout = refPi.gridLayout; } Q_ASSERT_X( planeLayout, "Chart::Private::slotLayoutPlanes()", "Invalid reference plane. Please check that the reference plane has been added to the Chart." ); } else { planesLayout->addLayout( planeLayout ); } /* Put the plane in the center of the layout. If this is our own, that's * the middle of the layout, if we are sharing, it's a cell in the center * column of the shared grid. */ planeLayoutItems << plane; plane->setParentLayout( planeLayout ); planeLayout->addItem( plane, row, column, 1, 1 ); //qDebug() << "Chart slotLayoutPlanes() calls planeLayout->addItem("<< row << column << ")"; planeLayout->setRowStretch( row, 2 ); planeLayout->setColumnStretch( column, 2 ); Q_FOREACH( AbstractDiagram* abstractDiagram, plane->diagrams() ) { AbstractCartesianDiagram* diagram = qobject_cast< AbstractCartesianDiagram* >( abstractDiagram ); if ( !diagram ) { continue; // FIXME what about polar ? } if ( pi.referencePlane != nullptr ) { pi.topAxesLayout = planeInfos[ pi.referencePlane ].topAxesLayout; pi.bottomAxesLayout = planeInfos[ pi.referencePlane ].bottomAxesLayout; pi.leftAxesLayout = planeInfos[ pi.referencePlane ].leftAxesLayout; pi.rightAxesLayout = planeInfos[ pi.referencePlane ].rightAxesLayout; } // collect all axes of a kind into sublayouts if ( pi.topAxesLayout == nullptr ) { pi.topAxesLayout = new QVBoxLayout; pi.topAxesLayout->setContentsMargins( 0, 0, 0, 0 ); pi.topAxesLayout->setObjectName( QString::fromLatin1( "topAxesLayout" ) ); } if ( pi.bottomAxesLayout == nullptr ) { pi.bottomAxesLayout = new QVBoxLayout; pi.bottomAxesLayout->setContentsMargins( 0, 0, 0, 0 ); pi.bottomAxesLayout->setObjectName( QString::fromLatin1( "bottomAxesLayout" ) ); } if ( pi.leftAxesLayout == nullptr ) { pi.leftAxesLayout = new QHBoxLayout; pi.leftAxesLayout->setContentsMargins( 0, 0, 0, 0 ); pi.leftAxesLayout->setObjectName( QString::fromLatin1( "leftAxesLayout" ) ); } if ( pi.rightAxesLayout == nullptr ) { pi.rightAxesLayout = new QHBoxLayout; pi.rightAxesLayout->setContentsMargins( 0, 0, 0, 0 ); pi.rightAxesLayout->setObjectName( QString::fromLatin1( "rightAxesLayout" ) ); } if ( pi.referencePlane != nullptr ) { planeInfos[ pi.referencePlane ].topAxesLayout = pi.topAxesLayout; planeInfos[ pi.referencePlane ].bottomAxesLayout = pi.bottomAxesLayout; planeInfos[ pi.referencePlane ].leftAxesLayout = pi.leftAxesLayout; planeInfos[ pi.referencePlane ].rightAxesLayout = pi.rightAxesLayout; } //pi.leftAxesLayout->setSizeConstraint( QLayout::SetFixedSize ); Q_FOREACH( CartesianAxis* axis, diagram->axes() ) { if ( axisInfos.contains( axis ) ) { continue; // already laid out this one } Q_ASSERT ( axis ); axis->setCachedSizeDirty(); //qDebug() << "--------------- axis added to planeLayoutItems -----------------"; planeLayoutItems << axis; switch ( axis->position() ) { case CartesianAxis::Top: axis->setParentLayout( pi.topAxesLayout ); pi.topAxesLayout->addItem( axis ); break; case CartesianAxis::Bottom: axis->setParentLayout( pi.bottomAxesLayout ); pi.bottomAxesLayout->addItem( axis ); break; case CartesianAxis::Left: axis->setParentLayout( pi.leftAxesLayout ); pi.leftAxesLayout->addItem( axis ); break; case CartesianAxis::Right: axis->setParentLayout( pi.rightAxesLayout ); pi.rightAxesLayout->addItem( axis ); break; default: Q_ASSERT_X( false, "Chart::paintEvent", "unknown axis position" ); break; }; axisInfos.insert( axis, AxisInfo() ); } /* Put each stack of axes-layouts in the cells surrounding the * associated plane. We are laying out in the oder the planes * were added, and the first one gets to lay out shared axes. * Private axes go here as well, of course. */ if ( !pi.topAxesLayout->parent() ) { planeLayout->addLayout( pi.topAxesLayout, row - 1, column ); } if ( !pi.bottomAxesLayout->parent() ) { planeLayout->addLayout( pi.bottomAxesLayout, row + 1, column ); } if ( !pi.leftAxesLayout->parent() ) { planeLayout->addLayout( pi.leftAxesLayout, row, column - 1 ); } if ( !pi.rightAxesLayout->parent() ) { planeLayout->addLayout( pi.rightAxesLayout,row, column + 1 ); } } // use up to four auto-spacer items in the corners around the diagrams: #define ADD_AUTO_SPACER_IF_NEEDED( \ spacerRow, spacerColumn, hLayoutIsAtTop, hLayout, vLayoutIsAtLeft, vLayout ) \ { \ if ( hLayout || vLayout ) { \ AutoSpacerLayoutItem * spacer \ = new AutoSpacerLayoutItem( hLayoutIsAtTop, hLayout, vLayoutIsAtLeft, vLayout ); \ planeLayout->addItem( spacer, spacerRow, spacerColumn, 1, 1 ); \ spacer->setParentLayout( planeLayout ); \ planeLayoutItems << spacer; \ } \ } if ( plane->isCornerSpacersEnabled() ) { ADD_AUTO_SPACER_IF_NEEDED( row - 1, column - 1, false, pi.leftAxesLayout, false, pi.topAxesLayout ) ADD_AUTO_SPACER_IF_NEEDED( row + 1, column - 1, true, pi.leftAxesLayout, false, pi.bottomAxesLayout ) ADD_AUTO_SPACER_IF_NEEDED( row - 1, column + 1, false, pi.rightAxesLayout, true, pi.topAxesLayout ) ADD_AUTO_SPACER_IF_NEEDED( row + 1, column + 1, true, pi.rightAxesLayout, true, pi.bottomAxesLayout ) } } // re-add our grid(s) to the chart's layout if ( dataAndLegendLayout ) { dataAndLegendLayout->addLayout( planesLayout, 1, 1 ); dataAndLegendLayout->setRowStretch( 1, 1000 ); dataAndLegendLayout->setColumnStretch( 1, 1000 ); } slotResizePlanes(); } } void Chart::Private::createLayouts() { // The toplevel layout provides the left and right global margins layout = new QHBoxLayout( chart ); layout->setContentsMargins( 0, 0, 0, 0 ); layout->setObjectName( QString::fromLatin1( "Chart::Private::layout" ) ); layout->addSpacing( globalLeadingLeft ); leftOuterSpacer = layout->itemAt( layout->count() - 1 )->spacerItem(); // The vLayout provides top and bottom global margins and lays // out headers, footers and the diagram area. vLayout = new QVBoxLayout(); vLayout->setContentsMargins( 0, 0, 0, 0 ); vLayout->setObjectName( QString::fromLatin1( "vLayout" ) ); layout->addLayout( vLayout, 1000 ); layout->addSpacing( globalLeadingRight ); rightOuterSpacer = layout->itemAt( layout->count() - 1 )->spacerItem(); // 1. the spacing above the header area vLayout->addSpacing( globalLeadingTop ); topOuterSpacer = vLayout->itemAt( vLayout->count() - 1 )->spacerItem(); // 2. the header area headerLayout = new QGridLayout(); headerLayout->setContentsMargins( 0, 0, 0, 0 ); vLayout->addLayout( headerLayout ); // 3. the area containing coordinate planes, axes, and legends dataAndLegendLayout = new QGridLayout(); dataAndLegendLayout->setContentsMargins( 0, 0, 0, 0 ); dataAndLegendLayout->setObjectName( QString::fromLatin1( "dataAndLegendLayout" ) ); vLayout->addLayout( dataAndLegendLayout, 1000 ); // 4. the footer area footerLayout = new QGridLayout(); footerLayout->setContentsMargins( 0, 0, 0, 0 ); footerLayout->setObjectName( QString::fromLatin1( "footerLayout" ) ); vLayout->addLayout( footerLayout ); // 5. Prepare the header / footer layout cells: // Each of the 9 header cells (the 9 footer cells) // contain their own QVBoxLayout // since there can be more than one header (footer) per cell. for ( int row = 0; row < 3; ++row ) { for ( int column = 0; column < 3; ++ column ) { const Qt::Alignment align = s_gridAlignments[ row ][ column ]; for ( int headOrFoot = 0; headOrFoot < 2; headOrFoot++ ) { QVBoxLayout* innerLayout = new QVBoxLayout(); innerLayout->setContentsMargins( 0, 0, 0, 0 ); innerLayout->setAlignment( align ); innerHdFtLayouts[ headOrFoot ][ row ][ column ] = innerLayout; QGridLayout* outerLayout = headOrFoot == 0 ? headerLayout : footerLayout; outerLayout->addLayout( innerLayout, row, column, align ); } } } // 6. the spacing below the footer area vLayout->addSpacing( globalLeadingBottom ); bottomOuterSpacer = vLayout->itemAt( vLayout->count() - 1 )->spacerItem(); // the data+axes area dataAndLegendLayout->addLayout( planesLayout, 1, 1 ); dataAndLegendLayout->setRowStretch( 1, 1 ); dataAndLegendLayout->setColumnStretch( 1, 1 ); } void Chart::Private::slotResizePlanes() { if ( !dataAndLegendLayout ) { return; } if ( !overrideSize.isValid() ) { // activate() takes the size from the layout's parent QWidget, which is not updated when overrideSize // is set. So don't let the layout grab the wrong size in that case. // When overrideSize *is* set, we call layout->setGeometry() in paint( QPainter*, const QRect& ), // which also "activates" the layout in the sense that it distributes space internally. layout->activate(); } // Adapt diagram drawing to the new size Q_FOREACH (AbstractCoordinatePlane* plane, coordinatePlanes ) { plane->layoutDiagrams(); } } void Chart::Private::updateDirtyLayouts() { if ( isPlanesLayoutDirty ) { Q_FOREACH ( AbstractCoordinatePlane* p, coordinatePlanes ) { p->setGridNeedsRecalculate(); p->layoutPlanes(); p->layoutDiagrams(); } } if ( isPlanesLayoutDirty || isFloatingLegendsLayoutDirty ) { chart->reLayoutFloatingLegends(); } isPlanesLayoutDirty = false; isFloatingLegendsLayoutDirty = false; } void Chart::Private::reapplyInternalLayouts() { QRect geo = layout->geometry(); invalidateLayoutTree( layout ); layout->setGeometry( geo ); slotResizePlanes(); } void Chart::Private::paintAll( QPainter* painter ) { updateDirtyLayouts(); QRect rect( QPoint( 0, 0 ), overrideSize.isValid() ? overrideSize : chart->size() ); //qDebug() << this<<"::paintAll() uses layout size" << currentLayoutSize; // Paint the background (if any) AbstractAreaBase::paintBackgroundAttributes( *painter, rect, backgroundAttributes ); // Paint the frame (if any) AbstractAreaBase::paintFrameAttributes( *painter, rect, frameAttributes ); chart->reLayoutFloatingLegends(); Q_FOREACH( AbstractLayoutItem* planeLayoutItem, planeLayoutItems ) { planeLayoutItem->paintAll( *painter ); } Q_FOREACH( TextArea* textLayoutItem, textLayoutItems ) { textLayoutItem->paintAll( *painter ); } Q_FOREACH( Legend *legend, legends ) { const bool hidden = legend->isHidden() && legend->testAttribute( Qt::WA_WState_ExplicitShowHide ); if ( !hidden ) { //qDebug() << "painting legend at " << legend->geometry(); legend->paintIntoRect( *painter, legend->geometry() ); } } } // ******** Chart interface implementation *********** #define d d_func() Chart::Chart ( QWidget* parent ) : QWidget ( parent ) , _d( new Private( this ) ) { #if defined KDAB_EVAL EvalDialog::checkEvalLicense( "KD Chart" ); #endif FrameAttributes frameAttrs; // no frame per default... // frameAttrs.setVisible( true ); frameAttrs.setPen( QPen( Qt::black ) ); frameAttrs.setPadding( 1 ); setFrameAttributes( frameAttrs ); addCoordinatePlane( new CartesianCoordinatePlane ( this ) ); d->createLayouts(); } Chart::~Chart() { delete d; } void Chart::setFrameAttributes( const FrameAttributes &a ) { d->frameAttributes = a; } FrameAttributes Chart::frameAttributes() const { return d->frameAttributes; } void Chart::setBackgroundAttributes( const BackgroundAttributes &a ) { d->backgroundAttributes = a; } BackgroundAttributes Chart::backgroundAttributes() const { return d->backgroundAttributes; } //TODO KChart 3.0; change QLayout into QBoxLayout::Direction void Chart::setCoordinatePlaneLayout( QLayout * layout ) { if (layout == d->planesLayout) return; if (d->planesLayout) { // detach all QLayoutItem's the previous planesLayout has cause // otherwise deleting the planesLayout would delete them too. for(int i = d->planesLayout->count() - 1; i >= 0; --i) { d->planesLayout->takeAt(i); } delete d->planesLayout; } d->planesLayout = qobject_cast( layout ); d->slotLayoutPlanes(); } QLayout* Chart::coordinatePlaneLayout() { return d->planesLayout; } AbstractCoordinatePlane* Chart::coordinatePlane() { if ( d->coordinatePlanes.isEmpty() ) { qWarning() << "Chart::coordinatePlane: warning: no coordinate plane defined."; return nullptr; } else { return d->coordinatePlanes.first(); } } CoordinatePlaneList Chart::coordinatePlanes() { return d->coordinatePlanes; } void Chart::addCoordinatePlane( AbstractCoordinatePlane* plane ) { // Append insertCoordinatePlane( d->coordinatePlanes.count(), plane ); } void Chart::insertCoordinatePlane( int index, AbstractCoordinatePlane* plane ) { if ( index < 0 || index > d->coordinatePlanes.count() ) { return; } connect( plane, SIGNAL(destroyedCoordinatePlane(AbstractCoordinatePlane*)), d, SLOT(slotUnregisterDestroyedPlane(AbstractCoordinatePlane*)) ); connect( plane, SIGNAL(needUpdate()), this, SLOT(update()) ); connect( plane, SIGNAL(needRelayout()), d, SLOT(slotResizePlanes()) ) ; connect( plane, SIGNAL(needLayoutPlanes()), d, SLOT(slotLayoutPlanes()) ) ; connect( plane, SIGNAL(propertiesChanged()),this, SIGNAL(propertiesChanged()) ); d->coordinatePlanes.insert( index, plane ); plane->setParent( this ); d->slotLayoutPlanes(); } void Chart::replaceCoordinatePlane( AbstractCoordinatePlane* plane, AbstractCoordinatePlane* oldPlane_ ) { if ( plane && oldPlane_ != plane ) { AbstractCoordinatePlane* oldPlane = oldPlane_; if ( d->coordinatePlanes.count() ) { if ( ! oldPlane ) { oldPlane = d->coordinatePlanes.first(); if ( oldPlane == plane ) return; } takeCoordinatePlane( oldPlane ); } delete oldPlane; addCoordinatePlane( plane ); } } void Chart::takeCoordinatePlane( AbstractCoordinatePlane* plane ) { const int idx = d->coordinatePlanes.indexOf( plane ); if ( idx != -1 ) { d->coordinatePlanes.takeAt( idx ); disconnect( plane, nullptr, d, nullptr ); disconnect( plane, nullptr, this, nullptr ); plane->removeFromParentLayout(); plane->setParent( nullptr ); d->mouseClickedPlanes.removeAll(plane); } d->slotLayoutPlanes(); // Need to emit the signal: In case somebody has connected the signal // to her own slot for e.g. calling update() on a widget containing the chart. emit propertiesChanged(); } void Chart::setGlobalLeading( int left, int top, int right, int bottom ) { setGlobalLeadingLeft( left ); setGlobalLeadingTop( top ); setGlobalLeadingRight( right ); setGlobalLeadingBottom( bottom ); } void Chart::setGlobalLeadingLeft( int leading ) { d->globalLeadingLeft = leading; d->leftOuterSpacer->changeSize( leading, 0, QSizePolicy::Fixed, QSizePolicy::Minimum ); d->reapplyInternalLayouts(); } int Chart::globalLeadingLeft() const { return d->globalLeadingLeft; } void Chart::setGlobalLeadingTop( int leading ) { d->globalLeadingTop = leading; d->topOuterSpacer->changeSize( 0, leading, QSizePolicy::Minimum, QSizePolicy::Fixed ); d->reapplyInternalLayouts(); } int Chart::globalLeadingTop() const { return d->globalLeadingTop; } void Chart::setGlobalLeadingRight( int leading ) { d->globalLeadingRight = leading; d->rightOuterSpacer->changeSize( leading, 0, QSizePolicy::Fixed, QSizePolicy::Minimum ); d->reapplyInternalLayouts(); } int Chart::globalLeadingRight() const { return d->globalLeadingRight; } void Chart::setGlobalLeadingBottom( int leading ) { d->globalLeadingBottom = leading; d->bottomOuterSpacer->changeSize( 0, leading, QSizePolicy::Minimum, QSizePolicy::Fixed ); d->reapplyInternalLayouts(); } int Chart::globalLeadingBottom() const { return d->globalLeadingBottom; } void Chart::paint( QPainter* painter, const QRect& rect ) { if ( rect.isEmpty() || !painter ) { return; } QPaintDevice* prevDevice = GlobalMeasureScaling::paintDevice(); GlobalMeasureScaling::setPaintDevice( painter->device() ); int prevScaleFactor = PrintingParameters::scaleFactor(); PrintingParameters::setScaleFactor( qreal( painter->device()->logicalDpiX() ) / qreal( logicalDpiX() ) ); const QRect oldGeometry( geometry() ); if ( oldGeometry != rect ) setGeometry( rect ); painter->translate( rect.left(), rect.top() ); d->paintAll( painter ); // for debugging // painter->setPen( QPen( Qt::blue, 8 ) ); // painter->drawRect( rect ); painter->translate( -rect.left(), -rect.top() ); if ( oldGeometry != rect ) setGeometry( oldGeometry ); PrintingParameters::setScaleFactor( prevScaleFactor ); GlobalMeasureScaling::setPaintDevice( prevDevice ); } void Chart::resizeEvent ( QResizeEvent* event ) { d->isPlanesLayoutDirty = true; d->isFloatingLegendsLayoutDirty = true; QWidget::resizeEvent( event ); } void Chart::reLayoutFloatingLegends() { Q_FOREACH( Legend *legend, d->legends ) { const bool hidden = legend->isHidden() && legend->testAttribute( Qt::WA_WState_ExplicitShowHide ); if ( legend->position().isFloating() && !hidden ) { // resize the legend const QSize legendSize( legend->sizeHint() ); legend->setGeometry( QRect( legend->geometry().topLeft(), legendSize ) ); // find the legends corner point (reference point plus any paddings) const RelativePosition relPos( legend->floatingPosition() ); QPointF pt( relPos.calculatedPoint( size() ) ); //qDebug() << pt; // calculate the legend's top left point const Qt::Alignment alignTopLeft = Qt::AlignBottom | Qt::AlignLeft; if ( (relPos.alignment() & alignTopLeft) != alignTopLeft ) { if ( relPos.alignment() & Qt::AlignRight ) pt.rx() -= legendSize.width(); else if ( relPos.alignment() & Qt::AlignHCenter ) pt.rx() -= 0.5 * legendSize.width(); if ( relPos.alignment() & Qt::AlignBottom ) pt.ry() -= legendSize.height(); else if ( relPos.alignment() & Qt::AlignVCenter ) pt.ry() -= 0.5 * legendSize.height(); } //qDebug() << pt << endl; legend->move( static_cast(pt.x()), static_cast(pt.y()) ); } } } void Chart::paintEvent( QPaintEvent* ) { QPainter painter( this ); d->paintAll( &painter ); emit finishedDrawing(); } void Chart::addHeaderFooter( HeaderFooter* hf ) { Q_ASSERT( hf->type() == HeaderFooter::Header || hf->type() == HeaderFooter::Footer ); int row; int column; getRowAndColumnForPosition( hf->position().value(), &row, &column ); if ( row == -1 ) { qWarning( "Unknown header/footer position" ); return; } d->headerFooters.append( hf ); d->textLayoutItems.append( hf ); connect( hf, SIGNAL(destroyedHeaderFooter(HeaderFooter*)), d, SLOT(slotUnregisterDestroyedHeaderFooter(HeaderFooter*)) ); connect( hf, SIGNAL(positionChanged(HeaderFooter*)), d, SLOT(slotHeaderFooterPositionChanged(HeaderFooter*)) ); // set the text attributes (why?) TextAttributes textAttrs( hf->textAttributes() ); Measure measure( textAttrs.fontSize() ); measure.setRelativeMode( this, KChartEnums::MeasureOrientationMinimum ); measure.setValue( 20 ); textAttrs.setFontSize( measure ); hf->setTextAttributes( textAttrs ); // add it to the appropriate layout int innerLayoutIdx = hf->type() == HeaderFooter::Header ? 0 : 1; QVBoxLayout* headerFooterLayout = d->innerHdFtLayouts[ innerLayoutIdx ][ row ][ column ]; hf->setParentLayout( headerFooterLayout ); hf->setAlignment( s_gridAlignments[ row ][ column ] ); headerFooterLayout->addItem( hf ); d->slotResizePlanes(); } void Chart::replaceHeaderFooter( HeaderFooter* headerFooter, HeaderFooter* oldHeaderFooter_ ) { if ( headerFooter && oldHeaderFooter_ != headerFooter ) { HeaderFooter* oldHeaderFooter = oldHeaderFooter_; if ( d->headerFooters.count() ) { if ( ! oldHeaderFooter ) { oldHeaderFooter = d->headerFooters.first(); if ( oldHeaderFooter == headerFooter ) return; } takeHeaderFooter( oldHeaderFooter ); } delete oldHeaderFooter; addHeaderFooter( headerFooter ); } } void Chart::takeHeaderFooter( HeaderFooter* headerFooter ) { const int idx = d->headerFooters.indexOf( headerFooter ); if ( idx == -1 ) { return; } disconnect( headerFooter, SIGNAL(destroyedHeaderFooter(HeaderFooter*)), d, SLOT(slotUnregisterDestroyedHeaderFooter(HeaderFooter*)) ); d->headerFooters.takeAt( idx ); headerFooter->removeFromParentLayout(); headerFooter->setParentLayout( nullptr ); d->textLayoutItems.remove( d->textLayoutItems.indexOf( headerFooter ) ); d->slotResizePlanes(); } void Chart::Private::slotHeaderFooterPositionChanged( HeaderFooter* hf ) { chart->takeHeaderFooter( hf ); chart->addHeaderFooter( hf ); } HeaderFooter* Chart::headerFooter() { if ( d->headerFooters.isEmpty() ) { return nullptr; } else { return d->headerFooters.first(); } } HeaderFooterList Chart::headerFooters() { return d->headerFooters; } void Chart::Private::slotLegendPositionChanged( AbstractAreaWidget* aw ) { Legend* legend = qobject_cast< Legend* >( aw ); Q_ASSERT( legend ); chart->takeLegend( legend ); chart->addLegendInternal( legend, false ); } void Chart::addLegend( Legend* legend ) { legend->show(); addLegendInternal( legend, true ); emit propertiesChanged(); } void Chart::addLegendInternal( Legend* legend, bool setMeasures ) { if ( !legend ) { return; } KChartEnums::PositionValue pos = legend->position().value(); if ( pos == KChartEnums::PositionCenter ) { qWarning( "Not showing legend because PositionCenter is not supported for legends." ); } int row; int column; getRowAndColumnForPosition( pos, &row, &column ); if ( row < 0 && pos != KChartEnums::PositionFloating ) { qWarning( "Not showing legend because of unknown legend position." ); return; } d->legends.append( legend ); legend->setParent( this ); // set text attributes (why?) if ( setMeasures ) { TextAttributes textAttrs( legend->textAttributes() ); Measure measure( textAttrs.fontSize() ); measure.setRelativeMode( this, KChartEnums::MeasureOrientationMinimum ); measure.setValue( 20 ); textAttrs.setFontSize( measure ); legend->setTextAttributes( textAttrs ); textAttrs = legend->titleTextAttributes(); measure.setRelativeMode( this, KChartEnums::MeasureOrientationMinimum ); measure.setValue( 24 ); textAttrs.setFontSize( measure ); legend->setTitleTextAttributes( textAttrs ); legend->setReferenceArea( this ); } // add it to the appropriate layout if ( pos != KChartEnums::PositionFloating ) { legend->needSizeHint(); // in each edge and corner of the outer layout, there's a grid for the different alignments that we create // on demand. we don't remove it when empty. QLayoutItem* edgeItem = d->dataAndLegendLayout->itemAtPosition( row, column ); QGridLayout* alignmentsLayout = dynamic_cast< QGridLayout* >( edgeItem ); Q_ASSERT( !edgeItem || alignmentsLayout ); // if it exists, it must be a QGridLayout if ( !alignmentsLayout ) { alignmentsLayout = new QGridLayout; d->dataAndLegendLayout->addLayout( alignmentsLayout, row, column ); alignmentsLayout->setContentsMargins( 0, 0, 0, 0 ); } // in case there are several legends in the same edge or corner with the same alignment, they are stacked // vertically using a QVBoxLayout. it is created on demand as above. row = 1; column = 1; for ( int i = 0; i < 3; i++ ) { for ( int j = 0; j < 3; j++ ) { Qt::Alignment align = s_gridAlignments[ i ][ j ]; if ( align == legend->alignment() ) { row = i; column = j; break; } } } QLayoutItem* alignmentItem = alignmentsLayout->itemAtPosition( row, column ); QVBoxLayout* sameAlignmentLayout = dynamic_cast< QVBoxLayout* >( alignmentItem ); Q_ASSERT( !alignmentItem || sameAlignmentLayout ); // if it exists, it must be a QVBoxLayout if ( !sameAlignmentLayout ) { sameAlignmentLayout = new QVBoxLayout; alignmentsLayout->addLayout( sameAlignmentLayout, row, column ); sameAlignmentLayout->setContentsMargins( 0, 0, 0, 0 ); } sameAlignmentLayout->addItem( new MyWidgetItem( legend, legend->alignment() ) ); } connect( legend, SIGNAL(destroyedLegend(Legend*)), d, SLOT(slotUnregisterDestroyedLegend(Legend*)) ); connect( legend, SIGNAL(positionChanged(AbstractAreaWidget*)), d, SLOT(slotLegendPositionChanged(AbstractAreaWidget*)) ); connect( legend, SIGNAL(propertiesChanged()), this, SIGNAL(propertiesChanged()) ); d->slotResizePlanes(); } void Chart::replaceLegend( Legend* legend, Legend* oldLegend_ ) { if ( legend && oldLegend_ != legend ) { Legend* oldLegend = oldLegend_; if ( d->legends.count() ) { if ( ! oldLegend ) { oldLegend = d->legends.first(); if ( oldLegend == legend ) return; } takeLegend( oldLegend ); } delete oldLegend; addLegend( legend ); } } void Chart::takeLegend( Legend* legend ) { const int idx = d->legends.indexOf( legend ); if ( idx == -1 ) { return; } d->legends.takeAt( idx ); disconnect( legend, nullptr, d, nullptr ); disconnect( legend, nullptr, this, nullptr ); // the following removes the legend from its layout and destroys its MyWidgetItem (the link to the layout) legend->setParent( nullptr ); d->slotResizePlanes(); emit propertiesChanged(); } Legend* Chart::legend() { return d->legends.isEmpty() ? nullptr : d->legends.first(); } LegendList Chart::legends() { return d->legends; } void Chart::mousePressEvent( QMouseEvent* event ) { const QPoint pos = mapFromGlobal( event->globalPos() ); Q_FOREACH( AbstractCoordinatePlane* plane, d->coordinatePlanes ) { if ( plane->geometry().contains( event->pos() ) && plane->diagrams().size() > 0 ) { QMouseEvent ev( QEvent::MouseButtonPress, pos, event->globalPos(), event->button(), event->buttons(), event->modifiers() ); plane->mousePressEvent( &ev ); d->mouseClickedPlanes.append( plane ); } } } void Chart::mouseDoubleClickEvent( QMouseEvent* event ) { const QPoint pos = mapFromGlobal( event->globalPos() ); Q_FOREACH( AbstractCoordinatePlane* plane, d->coordinatePlanes ) { if ( plane->geometry().contains( event->pos() ) && plane->diagrams().size() > 0 ) { QMouseEvent ev( QEvent::MouseButtonPress, pos, event->globalPos(), event->button(), event->buttons(), event->modifiers() ); plane->mouseDoubleClickEvent( &ev ); } } } void Chart::mouseMoveEvent( QMouseEvent* event ) { QSet< AbstractCoordinatePlane* > eventReceivers = QSet< AbstractCoordinatePlane* >::fromList( d->mouseClickedPlanes ); Q_FOREACH( AbstractCoordinatePlane* plane, d->coordinatePlanes ) { if ( plane->geometry().contains( event->pos() ) && plane->diagrams().size() > 0 ) { eventReceivers.insert( plane ); } } const QPoint pos = mapFromGlobal( event->globalPos() ); Q_FOREACH( AbstractCoordinatePlane* plane, eventReceivers ) { QMouseEvent ev( QEvent::MouseMove, pos, event->globalPos(), event->button(), event->buttons(), event->modifiers() ); plane->mouseMoveEvent( &ev ); } } void Chart::mouseReleaseEvent( QMouseEvent* event ) { QSet< AbstractCoordinatePlane* > eventReceivers = QSet< AbstractCoordinatePlane* >::fromList( d->mouseClickedPlanes ); Q_FOREACH( AbstractCoordinatePlane* plane, d->coordinatePlanes ) { if ( plane->geometry().contains( event->pos() ) && plane->diagrams().size() > 0 ) { eventReceivers.insert( plane ); } } const QPoint pos = mapFromGlobal( event->globalPos() ); Q_FOREACH( AbstractCoordinatePlane* plane, eventReceivers ) { QMouseEvent ev( QEvent::MouseButtonRelease, pos, event->globalPos(), event->button(), event->buttons(), event->modifiers() ); plane->mouseReleaseEvent( &ev ); } d->mouseClickedPlanes.clear(); } bool Chart::event( QEvent* event ) { if ( event->type() == QEvent::ToolTip ) { const QHelpEvent* const helpEvent = static_cast< QHelpEvent* >( event ); Q_FOREACH( const AbstractCoordinatePlane* const plane, d->coordinatePlanes ) { // iterate diagrams in reverse, so that the top-most painted diagram is // queried first for a tooltip before the diagrams behind it const ConstAbstractDiagramList& diagrams = plane->diagrams(); for (int i = diagrams.size() - 1; i >= 0; --i) { const AbstractDiagram* diagram = diagrams[i]; if (diagram->isHidden()) { continue; } const QModelIndex index = diagram->indexAt( helpEvent->pos() ); const QVariant toolTip = index.data( Qt::ToolTipRole ); if ( toolTip.isValid() ) { QPoint pos = mapFromGlobal( helpEvent->pos() ); QRect rect( pos - QPoint( 1, 1 ), QSize( 3, 3 ) ); QToolTip::showText( QCursor::pos(), toolTip.toString(), this, rect ); return true; } } } } return QWidget::event( event ); } bool Chart::useNewLayoutSystem() const { return d_func()->useNewLayoutSystem; } void Chart::setUseNewLayoutSystem( bool value ) { if ( d_func()->useNewLayoutSystem != value ) d_func()->useNewLayoutSystem = value; } diff --git a/src/KChart/KChartChart.h b/src/KChart/KChartChart.h index 134cd17..b132678 100644 --- a/src/KChart/KChartChart.h +++ b/src/KChart/KChartChart.h @@ -1,573 +1,573 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTCHART_H #define KCHARTCHART_H #include #include "kchart_export.h" #include "KChartGlobal.h" /* Simplified(*) overview of object ownership in a chart: Chart is-a QWidget | n CoordinatePlanes is-a AbstractArea is-a AbstractLayoutItem is-a QLayoutItem | n Diagrams is-a QAbstractItemView is-a QWidget / | \ AbstractGrid | Axes (can be shared between diagrams) is-a AbstractArea is-a... QLayoutItem (no base class) | Legends is-a AbstractAreaWidget is-a QWidget (*) less important classes, including base classes, removed. Layout rules: In principle, every size or existence change in one of the objects listed above must be propagated to all other objects. This could change their size. There are also settings changes that invalidate the size of other components, where the size changes are detected and propagated. Painting call tree (simplified): Chart::paint() (from users) / paintEvent() (from framework) ChartPrivate::paintAll()-----------------------------------------------\ CoordinatePlane::paintAll() (from AbstractArea)--------\ Axis::paintAll()-\ CoordinatePlane::paint() (from AbstractLayoutItem) Grid::drawGrid() Axis::paint() Diagram::paint( PaintContext* paintContext ) Note that grids are painted from the coordinate plane, not from the diagram as ownership would suggest. */ namespace KChart { class BackgroundAttributes; class FrameAttributes; class AbstractDiagram; class AbstractCoordinatePlane; class HeaderFooter; class Legend; typedef QList CoordinatePlaneList; typedef QList HeaderFooterList; typedef QList LegendList; /** * @class Chart KChartChart.h KChartChart * @brief A chart with one or more diagrams. * * The Chart class represents a drawing consisting of one or more diagrams * and various optional elements such as legends, axes, text boxes, headers * or footers. It takes ownership of all these elements when they are assigned * to it. Each diagram is associated with a coordinate plane, of which the chart * can have more than one. The coordinate planes (and thus the associated diagrams) * can be laid out in various ways. * * The Chart class makes heavy use of the Qt Interview framework for model/view * programming, and thus requires data to be presented to it in a QAbstractItemModel * compatible way. For many simple charts, especially if the visualized data is * static, KChart::Widget provides an abstracted interface, that hides the complexity * of Interview to a large extent. */ class KCHART_EXPORT Chart : public QWidget { Q_OBJECT // KD Chart 3.0: leading is inter-line distance of text. this here is MARGIN or SPACING. Q_PROPERTY( int globalLeadingTop READ globalLeadingTop WRITE setGlobalLeadingTop ) Q_PROPERTY( int globalLeadingBottom READ globalLeadingBottom WRITE setGlobalLeadingBottom ) Q_PROPERTY( int globalLeadingLeft READ globalLeadingLeft WRITE setGlobalLeadingLeft ) Q_PROPERTY( int globalLeadingRight READ globalLeadingRight WRITE setGlobalLeadingRight ) Q_PROPERTY( bool useNewLayoutSystem READ useNewLayoutSystem WRITE setUseNewLayoutSystem ) KCHART_DECLARE_PRIVATE_BASE_POLYMORPHIC_QWIDGET( Chart ) public: explicit Chart ( QWidget* parent = nullptr ); ~Chart(); /** * @brief useNewLayoutSystem * Be very careful activating the new layout system, * its still experimental and works only if the user knows * what he is doing. The reason is that the system does not prevent * the user from creating sharing graphs that are not layoutable in a * plane and still needs assistance from the user. */ bool useNewLayoutSystem() const; void setUseNewLayoutSystem( bool value ); /** \brief Specify the frame attributes to be used, by default is it a thin black line. To hide the frame line, you could do something like this: \verbatim KChart::FrameAttributes frameAttrs( my_chart->frameAttributes() ); frameAttrs.setVisible( false ); my_chart->setFrameAttributes( frameAttrs ); \endverbatim \sa setBackgroundAttributes */ void setFrameAttributes( const FrameAttributes &a ); FrameAttributes frameAttributes() const; /** \brief Specify the background attributes to be used, by default there is no background. To set a light blue background, you could do something like this: \verbatim KChart::BackgroundAttributes backgroundAttrs( my_chart->backgroundAttributes() ); backgroundAttrs.setVisible( true ); backgroundAttrs.setBrush( QColor(0xd0,0xd0,0xff) ); my_chart->setBackgroundAttributes( backgroundAttrs ); \endverbatim \sa setFrameAttributes */ void setBackgroundAttributes( const BackgroundAttributes &a ); BackgroundAttributes backgroundAttributes() const; /** * Each chart must have at least one coordinate plane. * Initially a default CartesianCoordinatePlane is created. * Use replaceCoordinatePlane() to replace it with a different * one, such as a PolarCoordinatePlane. * @return The first coordinate plane of the chart. */ AbstractCoordinatePlane* coordinatePlane(); /** * The list of coordinate planes. * @return The list of coordinate planes. */ CoordinatePlaneList coordinatePlanes(); /** * Adds a coordinate plane to the chart. The chart takes ownership. * @param plane The coordinate plane to add. * * \sa replaceCoordinatePlane, takeCoordinatePlane */ void addCoordinatePlane( AbstractCoordinatePlane* plane ); /** * Inserts a coordinate plane to the chart at index @p index. * The chart takes ownership. * * @param index The index where to add the plane * @param plane The coordinate plane to add. * * \sa replaceCoordinatePlane, takeCoordinatePlane */ void insertCoordinatePlane( int index, AbstractCoordinatePlane* plane ); /** * Replaces the old coordinate plane, or appends the * plane, it there is none yet. * * @param plane The coordinate plane to be used instead of the old plane. * This parameter must not be zero, or the method will do nothing. * * @param oldPlane The coordinate plane to be removed by the new plane. This * plane will be deleted automatically. If the parameter is omitted, * the very first coordinate plane will be replaced. In case, there was no * plane yet, the new plane will just be added. * * \note If you want to re-use the old coordinate plane, call takeCoordinatePlane and * addCoordinatePlane, instead of using replaceCoordinatePlane. * * \sa addCoordinatePlane, takeCoordinatePlane */ void replaceCoordinatePlane( AbstractCoordinatePlane* plane, AbstractCoordinatePlane* oldPlane = nullptr ); /** * Removes the coordinate plane from the chart, without deleting it. * * The chart no longer owns the plane, so it is * the caller's responsibility to delete the plane. * * \sa addCoordinatePlane, takeCoordinatePlane */ void takeCoordinatePlane( AbstractCoordinatePlane* plane ); /** * Set the coordinate plane layout that should be used as model for * the internal used layout. The layout needs to be an instance of * QHBoxLayout or QVBoxLayout. */ void setCoordinatePlaneLayout( QLayout * layout ); QLayout* coordinatePlaneLayout(); /** * The first header or footer of the chart. By default there is none. * @return The first header or footer of the chart or 0 if there was none * added to the chart. */ HeaderFooter* headerFooter(); /** * The list of headers and footers associated with the chart. * @return The list of headers and footers associated with the chart. */ HeaderFooterList headerFooters(); /** * Adds a header or a footer to the chart. The chart takes ownership. * @param headerFooter The header (or footer, resp.) to add. * * \sa replaceHeaderFooter, takeHeaderFooter */ void addHeaderFooter( HeaderFooter* headerFooter ); /** * Replaces the old header (or footer, resp.), or appends the * new header or footer, it there is none yet. * * @param headerFooter The header or footer to be used instead of the old one. * This parameter must not be zero, or the method will do nothing. * * @param oldHeaderFooter The header or footer to be removed by the new one. This * header or footer will be deleted automatically. If the parameter is omitted, * the very first header or footer will be replaced. In case, there was no * header and no footer yet, the new header or footer will just be added. * * \note If you want to re-use the old header or footer, call takeHeaderFooter and * addHeaderFooter, instead of using replaceHeaderFooter. * * \sa addHeaderFooter, takeHeaderFooter */ void replaceHeaderFooter ( HeaderFooter* headerFooter, HeaderFooter* oldHeaderFooter = nullptr ); /** * Removes the header (or footer, resp.) from the chart, without deleting it. * * The chart no longer owns the header or footer, so it is * the caller's responsibility to delete the header or footer. * * \sa addHeaderFooter, replaceHeaderFooter */ void takeHeaderFooter( HeaderFooter* headerFooter ); /** * The first legend of the chart or 0 if there was none added to the chart. * @return The first legend of the chart or 0 if none exists. */ Legend* legend(); /** * The list of all legends associated with the chart. * @return The list of all legends associated with the chart. */ LegendList legends(); /** * Add the given legend to the chart. The chart takes ownership. * @param legend The legend to add. * * \sa replaceLegend, takeLegend */ void addLegend( Legend* legend ); /** * Replaces the old legend, or appends the * new legend, it there is none yet. * * @param legend The legend to be used instead of the old one. * This parameter must not be zero, or the method will do nothing. * * @param oldLegend The legend to be removed by the new one. This * legend will be deleted automatically. If the parameter is omitted, * the very first legend will be replaced. In case, there was no * legend yet, the new legend will just be added. * * If you want to re-use the old legend, call takeLegend and * addLegend, instead of using replaceLegend. * * \note Whenever addLegend is called the font sizes used by the * Legend are set to relative and they get coupled to the Chart's size, * with their relative values being 20 for the item texts and 24 to the * title text. So if you want to use custom font sizes for the Legend * make sure to set them after calling addLegend. * * \sa addLegend, takeLegend */ void replaceLegend ( Legend* legend, Legend* oldLegend = nullptr ); /** * Removes the legend from the chart, without deleting it. * * The chart no longer owns the legend, so it is * the caller's responsibility to delete the legend. * * \sa addLegend, takeLegend */ void takeLegend( Legend* legend ); /** * Set the padding between the margin of the widget and the area that * the contents are drawn into. * @param left The padding on the left side. * @param top The padding at the top. * @param right The padding on the left hand side. * @param bottom The padding on the bottom. * * \note Using previous versions of KD Chart you might have called * setGlobalLeading() to make room for long Abscissa labels (or for an * overlapping top label of an Ordinate axis, resp.) that would not fit * into the normal axis area. This is \em no \em longer \em needed * because KD Chart now is using hidden auto-spacer items reserving * as much free space as is needed for axes with overlaping content * at the respective sides. * * \sa setGlobalLeadingTop, setGlobalLeadingBottom, setGlobalLeadingLeft, setGlobalLeadingRight * \sa globalLeadingTop, globalLeadingBottom, globalLeadingLeft, globalLeadingRight */ void setGlobalLeading( int left, int top, int right, int bottom ); /** * Set the padding between the start of the widget and the start * of the area that is used for drawing on the left. * @param leading The padding value. * * \sa setGlobalLeading */ void setGlobalLeadingLeft( int leading ); /** * The padding between the start of the widget and the start * of the area that is used for drawing on the left. * @return The padding between the start of the widget and the start * of the area that is used for drawing on the left. * * \sa setGlobalLeading */ int globalLeadingLeft() const; /** * Set the padding between the start of the widget and the start * of the area that is used for drawing at the top. * @param leading The padding value. * * \sa setGlobalLeading */ void setGlobalLeadingTop( int leading ); /** * The padding between the start of the widget and the start * of the area that is used for drawing at the top. * @return The padding between the start of the widget and the start * of the area that is used for drawing at the top. * * \sa setGlobalLeading */ int globalLeadingTop() const; /** * Set the padding between the start of the widget and the start * of the area that is used for drawing on the right. * @param leading The padding value. * * \sa setGlobalLeading */ void setGlobalLeadingRight( int leading ); /** * The padding between the start of the widget and the start * of the area that is used for drawing on the right. * @return The padding between the start of the widget and the start * of the area that is used for drawing on the right. * * \sa setGlobalLeading */ int globalLeadingRight() const; /** * Set the padding between the start of the widget and the start * of the area that is used for drawing on the bottom. * @param leading The padding value. * * \sa setGlobalLeading */ void setGlobalLeadingBottom( int leading ); /** * The padding between the start of the widget and the start * of the area that is used for drawing at the bottom. * @return The padding between the start of the widget and the start * of the area that is used for drawing at the bottom. * * \sa setGlobalLeading */ int globalLeadingBottom() const; /** * Paints all the contents of the chart. Use this method to make KChart * draw into your QPainter. * * \note Any global leading settings will be used by the paint method too, * so make sure to set them to zero, if you want the drawing to have the exact * size of the target rectangle. * * \param painter The painter to be drawn into. * \param rect The rectangle to be filled by the Chart's drawing. * * \sa setGlobalLeading */ void paint( QPainter* painter, const QRect& rect ); void reLayoutFloatingLegends(); Q_SIGNALS: /** Emitted upon change of a property of the Chart or any of its components. */ void propertiesChanged(); void finishedDrawing(); protected: /** * Adjusts the internal layout when the chart is resized. */ - /* reimp */ void resizeEvent ( QResizeEvent * event ) Q_DECL_OVERRIDE; + /* reimp */ void resizeEvent ( QResizeEvent * event ) override; /** * @brief Draws the background and frame, then calls paint(). * * In most cases there is no need to override this method in a derived * class, but if you do, do not forget to call paint(). * @sa paint */ - /* reimp */ void paintEvent( QPaintEvent* event ) Q_DECL_OVERRIDE; + /* reimp */ void paintEvent( QPaintEvent* event ) override; /** reimp */ - void mousePressEvent( QMouseEvent* event ) Q_DECL_OVERRIDE; + void mousePressEvent( QMouseEvent* event ) override; /** reimp */ - void mouseDoubleClickEvent( QMouseEvent* event ) Q_DECL_OVERRIDE; + void mouseDoubleClickEvent( QMouseEvent* event ) override; /** reimp */ - void mouseMoveEvent( QMouseEvent* event ) Q_DECL_OVERRIDE; + void mouseMoveEvent( QMouseEvent* event ) override; /** reimp */ - void mouseReleaseEvent( QMouseEvent* event ) Q_DECL_OVERRIDE; + void mouseReleaseEvent( QMouseEvent* event ) override; /** reimp */ - bool event( QEvent* event ) Q_DECL_OVERRIDE; + bool event( QEvent* event ) override; private: // TODO move this to the private class void addLegendInternal( Legend *legend, bool setMeasures ); }; // Here we have a few docu block to be included into the API documentation: /** * \dir src * \brief Implementation directory of KChart. * * This directory contains the header files and the source files of both, * the private and the public classes. * * \note Only classes that have an include wrapper in the \c $KCHARTDIR/include * directory are part of the supported API. * All other classes are to be considered as implemntation details, they * could be changed in future versions of KChart without notice. * * In other words: No class that is not mentioned in the \c $KCHARTDIR/include * directory may be directly used by your application. * * The recommended way to include classes of the KChart API is including * them by class name, so instead of including KChartChart.h you would say: * \verbatim #include \endverbatim * * When following this there is no reason to include the \c $KCHARTDIR/src * directory, it is sufficient to include \c $KCHARTDIR/include */ } /** * @class QAbstractItemView "(do not include)" * @brief Class only listed here to document inheritance of some KChart classes. * * Please consult the respective Qt documentation for details: * http://doc.trolltech.com/ */ /** * @class QAbstractProxyModel "(do not include)" * @brief Class only listed here to document inheritance of some KChart classes. * * Please consult the respective Qt documentation for details: * http://doc.trolltech.com/ */ /** * @class QFrame "(do not include)" * @brief Class only listed here to document inheritance of some KChart classes. * * Please consult the respective Qt documentation for details: * http://doc.trolltech.com/ */ /** * @class QObject "(do not include)" * @brief Class only listed here to document inheritance of some KChart classes. * * Please consult the respective Qt documentation for details: * http://doc.trolltech.com/ */ /** * @class QSortFilterProxyModel "(do not include)" * @brief Class only listed here to document inheritance of some KChart classes. * * Please consult the respective Qt documentation for details: * http://doc.trolltech.com/ */ /** * @class QWidget "(do not include)" * @brief Class only listed here to document inheritance of some KChart classes. * * Please consult the respective Qt documentation for details: * http://doc.trolltech.com/ */ /** * @class QTextDocument "(do not include)" * @brief Class only listed here to document inheritance of some KChart classes. * * Please consult the respective Qt documentation for details: * http://doc.trolltech.com/ */ /** * @class QLayoutItem "(do not include)" * @brief Class only listed here to document inheritance of some KChart classes. * * Please consult the respective Qt documentation for details: * http://doc.trolltech.com/ */ /** * @class QGraphicsPolygonItem "(do not include)" * @brief Class only listed here to document inheritance of some KChart classes. * * Please consult the respective Qt documentation for details: * http://doc.trolltech.com/ */ #endif diff --git a/src/KChart/KChartDatasetProxyModel.h b/src/KChart/KChartDatasetProxyModel.h index e1c0977..4024493 100644 --- a/src/KChart/KChartDatasetProxyModel.h +++ b/src/KChart/KChartDatasetProxyModel.h @@ -1,185 +1,185 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTDATASETPROXYMODEL_H #define KCHARTDATASETPROXYMODEL_H #include #include #include "kchart_export.h" namespace KChart { class IndexOutOfBoundsException; typedef QVector DatasetDescriptionVector; /** DatasetProxyModel takes a KChart dataset configuration and translates it into a filtering proxy model. The resulting model will only contain the part of the model that is selected by the dataset, and the according row and column header data. Currently, this model is implemented for table models only. The way it would work with models representing a tree is to be decided. The column selection is configured by passing a dataset description vector to the model. This vector (of integers) is supposed to have one value for each column of the original model. If the value at position x is -1, column x of the original model is not included in the dataset. If it is between 0 and (columnCount() -1), it is the column the source column is mapped to in the resulting model. Any other value is an error. */ class KCHART_EXPORT DatasetProxyModel : public QSortFilterProxyModel { Q_OBJECT public: /** Create a DatasetProxyModel. Without further configuration, this model is invalid. @see setDatasetDescriptionVector */ explicit DatasetProxyModel ( QObject* parent = nullptr ); - QModelIndex buddy( const QModelIndex& index ) const Q_DECL_OVERRIDE; + QModelIndex buddy( const QModelIndex& index ) const override; - Qt::ItemFlags flags( const QModelIndex& index ) const Q_DECL_OVERRIDE; + Qt::ItemFlags flags( const QModelIndex& index ) const override; QModelIndex index( int row, int column, - const QModelIndex &parent = QModelIndex() ) const Q_DECL_OVERRIDE; - QModelIndex parent(const QModelIndex &child ) const Q_DECL_OVERRIDE; + const QModelIndex &parent = QModelIndex() ) const override; + QModelIndex parent(const QModelIndex &child ) const override; /** Implements the mapping from the source to the proxy indexes. */ - QModelIndex mapFromSource ( const QModelIndex & sourceIndex ) const Q_DECL_OVERRIDE; + QModelIndex mapFromSource ( const QModelIndex & sourceIndex ) const override; /** Implements the mapping from the proxy to the source indexes. */ - QModelIndex mapToSource ( const QModelIndex& proxyIndex ) const Q_DECL_OVERRIDE; + QModelIndex mapToSource ( const QModelIndex& proxyIndex ) const override; /** Overloaded from base class. */ - QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE; + QVariant data(const QModelIndex &index, int role) const override; /** Overloaded from base class. */ - bool setData( const QModelIndex& index, const QVariant& value, int role ) Q_DECL_OVERRIDE; + bool setData( const QModelIndex& index, const QVariant& value, int role ) override; /** Overloaded from base class. */ - QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const Q_DECL_OVERRIDE; + QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override; /** Overloaded from base class. */ - void setSourceModel(QAbstractItemModel *sourceModel) Q_DECL_OVERRIDE; + void setSourceModel(QAbstractItemModel *sourceModel) override; /** Set the root index of the table in the source model */ void setSourceRootIndex(const QModelIndex& rootIdx); public Q_SLOTS: /** Reset all dataset description. After that, the result of the proxying is an empty model (a new dataset description needs to be set to achieve a non-empty result). */ void resetDatasetDescriptions(); /** Configure the dataset selection for the columns. Every call to this method resets the previous dataset description. */ void setDatasetColumnDescriptionVector ( const DatasetDescriptionVector& columnConfig ); /** Configure the dataset selection for the rows. Every call to this method resets the previous dataset description. */ void setDatasetRowDescriptionVector ( const DatasetDescriptionVector& rowConfig ); /** Convenience method to configure rows and columns in one step. */ void setDatasetDescriptionVectors ( const DatasetDescriptionVector& rowConfig, const DatasetDescriptionVector& columnConfig ); // FIXME: add convenience methods to configure common dataset // selections (like rectangular areas etc) protected: /** Decide whether the column is accepted. */ bool filterAcceptsColumn ( int sourceColumn, - const QModelIndex & ) const Q_DECL_OVERRIDE; + const QModelIndex & ) const override; /** Decide whether the row is accepted. */ - bool filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const Q_DECL_OVERRIDE; + bool filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const override; private: /** Map a proxy column to a source column. */ int mapProxyColumnToSource ( const int& proxyColumn ) const; /** Map a source column to a proxy column. */ int mapSourceColumnToProxy ( const int& sourceColumn ) const; /** Map a proxy row to a source row. */ int mapProxyRowToSource ( const int& proxyRow ) const; /** Map a source row to a proxy row. */ int mapSourceRowToProxy ( const int& sourceRow ) const; /** Initialize the transformation vectors from the dataset description. The input parameter "Configuration" is a vector that specifies what srce column will be mapped to what proxy column. Example: position: [0][1][2] value: [2][0][1] This will map the source column 2 to proxy column 0, source 0 to proxy 1, and source 1 to proxy 2. Source needs to have at least 2 column. The source-to-proxy mapping looks the same, except that it may contain values of -1, which means this column is not part of the resulting model. The values in the configuration vector must be unique (otherwise, a 1-to-1 mapping in both directions is impossible). sourceCount is the number of columns in the source model. The proxy-to-source map has as many elements as the proxy has columns, the source-to-proxy map has as many elements as the source has columns. Same goes for rows (the mapping logic is the same). */ void initializeDatasetDecriptors ( const DatasetDescriptionVector& inConfiguration, int sourceCount, DatasetDescriptionVector& outSourceToProxyMap, DatasetDescriptionVector& outProxyToSourceMap ); DatasetDescriptionVector mColSrcToProxyMap; DatasetDescriptionVector mColProxyToSrcMap; DatasetDescriptionVector mRowSrcToProxyMap; DatasetDescriptionVector mRowProxyToSrcMap; int mProxyRowCount; int mProxyColumnCount; QModelIndex mRootIndex; }; } #endif diff --git a/src/KChart/KChartLayoutItems.h b/src/KChart/KChartLayoutItems.h index 3d8d040..47e9d70 100644 --- a/src/KChart/KChartLayoutItems.h +++ b/src/KChart/KChartLayoutItems.h @@ -1,476 +1,476 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTLAYOUTITEMS_H #define KCHARTLAYOUTITEMS_H #include #include #include #include #include #include #include "KChartTextAttributes.h" #include "KChartMarkerAttributes.h" QT_BEGIN_NAMESPACE class QPainter; class KTextDocument; QT_END_NAMESPACE // TODO remove QRectF rotatedRect( const QRectF& pt, qreal rotation ); namespace KChart { class AbstractDiagram; class PaintContext; /** * Base class for all layout items of KChart * \internal */ class KCHART_EXPORT AbstractLayoutItem : public QLayoutItem { public: AbstractLayoutItem( Qt::Alignment itemAlignment = Qt::Alignment() ) : QLayoutItem( itemAlignment ), mParent( nullptr ), mParentLayout( nullptr ) {} /** * Default impl: just call paint. * * Derived classes like KChart::AbstractArea are providing * additional action here. */ virtual void paintAll( QPainter& painter ); virtual void paint( QPainter* ) = 0; virtual void paintCtx( PaintContext* context ); virtual void setParentWidget( QWidget* widget ); virtual void sizeHintChanged() const; void setParentLayout( QLayout* lay ) { mParentLayout = lay; } QLayout* parentLayout() { return mParentLayout; } void removeFromParentLayout() { if ( mParentLayout ) { if ( widget() ) mParentLayout->removeWidget( widget() ); else mParentLayout->removeItem( this ); } } protected: QWidget* mParent; QLayout* mParentLayout; }; /** * Layout item showing a text *\internal */ class KCHART_EXPORT TextLayoutItem : public AbstractLayoutItem { public: TextLayoutItem(); TextLayoutItem( const QString& text, const TextAttributes& attributes, const QObject* autoReferenceArea, KChartEnums::MeasureOrientation autoReferenceOrientation, Qt::Alignment alignment = Qt::Alignment() ); void setAutoReferenceArea( const QObject* area ); const QObject* autoReferenceArea() const; void setText(const QString & text); QString text() const; void setTextAlignment( Qt::Alignment ); Qt::Alignment textAlignment() const; void setTextAttributes( const TextAttributes& a ); TextAttributes textAttributes() const; /** pure virtual in QLayoutItem */ - bool isEmpty() const Q_DECL_OVERRIDE; + bool isEmpty() const override; /** pure virtual in QLayoutItem */ - Qt::Orientations expandingDirections() const Q_DECL_OVERRIDE; + Qt::Orientations expandingDirections() const override; /** pure virtual in QLayoutItem */ - QSize maximumSize() const Q_DECL_OVERRIDE; + QSize maximumSize() const override; /** pure virtual in QLayoutItem */ - QSize minimumSize() const Q_DECL_OVERRIDE; + QSize minimumSize() const override; /** pure virtual in QLayoutItem */ - QSize sizeHint() const Q_DECL_OVERRIDE; + QSize sizeHint() const override; /** pure virtual in QLayoutItem */ - void setGeometry( const QRect& r ) Q_DECL_OVERRIDE; + void setGeometry( const QRect& r ) override; /** pure virtual in QLayoutItem */ - QRect geometry() const Q_DECL_OVERRIDE; + QRect geometry() const override; virtual int marginWidth() const; virtual QSize sizeHintUnrotated() const; virtual bool intersects( const TextLayoutItem& other, const QPointF& myPos, const QPointF& otherPos ) const; virtual bool intersects( const TextLayoutItem& other, const QPoint& myPos, const QPoint& otherPos ) const; virtual qreal realFontSize() const; virtual QFont realFont() const; - void paint( QPainter* ) Q_DECL_OVERRIDE; + void paint( QPainter* ) override; QPolygon boundingPolygon() const; private: bool maybeUpdateRealFont() const; QSize unrotatedSizeHint( const QFont& fnt = QFont() ) const; QSize unrotatedTextSize( QFont fnt = QFont() ) const; QSize calcSizeHint( const QFont& font ) const; int marginWidth( const QSize& textSize ) const; qreal fitFontSizeToGeometry() const; QRect mRect; QString mText; Qt::Alignment mTextAlignment; TextAttributes mAttributes; const QObject* mAutoReferenceArea; KChartEnums::MeasureOrientation mAutoReferenceOrientation; mutable QSize cachedSizeHint; mutable QPolygon mCachedBoundingPolygon; mutable qreal cachedFontSize; mutable QFont cachedFont; }; class KCHART_EXPORT TextBubbleLayoutItem : public AbstractLayoutItem { public: TextBubbleLayoutItem(); TextBubbleLayoutItem( const QString& text, const TextAttributes& attributes, const QObject* autoReferenceArea, KChartEnums::MeasureOrientation autoReferenceOrientation, Qt::Alignment alignment = Qt::Alignment() ); ~TextBubbleLayoutItem(); void setAutoReferenceArea( const QObject* area ); const QObject* autoReferenceArea() const; void setText(const QString & text); QString text() const; void setTextAttributes( const TextAttributes& a ); TextAttributes textAttributes() const; /** pure virtual in QLayoutItem */ - bool isEmpty() const Q_DECL_OVERRIDE; + bool isEmpty() const override; /** pure virtual in QLayoutItem */ - Qt::Orientations expandingDirections() const Q_DECL_OVERRIDE; + Qt::Orientations expandingDirections() const override; /** pure virtual in QLayoutItem */ - QSize maximumSize() const Q_DECL_OVERRIDE; + QSize maximumSize() const override; /** pure virtual in QLayoutItem */ - QSize minimumSize() const Q_DECL_OVERRIDE; + QSize minimumSize() const override; /** pure virtual in QLayoutItem */ - QSize sizeHint() const Q_DECL_OVERRIDE; + QSize sizeHint() const override; /** pure virtual in QLayoutItem */ - void setGeometry( const QRect& r ) Q_DECL_OVERRIDE; + void setGeometry( const QRect& r ) override; /** pure virtual in QLayoutItem */ - QRect geometry() const Q_DECL_OVERRIDE; + QRect geometry() const override; - void paint( QPainter* painter ) Q_DECL_OVERRIDE; + void paint( QPainter* painter ) override; protected: int borderWidth() const; private: TextLayoutItem* const m_text; }; /** * Layout item showing a data point marker * \internal */ class KCHART_EXPORT MarkerLayoutItem : public AbstractLayoutItem { public: MarkerLayoutItem( AbstractDiagram* diagram, const MarkerAttributes& marker, const QBrush& brush, const QPen& pen, Qt::Alignment alignment = Qt::Alignment() ); - Qt::Orientations expandingDirections() const Q_DECL_OVERRIDE; - QRect geometry() const Q_DECL_OVERRIDE; - bool isEmpty() const Q_DECL_OVERRIDE; - QSize maximumSize() const Q_DECL_OVERRIDE; - QSize minimumSize() const Q_DECL_OVERRIDE; - void setGeometry( const QRect& r ) Q_DECL_OVERRIDE; - QSize sizeHint() const Q_DECL_OVERRIDE; + Qt::Orientations expandingDirections() const override; + QRect geometry() const override; + bool isEmpty() const override; + QSize maximumSize() const override; + QSize minimumSize() const override; + void setGeometry( const QRect& r ) override; + QSize sizeHint() const override; - void paint( QPainter* ) Q_DECL_OVERRIDE; + void paint( QPainter* ) override; static void paintIntoRect( QPainter* painter, const QRect& rect, AbstractDiagram* diagram, const MarkerAttributes& marker, const QBrush& brush, const QPen& pen ); private: AbstractDiagram* mDiagram; QRect mRect; MarkerAttributes mMarker; QBrush mBrush; QPen mPen; }; /** * Layout item showing a coloured line * \internal */ class KCHART_EXPORT LineLayoutItem : public AbstractLayoutItem { public: LineLayoutItem( AbstractDiagram* diagram, int length, const QPen& pen, Qt::Alignment mLegendLineSymbolAlignment, Qt::Alignment alignment = Qt::Alignment() ); - Qt::Orientations expandingDirections() const Q_DECL_OVERRIDE; - QRect geometry() const Q_DECL_OVERRIDE; - bool isEmpty() const Q_DECL_OVERRIDE; - QSize maximumSize() const Q_DECL_OVERRIDE; - QSize minimumSize() const Q_DECL_OVERRIDE; - void setGeometry( const QRect& r ) Q_DECL_OVERRIDE; - QSize sizeHint() const Q_DECL_OVERRIDE; + Qt::Orientations expandingDirections() const override; + QRect geometry() const override; + bool isEmpty() const override; + QSize maximumSize() const override; + QSize minimumSize() const override; + void setGeometry( const QRect& r ) override; + QSize sizeHint() const override; void setLegendLineSymbolAlignment(Qt::Alignment legendLineSymbolAlignment); virtual Qt::Alignment legendLineSymbolAlignment() const; - void paint( QPainter* ) Q_DECL_OVERRIDE; + void paint( QPainter* ) override; static void paintIntoRect( QPainter* painter, const QRect& rect, const QPen& pen, Qt::Alignment lineAlignment); private: AbstractDiagram* mDiagram; //TODO: not used. remove it int mLength; QPen mPen; QRect mRect; Qt::Alignment mLegendLineSymbolAlignment; }; /** * Layout item showing a coloured line and a data point marker * \internal */ class KCHART_EXPORT LineWithMarkerLayoutItem : public AbstractLayoutItem { public: LineWithMarkerLayoutItem( AbstractDiagram* diagram, int lineLength, const QPen& linePen, int markerOffs, const MarkerAttributes& marker, const QBrush& markerBrush, const QPen& markerPen, Qt::Alignment alignment = Qt::Alignment() ); - Qt::Orientations expandingDirections() const Q_DECL_OVERRIDE; - QRect geometry() const Q_DECL_OVERRIDE; - bool isEmpty() const Q_DECL_OVERRIDE; - QSize maximumSize() const Q_DECL_OVERRIDE; - QSize minimumSize() const Q_DECL_OVERRIDE; - void setGeometry( const QRect& r ) Q_DECL_OVERRIDE; - QSize sizeHint() const Q_DECL_OVERRIDE; + Qt::Orientations expandingDirections() const override; + QRect geometry() const override; + bool isEmpty() const override; + QSize maximumSize() const override; + QSize minimumSize() const override; + void setGeometry( const QRect& r ) override; + QSize sizeHint() const override; - void paint( QPainter* ) Q_DECL_OVERRIDE; + void paint( QPainter* ) override; private: AbstractDiagram* mDiagram; QRect mRect; int mLineLength; QPen mLinePen; int mMarkerOffs; MarkerAttributes mMarker; QBrush mMarkerBrush; QPen mMarkerPen; }; /** * Layout item showing a horizontal line * \internal */ class KCHART_EXPORT HorizontalLineLayoutItem : public AbstractLayoutItem { public: HorizontalLineLayoutItem(); - Qt::Orientations expandingDirections() const Q_DECL_OVERRIDE; - QRect geometry() const Q_DECL_OVERRIDE; - bool isEmpty() const Q_DECL_OVERRIDE; - QSize maximumSize() const Q_DECL_OVERRIDE; - QSize minimumSize() const Q_DECL_OVERRIDE; - void setGeometry( const QRect& r ) Q_DECL_OVERRIDE; - QSize sizeHint() const Q_DECL_OVERRIDE; + Qt::Orientations expandingDirections() const override; + QRect geometry() const override; + bool isEmpty() const override; + QSize maximumSize() const override; + QSize minimumSize() const override; + void setGeometry( const QRect& r ) override; + QSize sizeHint() const override; - void paint( QPainter* ) Q_DECL_OVERRIDE; + void paint( QPainter* ) override; private: QRect mRect; }; /** * Layout item showing a vertial line * \internal */ class KCHART_EXPORT VerticalLineLayoutItem : public AbstractLayoutItem { public: VerticalLineLayoutItem(); - Qt::Orientations expandingDirections() const Q_DECL_OVERRIDE; - QRect geometry() const Q_DECL_OVERRIDE; - bool isEmpty() const Q_DECL_OVERRIDE; - QSize maximumSize() const Q_DECL_OVERRIDE; - QSize minimumSize() const Q_DECL_OVERRIDE; - void setGeometry( const QRect& r ) Q_DECL_OVERRIDE; - QSize sizeHint() const Q_DECL_OVERRIDE; + Qt::Orientations expandingDirections() const override; + QRect geometry() const override; + bool isEmpty() const override; + QSize maximumSize() const override; + QSize minimumSize() const override; + void setGeometry( const QRect& r ) override; + QSize sizeHint() const override; - void paint( QPainter* ) Q_DECL_OVERRIDE; + void paint( QPainter* ) override; private: QRect mRect; }; /** * @brief An empty layout item * \internal * * The AutoSpacerLayoutItem is automatically put into each corner cell of * the planeLayout grid: one of its reference-layouts is a QVBoxLayout (for * the top, or bottom axes resp.), the other one is a QHBoxLayout (for the * left/right sided axes). * * The spacer reserves enough space so all of the AbstractAreas contained * in the two reference-layouts can display not only their in-bounds * content but also their overlapping content reaching out of their area. * * KChart's layouting is applying this schema: \verbatim +------------------+-------------------------+-----------------+ | +--------------+ | +---------------------+ | +-------------+ | | | | | | QVBoxLayout for | | | | | | | AUTO | | | the top axis/axes | | | AUTO | | | | SPACER | | +---------------------+ | | SPACER | | | | ITEM | | | | | | ITEM | | | | | | | | | | | | | +--------------+ | +---------------------+ | +-------------+ | +------------------+-------------------------+-----------------+ | +--------+-----+ | +---------------------+ | +-------+-----+ | | | | | | | | | | | | | | | | | | | | | | | | | | | QHBox- | | | | | | | Right | | | | | Layout | | | | | | | | | | | | | | | | | | | axes | | | | | for | | | | | | | | | | | | | | | | | | | layout| | | | | the | | | | DIAGRAM(s) | | | | | | | | | | | | | | | | | | | | left | | | | | | | | | | | | | | | | | | | | | | | | axis | | | | | | | | | | | | or | | | | | | | | | | | | axes | | | | | | | | | | | | | | | | | | | | | | | +--------+-----+ | +---------------------+ | +-------+-----+ | +------------------+-------------------------+-----------------+ | +--------------+ | +---------------------+ | +-------------+ | | | | | | QVBoxLayout for | | | | | | | AUTO | | | the bottom axes | | | AUTO | | | | SPACER | | +---------------------+ | | SPACER | | | | ITEM | | | | | | ITEM | | | | | | | | | | | | | +--------------+ | +---------------------+ | +-------------+ | +------------------+-------------------------+-----------------+ \endverbatim * * A typical use case is an Abscissa axis with long labels: \verbatim 2 -| | 1 -| | 0 -+------------------------------------ | | | | | Monday Tuesday Wednesday Thursday Friday \endverbatim * The last letters of the word "Friday" would have been * cut off in previous versions of KChart - that is * if you did not call KChart::Chart::setGlobalLeading(). * * Now the word will be shown completely because there * is an auto-spacer-item taking care for the additional * space needed in the lower/right corner. */ class KCHART_EXPORT AutoSpacerLayoutItem : public AbstractLayoutItem { public: AutoSpacerLayoutItem( bool layoutIsAtTopPosition, QHBoxLayout *rightLeftLayout, bool layoutIsAtLeftPosition, QVBoxLayout *topBottomLayout ); - Qt::Orientations expandingDirections() const Q_DECL_OVERRIDE; - QRect geometry() const Q_DECL_OVERRIDE; - bool isEmpty() const Q_DECL_OVERRIDE; - QSize maximumSize() const Q_DECL_OVERRIDE; - QSize minimumSize() const Q_DECL_OVERRIDE; - void setGeometry( const QRect& r ) Q_DECL_OVERRIDE; - QSize sizeHint() const Q_DECL_OVERRIDE; + Qt::Orientations expandingDirections() const override; + QRect geometry() const override; + bool isEmpty() const override; + QSize maximumSize() const override; + QSize minimumSize() const override; + void setGeometry( const QRect& r ) override; + QSize sizeHint() const override; - void paint( QPainter* ) Q_DECL_OVERRIDE; + void paint( QPainter* ) override; private: QRect mRect; bool mLayoutIsAtTopPosition; QHBoxLayout *mRightLeftLayout; bool mLayoutIsAtLeftPosition; QVBoxLayout *mTopBottomLayout; mutable QBrush mCommonBrush; mutable QSize mCachedSize; }; } #endif /* KCHARTLAYOUTITEMS_H */ diff --git a/src/KChart/KChartLegend.h b/src/KChart/KChartLegend.h index 30d925e..a79108d 100644 --- a/src/KChart/KChartLegend.h +++ b/src/KChart/KChartLegend.h @@ -1,408 +1,408 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTLEGEND_H #define KCHARTLEGEND_H #include "KChartAbstractAreaWidget.h" #include "KChartPosition.h" #include "KChartMarkerAttributes.h" class QTextTable; namespace KChart { class AbstractDiagram; typedef QList DiagramList; typedef QList ConstDiagramList; /** * @brief Legend defines the interface for the legend drawing class. * * Legend is the class for drawing legends for all kinds of diagrams ("chart types"). * * Legend is drawn on chart level, not per diagram, but you can have more than one * legend per chart, using KChart::Chart::addLegend(). * * \note Legend is different from all other classes ofd KChart, since it can be * displayed outside of the Chart's area. If you want to, you can embedd the legend * into your own widget, or into another part of a bigger layout, into which you might * have inserted the Chart. * * On the other hand, please note that you MUST call Chart::addLegend to get your * legend positioned into the correct place of your chart - if you want to have * the legend shown inside of the chart (that's probably true for most cases). */ class KCHART_EXPORT Legend : public AbstractAreaWidget { Q_OBJECT Q_DISABLE_COPY( Legend ) KCHART_DECLARE_PRIVATE_DERIVED_QWIDGET( Legend ) public: explicit Legend( QWidget* parent = nullptr ); explicit Legend( KChart::AbstractDiagram* diagram, QWidget* parent = nullptr ); virtual ~Legend(); enum LegendStyle { MarkersOnly = 0, LinesOnly = 1, MarkersAndLines = 2 }; void setLegendStyle( LegendStyle style ); LegendStyle legendStyle() const; virtual Legend * clone() const; /** * Returns true if both legends have the same settings. */ bool compare( const Legend* other ) const; - void resizeEvent( QResizeEvent * event ) Q_DECL_OVERRIDE; // TODO: should be protected + void resizeEvent( QResizeEvent * event ) override; // TODO: should be protected - virtual void paint( QPainter* painter ) Q_DECL_OVERRIDE; - void setVisible( bool visible ) Q_DECL_OVERRIDE; + virtual void paint( QPainter* painter ) override; + void setVisible( bool visible ) override; /** Specifies the reference area for font size of title text, and for font size of the item texts, IF automatic area detection is set. \note This parameter is ignored, if the Measure given for setTitleTextAttributes (or setTextAttributes, resp.) is not specifying automatic area detection. If no reference area is specified, but automatic area detection is set, then the size of the legend's parent widget will be used. \sa KChart::Measure, KChartEnums::MeasureCalculationMode */ void setReferenceArea( const QWidget* area ); /** Returns the reference area, that is used for font size of title text, and for font size of the item texts, IF automatic area detection is set. \sa setReferenceArea */ const QWidget* referenceArea() const; /** * The first diagram of the legend or 0 if there was none added to the legend. * @return The first diagram of the legend or 0. * * \sa diagrams, addDiagram, removeDiagram, removeDiagrams, replaceDiagram, setDiagram */ KChart::AbstractDiagram* diagram() const; /** * The list of all diagrams associated with the legend. * @return The list of all diagrams associated with the legend. * * \sa diagram, addDiagram, removeDiagram, removeDiagrams, replaceDiagram, setDiagram */ DiagramList diagrams() const; /** * @return The list of diagrams associated with this legend. */ ConstDiagramList constDiagrams() const; /** * Add the given diagram to the legend. * @param newDiagram The diagram to add. * * \sa diagram, diagrams, removeDiagram, removeDiagrams, replaceDiagram, setDiagram */ void addDiagram( KChart::AbstractDiagram* newDiagram ); /** * Removes the diagram from the legend's list of diagrams. * * \sa diagram, diagrams, addDiagram, removeDiagrams, replaceDiagram, setDiagram */ void removeDiagram( KChart::AbstractDiagram* oldDiagram ); /** * Removes all diagrams from the legend's list of diagrams. * * \sa diagram, diagrams, addDiagram, removeDiagram, replaceDiagram, setDiagram */ void removeDiagrams(); /** * Replaces the old diagram, or appends the * new diagram, it there is none yet. * * @param newDiagram The diagram to be used instead of the old one. * If this parameter is zero, the first diagram will just be removed. * * @param oldDiagram The diagram to be removed by the new one. This * diagram will be deleted automatically. If the parameter is omitted, * the very first diagram will be replaced. In case, there was no * diagram yet, the new diagram will just be added. * * \sa diagram, diagrams, addDiagram, removeDiagram, removeDiagrams, setDiagram */ void replaceDiagram( KChart::AbstractDiagram* newDiagram, KChart::AbstractDiagram* oldDiagram = nullptr ); /** * Returns the offset of the first dataset of \c diagram. * */ uint dataSetOffset( KChart::AbstractDiagram* diagram ); /** * @brief A convenience method doing the same as replaceDiagram( newDiagram, 0 ); * * Replaces the first diagram by the given diagram. * If the legend's list of diagram is empty the given diagram is added to the list. * * \sa diagram, diagrams, addDiagram, removeDiagram, removeDiagrams, replaceDiagram */ void setDiagram( KChart::AbstractDiagram* newDiagram ); /** * \brief Specify the position of a non-floating legend. * * Use setFloatingPosition to set position and alignment * if your legend is floating. * * \sa setAlignment, setFloatingPosition */ void setPosition( Position position ); /** * Returns the position of a non-floating legend. * \sa setPosition */ Position position() const; /** * \brief Specify the alignment of a non-floating legend. * * Use setFloatingPosition to set position and alignment * if your legend is floating. * * \sa alignment, setPosition, setFloatingPosition */ void setAlignment( Qt::Alignment ); /** * Returns the alignment of a non-floating legend. * \sa setAlignment */ Qt::Alignment alignment() const; /** * \brief Specify the alignment of the text elements within the legend * * \sa textAlignment() */ void setTextAlignment( Qt::Alignment ); /** * \brief Returns the alignment used while rendering text elements within the legend. * * \sa setTextAlignment() */ Qt::Alignment textAlignment() const; /** * \brief Specify the alignment of the legend symbol( alignment of Legend::LinesOnly) * within the legend * * \sa legendSymbolAlignment() */ void setLegendSymbolAlignment(Qt::Alignment); /** * \brief Returns the alignment used while drawing legend symbol(alignment of Legend::LinesOnly) * within the legend. * * \sa setLegendSymbolAlignment() */ Qt::Alignment legendSymbolAlignment() const; /** * \brief Specify the position and alignment of a floating legend. * * Use setPosition and setAlignment to set position and alignment * if your legend is non-floating. * * \note When setFloatingPosition is called, the Legend's position value is set to * KChart::Position::Floating automatically. * * If your Chart is pointed to by m_chart, your could have the floating legend * aligned exactly to the chart's coordinate plane's top-right corner * with the following commands: \verbatim KChart::RelativePosition relativePosition; relativePosition.setReferenceArea( m_chart->coordinatePlane() ); relativePosition.setReferencePosition( Position::NorthEast ); relativePosition.setAlignment( Qt::AlignTop | Qt::AlignRight ); relativePosition.setHorizontalPadding( KChart::Measure( -1.0, KChartEnums::MeasureCalculationModeAbsolute ) ); relativePosition.setVerticalPadding( KChart::Measure( 0.0, KChartEnums::MeasureCalculationModeAbsolute ) ); m_legend->setFloatingPosition( relativePosition ); \endverbatim * * To have the legend positioned at a fixed point, measured from the QPainter's top left corner, * you could use the following code code: * \verbatim KChart::RelativePosition relativePosition; relativePosition.setReferencePoints( PositionPoints( QPointF( 0.0, 0.0 ) ) ); relativePosition.setReferencePosition( Position::NorthWest ); relativePosition.setAlignment( Qt::AlignTop | Qt::AlignLeft ); relativePosition.setHorizontalPadding( KChart::Measure( 4.0, KChartEnums::MeasureCalculationModeAbsolute ) ); relativePosition.setVerticalPadding( KChart::Measure( 4.0, KChartEnums::MeasureCalculationModeAbsolute ) ); m_legend->setFloatingPosition( relativePosition ); \endverbatim * Actually that's exactly the code KChart is using as default position for any floating legends, * so if you just say setPosition( KChart::Position::Floating ) without calling setFloatingPosition * your legend will be positioned at point 4/4. * * \sa setPosition, setAlignment */ void setFloatingPosition( const RelativePosition& relativePosition ); /** * Returns the position of a floating legend. * \sa setFloatingPosition */ const RelativePosition floatingPosition() const; void setOrientation( Qt::Orientation orientation ); Qt::Orientation orientation() const; void setSortOrder( Qt::SortOrder order ); Qt::SortOrder sortOrder() const; void setShowLines( bool legendShowLines ); bool showLines() const; void resetTexts(); void setText( uint dataset, const QString& text ); QString text( uint dataset ) const; const QMap texts() const; /** * Sets a list of datasets that are to be hidden in the legend. * * By passing an empty list, you show all datasets. * All datasets are shown by default, which means * that hiddenDatasets() returns an empty list. */ void setHiddenDatasets( const QList hiddenDatasets ); const QList hiddenDatasets() const; void setDatasetHidden( uint dataset, bool hidden ); bool datasetIsHidden( uint dataset ) const; uint datasetCount() const; void setDefaultColors(); void setRainbowColors(); void setSubduedColors( bool ordered = false ); void setBrushesFromDiagram( KChart::AbstractDiagram* diagram ); /** * Note: there is no color() getter method, since setColor * just sets a QBrush with the respective color, so the * brush() getter method is sufficient. */ void setColor( uint dataset, const QColor& color ); void setBrush( uint dataset, const QBrush& brush ); QBrush brush( uint dataset ) const; const QMap brushes() const; void setPen( uint dataset, const QPen& pen ); QPen pen( uint dataset ) const; const QMap pens() const; /** * Note that any sizes specified via setMarkerAttributes are ignored, * unless you disable the automatic size calculation, by saying * setUseAutomaticMarkerSize( false ) */ void setMarkerAttributes( uint dataset, const MarkerAttributes& ); MarkerAttributes markerAttributes( uint dataset ) const; const QMap markerAttributes() const; /** * This option is on by default, it means that Marker sizes in the Legend * will be the same as the font height used for their respective label texts. * * Set this to false, if you want to specify the marker sizes via setMarkerAttributes * or if you want the Legend to use the same marker sizes as they are used in the Diagrams. */ void setUseAutomaticMarkerSize( bool useAutomaticMarkerSize ); bool useAutomaticMarkerSize() const; void setTextAttributes( const TextAttributes &a ); TextAttributes textAttributes() const; void setTitleText( const QString& text ); QString titleText() const; void setTitleTextAttributes( const TextAttributes &a ); TextAttributes titleTextAttributes() const; void setSpacing( uint space ); uint spacing() const; // called internally by KChart::Chart, when painting into a custom QPainter - void forceRebuild() Q_DECL_OVERRIDE; - - QSize minimumSizeHint() const Q_DECL_OVERRIDE; - QSize sizeHint() const Q_DECL_OVERRIDE; - bool hasHeightForWidth() const Q_DECL_OVERRIDE; - int heightForWidth( int width ) const Q_DECL_OVERRIDE; - void needSizeHint() Q_DECL_OVERRIDE; - void resizeLayout( const QSize& size ) Q_DECL_OVERRIDE; + void forceRebuild() override; + + QSize minimumSizeHint() const override; + QSize sizeHint() const override; + bool hasHeightForWidth() const override; + int heightForWidth( int width ) const override; + void needSizeHint() override; + void resizeLayout( const QSize& size ) override; Q_SIGNALS: void destroyedLegend( Legend* ); /** Emitted upon change of a property of the Legend or any of its components. */ void propertiesChanged(); private Q_SLOTS: void emitPositionChanged(); void resetDiagram( AbstractDiagram* ); void activateTheLayout(); void setNeedRebuild(); void buildLegend(); }; // End of class Legend } #endif // KCHARTLEGEND_H diff --git a/src/KChart/KChartModelDataCache_p.h b/src/KChart/KChartModelDataCache_p.h index 90c0f59..1f06c5f 100644 --- a/src/KChart/KChartModelDataCache_p.h +++ b/src/KChart/KChartModelDataCache_p.h @@ -1,351 +1,351 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTMODELDATACACHE_H #define KCHARTMODELDATACACHE_H #include #include #include #include #include "kchart_export.h" QT_BEGIN_NAMESPACE class QAbstractItemModel; QT_END_NAMESPACE namespace KChart { namespace ModelDataCachePrivate { class ModelSignalMapper { protected: ModelSignalMapper() {} public: virtual ~ModelSignalMapper() {} virtual void resetModel() = 0; virtual void columnsInserted( const QModelIndex&, int, int ) = 0; virtual void columnsRemoved( const QModelIndex&, int, int ) = 0; virtual void dataChanged( const QModelIndex&, const QModelIndex& ) = 0; virtual void layoutChanged() = 0; virtual void modelReset() = 0; virtual void rowsInserted( const QModelIndex&, int, int ) = 0; virtual void rowsRemoved( const QModelIndex&, int, int ) = 0; }; // this class maps slots to a non-QObject instantiating ModelSignalMapper class KCHART_EXPORT ModelSignalMapperConnector : public QObject { Q_OBJECT public: explicit ModelSignalMapperConnector( ModelSignalMapper& mapper ); ~ModelSignalMapperConnector(); void connectSignals( QAbstractItemModel* model ); void disconnectSignals( QAbstractItemModel* model ); protected Q_SLOTS: void resetModel(); void columnsInserted( const QModelIndex&, int, int ); void columnsRemoved( const QModelIndex&, int, int ); void dataChanged( const QModelIndex&, const QModelIndex& ); void layoutChanged(); void modelReset(); void rowsInserted( const QModelIndex&, int, int ); void rowsRemoved( const QModelIndex&, int, int ); private: ModelSignalMapper& m_mapper; }; template< class T> T nan() { return T(); } template<> inline qreal nan< qreal >() { return std::numeric_limits< qreal >::quiet_NaN(); } } template< class T, int ROLE > class ModelDataCache : public ModelDataCachePrivate::ModelSignalMapper { public: ModelDataCache() : m_model( nullptr ), m_connector( *this ) { } virtual ~ModelDataCache() { } T data( const QModelIndex& index ) const { if ( !index.isValid() || index.parent() != m_rootIndex || index.row() >= m_model->rowCount(m_rootIndex) || index.column() >= m_model->columnCount(m_rootIndex) ) return ModelDataCachePrivate::nan< T >(); if ( index.row() >= m_data.count() ) { qWarning( "KChart didn't receive signal rowsInserted, resetModel or layoutChanged, " "but an index with a row outside of the known bounds." ); // apparently, data were added behind our back (w/o signals) const_cast< ModelDataCache< T, ROLE >* >( this )->rowsInserted( m_rootIndex, m_data.count(), m_model->rowCount( m_rootIndex ) - 1 ); Q_ASSERT( index.row() < m_data.count() ); } if ( index.column() >= m_data.first().count() ) { qWarning( "KChart didn't got signal columnsInserted, resetModel or layoutChanged, " "but an index with a column outside of the known bounds." ); // apparently, data were added behind our back (w/o signals) const_cast< ModelDataCache< T, ROLE >* >( this )->columnsInserted( m_rootIndex, m_data.first().count(), m_model->columnCount( m_rootIndex ) - 1 ); Q_ASSERT( index.column() < m_data.first().count() ); } return data( index.row(), index.column() ); } T data( int row, int column ) const { if ( row < 0 || column < 0 ) return ModelDataCachePrivate::nan< T >(); Q_ASSERT( row < m_model->rowCount(m_rootIndex) ); Q_ASSERT( column < m_model->columnCount(m_rootIndex) ); Q_ASSERT( row < m_data.count() ); Q_ASSERT( column < m_data.first().count() ); if ( isCached( row, column ) ) return m_data.at( row ).at( column ); return fetchFromModel( row, column, ROLE ); } void setModel( QAbstractItemModel* model ) { if ( m_model != nullptr ) m_connector.disconnectSignals( m_model ); m_model = model; if ( m_model != nullptr ) m_connector.connectSignals( m_model ); modelReset(); } QAbstractItemModel* model() const { return m_model; } void setRootIndex( const QModelIndex& rootIndex ) { Q_ASSERT( rootIndex.model() == m_model || !rootIndex.isValid() ); m_rootIndex = rootIndex; modelReset(); } QModelIndex rootIndex() const { return m_rootIndex; } protected: bool isCached( int row, int column ) const { return m_cacheValid.at( row ).at( column ); } T fetchFromModel( int row, int column, int role ) const { Q_ASSERT( m_model != nullptr ); const QModelIndex index = m_model->index( row, column, m_rootIndex ); const QVariant data = index.data( role ); const T value = data.isNull() ? ModelDataCachePrivate::nan< T >() : ( data.value< T >() ); m_data[ row ][ column ] = value; m_cacheValid[ row ][ column ] = true; return value; } - void columnsInserted( const QModelIndex& parent, int start, int end ) Q_DECL_OVERRIDE + void columnsInserted( const QModelIndex& parent, int start, int end ) override { Q_ASSERT( m_model != nullptr ); Q_ASSERT( parent.model() == m_model || !parent.isValid() ); if ( parent != m_rootIndex ) return; Q_ASSERT( start <= end ); Q_ASSERT( start <= m_model->columnCount(m_rootIndex) ); const int rowCount = m_data.count(); for ( int row = 0; row < rowCount; ++row ) { m_data[ row ].insert( start, end - start + 1, T() ); m_cacheValid[ row ].insert( start, end - start + 1, false ); Q_ASSERT( m_data.at( row ).count() == m_model->columnCount( m_rootIndex ) ); Q_ASSERT( m_cacheValid.at( row ).count() == m_model->columnCount( m_rootIndex ) ); } } - void columnsRemoved( const QModelIndex& parent, int start, int end ) Q_DECL_OVERRIDE + void columnsRemoved( const QModelIndex& parent, int start, int end ) override { Q_ASSERT( m_model != nullptr ); Q_ASSERT( parent.model() == m_model || !parent.isValid() ); if ( parent != m_rootIndex ) return; Q_ASSERT( start <= end ); const int rowCount = m_data.count(); for ( int row = 0; row < rowCount; ++row ) { m_data[ row ].remove( start, end - start + 1 ); m_cacheValid[ row ].remove( start, end - start + 1 ); Q_ASSERT( m_data.at( row ).count() == m_model->columnCount( m_rootIndex ) ); Q_ASSERT( m_cacheValid.at( row ).count() == m_model->columnCount( m_rootIndex ) ); } } - void dataChanged( const QModelIndex& topLeft, const QModelIndex& bottomRight ) Q_DECL_OVERRIDE + void dataChanged( const QModelIndex& topLeft, const QModelIndex& bottomRight ) override { if ( !m_model ) return; Q_ASSERT( m_model != nullptr ); Q_ASSERT( topLeft.parent() == bottomRight.parent() ); if ( !topLeft.isValid() || !bottomRight.isValid() || topLeft.parent() != m_rootIndex ) return; Q_ASSERT( topLeft.model() == m_model && bottomRight.model() == m_model ); const int minRow = qMax( 0, topLeft.row() ); const int maxRow = bottomRight.row(); const int minCol = qMax( 0, topLeft.column() ); const int maxCol = bottomRight.column(); Q_ASSERT( minRow <= maxRow ); Q_ASSERT( minCol <= maxCol ); Q_ASSERT( maxRow < m_model->rowCount( m_rootIndex ) ); Q_ASSERT( maxCol < m_model->columnCount( m_rootIndex ) ); for ( int row = minRow; row <= maxRow; ++row ) { for ( int col = minCol; col <= maxCol; ++col ) { m_cacheValid[ row ][ col ] = false; Q_ASSERT( !isCached( row, col ) ); } } } - void layoutChanged() Q_DECL_OVERRIDE + void layoutChanged() override { modelReset(); } - void modelReset() Q_DECL_OVERRIDE + void modelReset() override { m_data.clear(); m_cacheValid.clear(); if ( m_model == nullptr ) return; m_data.fill( QVector< T >( m_model->columnCount( m_rootIndex ) ), m_model->rowCount( m_rootIndex ) ); m_cacheValid.fill( QVector< bool >( m_model->columnCount( m_rootIndex ), false ), m_model->rowCount( m_rootIndex ) ); Q_ASSERT( m_data.count() == m_model->rowCount( m_rootIndex ) ); Q_ASSERT( m_cacheValid.count() == m_model->rowCount( m_rootIndex ) ); } - void rowsInserted( const QModelIndex& parent, int start, int end ) Q_DECL_OVERRIDE + void rowsInserted( const QModelIndex& parent, int start, int end ) override { Q_ASSERT( m_model != nullptr ); Q_ASSERT( parent.model() == m_model || !parent.isValid() ); if ( parent != m_rootIndex || start >= m_model->rowCount(m_rootIndex) ) return; Q_ASSERT( start <= end ); Q_ASSERT( end - start + 1 <= m_model->rowCount(m_rootIndex) ); m_data.insert( start, end - start + 1, QVector< T >( m_model->columnCount( m_rootIndex ) ) ); m_cacheValid.insert( start, end - start + 1, QVector< bool >( m_model->columnCount( m_rootIndex ), false ) ); Q_ASSERT( m_data.count() == m_model->rowCount( m_rootIndex ) ); Q_ASSERT( m_cacheValid.count() == m_model->rowCount( m_rootIndex ) ); } - void rowsRemoved( const QModelIndex& parent, int start, int end ) Q_DECL_OVERRIDE + void rowsRemoved( const QModelIndex& parent, int start, int end ) override { Q_ASSERT( m_model != nullptr ); Q_ASSERT( parent.model() == m_model || !parent.isValid() ); if ( parent != m_rootIndex || start >= m_data.count() ) return; Q_ASSERT( start <= end ); m_data.remove( start, end - start + 1 ); m_cacheValid.remove( start, end - start + 1 ); Q_ASSERT( m_data.count() == m_model->rowCount( m_rootIndex ) ); Q_ASSERT( m_cacheValid.count() == m_model->rowCount( m_rootIndex ) ); } - void resetModel() Q_DECL_OVERRIDE + void resetModel() override { // no need to disconnect, this is a response to SIGNAL( destroyed() ) m_model = nullptr; modelReset(); } private: QAbstractItemModel* m_model; QModelIndex m_rootIndex; ModelDataCachePrivate::ModelSignalMapperConnector m_connector; mutable QVector< QVector< T > > m_data; mutable QVector< QVector< bool > > m_cacheValid; }; } #endif diff --git a/src/KChart/KChartTextArea.h b/src/KChart/KChartTextArea.h index ce05c05..2507d86 100644 --- a/src/KChart/KChartTextArea.h +++ b/src/KChart/KChartTextArea.h @@ -1,82 +1,82 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHART_TEXT_AREA_H #define KCHART_TEXT_AREA_H #include #include "KChartGlobal.h" #include "KChartAbstractAreaBase.h" #include "KChartLayoutItems.h" namespace KChart { /** * @class TextArea KChartTextArea.h * @brief A text area in the chart with a background, a frame, etc. * * TextArea is the base class for all text containing non-widget chart elements * that have a set of background attributes and frame attributes, such as * headers or footers. * * @note This class inherits AbstractAreaBase, TextLayoutItem, and QObject. * The reason for this triple inheritance is that neither AbstractAreaBase nor * TextLayoutItem inherit QObject. */ class KCHART_EXPORT TextArea : public QObject, public AbstractAreaBase, public TextLayoutItem { Q_OBJECT Q_DISABLE_COPY( TextArea ) KCHART_DECLARE_PRIVATE_DERIVED( TextArea ) public: virtual ~TextArea() ; // virtual TextArea * clone() const = 0; /** * @brief Draws the background and frame, then calls paint(). * * In most cases there is no need to overwrite this method in a derived * class, but you would overwrite TextLayoutItem::paint() instead. */ virtual void paintIntoRect( QPainter& painter, const QRect& rect ); /** * Call paintAll, if you want the background and the frame to be drawn * before the normal paint() is invoked automatically. */ - void paintAll( QPainter& painter ) Q_DECL_OVERRIDE; + void paintAll( QPainter& painter ) override; protected: TextArea(); - QRect areaGeometry() const Q_DECL_OVERRIDE; - void positionHasChanged() Q_DECL_OVERRIDE; + QRect areaGeometry() const override; + void positionHasChanged() override; Q_SIGNALS: void positionChanged( TextArea * ); //KCHART_DECLARE_PRIVATE_DERIVED(TextArea) }; // End of class TextArea } #endif // KCHART_TEXT_AREA_H diff --git a/src/KChart/KChartTextLabelCache.h b/src/KChart/KChartTextLabelCache.h index 49b9fad..c05cbaf 100644 --- a/src/KChart/KChartTextLabelCache.h +++ b/src/KChart/KChartTextLabelCache.h @@ -1,145 +1,145 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTTEXTLABELCACHE_H #define KCHARTTEXTLABELCACHE_H #include #include #include #include #include "KChartEnums.h" /** * @brief base class for prerendered elements like labels, pixmaps, markers, etc. */ class PrerenderedElement { public: PrerenderedElement(); virtual ~PrerenderedElement() {} /** Returns the rendered element. If any of the properties have change, the element will be regenerated. */ virtual const QPixmap& pixmap() const = 0; /** Return the location of the reference point relatively to the pixmap's origin. */ virtual QPointF referencePointLocation( KChartEnums::PositionValue ) const = 0; /** Set the position of the element. */ void setPosition( const QPointF& position ); /** Get the position of the element. */ const QPointF& position() const; /** Set the reference point of the element. Every element has nine possible reference points (all compass directions, plus the center. */ void setReferencePoint( KChartEnums::PositionValue ); /** Get the reference point of the element. */ KChartEnums::PositionValue referencePoint() const; protected: /** invalidate() needs to be called if any of the properties that determine the visual appearance of the prerendered element change. It can be called for a const object, as objects may need to force recalculation of the pixmap. */ virtual void invalidate() const = 0; private: QPointF m_position; KChartEnums::PositionValue m_referencePoint; }; /** @brief PrerenderedLabel is an internal KChart class that simplifies creation and caching of cached text labels. It provides referenze points to anchor the text to other elements. Reference points use the positions defined in KChartEnums. Usage:
     qreal angle = 90.0;
     CachedLabel label;
     label.paint( font, tr("Label"), angle );
     
*/ // FIXME this is merely a prototype // FIXME caching could be done by a second layer that can be used to, // e.g., query for a prerendered element by id or name, or by changing // the pixmap() method to do lazy evaluation. class PrerenderedLabel : public PrerenderedElement { public: PrerenderedLabel(); ~PrerenderedLabel(); void setFont( const QFont& font ); const QFont& font() const; void setText( const QString& text ); const QString& text() const; void setBrush( const QBrush& brush ); const QBrush& brush() const; void setPen( const QPen& ); const QPen& pen() const; void setAngle( qreal angle ); qreal angle() const; // reimpl PrerenderedElement: - const QPixmap& pixmap() const Q_DECL_OVERRIDE; - QPointF referencePointLocation( KChartEnums::PositionValue position ) const Q_DECL_OVERRIDE; + const QPixmap& pixmap() const override; + QPointF referencePointLocation( KChartEnums::PositionValue position ) const override; // overload: return location of referencePoint(): QPointF referencePointLocation() const; protected: - void invalidate() const Q_DECL_OVERRIDE; + void invalidate() const override; private: /** Create a label with the given text and the given rotation angle. Needs to be const, otherwise the pixmap() method cannot update when needed. */ void paint() const; // store the settings (these are used for the painting): mutable bool m_dirty; QFont m_font; QString m_text; QBrush m_brush; QPen m_pen; qreal m_angle; // these are valid once the label has been rendered: mutable QPixmap m_pixmap; mutable QPointF m_referenceBottomLeft; mutable QPointF m_textBaseLineVector; mutable QPointF m_textAscendVector; }; #endif diff --git a/src/KChart/Polar/KChartAbstractPolarDiagram_p.h b/src/KChart/Polar/KChartAbstractPolarDiagram_p.h index 679ddc2..bebd6eb 100644 --- a/src/KChart/Polar/KChartAbstractPolarDiagram_p.h +++ b/src/KChart/Polar/KChartAbstractPolarDiagram_p.h @@ -1,92 +1,92 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTABSTRACTPOLARDIAGRAM_P_H #define KCHARTABSTRACTPOLARDIAGRAM_P_H // // W A R N I N G // ------------- // // This file is not part of the KD Chart API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include "KChartAbstractPolarDiagram.h" #include "KChartAbstractDiagram_p.h" #include #include "KChartMath_p.h" namespace KChart { class PolarCoordinatePlane; /** * \internal */ class Q_DECL_HIDDEN AbstractPolarDiagram::Private : public AbstractDiagram::Private { friend class AbstractPolarDiagram; public: Private(); ~Private(); Private( const Private& rhs ) : AbstractDiagram::Private( rhs ), granularity( 0 ) { // just for consistency } /** \reimpl */ // FIXME: Optimize when needed - qreal calcPercentValue( const QModelIndex & index ) const Q_DECL_OVERRIDE + qreal calcPercentValue( const QModelIndex & index ) const override { Q_ASSERT( index.isValid() ); qreal sum = 0.0; for ( int row = 0; row < attributesModel->rowCount( QModelIndex() ); row++ ) sum += attributesModel->data( attributesModel->index( row, index.column(), QModelIndex() ) ).toReal(); // checked if ( sum == 0.0 ) return 0.0; return attributesModel->data( attributesModel->mapFromSource( index ) ).toReal() / sum * 100.0; } private: qreal granularity; }; KCHART_IMPL_DERIVED_DIAGRAM( AbstractPolarDiagram, AbstractDiagram, PolarCoordinatePlane ) /* inline AbstractPolarDiagram::AbstractPolarDiagram( Private * p ) : AbstractDiagram( p ) { init(); } inline AbstractPolarDiagram::AbstractPolarDiagram( Private *p, QWidget* parent, PolarCoordinatePlane* plane ) : AbstractDiagram( p, parent, plane ) { init(); } inline AbstractPolarDiagram::Private * AbstractPolarDiagram::d_func() { return static_cast( AbstractDiagram::d_func() ); } inline const AbstractPolarDiagram::Private * AbstractPolarDiagram::d_func() const { return static_cast( AbstractDiagram::d_func() ); } */ } #endif /* KCHARTABSTRACTCARTESIANDIAGRAM_P_H */ diff --git a/src/KChart/Polar/KChartPieDiagram.h b/src/KChart/Polar/KChartPieDiagram.h index 7cb6634..e4b1105 100644 --- a/src/KChart/Polar/KChartPieDiagram.h +++ b/src/KChart/Polar/KChartPieDiagram.h @@ -1,123 +1,123 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTPIEDIAGRAM_H #define KCHARTPIEDIAGRAM_H #include "KChartAbstractPieDiagram.h" namespace KChart { class LabelPaintCache; /** * @brief PieDiagram defines a common pie diagram */ class KCHART_EXPORT PieDiagram : public AbstractPieDiagram { Q_OBJECT Q_DISABLE_COPY( PieDiagram ) KCHART_DECLARE_DERIVED_DIAGRAM( PieDiagram, PolarCoordinatePlane ) public: explicit PieDiagram( QWidget* parent = nullptr, PolarCoordinatePlane* plane = nullptr ); virtual ~PieDiagram(); protected: // Implement AbstractDiagram /** \reimpl */ - void paint( PaintContext* paintContext ) Q_DECL_OVERRIDE; + void paint( PaintContext* paintContext ) override; public: /** * Describes which decorations are painted around data labels. */ enum LabelDecoration { NoDecoration = 0, ///< No decoration FrameDecoration = 1, ///< A rectangular frame is painted around the label text LineFromSliceDecoration = 2 ///< A line is drawn from the pie slice to its label }; Q_DECLARE_FLAGS( LabelDecorations, LabelDecoration ) /// Set the decorations to be painted around data labels according to @p decorations. void setLabelDecorations( LabelDecorations decorations ); /// Return the decorations to be painted around data labels. LabelDecorations labelDecorations() const; /// If @p enabled is set to true, labels that would overlap will be shuffled to avoid overlap. /// \note Collision avoidance may allow labels to be closer than AbstractDiagram with /// allowOverlappingDataValueTexts() == false, so you should usually also call /// setAllowOverlappingDataValueTexts( true ) if you enable this feature. void setLabelCollisionAvoidanceEnabled( bool enabled ); /// Return whether overlapping labels will be moved to until they don't overlap anymore. bool isLabelCollisionAvoidanceEnabled() const; /** \reimpl */ - void resize ( const QSizeF& area ) Q_DECL_OVERRIDE; + void resize ( const QSizeF& area ) override; // Implement AbstractPolarDiagram /** \reimpl */ - qreal valueTotals () const Q_DECL_OVERRIDE; + qreal valueTotals () const override; /** \reimpl */ - qreal numberOfValuesPerDataset() const Q_DECL_OVERRIDE; + qreal numberOfValuesPerDataset() const override; /** \reimpl */ - qreal numberOfGridRings() const Q_DECL_OVERRIDE; + qreal numberOfGridRings() const override; virtual PieDiagram * clone() const; protected: /** \reimpl */ - const QPair calculateDataBoundaries() const Q_DECL_OVERRIDE; - void paintEvent( QPaintEvent* ) Q_DECL_OVERRIDE; - void resizeEvent( QResizeEvent* ) Q_DECL_OVERRIDE; + const QPair calculateDataBoundaries() const override; + void paintEvent( QPaintEvent* ) override; + void resizeEvent( QResizeEvent* ) override; private: // ### move to private class? void placeLabels( PaintContext* paintContext ); // Solve problems with label overlap by changing label positions inside d->labelPaintCache. void shuffleLabels( QRectF* textBoundingRect ); void paintInternal( PaintContext* paintContext ); void drawSlice( QPainter* painter, const QRectF& drawPosition, uint slice ); void drawSliceSurface( QPainter* painter, const QRectF& drawPosition, uint slice ); void addSliceLabel( LabelPaintCache* lpc, const QRectF& drawPosition, uint slice ); void draw3DEffect( QPainter* painter, const QRectF& drawPosition, uint slice ); void draw3dCutSurface( QPainter* painter, const QRectF& rect, qreal threeDHeight, qreal angle ); void draw3dOuterRim( QPainter* painter, const QRectF& rect, qreal threeDHeight, qreal startAngle, qreal endAngle ); void calcSliceAngles(); void calcPieSize( const QRectF &contentsRect ); QRectF twoDPieRect( const QRectF &contentsRect, const ThreeDPieAttributes& threeDAttrs ) const; QRectF explodedDrawPosition( const QRectF& drawPosition, uint slice ) const; uint findSliceAt( qreal angle, int columnCount ); uint findLeftSlice( uint slice, int columnCount ); uint findRightSlice( uint slice, int columnCount ); QPointF pointOnEllipse( const QRectF& boundingBox, qreal angle ); }; // End of class KChartPieDiagram Q_DECLARE_OPERATORS_FOR_FLAGS( PieDiagram::LabelDecorations ) } #endif // KCHARTPIEDIAGRAM_H diff --git a/src/KChart/Polar/KChartPolarCoordinatePlane.h b/src/KChart/Polar/KChartPolarCoordinatePlane.h index 922344e..2a14243 100644 --- a/src/KChart/Polar/KChartPolarCoordinatePlane.h +++ b/src/KChart/Polar/KChartPolarCoordinatePlane.h @@ -1,164 +1,164 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHART_POLAR_COORDINATEPLANE_H #define KCHART_POLAR_COORDINATEPLANE_H #include "KChartAbstractCoordinatePlane.h" namespace KChart { class Chart; class PaintContext; /** * @brief Polar coordinate plane */ class KCHART_EXPORT PolarCoordinatePlane : public AbstractCoordinatePlane { Q_OBJECT Q_DISABLE_COPY( PolarCoordinatePlane ) KCHART_DECLARE_PRIVATE_DERIVED_PARENT( PolarCoordinatePlane, Chart* ) public: struct CoordinateTransformation; typedef QList CoordinateTransformationList; explicit PolarCoordinatePlane ( Chart* parent = nullptr ); ~PolarCoordinatePlane(); - void addDiagram ( AbstractDiagram* diagram ) Q_DECL_OVERRIDE; + void addDiagram ( AbstractDiagram* diagram ) override; - const QPointF translate ( const QPointF& diagramPoint ) const Q_DECL_OVERRIDE; + const QPointF translate ( const QPointF& diagramPoint ) const override; const QPointF translatePolar ( const QPointF& diagramPoint ) const; /** \brief Specify the rotation of the coordinate plane. * * In a pie diagram this indicates the position where the first pie starts, * in a polar diagram it specifies the Zero position of the circular axis: * * \image html polar-plane-start-position.png "Illustration of \"start position\" property" * * \sa startPosition */ void setStartPosition( qreal degrees ); /** Retrieve the rotation of the coordinate plane. * \sa setStartPosition */ qreal startPosition() const; - qreal zoomFactorX() const Q_DECL_OVERRIDE; - qreal zoomFactorY() const Q_DECL_OVERRIDE; + qreal zoomFactorX() const override; + qreal zoomFactorY() const override; - void setZoomFactors( qreal factorX, qreal factorY ) Q_DECL_OVERRIDE; - void setZoomFactorX( qreal factor ) Q_DECL_OVERRIDE; - void setZoomFactorY( qreal factor ) Q_DECL_OVERRIDE; + void setZoomFactors( qreal factorX, qreal factorY ) override; + void setZoomFactorX( qreal factor ) override; + void setZoomFactorY( qreal factor ) override; - QPointF zoomCenter() const Q_DECL_OVERRIDE; + QPointF zoomCenter() const override; - void setZoomCenter( const QPointF& center ) Q_DECL_OVERRIDE; + void setZoomCenter( const QPointF& center ) override; /** * Set the attributes to be used for grid lines drawn in circular * direction (or in sagittal direction, resp.). * * To disable circular grid painting, for example, your code should like this: * \code * GridAttributes ga = plane->gridAttributes( bool ); * ga.setGridVisible( false ); * plane-setGridAttributes( bool, ga ); * \endcode * * \note setGridAttributes overwrites the global attributes that * were set by AbstractCoordinatePlane::setGlobalGridAttributes. * To re-activate these global attributes you can call * resetGridAttributes. * * \sa resetGridAttributes, gridAttributes * \sa AbstractCoordinatePlane::setGlobalGridAttributes * \sa hasOwnGridAttributes */ void setGridAttributes( bool circular, const GridAttributes & ); /** * Reset the attributes to be used for grid lines drawn in circular * direction (or in sagittal direction, resp.). * By calling this method you specify that the global attributes set by * AbstractCoordinatePlane::setGlobalGridAttributes be used. * * \sa setGridAttributes, gridAttributes * \sa AbstractCoordinatePlane::globalGridAttributes * \sa hasOwnGridAttributes */ void resetGridAttributes( bool circular ); /** * \return The attributes used for grid lines drawn in circular * direction (or in sagittal direction, resp.). * * \note This function always returns a valid set of grid attributes: * If no special grid attributes were set for this direction * the global attributes are returned, as returned by * AbstractCoordinatePlane::globalGridAttributes. * * \sa setGridAttributes * \sa resetGridAttributes * \sa AbstractCoordinatePlane::globalGridAttributes * \sa hasOwnGridAttributes */ const GridAttributes gridAttributes( bool circular ) const; /** * \return Returns whether the grid attributes have been set for the * respective direction via setGridAttributes( bool circular ). * * If false, the grid will use the global attributes set * by AbstractCoordinatePlane::globalGridAttributes (or the default * attributes, resp.) * * \sa setGridAttributes * \sa resetGridAttributes * \sa AbstractCoordinatePlane::globalGridAttributes */ bool hasOwnGridAttributes( bool circular ) const; qreal angleUnit() const; qreal radiusUnit() const; /** reimpl */ - void paint( QPainter* ) Q_DECL_OVERRIDE; + void paint( QPainter* ) override; protected: - DataDimensionsList getDataDimensionsList() const Q_DECL_OVERRIDE; + DataDimensionsList getDataDimensionsList() const override; void paintEvent ( QPaintEvent* ); void resizeEvent ( QResizeEvent* ); - void layoutDiagrams() Q_DECL_OVERRIDE; + void layoutDiagrams() override; protected Q_SLOTS: void slotLayoutChanged( AbstractDiagram* diagram ); void adjustZoomAndRepaint(); private: void setHasOwnGridAttributes( bool circular, bool on ); }; } #endif diff --git a/src/KChart/Polar/KChartPolarCoordinatePlane_p.h b/src/KChart/Polar/KChartPolarCoordinatePlane_p.h index fdb8fac..90aa78f 100644 --- a/src/KChart/Polar/KChartPolarCoordinatePlane_p.h +++ b/src/KChart/Polar/KChartPolarCoordinatePlane_p.h @@ -1,138 +1,138 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTPOLARCOORDINATEPLANE_P_H #define KCHARTPOLARCOORDINATEPLANE_P_H // // W A R N I N G // ------------- // // This file is not part of the KD Chart API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include "KChartAbstractCoordinatePlane_p.h" #include "KChartZoomParameters.h" #include "KChartPolarGrid.h" #include "KChartMath_p.h" namespace KChart { /** * \internal */ struct PolarCoordinatePlane::CoordinateTransformation { // represents the distance of the diagram coordinate origin to the // origin of the coordinate plane space: QPointF originTranslation; qreal radiusUnit; qreal angleUnit; qreal minValue; qreal startPosition; ZoomParameters zoom; static QPointF polarToCartesian( qreal R, qreal theta ) { // de-inline me return QPointF( R * cos( DEGTORAD( theta ) ), R * sin( DEGTORAD( theta ) ) ); } inline const QPointF translate( const QPointF& diagramPoint ) const { // ### de-inline me // calculate the polar coordinates const qreal x = (diagramPoint.x() * radiusUnit) - (minValue * radiusUnit); //qDebug() << x << "=" << diagramPoint.x() << "*" << radiusUnit << " startPosition: " << startPosition; const qreal y = ( diagramPoint.y() * -angleUnit) - 90.0 - startPosition; // convert to cartesian coordinates QPointF cartesianPoint = polarToCartesian( x, y ); cartesianPoint.setX( cartesianPoint.x() * zoom.xFactor ); cartesianPoint.setY( cartesianPoint.y() * zoom.yFactor ); QPointF newOrigin = originTranslation; qreal minOrigin = qMin( newOrigin.x(), newOrigin.y() ); newOrigin.setX( newOrigin.x() + minOrigin * ( 1 - zoom.xCenter * 2 ) * zoom.xFactor ); newOrigin.setY( newOrigin.y() + minOrigin * ( 1 - zoom.yCenter * 2 ) * zoom.yFactor ); return newOrigin + cartesianPoint; } inline const QPointF translatePolar( const QPointF& diagramPoint ) const { // ### de-inline me return QPointF( diagramPoint.x() * angleUnit, diagramPoint.y() * radiusUnit ); } }; class Q_DECL_HIDDEN PolarCoordinatePlane::Private : public AbstractCoordinatePlane::Private { friend class PolarCoordinatePlane; public: explicit Private() : currentTransformation(nullptr) , initialResizeEventReceived(false ) , hasOwnGridAttributesCircular ( false ) , hasOwnGridAttributesSagittal ( false ) {} virtual ~Private() { } - void initialize() Q_DECL_OVERRIDE + void initialize() override { grid = new PolarGrid(); } static QRectF contentsRect( const PolarCoordinatePlane* plane ); // the coordinate plane will calculate coordinate transformations for all // diagrams and store them here: CoordinateTransformationList coordinateTransformations; // when painting, this pointer selects the coordinate transformation for // the current diagram: CoordinateTransformation* currentTransformation; // the reactangle occupied by the diagrams, in plane coordinates QRectF contentRect; // true after the first resize event came in bool initialResizeEventReceived; // true after setGridAttributes( Qt::Orientation ) was used, // false if resetGridAttributes( Qt::Orientation ) was called bool hasOwnGridAttributesCircular; bool hasOwnGridAttributesSagittal; GridAttributes gridAttributesCircular; GridAttributes gridAttributesSagittal; qreal newZoomX, newZoomY; }; KCHART_IMPL_DERIVED_PLANE(PolarCoordinatePlane, AbstractCoordinatePlane) } #endif /* KCHARTBARDIAGRAM_P_H */ diff --git a/src/KChart/Polar/KChartPolarDiagram.h b/src/KChart/Polar/KChartPolarDiagram.h index ab04201..cdc9e61 100644 --- a/src/KChart/Polar/KChartPolarDiagram.h +++ b/src/KChart/Polar/KChartPolarDiagram.h @@ -1,106 +1,106 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTPOLARDIAGRAM_H #define KCHARTPOLARDIAGRAM_H #include "KChartPosition.h" #include "KChartAbstractPolarDiagram.h" QT_BEGIN_NAMESPACE class QPolygonF; QT_END_NAMESPACE namespace KChart { /** * @brief PolarDiagram defines a common polar diagram */ class KCHART_EXPORT PolarDiagram : public AbstractPolarDiagram { Q_OBJECT Q_DISABLE_COPY( PolarDiagram ) KCHART_DECLARE_DERIVED_DIAGRAM( PolarDiagram, PolarCoordinatePlane ) public: explicit PolarDiagram( QWidget* parent = nullptr, PolarCoordinatePlane* plane = nullptr ); virtual ~PolarDiagram(); protected: // Implement AbstractDiagram /** \reimpl */ - void paint ( PaintContext* paintContext ) Q_DECL_OVERRIDE; + void paint ( PaintContext* paintContext ) override; public: /** \reimpl */ - void resize ( const QSizeF& area ) Q_DECL_OVERRIDE; + void resize ( const QSizeF& area ) override; // Implement AbstractPolarDiagram /** \reimpl */ - qreal valueTotals () const Q_DECL_OVERRIDE; + qreal valueTotals () const override; /** \reimpl */ - qreal numberOfValuesPerDataset() const Q_DECL_OVERRIDE; + qreal numberOfValuesPerDataset() const override; /** \reimpl */ - qreal numberOfGridRings() const Q_DECL_OVERRIDE; + qreal numberOfGridRings() const override; virtual PolarDiagram * clone() const; /** \deprecated Use PolarCoordinatePlane::setStartPosition( qreal degrees ) instead. */ void setZeroDegreePosition( int degrees ); /** \deprecated Use qreal PolarCoordinatePlane::startPosition instead. */ int zeroDegreePosition() const; void setRotateCircularLabels( bool rotateCircularLabels ); bool rotateCircularLabels() const; /** Close each of the data series by connecting the last point to its * respective start point */ void setCloseDatasets( bool closeDatasets ); bool closeDatasets() const; void setShowDelimitersAtPosition( Position position, bool showDelimiters ); void setShowLabelsAtPosition( Position position, bool showLabels ); bool showDelimitersAtPosition( Position position ) const; bool showLabelsAtPosition( Position position ) const; virtual void paint ( PaintContext* paintContext, bool calculateListAndReturnScale, qreal& newZoomX, qreal& newZoomY ); // KChart 3: references -> pointers protected: /** \reimpl */ - const QPair calculateDataBoundaries() const Q_DECL_OVERRIDE; - void paintEvent ( QPaintEvent* ) Q_DECL_OVERRIDE; - void resizeEvent ( QResizeEvent* ) Q_DECL_OVERRIDE; + const QPair calculateDataBoundaries() const override; + void paintEvent ( QPaintEvent* ) override; + void resizeEvent ( QResizeEvent* ) override; virtual void paintPolarMarkers( PaintContext* ctx, const QPolygonF& polygon ); }; // End of class PolarDiagram } #endif // KCHARTPOLARDIAGRAM_H diff --git a/src/KChart/Polar/KChartPolarGrid.h b/src/KChart/Polar/KChartPolarGrid.h index 5afe783..5b5bba7 100644 --- a/src/KChart/Polar/KChartPolarGrid.h +++ b/src/KChart/Polar/KChartPolarGrid.h @@ -1,56 +1,56 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTPOLARGrid_H #define KCHARTPOLARGrid_H #include "KChartPolarCoordinatePlane.h" #include "KChartAbstractGrid.h" namespace KChart { class PaintContext; class PolarCoordinatePlane; /** * \internal * * \brief Class for the grid in a polar plane. * * The PolarGrid interface is used * for calculating and for drawing * the sagittal grid lines, and the circular grid lines * of a polar coordinate plane. */ class PolarGrid : public AbstractGrid { public: PolarGrid() : AbstractGrid() {} virtual ~PolarGrid() {} - void drawGrid( PaintContext* context ) Q_DECL_OVERRIDE; + void drawGrid( PaintContext* context ) override; private: DataDimensionsList calculateGrid( - const DataDimensionsList& rawDataDimensions ) const Q_DECL_OVERRIDE; + const DataDimensionsList& rawDataDimensions ) const override; }; } #endif diff --git a/src/KChart/Polar/KChartRadarCoordinatePlane_p.h b/src/KChart/Polar/KChartRadarCoordinatePlane_p.h index 73a861e..2c95854 100644 --- a/src/KChart/Polar/KChartRadarCoordinatePlane_p.h +++ b/src/KChart/Polar/KChartRadarCoordinatePlane_p.h @@ -1,61 +1,61 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTRADARCOORDINATEPLANE_P_H #define KCHARTRADARCOORDINATEPLANE_P_H // // W A R N I N G // ------------- // // This file is not part of the KD Chart API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include "KChartPolarCoordinatePlane_p.h" #include "KChartRadarCoordinatePlane.h" #include "KChartRadarGrid.h" namespace KChart { class Q_DECL_HIDDEN RadarCoordinatePlane::Private : public PolarCoordinatePlane::Private { friend class RadarCoordinatePlane; public: explicit Private() { } virtual ~Private() { } TextAttributes textAttributes; - void initialize() Q_DECL_OVERRIDE + void initialize() override { grid = new RadarGrid(); } }; KCHART_IMPL_DERIVED_PLANE(RadarCoordinatePlane, PolarCoordinatePlane) } #endif /* KCHARTBARDIAGRAM_P_H */ diff --git a/src/KChart/Polar/KChartRadarDiagram.h b/src/KChart/Polar/KChartRadarDiagram.h index 5203683..ba4b4ff 100644 --- a/src/KChart/Polar/KChartRadarDiagram.h +++ b/src/KChart/Polar/KChartRadarDiagram.h @@ -1,98 +1,98 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTRADARDIAGRAM_H #define KCHARTRADARDIAGRAM_H #include "KChartPosition.h" #include "KChartPolarDiagram.h" #include "KChartRadarCoordinatePlane.h" QT_BEGIN_NAMESPACE class QPolygonF; QT_END_NAMESPACE namespace KChart { /** * @brief RadarDiagram defines a common radar diagram */ class KCHART_EXPORT RadarDiagram : public AbstractPolarDiagram { Q_OBJECT Q_DISABLE_COPY( RadarDiagram ) KCHART_DECLARE_DERIVED_DIAGRAM( RadarDiagram, RadarCoordinatePlane ) public: explicit RadarDiagram( QWidget* parent = nullptr, RadarCoordinatePlane* plane = nullptr ); virtual ~RadarDiagram(); virtual void paint ( PaintContext* paintContext, bool calculateListAndReturnScale, qreal& newZoomX, qreal& newZoomY ); /** \reimpl */ - void resize ( const QSizeF& area ) Q_DECL_OVERRIDE; + void resize ( const QSizeF& area ) override; /** \reimpl */ - qreal valueTotals () const Q_DECL_OVERRIDE; + qreal valueTotals () const override; /** \reimpl */ - qreal numberOfValuesPerDataset() const Q_DECL_OVERRIDE; + qreal numberOfValuesPerDataset() const override; /** \reimpl */ - qreal numberOfGridRings() const Q_DECL_OVERRIDE; + qreal numberOfGridRings() const override; /** * if val is true the diagram will mirror the diagram datapoints */ void setReverseData( bool val ); bool reverseData(); virtual RadarDiagram * clone() const; /** * Close each of the data series by connecting the last point to its * respective start point */ void setCloseDatasets( bool closeDatasets ); bool closeDatasets() const; /** * Fill the areas of the radar chart with there respective color defined * via KChart::DatasetBrushRole. The value defines the alpha of the * color to use. If set to 0.0 (the default) then the radar areas will * not be filled with any color. If set to 1.0 then the areas will be * solid filled and are not transparent. */ qreal fillAlpha() const; void setFillAlpha(qreal alphaF); protected: /** \reimpl */ - const QPair calculateDataBoundaries() const Q_DECL_OVERRIDE; - void paintEvent ( QPaintEvent* ) Q_DECL_OVERRIDE; - void resizeEvent ( QResizeEvent* ) Q_DECL_OVERRIDE; - void paint ( PaintContext* paintContext ) Q_DECL_OVERRIDE; + const QPair calculateDataBoundaries() const override; + void paintEvent ( QPaintEvent* ) override; + void resizeEvent ( QResizeEvent* ) override; + void paint ( PaintContext* paintContext ) override; }; // End of class RadarDiagram } #endif // KCHARTRADARDIAGRAM_H diff --git a/src/KChart/Polar/KChartRadarGrid.h b/src/KChart/Polar/KChartRadarGrid.h index 380880a..03ec6aa 100644 --- a/src/KChart/Polar/KChartRadarGrid.h +++ b/src/KChart/Polar/KChartRadarGrid.h @@ -1,56 +1,56 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTRADARGrid_H #define KCHARTRADARGrid_H //#include "KChartRadarCoordinatePlane.h" #include "KChartAbstractGrid.h" namespace KChart { class PaintContext; class RadarCoordinatePlane; /** * \internal * * \brief Class for the grid in a radar plane. * * The RadarGrid interface is used * for calculating and for drawing * the grid lines of a radar charts including "axis" * labels. */ class RadarGrid : public AbstractGrid { public: RadarGrid() : AbstractGrid() {} virtual ~RadarGrid() {} - void drawGrid( PaintContext* context ) Q_DECL_OVERRIDE; + void drawGrid( PaintContext* context ) override; private: DataDimensionsList calculateGrid( - const DataDimensionsList& rawDataDimensions ) const Q_DECL_OVERRIDE; + const DataDimensionsList& rawDataDimensions ) const override; }; } #endif diff --git a/src/KChart/Polar/KChartRingDiagram.h b/src/KChart/Polar/KChartRingDiagram.h index 84acf7d..8f6fbfd 100644 --- a/src/KChart/Polar/KChartRingDiagram.h +++ b/src/KChart/Polar/KChartRingDiagram.h @@ -1,89 +1,89 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTRINGDIAGRAM_H #define KCHARTRINGDIAGRAM_H #include "KChartAbstractPieDiagram.h" namespace KChart { /** * @brief RingDiagram defines a common ring diagram */ class KCHART_EXPORT RingDiagram : public AbstractPieDiagram { Q_OBJECT Q_DISABLE_COPY( RingDiagram ) KCHART_DECLARE_DERIVED_DIAGRAM( RingDiagram, PolarCoordinatePlane ) public: explicit RingDiagram( QWidget* parent = nullptr, PolarCoordinatePlane* plane = nullptr ); virtual ~RingDiagram(); protected: // Implement AbstractDiagram /** \reimpl */ - void paint( PaintContext* paintContext ) Q_DECL_OVERRIDE; + void paint( PaintContext* paintContext ) override; public: /** \reimpl */ - void resize( const QSizeF& area ) Q_DECL_OVERRIDE; + void resize( const QSizeF& area ) override; // Implement AbstractPolarDiagram /** \reimpl */ - qreal valueTotals() const Q_DECL_OVERRIDE; + qreal valueTotals() const override; /** \reimpl */ - qreal numberOfValuesPerDataset() const Q_DECL_OVERRIDE; - qreal numberOfDatasets() const Q_DECL_OVERRIDE; + qreal numberOfValuesPerDataset() const override; + qreal numberOfDatasets() const override; /** \reimpl */ - qreal numberOfGridRings() const Q_DECL_OVERRIDE; + qreal numberOfGridRings() const override; qreal valueTotals( int dataset ) const; virtual RingDiagram * clone() const; /** * Returns true if both diagrams have the same settings. */ bool compare( const RingDiagram* other ) const; void setRelativeThickness( bool relativeThickness ); bool relativeThickness() const; virtual void setExpandWhenExploded( bool expand ); virtual bool expandWhenExploded() const; protected: /** \reimpl */ - const QPair calculateDataBoundaries() const Q_DECL_OVERRIDE; - void paintEvent( QPaintEvent* ) Q_DECL_OVERRIDE; - void resizeEvent( QResizeEvent* ) Q_DECL_OVERRIDE; + const QPair calculateDataBoundaries() const override; + void paintEvent( QPaintEvent* ) override; + void resizeEvent( QResizeEvent* ) override; private: void drawOneSlice( QPainter* painter, uint dataset, uint slice, qreal granularity ); void drawPieSurface( QPainter* painter, uint dataset, uint slice, qreal granularity ); QPointF pointOnEllipse( const QRectF& rect, int dataset, int slice, bool outer, qreal angle, qreal totalGapFactor, qreal totalExplodeFactor ); }; // End of class RingDiagram } #endif // KCHARTRINGDIAGRAM_H diff --git a/src/KChart/Ternary/KChartAbstractTernaryDiagram.h b/src/KChart/Ternary/KChartAbstractTernaryDiagram.h index 9a18685..cdb1688 100644 --- a/src/KChart/Ternary/KChartAbstractTernaryDiagram.h +++ b/src/KChart/Ternary/KChartAbstractTernaryDiagram.h @@ -1,59 +1,59 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTABSTRACTTERNARYDIAGRAM_H #define KCHARTABSTRACTTERNARYDIAGRAM_H #include "KChartAbstractDiagram.h" #include "KChartTernaryAxis.h" namespace KChart { class TernaryCoordinatePlane; class TernaryAxis; /** * @brief Base class for diagrams based on a ternary coordinate plane. */ class KCHART_EXPORT AbstractTernaryDiagram : public AbstractDiagram { Q_OBJECT Q_DISABLE_COPY( AbstractTernaryDiagram ) KCHART_DECLARE_DERIVED_DIAGRAM( AbstractTernaryDiagram, TernaryCoordinatePlane ) public: explicit AbstractTernaryDiagram ( QWidget* parent = nullptr, TernaryCoordinatePlane* plane = nullptr ); virtual ~AbstractTernaryDiagram(); - void paint (PaintContext *paintContext) Q_DECL_OVERRIDE; + void paint (PaintContext *paintContext) override; virtual void addAxis( TernaryAxis* axis ); virtual void takeAxis( TernaryAxis* axis ); virtual TernaryAxisList axes () const; protected: - const QPair< QPointF, QPointF > calculateDataBoundaries () const Q_DECL_OVERRIDE = 0; + const QPair< QPointF, QPointF > calculateDataBoundaries () const override = 0; }; } #endif diff --git a/src/KChart/Ternary/KChartTernaryAxis.h b/src/KChart/Ternary/KChartTernaryAxis.h index b509031..e1dfd3e 100644 --- a/src/KChart/Ternary/KChartTernaryAxis.h +++ b/src/KChart/Ternary/KChartTernaryAxis.h @@ -1,93 +1,93 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTTERNARYAXIS_H #define KCHARTTERNARYAXIS_H #include #include #include class PrerenderedLabel; namespace KChart { class AbstractTernaryDiagram; /** * The class for ternary axes */ class KCHART_EXPORT TernaryAxis : public AbstractAxis { Q_OBJECT Q_DISABLE_COPY( TernaryAxis ) KCHART_DECLARE_PRIVATE_DERIVED_PARENT( TernaryAxis, AbstractDiagram* ) public: explicit TernaryAxis ( AbstractTernaryDiagram* diagram = nullptr ); ~TernaryAxis(); - void paintAll( QPainter &) Q_DECL_OVERRIDE; - void paint (QPainter *) Q_DECL_OVERRIDE; - void paintCtx (PaintContext *) Q_DECL_OVERRIDE; - - QRect geometry () const Q_DECL_OVERRIDE; - void setGeometry (const QRect &rect) Q_DECL_OVERRIDE; - - bool isEmpty () const Q_DECL_OVERRIDE; - QSize minimumSize () const Q_DECL_OVERRIDE; - QSize maximumSize () const Q_DECL_OVERRIDE; - QSize sizeHint () const Q_DECL_OVERRIDE; - Qt::Orientations expandingDirections () const Q_DECL_OVERRIDE; + void paintAll( QPainter &) override; + void paint (QPainter *) override; + void paintCtx (PaintContext *) override; + + QRect geometry () const override; + void setGeometry (const QRect &rect) override; + + bool isEmpty () const override; + QSize minimumSize () const override; + QSize maximumSize () const override; + QSize sizeHint () const override; + Qt::Orientations expandingDirections () const override; virtual const Position position () const; virtual void setPosition (Position p); void setTitleText( const QString& text ); QString titleText() const; void setTitleTextAttributes( const TextAttributes &a ); TextAttributes titleTextAttributes() const; void resetTitleTextAttributes(); bool hasDefaultTitleTextAttributes() const; QPair requiredMargins() const; private: void updatePrerenderedLabels(); // TODO, move class variables to private class QRect m_geometry; Position m_position; QString m_title; TextAttributes m_titleAttributes; // FIXME (Mirko): Move axis labels from grid to here, do not // expose them, just paint them. Use title text for text. Make // a function to allow the coordinate plane to calculate the // necessary margins, like this: PrerenderedLabel* m_label; PrerenderedLabel* m_fifty; }; typedef QList TernaryAxisList; } #endif diff --git a/src/KChart/Ternary/KChartTernaryCoordinatePlane.h b/src/KChart/Ternary/KChartTernaryCoordinatePlane.h index 08e1da2..6956e32 100644 --- a/src/KChart/Ternary/KChartTernaryCoordinatePlane.h +++ b/src/KChart/Ternary/KChartTernaryCoordinatePlane.h @@ -1,63 +1,63 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTTERNARYCOORDINATEPLANE_H #define KCHARTTERNARYCOORDINATEPLANE_H #include "KChartAbstractCoordinatePlane.h" namespace KChart { class TernaryGrid; /** * @brief Ternary coordinate plane */ class KCHART_EXPORT TernaryCoordinatePlane : public AbstractCoordinatePlane { Q_OBJECT Q_DISABLE_COPY( TernaryCoordinatePlane ) KCHART_DECLARE_PRIVATE_DERIVED_PARENT( TernaryCoordinatePlane, Chart* ) public: explicit TernaryCoordinatePlane( Chart* parent = nullptr ); ~TernaryCoordinatePlane(); - void addDiagram( AbstractDiagram* diagram ) Q_DECL_OVERRIDE; + void addDiagram( AbstractDiagram* diagram ) override; - void layoutDiagrams() Q_DECL_OVERRIDE; + void layoutDiagrams() override; - const QPointF translate ( const QPointF& diagramPoint ) const Q_DECL_OVERRIDE; + const QPointF translate ( const QPointF& diagramPoint ) const override; - void paint( QPainter* ) Q_DECL_OVERRIDE; - DataDimensionsList getDataDimensionsList() const Q_DECL_OVERRIDE; + void paint( QPainter* ) override; + DataDimensionsList getDataDimensionsList() const override; /** \reimpl */ QSize minimumSizeHint() const; /** \reimpl */ QSizePolicy sizePolicy() const; private: TernaryGrid* grid() const; }; } #endif diff --git a/src/KChart/Ternary/KChartTernaryCoordinatePlane_p.h b/src/KChart/Ternary/KChartTernaryCoordinatePlane_p.h index afb3364..f0ce79f 100644 --- a/src/KChart/Ternary/KChartTernaryCoordinatePlane_p.h +++ b/src/KChart/Ternary/KChartTernaryCoordinatePlane_p.h @@ -1,87 +1,87 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTTERNARYCOORDINATEPLANE_P_H #define KCHARTTERNARYCOORDINATEPLANE_P_H // // W A R N I N G // ------------- // // This file is not part of the KD Chart API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include "KChartTernaryCoordinatePlane.h" #include "KChartTernaryGrid.h" #include "KChartAbstractCoordinatePlane_p.h" #include "KChartMath_p.h" #include namespace KChart { class TernaryAxis; /** * \internal */ class Q_DECL_HIDDEN TernaryCoordinatePlane::Private : public AbstractCoordinatePlane::Private { friend class TernaryCoordinatePlane; public: explicit Private(); virtual ~Private() { // grid is delete in base class dtor } - void initialize() Q_DECL_OVERRIDE + void initialize() override { grid = new TernaryGrid(); xUnit = 0.0; yUnit = 0.0; } QList axes; TextAttributes labelAttributes; // the diagram is drawn within this rectangle, which is within // this widget: QRectF diagramRectContainer; // this is the "frame" of the plot area QRectF diagramRect; // multiply m_xUnit with a [0..1] value to get an isometric // widget coordinate qreal xUnit; // same for y: qreal yUnit; }; KCHART_IMPL_DERIVED_PLANE(TernaryCoordinatePlane, AbstractCoordinatePlane) } #endif /* KCHARTTERNARYCOORDINATEPLANE_P_H */ diff --git a/src/KChart/Ternary/KChartTernaryGrid.h b/src/KChart/Ternary/KChartTernaryGrid.h index 391c145..2cc2498 100644 --- a/src/KChart/Ternary/KChartTernaryGrid.h +++ b/src/KChart/Ternary/KChartTernaryGrid.h @@ -1,73 +1,73 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTTERNARYGRID_H #define KCHARTTERNARYGRID_H #include #include "KChartAbstractGrid.h" #include "KChartTextLabelCache.h" namespace KChart { struct TickInfo { TickInfo( qreal percentage = 0, int depth = 0 ); qreal percentage; int depth; }; bool operator==(const TickInfo&, const TickInfo& ); class PaintContext; // VERIFY: Grids are not public API, are they? class TernaryGrid : public AbstractGrid { public: TernaryGrid(); virtual ~TernaryGrid(); - void drawGrid( PaintContext* context ) Q_DECL_OVERRIDE; - DataDimensionsList calculateGrid( const DataDimensionsList& rawDataDimensions ) const Q_DECL_OVERRIDE; + void drawGrid( PaintContext* context ) override; + DataDimensionsList calculateGrid( const DataDimensionsList& rawDataDimensions ) const override; /** Returns two QSizeF objects specifying the dimension of the margins needed between each corner of the diagram and the border of the drawing area. Margins are required because the tick marks are placed outside of the trianges containing rectangle. The margins are returned in diagram coordinates, since the grid does not know about widget coordinates. */ QPair requiredMargins() const; /** Return the locations of the grid lines, so that axes can draw axis rulers at the correct positions. This information is valid after the grid has been painted (that is, the axes need to be painted after the grid. */ const QVector& tickInfo() const; private: QVector m_tickInfo; // QList m_labels; }; } #endif diff --git a/src/KChart/Ternary/KChartTernaryLineDiagram.h b/src/KChart/Ternary/KChartTernaryLineDiagram.h index 3eb7db3..65b2a4f 100644 --- a/src/KChart/Ternary/KChartTernaryLineDiagram.h +++ b/src/KChart/Ternary/KChartTernaryLineDiagram.h @@ -1,51 +1,51 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTTERNARYLINEDIAGRAM_H #define KCHARTTERNARYLINEDIAGRAM_H #include "KChartTernaryCoordinatePlane.h" #include "KChartAbstractTernaryDiagram.h" namespace KChart { /** * @brief A TernaryLineDiagram is a line diagram with a ternary coordinate plane */ class KCHART_EXPORT TernaryLineDiagram : public AbstractTernaryDiagram { Q_OBJECT Q_DISABLE_COPY( TernaryLineDiagram ) KCHART_DECLARE_DERIVED_DIAGRAM( TernaryLineDiagram, TernaryCoordinatePlane ) public: explicit TernaryLineDiagram ( QWidget* parent = nullptr, TernaryCoordinatePlane* plane = nullptr ); virtual ~TernaryLineDiagram(); - void resize (const QSizeF &area) Q_DECL_OVERRIDE; - void paint (PaintContext *paintContext) Q_DECL_OVERRIDE; + void resize (const QSizeF &area) override; + void paint (PaintContext *paintContext) override; protected: - const QPair< QPointF, QPointF > calculateDataBoundaries () const Q_DECL_OVERRIDE; + const QPair< QPointF, QPointF > calculateDataBoundaries () const override; }; } #endif diff --git a/src/KChart/Ternary/KChartTernaryPointDiagram.h b/src/KChart/Ternary/KChartTernaryPointDiagram.h index 95e5872..3f98732 100644 --- a/src/KChart/Ternary/KChartTernaryPointDiagram.h +++ b/src/KChart/Ternary/KChartTernaryPointDiagram.h @@ -1,50 +1,50 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KD Chart library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KCHARTTERNARYPOINTDIAGRAM_H #define KCHARTTERNARYPOINTDIAGRAM_H #include "KChartTernaryCoordinatePlane.h" #include "KChartAbstractTernaryDiagram.h" namespace KChart { /** * @brief A TernaryPointDiagram is a point diagram within a ternary coordinate plane */ class KCHART_EXPORT TernaryPointDiagram : public AbstractTernaryDiagram { Q_OBJECT Q_DISABLE_COPY( TernaryPointDiagram ) KCHART_DECLARE_DERIVED_DIAGRAM( TernaryPointDiagram, TernaryCoordinatePlane ) public: explicit TernaryPointDiagram ( QWidget* parent = nullptr, TernaryCoordinatePlane* plane = nullptr ); virtual ~TernaryPointDiagram(); - void resize (const QSizeF &area) Q_DECL_OVERRIDE; - void paint (PaintContext *paintContext) Q_DECL_OVERRIDE; + void resize (const QSizeF &area) override; + void paint (PaintContext *paintContext) override; protected: - const QPair< QPointF, QPointF > calculateDataBoundaries () const Q_DECL_OVERRIDE; + const QPair< QPointF, QPointF > calculateDataBoundaries () const override; }; } #endif diff --git a/src/KGantt/kganttconstraintgraphicsitem.h b/src/KGantt/kganttconstraintgraphicsitem.h index 6b7ad05..9685f71 100644 --- a/src/KGantt/kganttconstraintgraphicsitem.h +++ b/src/KGantt/kganttconstraintgraphicsitem.h @@ -1,64 +1,64 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KGantt library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KGANTTCONSTRAINTGRAPHICSITEM_H #define KGANTTCONSTRAINTGRAPHICSITEM_H #include #include "kganttconstraint.h" namespace KGantt { class GraphicsScene; class KGANTT_EXPORT ConstraintGraphicsItem : public QGraphicsItem { public: enum { Type = UserType + 43 }; explicit ConstraintGraphicsItem( const Constraint& c, QGraphicsItem* parent = nullptr, GraphicsScene* scene = nullptr ); virtual ~ConstraintGraphicsItem(); - /*reimp*/ int type() const Q_DECL_OVERRIDE; + /*reimp*/ int type() const override; /*reimp (non virtual)*/GraphicsScene* scene() const; /*reimp*/ QString ganttToolTip() const; - /*reimp*/ QRectF boundingRect() const Q_DECL_OVERRIDE; + /*reimp*/ QRectF boundingRect() const override; /*reimp*/ void paint( QPainter* painter, const QStyleOptionGraphicsItem* option, - QWidget* widget = nullptr ) Q_DECL_OVERRIDE; + QWidget* widget = nullptr ) override; inline const Constraint& constraint() const { return m_constraint; } Constraint proxyConstraint() const; void setStart( const QPointF& start ); inline QPointF start() const { return m_start; } void setEnd( const QPointF& end ); inline QPointF end() const { return m_end; } void updateItem( const QPointF& start,const QPointF& end ); private: Constraint m_constraint; QPointF m_start; QPointF m_end; }; } #endif /* KGANTTCONSTRAINTGRAPHICSITEM_H */ diff --git a/src/KGantt/kganttdatetimegrid.cpp b/src/KGantt/kganttdatetimegrid.cpp index 46c48ab..8ce6ffc 100644 --- a/src/KGantt/kganttdatetimegrid.cpp +++ b/src/KGantt/kganttdatetimegrid.cpp @@ -1,1396 +1,1396 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KGantt library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "kganttdatetimegrid.h" #include "kganttdatetimegrid_p.h" #include "kganttabstractrowcontroller.h" #include #include #include #include #include #include #include #include #include #include using namespace KGantt; QDebug operator<<( QDebug dbg, KGantt::DateTimeScaleFormatter::Range range ) { switch ( range ) { case KGantt::DateTimeScaleFormatter::Second: dbg << "KGantt::DateTimeScaleFormatter::Second"; break; case KGantt::DateTimeScaleFormatter::Minute: dbg << "KGantt::DateTimeScaleFormatter::Minute"; break; case KGantt::DateTimeScaleFormatter::Hour: dbg << "KGantt::DateTimeScaleFormatter::Hour"; break; case KGantt::DateTimeScaleFormatter::Day: dbg << "KGantt::DateTimeScaleFormatter::Day"; break; case KGantt::DateTimeScaleFormatter::Week: dbg << "KGantt::DateTimeScaleFormatter::Week"; break; case KGantt::DateTimeScaleFormatter::Month: dbg << "KGantt::DateTimeScaleFormatter::Month"; break; case KGantt::DateTimeScaleFormatter::Year: dbg << "KGantt::DateTimeScaleFormatter::Year"; break; } return dbg; } /*!\class KGantt::DateTimeGrid * \ingroup KGantt * * This implementation of AbstractGrid works with QDateTime * and shows days and week numbers in the header */ qreal DateTimeGrid::Private::dateTimeToChartX( const QDateTime& dt ) const { assert( startDateTime.isValid() ); qreal result = startDateTime.date().daysTo(dt.date())*24.*60.*60.; result += startDateTime.time().msecsTo(dt.time())/1000.; result *= dayWidth/( 24.*60.*60. ); return result; } QDateTime DateTimeGrid::Private::chartXtoDateTime( qreal x ) const { assert( startDateTime.isValid() ); int days = static_cast( x/dayWidth ); qreal secs = x*( 24.*60.*60. )/dayWidth; QDateTime dt = startDateTime; QDateTime result = dt.addDays( days ) .addSecs( static_cast(secs-(days*24.*60.*60.) ) ) .addMSecs( qRound( ( secs-static_cast( secs ) )*1000. ) ); return result; } #define d d_func() /*!\class KGantt::DateTimeScaleFormatter * \ingroup KGantt * * This class formats dates and times used in DateTimeGrid follawing a given format. * * The format follows the format of QDateTime::toString(), with one addition: * "w" is replaced with the week number of the date as number without a leading zero (1-53) * "ww" is replaced with the week number of the date as number with a leading zero (01-53) * * For example: * * \code * // formatter to print the complete date over the current week * // This leads to the first day of the week being printed * DateTimeScaleFormatter formatter = DateTimeScaleFormatter( DateTimeScaleFormatter::Week, "yyyy-MM-dd" ); * \endcode * * Optionally, you can set an user defined text alignment flag. The default value is Qt::AlignCenter. * \sa DateTimeScaleFormatter::DateTimeScaleFormatter * * This class even controls the range of the grid sections. * \sa KGanttDateTimeScaleFormatter::Range */ /*! Creates a DateTimeScaleFormatter using \a range and \a format. * The text on the header is aligned following \a alignment. */ DateTimeScaleFormatter::DateTimeScaleFormatter( Range range, const QString& format, const QString& templ, Qt::Alignment alignment ) : _d( new Private( range, format, templ, alignment ) ) { } DateTimeScaleFormatter::DateTimeScaleFormatter( Range range, const QString& format, Qt::Alignment alignment ) : _d( new Private( range, format, QString::fromLatin1( "%1" ), alignment ) ) { } DateTimeScaleFormatter::DateTimeScaleFormatter( const DateTimeScaleFormatter& other ) : _d( new Private( other.range(), other.format(), other.d->templ, other.alignment() ) ) { } DateTimeScaleFormatter::~DateTimeScaleFormatter() { delete _d; } DateTimeScaleFormatter& DateTimeScaleFormatter::operator=( const DateTimeScaleFormatter& other ) { if ( this == &other ) return *this; delete _d; _d = new Private( other.range(), other.format(), other.d->templ, other.alignment() ); return *this; } /*! \returns The format being used for formatting dates and times. */ QString DateTimeScaleFormatter::format() const { return d->format; } /*! \returns The \a datetime as string respecting the format. */ QString DateTimeScaleFormatter::format( const QDateTime& datetime ) const { QString result = d->format; // additional feature: Weeknumber const QString shortWeekNumber = QString::number( datetime.date().weekNumber()) + QLatin1String("/") + QString::number( datetime.date().year()); const QString longWeekNumber = ( shortWeekNumber.length() == 1 ? QString::fromLatin1( "0" ) : QString() ) + shortWeekNumber; result.replace( QString::fromLatin1( "ww" ), longWeekNumber ); result.replace( QString::fromLatin1( "w" ), shortWeekNumber ); result = datetime.toLocalTime().toString( result ); return result; } QString DateTimeScaleFormatter::text( const QDateTime& datetime ) const { return d->templ.arg( format( datetime ) ); } /*! \returns The range of each item on a DateTimeGrid header. * \sa DateTimeScaleFormatter::Range */ DateTimeScaleFormatter::Range DateTimeScaleFormatter::range() const { return d->range; } Qt::Alignment DateTimeScaleFormatter::alignment() const { return d->alignment; } /*! \returns the QDateTime being the begin of the range after the one containing \a datetime * \sa currentRangeBegin */ QDateTime DateTimeScaleFormatter::nextRangeBegin( const QDateTime& datetime ) const { QDateTime result = datetime; switch ( d->range ) { case Second: result = result.addSecs( 60 ); break; case Minute: // set it to the begin of the next minute result.setTime( QTime( result.time().hour(), result.time().minute() ) ); result = result.addSecs( 60 ); break; case Hour: // set it to the begin of the next hour result.setTime( QTime( result.time().hour(), 0 ) ); result = result.addSecs( 60 * 60 ); break; case Day: // set it to midnight the next day result.setTime( QTime( 0, 0 ) ); result = result.addDays( 1 ); break; case Week: // set it to midnight result.setTime( QTime( 0, 0 ) ); // iterate day-wise, until weekNumber changes { const int weekNumber = result.date().weekNumber(); while ( weekNumber == result.date().weekNumber() ) result = result.addDays( 1 ); } break; case Month: // set it to midnight result.setTime( QTime( 0, 0 ) ); // set it to the first of the next month result.setDate( QDate( result.date().year(), result.date().month(), 1 ).addMonths( 1 ) ); break; case Year: // set it to midnight result.setTime( QTime( 0, 0 ) ); // set it to the first of the next year result.setDate( QDate( result.date().year(), 1, 1 ).addYears( 1 ) ); break; } //result = result.toLocalTime(); assert( result != datetime ); //qDebug() << "DateTimeScaleFormatter::nextRangeBegin("<range<range ) { case Second: break; // nothing case Minute: // set it to the begin of the current minute result.setTime( QTime( result.time().hour(), result.time().minute() ) ); break; case Hour: // set it to the begin of the current hour result.setTime( QTime( result.time().hour(), 0 ) ); break; case Day: // set it to midnight the current day result.setTime( QTime( 0, 0 ) ); break; case Week: // set it to midnight result.setTime( QTime( 0, 0 ) ); // iterate day-wise, as long weekNumber is the same { const int weekNumber = result.date().weekNumber(); while ( weekNumber == result.date().addDays( -1 ).weekNumber() ) result = result.addDays( -1 ); } break; case Month: // set it to midnight result.setTime( QTime( 0, 0 ) ); // set it to the first of the current month result.setDate( QDate( result.date().year(), result.date().month(), 1 ) ); break; case Year: // set it to midnight result.setTime( QTime( 0, 0 ) ); // set it to the first of the current year result.setDate( QDate( result.date().year(), 1, 1 ) ); break; } return result; } DateTimeGrid::DateTimeGrid() : AbstractGrid( new Private ) { } DateTimeGrid::~DateTimeGrid() { } /*! \returns The QDateTime used as start date for the grid. * * The default is three days before the current date. */ QDateTime DateTimeGrid::startDateTime() const { return d->startDateTime; } /*! \param dt The start date of the grid. It is used as the beginning of the * horizontal scrollbar in the view. * * Emits gridChanged() after the start date has changed. */ void DateTimeGrid::setStartDateTime( const QDateTime& dt ) { d->startDateTime = dt; emit gridChanged(); } /*! \returns The width in pixels for each day in the grid. * * The default is 100 pixels. */ qreal DateTimeGrid::dayWidth() const { return d->dayWidth; } /*! Maps a given point in time \a dt to an X value in the scene. */ qreal DateTimeGrid::mapFromDateTime( const QDateTime& dt) const { return d->dateTimeToChartX( dt ); } /*! Maps a given X value \a x in scene coordinates to a point in time. */ QDateTime DateTimeGrid::mapToDateTime( qreal x ) const { return d->chartXtoDateTime( x ); } /*! \param w The width in pixels for each day in the grid. * * The signal gridChanged() is emitted after the day width is changed. */ void DateTimeGrid::setDayWidth( qreal w ) { assert( w>0 ); d->dayWidth = w; emit gridChanged(); } /*! \param s The scale to be used to paint the grid. * * The signal gridChanged() is emitted after the scale has changed. * \sa Scale * * Following example demonstrates how to change the format of the header to use * a date-scaling with the header-label displayed with the ISO date-notation. * \code * DateTimeScaleFormatter* formatter = new DateTimeScaleFormatter(DateTimeScaleFormatter::Day, QString::fromLatin1("yyyy-MMMM-dddd")); * grid->setUserDefinedUpperScale( formatter ); * grid->setUserDefinedLowerScale( formatter ); * grid->setScale( DateTimeGrid::ScaleUserDefined ); * \endcode */ void DateTimeGrid::setScale( Scale s ) { d->scale = s; emit gridChanged(); } /*! \returns The scale used to paint the grid. * * The default is ScaleAuto, which means the day scale will be used * as long as the day width is less or equal to 500. * \sa Scale */ DateTimeGrid::Scale DateTimeGrid::scale() const { return d->scale; } /*! Sets the scale formatter for the lower part of the header to the * user defined formatter to \a lower. The DateTimeGrid object takes * ownership of the formatter, which has to be allocated with new. * * You have to set the scale to ScaleUserDefined for this setting to take effect. * \sa DateTimeScaleFormatter */ void DateTimeGrid::setUserDefinedLowerScale( DateTimeScaleFormatter* lower ) { delete d->lower; d->lower = lower; emit gridChanged(); } /*! Sets the scale formatter for the upper part of the header to the * user defined formatter to \a upper. The DateTimeGrid object takes * ownership of the formatter, which has to be allocated with new. * * You have to set the scale to ScaleUserDefined for this setting to take effect. * \sa DateTimeScaleFormatter */ void DateTimeGrid::setUserDefinedUpperScale( DateTimeScaleFormatter* upper ) { delete d->upper; d->upper = upper; emit gridChanged(); } /*! \return The DateTimeScaleFormatter being used to render the lower scale. */ DateTimeScaleFormatter* DateTimeGrid::userDefinedLowerScale() const { return d->lower; } /*! \return The DateTimeScaleFormatter being used to render the upper scale. */ DateTimeScaleFormatter* DateTimeGrid::userDefinedUpperScale() const { return d->upper; } /*! \param ws The start day of the week. * * A solid line is drawn on the grid to mark the beginning of a new week. * Emits gridChanged() after the start day has changed. */ void DateTimeGrid::setWeekStart( Qt::DayOfWeek ws ) { d->weekStart = ws; emit gridChanged(); } /*! \returns The start day of the week */ Qt::DayOfWeek DateTimeGrid::weekStart() const { return d->weekStart; } /*! \param fd A set of days to mark as free in the grid. * * Free days are filled with the alternate base brush of the * palette used by the view. * The signal gridChanged() is emitted after the free days are changed. */ void DateTimeGrid::setFreeDays( const QSet& fd ) { d->freeDays = fd; emit gridChanged(); } /*! \returns The days marked as free in the grid. */ QSet DateTimeGrid::freeDays() const { return d->freeDays; } /*! Sets the brush to use to paint free days. */ void DateTimeGrid::setFreeDaysBrush(const QBrush brush) { d->freeDaysBrush = brush; } /*! \returns The brush used to paint free days. */ QBrush DateTimeGrid::freeDaysBrush() const { return d->freeDaysBrush; } /*! \returns true if row separators are used. */ bool DateTimeGrid::rowSeparators() const { return d->rowSeparators; } /*! \param enable Whether to use row separators or not. */ void DateTimeGrid::setRowSeparators( bool enable ) { d->rowSeparators = enable; } /*! Sets the brush used to display rows where no data is found. * Default is a red pattern. If set to QBrush() rows with no * information will not be marked. */ void DateTimeGrid::setNoInformationBrush( const QBrush& brush ) { d->noInformationBrush = brush; emit gridChanged(); } /*! \returns the brush used to mark rows with no information. */ QBrush DateTimeGrid::noInformationBrush() const { return d->noInformationBrush; } /*! * \param value The datetime to get the x value for. * \returns The x value corresponding to \a value or -1.0 if \a value is not a datetime variant. */ qreal DateTimeGrid::mapToChart( const QVariant& value ) const { if ( ! value.canConvert( QVariant::DateTime ) || ( value.type() == QVariant::String && value.toString().isEmpty() ) ) { return -1.0; } return d->dateTimeToChartX( value.toDateTime() ); } /*! * \param x The x value get the datetime for. * \returns The datetime corresponding to \a x or an invalid datetime if x cannot be mapped. */ QVariant DateTimeGrid::mapFromChart( qreal x ) const { return d->chartXtoDateTime( x ); } /*! \param idx The index to get the Span for. * \returns The start and end pixels, in a Span, of the specified index. */ Span DateTimeGrid::mapToChart( const QModelIndex& idx ) const { assert( model() ); if ( !idx.isValid() ) return Span(); assert( idx.model()==model() ); const QVariant sv = model()->data( idx, StartTimeRole ); const QVariant ev = model()->data( idx, EndTimeRole ); if ( sv.canConvert( QVariant::DateTime ) && ev.canConvert( QVariant::DateTime ) && !(sv.type() == QVariant::String && sv.toString().isEmpty()) && !(ev.type() == QVariant::String && ev.toString().isEmpty()) ) { QDateTime st = sv.toDateTime(); QDateTime et = ev.toDateTime(); if ( et.isValid() && st.isValid() ) { qreal sx = d->dateTimeToChartX( st ); qreal ex = d->dateTimeToChartX( et )-sx; //qDebug() << "DateTimeGrid::mapToChart("< "<< Span( sx, ex ); return Span( sx, ex); } } // Special case for Events with only a start date if ( sv.canConvert( QVariant::DateTime ) && !(sv.type() == QVariant::String && sv.toString().isEmpty()) ) { QDateTime st = sv.toDateTime(); if ( st.isValid() ) { qreal sx = d->dateTimeToChartX( st ); return Span( sx, 0 ); } } return Span(); } #if 0 static void debug_print_idx( const QModelIndex& idx ) { if ( !idx.isValid() ) { qDebug() << "[Invalid]"; return; } QDateTime st = idx.data( StartTimeRole ).toDateTime(); QDateTime et = idx.data( EndTimeRole ).toDateTime(); qDebug() << idx << "["<& constraints ) const { assert( model() ); if ( !idx.isValid() ) return false; assert( idx.model()==model() ); QDateTime st = d->chartXtoDateTime(span.start()); QDateTime et = d->chartXtoDateTime(span.start()+span.length()); //qDebug() << "DateTimeGrid::mapFromChart("< "<< st << et; Q_FOREACH( const Constraint& c, constraints ) { if ( c.type() != Constraint::TypeHard || !isSatisfiedConstraint( c )) continue; if ( c.startIndex() == idx ) { QDateTime tmpst = model()->data( c.endIndex(), StartTimeRole ).toDateTime(); //qDebug() << tmpst << "<" << et <<"?"; if ( tmpstdata( c.startIndex(), EndTimeRole ).toDateTime(); //qDebug() << tmpet << ">" << st <<"?"; if ( tmpet>st ) return false; } } return model()->setData( idx, QVariant::fromValue(st), StartTimeRole ) && model()->setData( idx, QVariant::fromValue(et), EndTimeRole ); } Qt::PenStyle DateTimeGrid::Private::gridLinePenStyle( QDateTime dt, Private::HeaderType headerType ) const { switch ( headerType ) { case Private::HeaderHour: // Midnight if ( dt.time().hour() == 0 ) return Qt::SolidLine; return Qt::DashLine; case Private::HeaderDay: // First day of the week if ( dt.date().dayOfWeek() == weekStart ) return Qt::SolidLine; return Qt::DashLine; case Private::HeaderWeek: // First day of the month if ( dt.date().day() == 1 ) return Qt::SolidLine; // First day of the week if ( dt.date().dayOfWeek() == weekStart ) return Qt::DashLine; return Qt::NoPen; case Private::HeaderMonth: // First day of the year if ( dt.date().dayOfYear() == 1 ) return Qt::SolidLine; // First day of the month if ( dt.date().day() == 1 ) return Qt::DashLine; return Qt::NoPen; default: // Nothing to do here break; } // Default return Qt::NoPen; } QDateTime DateTimeGrid::Private::adjustDateTimeForHeader( QDateTime dt, Private::HeaderType headerType ) const { // In any case, set time to 00:00:00:00 dt.setTime( QTime( 0, 0, 0, 0 ) ); switch ( headerType ) { case Private::HeaderWeek: // Set day to beginning of the week while ( dt.date().dayOfWeek() != weekStart ) dt = dt.addDays( -1 ); break; case Private::HeaderMonth: // Set day to beginning of the month dt = dt.addDays( 1 - dt.date().day() ); break; case Private::HeaderYear: // Set day to first day of the year dt = dt.addDays( 1 - dt.date().dayOfYear() ); break; default: // In any other case, we don't need to adjust the date time break; } return dt; } void DateTimeGrid::Private::paintVerticalLines( QPainter* painter, const QRectF& sceneRect, const QRectF& exposedRect, QWidget* widget, Private::HeaderType headerType ) { QDateTime dt = chartXtoDateTime( exposedRect.left() ); dt = adjustDateTimeForHeader( dt, headerType ); int offsetSeconds = 0; int offsetDays = 0; // Determine the time step per grid line if ( headerType == Private::HeaderHour ) offsetSeconds = 60*60; else offsetDays = 1; for ( qreal x = dateTimeToChartX( dt ); x < exposedRect.right(); dt = dt.addSecs( offsetSeconds ), dt = dt.addDays( offsetDays ), x = dateTimeToChartX( dt ) ) { //TODO not the best solution as it might be one paint too much, but i don't know what //causes the test to fail yet, i think it might be a rounding error //if ( x >= exposedRect.left() ) { QPen pen = painter->pen(); pen.setBrush( QApplication::palette().dark() ); pen.setStyle( gridLinePenStyle( dt, headerType ) ); painter->setPen( pen ); if ( freeDays.contains( static_cast( dt.date().dayOfWeek() ) ) ) { if (freeDaysBrush.style() == Qt::NoBrush) painter->setBrush( widget?widget->palette().midlight() :QApplication::palette().midlight() ); else painter->setBrush(freeDaysBrush); painter->fillRect( QRectF( x, exposedRect.top(), dayWidth, exposedRect.height() ), painter->brush() ); } painter->drawLine( QPointF( x, sceneRect.top() ), QPointF( x, sceneRect.bottom() ) ); //} } } void DateTimeGrid::Private::paintVerticalUserDefinedLines( QPainter* painter, const QRectF& sceneRect, const QRectF& exposedRect, const DateTimeScaleFormatter* formatter, QWidget* widget ) { Q_UNUSED( widget ); QDateTime dt = chartXtoDateTime( exposedRect.left() ); dt = formatter->currentRangeBegin( dt ); QPen pen = painter->pen(); pen.setBrush( QApplication::palette().dark() ); pen.setStyle( Qt::DashLine ); painter->setPen( pen ); for ( qreal x = dateTimeToChartX( dt ); x < exposedRect.right(); dt = formatter->nextRangeBegin( dt ),x=dateTimeToChartX( dt ) ) { if ( freeDays.contains( static_cast( dt.date().dayOfWeek() ) ) ) { QBrush oldBrush = painter->brush(); if (freeDaysBrush.style() == Qt::NoBrush) painter->setBrush( widget?widget->palette().midlight() :QApplication::palette().midlight() ); else painter->setBrush(freeDaysBrush); painter->fillRect( QRectF( x, exposedRect.top(), dayWidth, exposedRect.height() ), painter->brush() ); painter->setBrush( oldBrush ); } //TODO not the best solution as it might be one paint too much, but i don't know what //causes the test to fail yet, i think it might be a rounding error //if ( x >= exposedRect.left() ) { // FIXME: Also fill area between this and the next vertical line to indicate free days? (Johannes) painter->drawLine( QPointF( x, sceneRect.top() ), QPointF( x, sceneRect.bottom() ) ); //} } } DateTimeGrid::Private::HeaderType DateTimeGrid::Private::headerTypeForScale( DateTimeGrid::Scale scale ) { switch ( scale ) { case ScaleHour: return Private::HeaderHour; case ScaleDay: return Private::HeaderDay; case ScaleWeek: return Private::HeaderWeek; case ScaleMonth: return Private::HeaderMonth; default: // There are no specific header types for any other scale! assert( false ); break; } return Private::HeaderDay; } void DateTimeGrid::paintGrid( QPainter* painter, const QRectF& sceneRect, const QRectF& exposedRect, AbstractRowController* rowController, QWidget* widget ) { // TODO: Support hours and weeks switch ( scale() ) { case ScaleHour: case ScaleDay: case ScaleWeek: case ScaleMonth: d->paintVerticalLines( painter, sceneRect, exposedRect, widget, d->headerTypeForScale( scale() ) ); break; case ScaleAuto: { const qreal tabw = QApplication::fontMetrics().boundingRect( QLatin1String( "XXXXX" ) ).width(); const qreal dayw = dayWidth(); if ( dayw > 24*60*60*tabw ) { d->paintVerticalUserDefinedLines( painter, sceneRect, exposedRect, &d->minute_lower, widget ); } else if ( dayw > 24*60*tabw ) { d->paintVerticalLines( painter, sceneRect, exposedRect, widget, Private::HeaderHour ); } else if ( dayw > 24*tabw ) { d->paintVerticalLines( painter, sceneRect, exposedRect, widget, Private::HeaderDay ); } else if ( dayw > tabw ) { d->paintVerticalUserDefinedLines( painter, sceneRect, exposedRect, &d->week_lower, widget ); } else if ( 4*dayw > tabw ) { d->paintVerticalUserDefinedLines( painter, sceneRect, exposedRect, &d->month_lower, widget ); } else { d->paintVerticalUserDefinedLines( painter, sceneRect, exposedRect, &d->year_lower, widget ); } break; } case ScaleUserDefined: d->paintVerticalUserDefinedLines( painter, sceneRect, exposedRect, d->lower, widget ); break; } if ( rowController ) { // First draw the rows QPen pen = painter->pen(); pen.setBrush( QApplication::palette().dark() ); pen.setStyle( Qt::DashLine ); painter->setPen( pen ); QModelIndex idx = rowController->indexAt( qRound( exposedRect.top() ) ); if ( rowController->indexAbove( idx ).isValid() ) idx = rowController->indexAbove( idx ); qreal y = 0; while ( y < exposedRect.bottom() && idx.isValid() ) { const Span s = rowController->rowGeometry( idx ); y = s.start()+s.length(); if ( d->rowSeparators ) { painter->drawLine( QPointF( sceneRect.left(), y ), QPointF( sceneRect.right(), y ) ); } if ( !idx.data( ItemTypeRole ).isValid() && d->noInformationBrush.style() != Qt::NoBrush ) { painter->fillRect( QRectF( exposedRect.left(), s.start(), exposedRect.width(), s.length() ), d->noInformationBrush ); } // Is alternating background better? //if ( idx.row()%2 ) painter->fillRect( QRectF( exposedRect.x(), s.start(), exposedRect.width(), s.length() ), QApplication::palette().alternateBase() ); idx = rowController->indexBelow( idx ); } } } int DateTimeGrid::Private::tabHeight( const QString& txt, QWidget* widget ) const { QStyleOptionHeader opt; if ( widget ) opt.initFrom( widget ); opt.text = txt; QStyle* style; if ( widget ) style = widget->style(); else style = QApplication::style(); QSize s = style->sizeFromContents(QStyle::CT_HeaderSection, &opt, QSize(), widget); return s.height(); } void DateTimeGrid::Private::getAutomaticFormatters( DateTimeScaleFormatter** lower, DateTimeScaleFormatter** upper) { const qreal tabw = QApplication::fontMetrics().boundingRect( QLatin1String( "XXXXX" ) ).width(); const qreal dayw = dayWidth; if ( dayw > 24*60*60*tabw ) { *lower = &minute_lower; *upper = &minute_upper; } else if ( dayw > 24*60*tabw ) { *lower = &hour_lower; *upper = &hour_upper; } else if ( dayw > 24*tabw ) { *lower = &day_lower; *upper = &day_upper; } else if ( dayw > tabw ) { *lower = &week_lower; *upper = &week_upper; } else if ( 4*dayw > tabw ) { *lower = &month_lower; *upper = &month_upper; } else { *lower = &year_lower; *upper = &year_upper; } } void DateTimeGrid::paintHeader( QPainter* painter, const QRectF& headerRect, const QRectF& exposedRect, qreal offset, QWidget* widget ) { painter->save(); QPainterPath clipPath; clipPath.addRect( headerRect ); painter->setClipPath( clipPath, Qt::IntersectClip ); switch ( scale() ) { case ScaleHour: paintHourScaleHeader( painter, headerRect, exposedRect, offset, widget ); break; case ScaleDay: paintDayScaleHeader( painter, headerRect, exposedRect, offset, widget ); break; case ScaleWeek: paintWeekScaleHeader( painter, headerRect, exposedRect, offset, widget ); break; case ScaleMonth: paintMonthScaleHeader( painter, headerRect, exposedRect, offset, widget ); break; case ScaleAuto: { DateTimeScaleFormatter *lower, *upper; d->getAutomaticFormatters( &lower, &upper ); const qreal lowerHeight = d->tabHeight( lower->text( startDateTime() ) ); const qreal upperHeight = d->tabHeight( upper->text( startDateTime() ) ); const qreal upperRatio = upperHeight/( lowerHeight+upperHeight ); const QRectF upperHeaderRect( headerRect.x(), headerRect.top(), headerRect.width()-1, headerRect.height() * upperRatio ); const QRectF lowerHeaderRect( headerRect.x(), upperHeaderRect.bottom()+1, headerRect.width()-1, headerRect.height()-upperHeaderRect.height()-1 ); paintUserDefinedHeader( painter, lowerHeaderRect, exposedRect, offset, lower, widget ); paintUserDefinedHeader( painter, upperHeaderRect, exposedRect, offset, upper, widget ); break; } case ScaleUserDefined: { const qreal lowerHeight = d->tabHeight( d->lower->text( startDateTime() ) ); const qreal upperHeight = d->tabHeight( d->upper->text( startDateTime() ) ); const qreal upperRatio = upperHeight/( lowerHeight+upperHeight ); const QRectF upperHeaderRect( headerRect.x(), headerRect.top(), headerRect.width()-1, headerRect.height() * upperRatio ); const QRectF lowerHeaderRect( headerRect.x(), upperHeaderRect.bottom()+1, headerRect.width()-1, headerRect.height()-upperHeaderRect.height()-1 ); paintUserDefinedHeader( painter, lowerHeaderRect, exposedRect, offset, d->lower, widget ); paintUserDefinedHeader( painter, upperHeaderRect, exposedRect, offset, d->upper, widget ); } break; } painter->restore(); } void DateTimeGrid::paintUserDefinedHeader( QPainter* painter, const QRectF& headerRect, const QRectF& exposedRect, qreal offset, const DateTimeScaleFormatter* formatter, QWidget* widget ) { const QStyle* const style = widget ? widget->style() : QApplication::style(); QDateTime dt = formatter->currentRangeBegin( d->chartXtoDateTime( offset + exposedRect.left() )); qreal x = d->dateTimeToChartX( dt ); while ( x < exposedRect.right() + offset ) { const QDateTime next = formatter->nextRangeBegin( dt ); const qreal nextx = d->dateTimeToChartX( next ); QStyleOptionHeader opt; if ( widget ) opt.init( widget ); opt.rect = QRectF( x - offset+1, headerRect.top(), qMax( 1., nextx-x-1 ), headerRect.height() ).toAlignedRect(); opt.textAlignment = formatter->alignment(); opt.text = formatter->text( dt ); style->drawControl( QStyle::CE_Header, &opt, painter, widget ); dt = next; x = nextx; } } void DateTimeGrid::Private::paintHeader( QPainter* painter, const QRectF& headerRect, const QRectF& exposedRect, qreal offset, QWidget* widget, Private::HeaderType headerType, DateTextFormatter *formatter ) { QStyle* style = widget?widget->style():QApplication::style(); const qreal left = exposedRect.left() + offset; const qreal right = exposedRect.right() + offset; // Paint a section for each hour QDateTime dt = chartXtoDateTime( left ); dt = adjustDateTimeForHeader( dt, headerType ); // Determine the time step per grid line int offsetSeconds = 0; int offsetDays = 0; int offsetMonths = 0; switch ( headerType ) { case Private::HeaderHour: offsetSeconds = 60*60; break; case Private::HeaderDay: offsetDays = 1; break; case Private::HeaderWeek: offsetDays = 7; break; case Private::HeaderMonth: offsetMonths = 1; break; case Private::HeaderYear: offsetMonths = 12; break; default: // Other scales cannot be painted with this method! assert( false ); break; } for ( qreal x = dateTimeToChartX( dt ); x < right; dt = dt.addSecs( offsetSeconds ), dt = dt.addDays( offsetDays ), dt = dt.addMonths( offsetMonths ), x = dateTimeToChartX( dt ) ) { QStyleOptionHeader opt; if ( widget ) opt.init( widget ); opt.rect = formatter->textRect( x, offset, dayWidth, headerRect, dt ); opt.text = formatter->format( dt ); opt.textAlignment = Qt::AlignCenter; style->drawControl(QStyle::CE_Header, &opt, painter, widget); } } /*! Paints the hour scale header. * \sa paintHeader() */ void DateTimeGrid::paintHourScaleHeader( QPainter* painter, const QRectF& headerRect, const QRectF& exposedRect, qreal offset, QWidget* widget ) { class HourFormatter : public Private::DateTextFormatter { public: virtual ~HourFormatter() {} - QString format( const QDateTime& dt ) Q_DECL_OVERRIDE { + QString format( const QDateTime& dt ) override { return dt.time().toString( QString::fromLatin1( "hh" ) ); } - QRect textRect( qreal x, qreal offset, qreal dayWidth, const QRectF& headerRect, const QDateTime& dt ) Q_DECL_OVERRIDE { + QRect textRect( qreal x, qreal offset, qreal dayWidth, const QRectF& headerRect, const QDateTime& dt ) override { Q_UNUSED(dt); return QRectF( QPointF( x, headerRect.top() ) + QPointF( -offset + 1.0, headerRect.height() / 2.0 ), QSizeF( dayWidth / 24.0, headerRect.height() / 2.0 ) ).toAlignedRect(); } }; d->paintHeader( painter, headerRect, exposedRect, offset, widget, // General parameters Private::HeaderHour, new HourFormatter ); // Custom parameters class DayFormatter : public Private::DateTextFormatter { public: virtual ~DayFormatter() {} - QString format( const QDateTime& dt ) Q_DECL_OVERRIDE { + QString format( const QDateTime& dt ) override { return dt.date().toString(); } - QRect textRect( qreal x, qreal offset, qreal dayWidth, const QRectF& headerRect, const QDateTime& dt ) Q_DECL_OVERRIDE { + QRect textRect( qreal x, qreal offset, qreal dayWidth, const QRectF& headerRect, const QDateTime& dt ) override { Q_UNUSED(dt); return QRectF( QPointF( x, headerRect.top() ) + QPointF( -offset, 0.0 ), QSizeF( dayWidth, headerRect.height() / 2.0 ) ).toRect(); } }; d->paintHeader( painter, headerRect, exposedRect, offset, widget, // General parameters Private::HeaderDay, new DayFormatter ); // Custom parameters } /*! Paints the day scale header. * \sa paintHeader() */ void DateTimeGrid::paintDayScaleHeader( QPainter* painter, const QRectF& headerRect, const QRectF& exposedRect, qreal offset, QWidget* widget ) { class DayFormatter : public Private::DateTextFormatter { public: virtual ~DayFormatter() {} - QString format( const QDateTime& dt ) Q_DECL_OVERRIDE { + QString format( const QDateTime& dt ) override { return dt.toString( QString::fromLatin1( "ddd" ) ).left( 1 ); } - QRect textRect( qreal x, qreal offset, qreal dayWidth, const QRectF& headerRect, const QDateTime& dt ) Q_DECL_OVERRIDE { + QRect textRect( qreal x, qreal offset, qreal dayWidth, const QRectF& headerRect, const QDateTime& dt ) override { Q_UNUSED(dt); return QRectF( QPointF( x, headerRect.top() ) + QPointF( -offset + 1.0, headerRect.height() / 2.0 ), QSizeF( dayWidth, headerRect.height() / 2.0 ) ).toAlignedRect(); } }; d->paintHeader( painter, headerRect, exposedRect, offset, widget, // General parameters Private::HeaderDay, new DayFormatter ); // Custom parameters class WeekFormatter : public Private::DateTextFormatter { public: virtual ~WeekFormatter() {} - QString format( const QDateTime& dt ) Q_DECL_OVERRIDE { + QString format( const QDateTime& dt ) override { return QString::number(dt.date().weekNumber()) + QLatin1String("/") + QString::number(dt.date().year()); } - QRect textRect( qreal x, qreal offset, qreal dayWidth, const QRectF& headerRect, const QDateTime& dt ) Q_DECL_OVERRIDE { + QRect textRect( qreal x, qreal offset, qreal dayWidth, const QRectF& headerRect, const QDateTime& dt ) override { Q_UNUSED(dt); return QRectF( QPointF( x, headerRect.top() ) + QPointF( -offset, 0.0 ), QSizeF( dayWidth * 7, headerRect.height() / 2.0 ) ).toRect(); } }; d->paintHeader( painter, headerRect, exposedRect, offset, widget, // General parameters Private::HeaderWeek, new WeekFormatter ); // Custom parameters } /*! Paints the week scale header. * \sa paintHeader() */ void DateTimeGrid::paintWeekScaleHeader( QPainter* painter, const QRectF& headerRect, const QRectF& exposedRect, qreal offset, QWidget* widget ) { class WeekFormatter : public Private::DateTextFormatter { public: virtual ~WeekFormatter() {} - QString format( const QDateTime& dt ) Q_DECL_OVERRIDE { + QString format( const QDateTime& dt ) override { return QString::number( dt.date().weekNumber() ); } - QRect textRect( qreal x, qreal offset, qreal dayWidth, const QRectF& headerRect, const QDateTime& dt ) Q_DECL_OVERRIDE { + QRect textRect( qreal x, qreal offset, qreal dayWidth, const QRectF& headerRect, const QDateTime& dt ) override { Q_UNUSED(dt); return QRectF( QPointF( x, headerRect.top() ) + QPointF( -offset, headerRect.height() / 2.0 ), QSizeF( dayWidth * 7, headerRect.height() / 2.0 ) ).toRect(); } }; d->paintHeader( painter, headerRect, exposedRect, offset, widget, // General parameters Private::HeaderWeek, new WeekFormatter ); // Custom parameters class MonthFormatter : public Private::DateTextFormatter { public: virtual ~MonthFormatter() {} - QString format( const QDateTime& dt ) Q_DECL_OVERRIDE { + QString format( const QDateTime& dt ) override { return QLocale().monthName(dt.date().month(), QLocale::LongFormat) + QLatin1String("/") + QString::number(dt.date().year()); } - QRect textRect( qreal x, qreal offset, qreal dayWidth, const QRectF& headerRect, const QDateTime& dt ) Q_DECL_OVERRIDE { + QRect textRect( qreal x, qreal offset, qreal dayWidth, const QRectF& headerRect, const QDateTime& dt ) override { return QRectF( QPointF( x, headerRect.top() ) + QPointF( -offset, 0.0 ), QSizeF( dayWidth * dt.date().daysInMonth(), headerRect.height() / 2.0 ) ).toRect(); } }; d->paintHeader( painter, headerRect, exposedRect, offset, widget, // General parameters Private::HeaderMonth, new MonthFormatter ); // Custom parameters } /*! Paints the week scale header. * \sa paintHeader() */ void DateTimeGrid::paintMonthScaleHeader( QPainter* painter, const QRectF& headerRect, const QRectF& exposedRect, qreal offset, QWidget* widget ) { class MonthFormatter : public Private::DateTextFormatter { public: virtual ~MonthFormatter() {} - QString format( const QDateTime& dt ) Q_DECL_OVERRIDE { + QString format( const QDateTime& dt ) override { return QLocale().monthName(dt.date().month(), QLocale::ShortFormat) + QLatin1String("/") + QString::number(dt.date().year()); } - QRect textRect( qreal x, qreal offset, qreal dayWidth, const QRectF& headerRect, const QDateTime& dt ) Q_DECL_OVERRIDE { + QRect textRect( qreal x, qreal offset, qreal dayWidth, const QRectF& headerRect, const QDateTime& dt ) override { return QRectF( QPointF( x, headerRect.top() ) + QPointF( -offset, headerRect.height() / 2.0 ), QSizeF( dayWidth * dt.date().daysInMonth(), headerRect.height() / 2.0 ) ).toRect(); } }; d->paintHeader( painter, headerRect, exposedRect, offset, widget, // General parameters Private::HeaderMonth, new MonthFormatter ); // Custom parameters class YearFormatter : public Private::DateTextFormatter { public: virtual ~YearFormatter() {} - QString format( const QDateTime& dt ) Q_DECL_OVERRIDE { + QString format( const QDateTime& dt ) override { return QString::number( dt.date().year() ); } - QRect textRect( qreal x, qreal offset, qreal dayWidth, const QRectF& headerRect, const QDateTime& dt ) Q_DECL_OVERRIDE { + QRect textRect( qreal x, qreal offset, qreal dayWidth, const QRectF& headerRect, const QDateTime& dt ) override { return QRectF( QPointF( x, headerRect.top() ) + QPointF( -offset, 0.0 ), QSizeF( dayWidth * dt.date().daysInYear(), headerRect.height() / 2.0 ) ).toRect(); } }; d->paintHeader( painter, headerRect, exposedRect, offset, widget, // General parameters Private::HeaderYear, new YearFormatter ); // Custom parameters } /*! Draw the background for a day. */ void DateTimeGrid::drawDayBackground(QPainter* painter, const QRectF& rect, const QDate& date) { Q_UNUSED(date); if (d->timeLine->options() & DateTimeTimeLine::Background) { d->drawTimeLine(painter, rect); } } /*! Draw the foreground for a day. */ void DateTimeGrid::drawDayForeground(QPainter* painter, const QRectF& rect, const QDate& date) { Q_UNUSED(date); if (d->timeLine->options() & DateTimeTimeLine::Foreground) { d->drawTimeLine(painter, rect); } } /** Return the rectangle that represents the date-range. */ QRectF DateTimeGrid::computeRect(const QDateTime& from, const QDateTime& to, const QRectF& rect) const { qreal topLeft = d->dateTimeToChartX(from); qreal topRight = d->dateTimeToChartX(to); return QRectF(topLeft, rect.top(), topRight - topLeft, rect.height()); } /** Return a date-range represented by the rectangle. */ QPair DateTimeGrid::dateTimeRange(const QRectF& rect) const { QDateTime start; QDateTime end; start = d->chartXtoDateTime(rect.left()); end = d->chartXtoDateTime(rect.right()); return qMakePair(start, end); } void DateTimeGrid::drawBackground(QPainter* paint, const QRectF& rect) { int offset = (int)dayWidth(); assert( offset>0 ); // Figure out the date at the extreme left QDate date = d->chartXtoDateTime(rect.left()).date(); // We need to paint from one end to the other int startx = rect.left(); int endx = rect.right(); // Save the painter state paint->save(); // Paint the first date column while (1) { QDate nextDate = d->chartXtoDateTime(startx+1).date(); if (date != nextDate) { QRectF dayRect(startx-dayWidth(), rect.top(), dayWidth(), rect.height()); dayRect = dayRect.adjusted(1, 0, 0, 0); drawDayBackground(paint, dayRect, date); break; } ++startx; } // Paint the remaining dates for (int i=startx; ichartXtoDateTime(i+1).date(); QRectF dayRect(i, rect.top(), dayWidth(), rect.height()); dayRect = dayRect.adjusted(1, 0, 0, 0); drawDayBackground(paint, dayRect, date); } // Restore the painter state paint->restore(); } void DateTimeGrid::drawForeground(QPainter* paint, const QRectF& rect) { int offset = (int)dayWidth(); // Figure out the date at the extreme left QDate date = d->chartXtoDateTime(rect.left()).date(); // We need to paint from one end to the other int startx = rect.left(); int endx = rect.right(); // Save the painter state paint->save(); // Paint the first date column while (1) { QDate nextDate = d->chartXtoDateTime(startx+1).date(); if (date != nextDate) { QRectF dayRect(startx-dayWidth(), rect.top(), dayWidth(), rect.height()); dayRect = dayRect.adjusted(1, 0, 0, 0); drawDayForeground(paint, dayRect, date); break; } ++startx; } // Paint the remaining dates for (int i=startx; ichartXtoDateTime(i+1).date(); QRectF dayRect(i, rect.top(), dayWidth(), rect.height()); dayRect = dayRect.adjusted(1, 0, 0, 0); drawDayForeground(paint, dayRect, date); } // Restore the painter state paint->restore(); } /** * @return the timeline control object */ DateTimeTimeLine *DateTimeGrid::timeLine() const { return d->timeLine; } void DateTimeGrid::Private::drawTimeLine(QPainter* painter, const QRectF& rect) { qreal x = dateTimeToChartX(timeLine->dateTime()); if (rect.contains(x, rect.top())) { painter->save(); painter->setPen(timeLine->pen()); painter->drawLine(x, rect.top(), x, rect.bottom()); painter->restore(); } } #undef d #ifndef KDAB_NO_UNIT_TESTS #include #include "unittest/test.h" static std::ostream& operator<<( std::ostream& os, const QDateTime& dt ) { #ifdef QT_NO_STL os << dt.toString().toLatin1().constData(); #else os << dt.toString().toStdString(); #endif return os; } KDAB_SCOPED_UNITTEST_SIMPLE( KGantt, DateTimeGrid, "test" ) { QStandardItemModel model( 3, 2 ); DateTimeGrid grid; QDateTime dt = QDateTime::currentDateTime(); grid.setModel( &model ); QDateTime startdt = dt.addDays( -10 ); grid.setStartDateTime( startdt ); model.setData( model.index( 0, 0 ), dt, StartTimeRole ); model.setData( model.index( 0, 0 ), dt.addDays( 17 ), EndTimeRole ); model.setData( model.index( 2, 0 ), dt.addDays( 18 ), StartTimeRole ); model.setData( model.index( 2, 0 ), dt.addDays( 19 ), EndTimeRole ); Span s = grid.mapToChart( model.index( 0, 0 ) ); //qDebug() << "span="<0 ); assertTrue( s.length()>0 ); assertTrue( startdt == grid.mapToDateTime( grid.mapFromDateTime( startdt ) ) ); grid.mapFromChart( s, model.index( 1, 0 ) ); QDateTime s1 = model.data( model.index( 0, 0 ), StartTimeRole ).toDateTime(); QDateTime e1 = model.data( model.index( 0, 0 ), EndTimeRole ).toDateTime(); QDateTime s2 = model.data( model.index( 1, 0 ), StartTimeRole ).toDateTime(); QDateTime e2 = model.data( model.index( 1, 0 ), EndTimeRole ).toDateTime(); assertTrue( s1.isValid() ); assertTrue( e1.isValid() ); assertTrue( s2.isValid() ); assertTrue( e2.isValid() ); assertEqual( s1, s2 ); assertEqual( e1, e2 ); assertTrue( grid.isSatisfiedConstraint( Constraint( model.index( 0, 0 ), model.index( 2, 0 ) ) ) ); assertFalse( grid.isSatisfiedConstraint( Constraint( model.index( 2, 0 ), model.index( 0, 0 ) ) ) ); s = grid.mapToChart( model.index( 0, 0 ) ); s.setEnd( s.end()+100000. ); bool rc = grid.mapFromChart( s, model.index( 0, 0 ) ); assertTrue( rc ); assertEqual( s1, model.data( model.index( 0, 0 ), StartTimeRole ).toDateTime() ); Span newspan = grid.mapToChart( model.index( 0, 0 ) ); assertEqual( newspan.start(), s.start() ); assertEqual( newspan.length(), s.length() ); { QDateTime startDateTime = QDateTime::currentDateTime(); qreal dayWidth = 100; QDate currentDate = QDate::currentDate(); QDateTime dt( QDate(currentDate.year(), 1, 1), QTime( 0, 0, 0, 0 ) ); assert( dt.isValid() ); qreal result = startDateTime.date().daysTo(dt.date())*24.*60.*60.; result += startDateTime.time().msecsTo(dt.time())/1000.; result *= dayWidth/( 24.*60.*60. ); int days = static_cast( result/dayWidth ); qreal secs = result*( 24.*60.*60. )/dayWidth; QDateTime dt2 = startDateTime; QDateTime result2 = dt2.addDays( days ).addSecs( static_cast(secs-(days*24.*60.*60.) ) ).addMSecs( qRound( ( secs-static_cast( secs ) )*1000. ) ); assertEqual( dt, result2 ); } } #endif /* KDAB_NO_UNIT_TESTS */ #include "moc_kganttdatetimegrid.cpp" diff --git a/src/KGantt/kganttdatetimegrid.h b/src/KGantt/kganttdatetimegrid.h index 1c78544..74bc88f 100644 --- a/src/KGantt/kganttdatetimegrid.h +++ b/src/KGantt/kganttdatetimegrid.h @@ -1,169 +1,169 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KGantt library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KGANTTDATETIMEGRID_H #define KGANTTDATETIMEGRID_H #include "kganttabstractgrid.h" #include #include #include namespace KGantt { class DateTimeScaleFormatter; class DateTimeTimeLine; class KGANTT_EXPORT DateTimeGrid : public AbstractGrid { Q_OBJECT KGANTT_DECLARE_PRIVATE_DERIVED( DateTimeGrid ) public: enum Scale { ScaleAuto, ScaleHour, ScaleDay, ScaleWeek, ScaleMonth, ScaleUserDefined }; DateTimeGrid(); virtual ~DateTimeGrid(); QDateTime startDateTime() const; void setStartDateTime( const QDateTime& dt ); qreal dayWidth() const; void setDayWidth( qreal ); qreal mapFromDateTime( const QDateTime& dt) const; QDateTime mapToDateTime( qreal x ) const; void setWeekStart( Qt::DayOfWeek ); Qt::DayOfWeek weekStart() const; void setFreeDays( const QSet& fd ); QSet freeDays() const; void setFreeDaysBrush(const QBrush brush); QBrush freeDaysBrush() const; void setScale( Scale s ); Scale scale() const; void setUserDefinedLowerScale( DateTimeScaleFormatter* lower ); void setUserDefinedUpperScale( DateTimeScaleFormatter* upper ); DateTimeScaleFormatter* userDefinedLowerScale() const; DateTimeScaleFormatter* userDefinedUpperScale() const; bool rowSeparators() const; void setRowSeparators( bool enable ); void setNoInformationBrush( const QBrush& brush ); QBrush noInformationBrush() const; - /*reimp*/ Span mapToChart( const QModelIndex& idx ) const Q_DECL_OVERRIDE; + /*reimp*/ Span mapToChart( const QModelIndex& idx ) const override; /*reimp*/ bool mapFromChart( const Span& span, const QModelIndex& idx, - const QList& constraints=QList() ) const Q_DECL_OVERRIDE; - /*reimp*/ qreal mapToChart( const QVariant& value ) const Q_DECL_OVERRIDE; - /*reimp*/ QVariant mapFromChart( qreal x ) const Q_DECL_OVERRIDE; + const QList& constraints=QList() ) const override; + /*reimp*/ qreal mapToChart( const QVariant& value ) const override; + /*reimp*/ QVariant mapFromChart( qreal x ) const override; /*reimp*/ void paintGrid( QPainter* painter, const QRectF& sceneRect, const QRectF& exposedRect, AbstractRowController* rowController = nullptr, - QWidget* widget = nullptr ) Q_DECL_OVERRIDE; + QWidget* widget = nullptr ) override; /*reimp*/ void paintHeader( QPainter* painter, const QRectF& headerRect, const QRectF& exposedRect, - qreal offset, QWidget* widget = nullptr ) Q_DECL_OVERRIDE; + qreal offset, QWidget* widget = nullptr ) override; DateTimeTimeLine *timeLine() const; protected: virtual void paintHourScaleHeader( QPainter* painter, const QRectF& headerRect, const QRectF& exposedRect, qreal offset, QWidget* widget = nullptr ); virtual void paintDayScaleHeader( QPainter* painter, const QRectF& headerRect, const QRectF& exposedRect, qreal offset, QWidget* widget = nullptr ); virtual void paintWeekScaleHeader( QPainter* painter, const QRectF& headerRect, const QRectF& exposedRect, qreal offset, QWidget* widget = nullptr ); virtual void paintMonthScaleHeader( QPainter* painter, const QRectF& headerRect, const QRectF& exposedRect, qreal offset, QWidget* widget = nullptr ); virtual void paintUserDefinedHeader( QPainter* painter, const QRectF& headerRect, const QRectF& exposedRect, qreal offset, const DateTimeScaleFormatter* formatter, QWidget* widget = nullptr ); virtual void drawDayBackground(QPainter* painter, const QRectF& rect, const QDate& date); virtual void drawDayForeground(QPainter* painter, const QRectF& rect, const QDate& date); QRectF computeRect(const QDateTime& from, const QDateTime& to, const QRectF& rect) const; QPair dateTimeRange(const QRectF& rect) const; - /* reimp */ void drawBackground(QPainter* paint, const QRectF& rect) Q_DECL_OVERRIDE; - /* reimp */ void drawForeground(QPainter* paint, const QRectF& rect) Q_DECL_OVERRIDE; + /* reimp */ void drawBackground(QPainter* paint, const QRectF& rect) override; + /* reimp */ void drawForeground(QPainter* paint, const QRectF& rect) override; }; class KGANTT_EXPORT DateTimeScaleFormatter { KGANTT_DECLARE_PRIVATE_BASE_POLYMORPHIC( DateTimeScaleFormatter ) public: enum Range { Second, Minute, Hour, Day, Week, Month, Year }; DateTimeScaleFormatter( Range range, const QString& formatString, Qt::Alignment alignment = Qt::AlignCenter ); DateTimeScaleFormatter( Range range, const QString& formatString, const QString& templ, Qt::Alignment alignment = Qt::AlignCenter ); DateTimeScaleFormatter( const DateTimeScaleFormatter& other ); virtual ~DateTimeScaleFormatter(); DateTimeScaleFormatter& operator=( const DateTimeScaleFormatter& other ); QString format() const; Range range() const; Qt::Alignment alignment() const; virtual QDateTime nextRangeBegin( const QDateTime& datetime ) const; virtual QDateTime currentRangeBegin( const QDateTime& datetime ) const; QString format( const QDateTime& datetime ) const; virtual QString text( const QDateTime& datetime ) const; }; } #ifndef QT_NO_DEBUG_STREAM QDebug KGANTT_EXPORT operator<<( QDebug dbg, KGantt::DateTimeScaleFormatter::Range ); #endif #endif /* KGANTTDATETIMEGRID_H */ diff --git a/src/KGantt/kganttforwardingproxymodel.h b/src/KGantt/kganttforwardingproxymodel.h index ed098c5..5af6bdd 100644 --- a/src/KGantt/kganttforwardingproxymodel.h +++ b/src/KGantt/kganttforwardingproxymodel.h @@ -1,71 +1,71 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KGantt library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KGANTTFORWARDINGPROXYMODEL_H #define KGANTTFORWARDINGPROXYMODEL_H #include #include "kganttglobal.h" namespace KGantt { class KGANTT_EXPORT ForwardingProxyModel : public QAbstractProxyModel { Q_OBJECT Q_DISABLE_COPY(ForwardingProxyModel) public: explicit ForwardingProxyModel( QObject* parent = nullptr ); virtual ~ForwardingProxyModel(); - /*reimp*/ QModelIndex mapFromSource ( const QModelIndex & sourceIndex ) const Q_DECL_OVERRIDE; - /*reimp*/ QModelIndex mapToSource ( const QModelIndex & proxyIndex ) const Q_DECL_OVERRIDE; + /*reimp*/ QModelIndex mapFromSource ( const QModelIndex & sourceIndex ) const override; + /*reimp*/ QModelIndex mapToSource ( const QModelIndex & proxyIndex ) const override; - /*reimp*/ void setSourceModel( QAbstractItemModel* model ) Q_DECL_OVERRIDE; + /*reimp*/ void setSourceModel( QAbstractItemModel* model ) override; - /*reimp*/ QModelIndex index( int row, int column, const QModelIndex& parent = QModelIndex() ) const Q_DECL_OVERRIDE; - /*reimp*/ QModelIndex parent( const QModelIndex& idx ) const Q_DECL_OVERRIDE; + /*reimp*/ QModelIndex index( int row, int column, const QModelIndex& parent = QModelIndex() ) const override; + /*reimp*/ QModelIndex parent( const QModelIndex& idx ) const override; - /*reimp*/ int rowCount( const QModelIndex& idx = QModelIndex() ) const Q_DECL_OVERRIDE; - /*reimp*/ int columnCount( const QModelIndex& idx = QModelIndex() ) const Q_DECL_OVERRIDE; + /*reimp*/ int rowCount( const QModelIndex& idx = QModelIndex() ) const override; + /*reimp*/ int columnCount( const QModelIndex& idx = QModelIndex() ) const override; - /*reimp*/ bool setData( const QModelIndex& index, const QVariant& value, int role = Qt::EditRole ) Q_DECL_OVERRIDE; + /*reimp*/ bool setData( const QModelIndex& index, const QVariant& value, int role = Qt::EditRole ) override; - /*reimp*/ QMimeData *mimeData(const QModelIndexList &indexes) const Q_DECL_OVERRIDE; - /*reimp*/ bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) Q_DECL_OVERRIDE; - /*reimp*/ QStringList mimeTypes() const Q_DECL_OVERRIDE; - /*reimp*/ Qt::DropActions supportedDropActions() const Q_DECL_OVERRIDE; + /*reimp*/ QMimeData *mimeData(const QModelIndexList &indexes) const override; + /*reimp*/ bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override; + /*reimp*/ QStringList mimeTypes() const override; + /*reimp*/ Qt::DropActions supportedDropActions() const override; protected Q_SLOTS: virtual void sourceModelAboutToBeReset(); virtual void sourceModelReset(); virtual void sourceLayoutAboutToBeChanged(); virtual void sourceLayoutChanged(); virtual void sourceDataChanged( const QModelIndex& from, const QModelIndex& to ); virtual void sourceColumnsAboutToBeInserted( const QModelIndex& idx, int start, int end ); virtual void sourceColumnsInserted( const QModelIndex& idx, int start, int end ); virtual void sourceColumnsAboutToBeRemoved( const QModelIndex& idx, int start, int end ); virtual void sourceColumnsRemoved( const QModelIndex& idx, int start, int end ); virtual void sourceRowsAboutToBeInserted( const QModelIndex& idx, int start, int end ); virtual void sourceRowsInserted( const QModelIndex& idx, int start, int end ); virtual void sourceRowsAboutToBeRemoved( const QModelIndex&, int start, int end ); virtual void sourceRowsRemoved( const QModelIndex&, int start, int end ); }; } #endif /* KGANTTFORWARDINGPROXYMODEL_H */ diff --git a/src/KGantt/kganttgraphicsitem.h b/src/KGantt/kganttgraphicsitem.h index f02f743..8070bc8 100644 --- a/src/KGantt/kganttgraphicsitem.h +++ b/src/KGantt/kganttgraphicsitem.h @@ -1,116 +1,116 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KGantt library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KGANTTGRAPHICSITEM_H #define KGANTTGRAPHICSITEM_H #include "kganttglobal.h" #include "kganttstyleoptionganttitem.h" #include #include #include QT_BEGIN_NAMESPACE class QGraphicsLineItem; QT_END_NAMESPACE namespace KGantt { class GraphicsScene; class ConstraintGraphicsItem; /* Can we fit every kind of item into one gfxitem class? */ class GraphicsItem : public QGraphicsItem { public: enum { Type = UserType + 42 }; explicit GraphicsItem( QGraphicsItem* parent = nullptr, GraphicsScene* scene = nullptr ); explicit GraphicsItem( const QModelIndex& idx, QGraphicsItem* parent = nullptr, GraphicsScene* scene = nullptr ); virtual ~GraphicsItem(); - /*reimp*/int type() const Q_DECL_OVERRIDE; + /*reimp*/int type() const override; /*reimp (non-virtual)*/ GraphicsScene* scene() const; void updateItem( const Span& rowgeometry, const QPersistentModelIndex& idx ); //virtual ItemType itemType() const = 0; //qreal dateTimeToSceneX( const QDateTime& dt ) const; //QDateTime sceneXtoDateTime( qreal x ) const; QRectF rect() const { return m_rect; } void setRect( const QRectF& r ); void setBoundingRect( const QRectF& r ); virtual QString ganttToolTip() const; const QPersistentModelIndex& index() const { return m_index; } void setIndex( const QPersistentModelIndex& idx ); bool isEditable() const; bool isUpdating() const { return m_isupdating; } void addStartConstraint( ConstraintGraphicsItem* ); void addEndConstraint( ConstraintGraphicsItem* ); void removeStartConstraint( ConstraintGraphicsItem* ); void removeEndConstraint( ConstraintGraphicsItem* ); QList startConstraints() const { return m_startConstraints; } QList endConstraints() const { return m_endConstraints; } - /*reimp*/ QRectF boundingRect() const Q_DECL_OVERRIDE; + /*reimp*/ QRectF boundingRect() const override; /*reimp*/ void paint( QPainter* painter, const QStyleOptionGraphicsItem* option, - QWidget* widget = nullptr ) Q_DECL_OVERRIDE; + QWidget* widget = nullptr ) override; - /*reimp*/ QVariant itemChange( GraphicsItemChange, const QVariant& value ) Q_DECL_OVERRIDE; + /*reimp*/ QVariant itemChange( GraphicsItemChange, const QVariant& value ) override; protected: - /*reimp*/ void focusInEvent( QFocusEvent* event ) Q_DECL_OVERRIDE; - /*reimp*/ void hoverMoveEvent( QGraphicsSceneHoverEvent* ) Q_DECL_OVERRIDE; - /*reimp*/ void hoverLeaveEvent( QGraphicsSceneHoverEvent* ) Q_DECL_OVERRIDE; - /*reimp*/ void mousePressEvent( QGraphicsSceneMouseEvent* ) Q_DECL_OVERRIDE; - /*reimp*/ void mouseReleaseEvent( QGraphicsSceneMouseEvent* ) Q_DECL_OVERRIDE; - /*reimp*/ void mouseDoubleClickEvent( QGraphicsSceneMouseEvent* ) Q_DECL_OVERRIDE; - /*reimp*/ void mouseMoveEvent( QGraphicsSceneMouseEvent* ) Q_DECL_OVERRIDE; + /*reimp*/ void focusInEvent( QFocusEvent* event ) override; + /*reimp*/ void hoverMoveEvent( QGraphicsSceneHoverEvent* ) override; + /*reimp*/ void hoverLeaveEvent( QGraphicsSceneHoverEvent* ) override; + /*reimp*/ void mousePressEvent( QGraphicsSceneMouseEvent* ) override; + /*reimp*/ void mouseReleaseEvent( QGraphicsSceneMouseEvent* ) override; + /*reimp*/ void mouseDoubleClickEvent( QGraphicsSceneMouseEvent* ) override; + /*reimp*/ void mouseMoveEvent( QGraphicsSceneMouseEvent* ) override; private: void init(); QPointF startConnector( int relationType ) const; QPointF endConnector( int relationType ) const; void updateConstraintItems(); StyleOptionGanttItem getStyleOption() const; void updateModel(); void updateItemFromMouse( const QPointF& scenepos ); void constraintsChanged(); QRectF m_rect; QRectF m_boundingrect; QPersistentModelIndex m_index; bool m_isupdating; int m_istate; QPointF m_presspos; QPointF m_pressscenepos; QGraphicsLineItem* m_dragline; GraphicsItem* m_dragtarget; QList m_startConstraints; QList m_endConstraints; }; } #endif /* KGANTTGRAPHICSITEM_H */ diff --git a/src/KGantt/kganttgraphicsscene.cpp b/src/KGantt/kganttgraphicsscene.cpp index e3c4d77..8055473 100644 --- a/src/KGantt/kganttgraphicsscene.cpp +++ b/src/KGantt/kganttgraphicsscene.cpp @@ -1,954 +1,954 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KGantt library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "kganttgraphicsscene.h" #include "kganttgraphicsscene_p.h" #include "kganttgraphicsitem.h" #include "kganttconstraint.h" #include "kganttconstraintgraphicsitem.h" #include "kganttitemdelegate.h" #include "kganttabstractrowcontroller.h" #include "kganttdatetimegrid.h" #include "kganttsummaryhandlingproxymodel.h" #include #include #include #include #include #include #include #include #include #include #include // defines HAVE_PRINTER if support for printing should be included #ifdef _WIN32_WCE // There is no printer support under wince even if QT_NO_PRINTER is not set #else #ifndef QT_NO_PRINTER #define HAVE_PRINTER #endif #endif /*!\class KGantt::GraphicsScene * \internal */ using namespace KGantt; GraphicsScene::Private::Private( GraphicsScene* _q ) : q( _q ), dragSource( nullptr ), itemDelegate( new ItemDelegate( _q ) ), rowController( nullptr ), grid( &default_grid ), readOnly( false ), isPrinting( false ), drawColumnLabels( true ), labelsWidth( 0.0 ), summaryHandlingModel( new SummaryHandlingProxyModel( _q ) ), selectionModel( nullptr ) { default_grid.setStartDateTime( QDateTime::currentDateTime().addDays( -1 ) ); } void GraphicsScene::Private::clearConstraintItems() { for(ConstraintGraphicsItem *citem : constraintItems) { // remove constraint from items first for(GraphicsItem *item : items) { item->removeStartConstraint(citem); item->removeEndConstraint(citem); } q->removeItem(citem); delete citem; } constraintItems.clear(); } void GraphicsScene::Private::resetConstraintItems() { clearConstraintItems(); if ( constraintModel.isNull() ) return; QList clst = constraintModel->constraints(); Q_FOREACH( const Constraint& c, clst ) { createConstraintItem( c ); } q->updateItems(); } void GraphicsScene::Private::createConstraintItem( const Constraint& c ) { GraphicsItem* sitem = q->findItem( summaryHandlingModel->mapFromSource( c.startIndex() ) ); GraphicsItem* eitem = q->findItem( summaryHandlingModel->mapFromSource( c.endIndex() ) ); if ( sitem && eitem ) { ConstraintGraphicsItem* citem = new ConstraintGraphicsItem( c ); sitem->addStartConstraint( citem ); eitem->addEndConstraint( citem ); constraintItems.append( citem ); q->addItem( citem ); } //q->insertConstraintItem( c, citem ); } // Delete the constraint item, and clean up pointers in the start- and end item void GraphicsScene::Private::deleteConstraintItem( ConstraintGraphicsItem *citem ) { //qDebug()<<"GraphicsScene::Private::deleteConstraintItem citem="<constraint(); GraphicsItem* item = items.value( summaryHandlingModel->mapFromSource( c.startIndex() ), nullptr ); if ( item ) { item->removeStartConstraint( citem ); } item = items.value( summaryHandlingModel->mapFromSource( c.endIndex() ), nullptr ); if ( item ) { item->removeEndConstraint( citem ); } constraintItems.removeAt(constraintItems.indexOf(citem)); delete citem; } void GraphicsScene::Private::deleteConstraintItem( const Constraint& c ) { deleteConstraintItem( findConstraintItem( c ) ); } ConstraintGraphicsItem* GraphicsScene::Private::findConstraintItem( const Constraint& c ) const { GraphicsItem* item = items.value( summaryHandlingModel->mapFromSource( c.startIndex() ), nullptr ); if ( item ) { const QList clst = item->startConstraints(); QList::const_iterator it = clst.begin(); for ( ; it != clst.end() ; ++it ) { if ( c.compareIndexes((*it)->constraint()) ) break; } if ( it != clst.end() ) { return *it; } } item = items.value( summaryHandlingModel->mapFromSource( c.endIndex() ), nullptr ); if ( item ) { const QList clst = item->endConstraints(); QList::const_iterator it = clst.begin(); for ( ; it != clst.end() ; ++it ) { if ( c.compareIndexes( (*it)->constraint() ) ) break; } if ( it != clst.end() ) { return *it; } } return nullptr; } // NOTE: we might get here after indexes are invalidated, so cannot do any controlled cleanup void GraphicsScene::Private::clearItems() { for(GraphicsItem *item : items) { q->removeItem(item); delete item; } items.clear(); // do last to avoid cleaning up items clearConstraintItems(); } GraphicsScene::GraphicsScene( QObject* parent ) : QGraphicsScene( parent ), _d( new Private( this ) ) { init(); } GraphicsScene::~GraphicsScene() { qDeleteAll( items() ); delete _d; } #define d d_func() void GraphicsScene::init() { setItemIndexMethod( QGraphicsScene::NoIndex ); setConstraintModel( new ConstraintModel( this ) ); connect( d->grid, SIGNAL(gridChanged()), this, SLOT(slotGridChanged()) ); } /* NOTE: The delegate should really be a property * of the view, but that doesn't really fit at * this time */ void GraphicsScene::setItemDelegate( ItemDelegate* delegate ) { if ( !d->itemDelegate.isNull() && d->itemDelegate->parent()==this ) delete d->itemDelegate; d->itemDelegate = delegate; update(); } ItemDelegate* GraphicsScene::itemDelegate() const { return d->itemDelegate; } QAbstractItemModel* GraphicsScene::model() const { assert(!d->summaryHandlingModel.isNull()); return d->summaryHandlingModel->sourceModel(); } void GraphicsScene::setModel( QAbstractItemModel* model ) { assert(!d->summaryHandlingModel.isNull()); d->summaryHandlingModel->setSourceModel(model); d->grid->setModel( d->summaryHandlingModel ); setSelectionModel( new QItemSelectionModel( model, this ) ); } QAbstractProxyModel* GraphicsScene::summaryHandlingModel() const { return d->summaryHandlingModel; } void GraphicsScene::setSummaryHandlingModel( QAbstractProxyModel* proxyModel ) { proxyModel->setSourceModel( model() ); d->summaryHandlingModel = proxyModel; } void GraphicsScene::setRootIndex( const QModelIndex& idx ) { d->grid->setRootIndex( idx ); } QModelIndex GraphicsScene::rootIndex() const { return d->grid->rootIndex(); } ConstraintModel* GraphicsScene::constraintModel() const { return d->constraintModel; } void GraphicsScene::setConstraintModel( ConstraintModel* cm ) { if ( !d->constraintModel.isNull() ) { d->constraintModel->disconnect( this ); d->clearConstraintItems(); } d->constraintModel = cm; connect( cm, SIGNAL(constraintAdded(KGantt::Constraint)), this, SLOT(slotConstraintAdded(KGantt::Constraint)) ); connect( cm, SIGNAL(constraintRemoved(KGantt::Constraint)), this, SLOT(slotConstraintRemoved(KGantt::Constraint)) ); d->resetConstraintItems(); } void GraphicsScene::setSelectionModel( QItemSelectionModel* smodel ) { d->selectionModel = smodel; // TODO: update selection from model and connect signals } QItemSelectionModel* GraphicsScene::selectionModel() const { return d->selectionModel; } void GraphicsScene::setRowController( AbstractRowController* rc ) { d->rowController = rc; } AbstractRowController* GraphicsScene::rowController() const { return d->rowController; } void GraphicsScene::setGrid( AbstractGrid* grid ) { QAbstractItemModel* model = nullptr; if ( grid == nullptr ) grid = &d->default_grid; if ( d->grid ) { d->grid->disconnect( this ); model = d->grid->model(); } d->grid = grid; connect( d->grid, SIGNAL(gridChanged()), this, SLOT(slotGridChanged()) ); d->grid->setModel( model ); slotGridChanged(); } AbstractGrid* GraphicsScene::grid() const { return d->grid; } void GraphicsScene::setReadOnly( bool ro ) { d->readOnly = ro; } bool GraphicsScene::isReadOnly() const { return d->readOnly; } /* Returns the index with column=0 fromt the * same row as idx and with the same parent. * This is used to traverse the tree-structure * of the model */ QModelIndex GraphicsScene::mainIndex( const QModelIndex& idx ) { #if 0 if ( idx.isValid() ) { return idx.model()->index( idx.row(), 0,idx.parent() ); } else { return QModelIndex(); } #else return idx; #endif } /*! Returns the index pointing to the last column * in the same row as idx. This can be thought of * as in "inverse" of mainIndex() */ QModelIndex GraphicsScene::dataIndex( const QModelIndex& idx ) { #if 0 if ( idx.isValid() ) { const QAbstractItemModel* model = idx.model(); return model->index( idx.row(), model->columnCount( idx.parent() )-1,idx.parent() ); } else { return QModelIndex(); } #else return idx; #endif } /*! Creates a new item of type type. * TODO: If the user should be allowed to override * this in any way, it needs to be in View! */ GraphicsItem* GraphicsScene::createItem( ItemType type ) const { #if 0 switch ( type ) { case TypeEvent: return 0; case TypeTask: return new TaskItem; case TypeSummary: return new SummaryItem; default: return 0; } #endif //qDebug() << "GraphicsScene::createItem("<findItem( idx ); const int itemtype = summaryHandlingModel->data( idx, ItemTypeRole ).toInt(); if (!item) { item = q->createItem( static_cast( itemtype ) ); item->setIndex( idx ); q->insertItem( idx, item); } item->updateItem( span, idx ); QModelIndex child; int cr = 0; while ( ( child = idx.child( cr, 0 ) ).isValid() ) { recursiveUpdateMultiItem( span, child ); ++cr; } } void GraphicsScene::updateRow( const QModelIndex& rowidx ) { //qDebug() << "GraphicsScene::updateRow("<mapToSource( rowidx ); Span rg = rowController()->rowGeometry( sidx ); for ( QModelIndex treewalkidx = sidx; treewalkidx.isValid(); treewalkidx = treewalkidx.parent() ) { if ( treewalkidx.data( ItemTypeRole ).toInt() == TypeMulti && !rowController()->isRowExpanded( treewalkidx )) { rg = rowController()->rowGeometry( treewalkidx ); } } bool blocked = blockSignals( true ); for ( int col = 0; col < summaryHandlingModel()->columnCount( rowidx.parent() ); ++col ) { const QModelIndex idx = summaryHandlingModel()->index( rowidx.row(), col, rowidx.parent() ); const QModelIndex sidx = summaryHandlingModel()->mapToSource( idx ); const int itemtype = summaryHandlingModel()->data( idx, ItemTypeRole ).toInt(); const bool isExpanded = rowController()->isRowExpanded( sidx ); if ( itemtype == TypeNone ) { removeItem( idx ); continue; } if ( itemtype == TypeMulti && !isExpanded ) { d->recursiveUpdateMultiItem( rg, idx ); } else { if ( summaryHandlingModel()->data( rowidx.parent(), ItemTypeRole ).toInt() == TypeMulti && !isExpanded ) { //continue; } GraphicsItem* item = findItem( idx ); if (!item) { item = createItem( static_cast( itemtype ) ); item->setIndex( idx ); insertItem(idx, item); } const Span span = rowController()->rowGeometry( sidx ); item->updateItem( span, idx ); } } blockSignals( blocked ); } void GraphicsScene::insertItem( const QPersistentModelIndex& idx, GraphicsItem* item ) { if ( !d->constraintModel.isNull() ) { // Create items for constraints const QModelIndex sidx = summaryHandlingModel()->mapToSource( idx ); const QList clst = d->constraintModel->constraintsForIndex( sidx ); Q_FOREACH( const Constraint& c, clst ) { QModelIndex other_idx; if ( c.startIndex() == sidx ) { other_idx = c.endIndex(); GraphicsItem* other_item = d->items.value(summaryHandlingModel()->mapFromSource( other_idx ),nullptr); if ( !other_item ) continue; ConstraintGraphicsItem* citem = new ConstraintGraphicsItem( c ); item->addStartConstraint( citem ); other_item->addEndConstraint( citem ); d->constraintItems.append( citem ); addItem( citem ); } else if ( c.endIndex() == sidx ) { other_idx = c.startIndex(); GraphicsItem* other_item = d->items.value(summaryHandlingModel()->mapFromSource( other_idx ),nullptr); if ( !other_item ) continue; ConstraintGraphicsItem* citem = new ConstraintGraphicsItem( c ); other_item->addStartConstraint( citem ); item->addEndConstraint( citem ); d->constraintItems.append( citem ); addItem( citem ); } else { assert( 0 ); // Impossible } } } d->items.insert( idx, item ); addItem( item ); } void GraphicsScene::removeItem( const QModelIndex& idx ) { //qDebug() << "GraphicsScene::removeItem("<::iterator it = d->items.find( idx ); if ( it != d->items.end() ) { GraphicsItem* item = *it; assert( item ); // We have to remove the item from the list first because // there is a good chance there will be reentrant calls d->items.erase( it ); { // Remove any constraintitems attached const QSet clst = QSet::fromList( item->startConstraints() ) + QSet::fromList( item->endConstraints() ); Q_FOREACH( ConstraintGraphicsItem* citem, clst ) { d->deleteConstraintItem( citem ); } } // Get rid of the item delete item; } } GraphicsItem* GraphicsScene::findItem( const QModelIndex& idx ) const { if ( !idx.isValid() ) return nullptr; assert( idx.model() == summaryHandlingModel() ); QHash::const_iterator it = d->items.find( idx ); return ( it != d->items.end() )?*it:nullptr; } GraphicsItem* GraphicsScene::findItem( const QPersistentModelIndex& idx ) const { if ( !idx.isValid() ) return nullptr; assert( idx.model() == summaryHandlingModel() ); QHash::const_iterator it = d->items.find( idx ); return ( it != d->items.end() )?*it:nullptr; } void GraphicsScene::clearItems() { d->clearItems(); } void GraphicsScene::updateItems() { for ( QHash::iterator it = d->items.begin(); it != d->items.end(); ++it ) { GraphicsItem* const item = it.value(); const QPersistentModelIndex& idx = it.key(); item->updateItem( Span( item->pos().y(), item->rect().height() ), idx ); } invalidate( QRectF(), QGraphicsScene::BackgroundLayer ); } void GraphicsScene::deleteSubtree( const QModelIndex& _idx ) { QModelIndex idx = dataIndex( _idx ); if ( !idx.model() ) return; const QModelIndex parent( idx.parent() ); const int colcount = idx.model()->columnCount( parent ); {for ( int i = 0; i < colcount; ++i ) { removeItem( parent.child( idx.row(), i ) ); }} const int rowcount = summaryHandlingModel()->rowCount( _idx ); {for ( int i = 0; i < rowcount; ++i ) { deleteSubtree( summaryHandlingModel()->index( i, summaryHandlingModel()->columnCount(_idx)-1, _idx ) ); }} } ConstraintGraphicsItem* GraphicsScene::findConstraintItem( const Constraint& c ) const { return d->findConstraintItem( c ); } void GraphicsScene::slotConstraintAdded( const KGantt::Constraint& c ) { d->createConstraintItem( c ); } void GraphicsScene::slotConstraintRemoved( const KGantt::Constraint& c ) { d->deleteConstraintItem( c ); } void GraphicsScene::slotGridChanged() { updateItems(); update(); emit gridChanged(); } void GraphicsScene::helpEvent( QGraphicsSceneHelpEvent *helpEvent ) { #ifndef QT_NO_TOOLTIP QGraphicsItem *item = itemAt( helpEvent->scenePos(), QTransform() ); if ( GraphicsItem* gitem = qgraphicsitem_cast( item ) ) { QToolTip::showText(helpEvent->screenPos(), gitem->ganttToolTip()); } else if ( ConstraintGraphicsItem* citem = qgraphicsitem_cast( item ) ) { QToolTip::showText(helpEvent->screenPos(), citem->ganttToolTip()); } else { QGraphicsScene::helpEvent( helpEvent ); } #endif /* QT_NO_TOOLTIP */ } void GraphicsScene::drawBackground( QPainter* painter, const QRectF& _rect ) { QRectF scn( sceneRect() ); QRectF rect( _rect ); if ( d->isPrinting && d->drawColumnLabels ) { QRectF headerRect( scn.topLeft()+QPointF( d->labelsWidth, 0 ), QSizeF( scn.width()-d->labelsWidth, d->rowController->headerHeight() )); d->grid->paintHeader( painter, headerRect, rect, 0, nullptr ); #if 0 /* We have to blank out the part of the header that is invisible during * normal rendering when we are printing. */ QRectF labelsTabRect( scn.topLeft(), QSizeF( d->labelsWidth, headerRect.height() ) ); QStyleOptionHeader opt; opt.rect = labelsTabRect.toRect(); opt.text = QLatin1String(""); opt.textAlignment = Qt::AlignCenter; style()->drawControl(QStyle::CE_Header, &opt, painter, 0); #endif scn.setTop( headerRect.bottom() ); scn.setLeft( headerRect.left() ); rect = rect.intersected( scn ); } d->grid->paintGrid( painter, scn, rect, d->rowController ); d->grid->drawBackground(painter, rect); } void GraphicsScene::drawForeground( QPainter* painter, const QRectF& rect ) { d->grid->drawForeground(painter, rect); } void GraphicsScene::itemEntered( const QModelIndex& idx ) { emit entered( idx ); } void GraphicsScene::itemPressed( const QModelIndex& idx ) { emit pressed( idx ); } void GraphicsScene::itemClicked( const QModelIndex& idx ) { emit clicked( idx ); } void GraphicsScene::itemDoubleClicked( const QModelIndex& idx ) { emit qrealClicked( idx ); } void GraphicsScene::setDragSource( GraphicsItem* item ) { d->dragSource = item; } GraphicsItem* GraphicsScene::dragSource() const { return d->dragSource; } /*! Print the Gantt chart using \a printer. If \a drawRowLabels * is true (the default), each row will have it's label printed * on the left side. If \a drawColumnLabels is true (the * default), each column will have it's label printed at the * top side. * * This version of print() will print multiple pages. */ void GraphicsScene::print( QPrinter* printer, bool drawRowLabels, bool drawColumnLabels ) { #ifndef HAVE_PRINTER Q_UNUSED( printer ); Q_UNUSED( drawRowLabels ); Q_UNUSED( drawColumnLabels ); #else QPainter painter( printer ); doPrint( &painter, printer->pageRect(), sceneRect().left(), sceneRect().right(), printer, drawRowLabels, drawColumnLabels ); #endif } /*! Print part of the Gantt chart from \a start to \a end using \a printer. * If \a drawRowLabels is true (the default), each row will have it's * label printed on the left side. If \a drawColumnLabels is true (the * default), each column will have it's label printed at the * top side. * * This version of print() will print multiple pages. * * To print a certain range of a chart with a DateTimeGrid, use * qreal DateTimeGrid::mapFromDateTime( const QDateTime& dt) const * to figure out the values for \a start and \a end. */ void GraphicsScene::print( QPrinter* printer, qreal start, qreal end, bool drawRowLabels, bool drawColumnLabels ) { #ifndef HAVE_PRINTER Q_UNUSED( printer ); Q_UNUSED( start ); Q_UNUSED( end ); Q_UNUSED( drawRowLabels ); Q_UNUSED( drawColumnLabels ); #else QPainter painter( printer ); doPrint( &painter, printer->pageRect(), start, end, printer, drawRowLabels, drawColumnLabels ); #endif } /*! Render the GanttView inside the rectangle \a target using the painter \a painter. * If \a drawRowLabels is true (the default), each row will have it's * label printed on the left side. If \a drawColumnLabels is true (the * default), each column will have it's label printed at the * top side. */ void GraphicsScene::print( QPainter* painter, const QRectF& _targetRect, bool drawRowLabels, bool drawColumnLabels ) { QRectF targetRect( _targetRect ); if ( targetRect.isNull() ) { targetRect = sceneRect(); } doPrint( painter, targetRect, sceneRect().left(), sceneRect().right(), nullptr, drawRowLabels, drawColumnLabels ); } /*! Render the GanttView inside the rectangle \a target using the painter \a painter. * If \a drawRowLabels is true (the default), each row will have it's * label printed on the left side. If \a drawColumnLabels is true (the * default), each column will have it's label printed at the * top side. * * To print a certain range of a chart with a DateTimeGrid, use * qreal DateTimeGrid::mapFromDateTime( const QDateTime& dt) const * to figure out the values for \a start and \a end. */ void GraphicsScene::print( QPainter* painter, qreal start, qreal end, const QRectF& _targetRect, bool drawRowLabels, bool drawColumnLabels ) { QRectF targetRect( _targetRect ); if ( targetRect.isNull() ) { targetRect = sceneRect(); } doPrint( painter, targetRect, start, end, nullptr, drawRowLabels, drawColumnLabels ); } /*!\internal */ void GraphicsScene::doPrint( QPainter* painter, const QRectF& targetRect, qreal start, qreal end, QPrinter* printer, bool drawRowLabels, bool drawColumnLabels ) { assert( painter ); d->isPrinting = true; d->drawColumnLabels = drawColumnLabels; d->labelsWidth = 0.0; QFont sceneFont( font() ); #ifdef HAVE_PRINTER if ( printer ) { sceneFont = QFont( font(), printer ); if ( font().pointSizeF() >= 0.0 ) sceneFont.setPointSizeF( font().pointSizeF() ); else if ( font().pointSize() >= 0 ) sceneFont.setPointSize( font().pointSize() ); else sceneFont.setPixelSize( font().pixelSize() ); } #endif QGraphicsTextItem dummyTextItem( QLatin1String("X") ); dummyTextItem.adjustSize(); QFontMetrics fm(dummyTextItem.font()); sceneFont.setPixelSize( fm.height() ); const QRectF oldScnRect( sceneRect() ); QRectF scnRect( oldScnRect ); scnRect.setLeft( start ); scnRect.setRight( end ); bool b = blockSignals( true ); /* column labels */ if ( d->drawColumnLabels ) { QRectF headerRect( scnRect ); headerRect.setHeight( - d->rowController->headerHeight() ); scnRect.setTop(scnRect.top() - d->rowController->headerHeight()); } /* row labels */ QVector textLabels; if ( drawRowLabels ) { qreal textWidth = 0.; qreal charWidth = QFontMetricsF(sceneFont).boundingRect( QString::fromLatin1( "X" ) ).width(); QModelIndex sidx = summaryHandlingModel()->mapToSource( summaryHandlingModel()->index( 0, 0, rootIndex()) ); do { QModelIndex idx = summaryHandlingModel()->mapFromSource( sidx ); const Span rg=rowController()->rowGeometry( sidx ); const QString txt = idx.data( Qt::DisplayRole ).toString(); QGraphicsTextItem* item = new QGraphicsTextItem( txt ); addItem( item ); textLabels << item; item->setTextWidth( QFontMetricsF(sceneFont).boundingRect( txt ).width() + charWidth ); textWidth = qMax( item->textWidth(), textWidth ); item->setPos( 0, rg.start() ); } while ( ( sidx = rowController()->indexBelow( sidx ) ).isValid() ); Q_FOREACH( QGraphicsTextItem* item, textLabels ) { item->setPos( scnRect.left()-textWidth, item->y() ); item->show(); } scnRect.setLeft( scnRect.left()-textWidth ); d->labelsWidth = textWidth; } setSceneRect( scnRect ); painter->save(); painter->setClipRect( targetRect ); qreal yratio = targetRect.height()/scnRect.height(); /* If we're not printing multiple pages, * check if the span fits and adjust: */ if ( !printer && targetRect.width()/scnRect.width() < yratio ) { yratio = targetRect.width()/scnRect.width(); } qreal offset = scnRect.left(); int pagecount = 0; while ( offset < scnRect.right() ) { painter->setFont( sceneFont ); render( painter, targetRect, QRectF( QPointF( offset, scnRect.top()), QSizeF( targetRect.width()/yratio, scnRect.height() ) ) ); offset += targetRect.width()/yratio; ++pagecount; if ( printer && offset < scnRect.right() ) { #ifdef HAVE_PRINTER printer->newPage(); #endif } else { break; } } d->isPrinting = false; d->drawColumnLabels = true; d->labelsWidth = 0.0; qDeleteAll( textLabels ); blockSignals( b ); setSceneRect( oldScnRect ); painter->restore(); } #include "moc_kganttgraphicsscene.cpp" #ifndef KDAB_NO_UNIT_TESTS #include "unittest/test.h" #include #include #include #include "kganttgraphicsview.h" class SceneTestRowController : public KGantt::AbstractRowController { private: static const int ROW_HEIGHT; QPointer m_model; public: SceneTestRowController() { } void setModel( QAbstractItemModel* model ) { m_model = model; } - /*reimp*/int headerHeight() const Q_DECL_OVERRIDE { return 40; } + /*reimp*/int headerHeight() const override { return 40; } - /*reimp*/ bool isRowVisible( const QModelIndex& ) const Q_DECL_OVERRIDE { return true;} - /*reimp*/ bool isRowExpanded( const QModelIndex& ) const Q_DECL_OVERRIDE { return false; } - /*reimp*/ KGantt::Span rowGeometry( const QModelIndex& idx ) const Q_DECL_OVERRIDE + /*reimp*/ bool isRowVisible( const QModelIndex& ) const override { return true;} + /*reimp*/ bool isRowExpanded( const QModelIndex& ) const override { return false; } + /*reimp*/ KGantt::Span rowGeometry( const QModelIndex& idx ) const override { return KGantt::Span( idx.row() * ROW_HEIGHT, ROW_HEIGHT ); } - /*reimp*/ int maximumItemHeight() const Q_DECL_OVERRIDE { + /*reimp*/ int maximumItemHeight() const override { return ROW_HEIGHT/2; } - /*reimp*/int totalHeight() const Q_DECL_OVERRIDE { + /*reimp*/int totalHeight() const override { return m_model->rowCount()* ROW_HEIGHT; } - /*reimp*/ QModelIndex indexAt( int height ) const Q_DECL_OVERRIDE { + /*reimp*/ QModelIndex indexAt( int height ) const override { return m_model->index( height/ROW_HEIGHT, 0 ); } - /*reimp*/ QModelIndex indexBelow( const QModelIndex& idx ) const Q_DECL_OVERRIDE { + /*reimp*/ QModelIndex indexBelow( const QModelIndex& idx ) const override { if ( !idx.isValid() )return QModelIndex(); return idx.model()->index( idx.row()+1, idx.column(), idx.parent() ); } - /*reimp*/ QModelIndex indexAbove( const QModelIndex& idx ) const Q_DECL_OVERRIDE { + /*reimp*/ QModelIndex indexAbove( const QModelIndex& idx ) const override { if ( !idx.isValid() )return QModelIndex(); return idx.model()->index( idx.row()-1, idx.column(), idx.parent() ); } }; class TestLineItem : public QGraphicsLineItem { public: TestLineItem( bool *destroyedFlag ) : QGraphicsLineItem( 0, 0, 10, 10 ), // geometry doesn't matter m_destroyedFlag( destroyedFlag ) {} ~TestLineItem() { *m_destroyedFlag = true; } private: bool *m_destroyedFlag; }; const int SceneTestRowController::ROW_HEIGHT = 30; KDAB_SCOPED_UNITTEST_SIMPLE( KGantt, GraphicsView, "test" ) { QStandardItemModel model; QStandardItem* item = new QStandardItem(); item->setData( KGantt::TypeTask, KGantt::ItemTypeRole ); item->setData( QString::fromLatin1( "Decide on new product" ) ); item->setData( QDateTime( QDate( 2007, 3, 1 ) ), KGantt::StartTimeRole ); item->setData( QDateTime( QDate( 2007, 3, 3 ) ), KGantt::EndTimeRole ); QStandardItem* item2 = new QStandardItem(); item2->setData( KGantt::TypeTask, KGantt::ItemTypeRole ); item2->setData( QString::fromLatin1( "Educate personnel" ) ); item2->setData( QDateTime( QDate( 2007, 3, 3 ) ), KGantt::StartTimeRole ); item2->setData( QDateTime( QDate( 2007, 3, 6 ) ), KGantt::EndTimeRole ); model.appendRow( item ); model.appendRow( item2 ); SceneTestRowController rowController; rowController.setModel( &model ); KGantt::GraphicsView graphicsView; graphicsView.setRowController( &rowController ); graphicsView.setModel( &model ); // Now the interesting stuff - the items above are just for a "realistic environment" bool foreignItemDestroyed = false; TestLineItem *foreignItem = new TestLineItem( &foreignItemDestroyed ); graphicsView.scene()->addItem( foreignItem ); assertFalse( foreignItemDestroyed ); graphicsView.updateScene(); assertFalse( foreignItemDestroyed ); } #endif /* KDAB_NO_UNIT_TESTS */ diff --git a/src/KGantt/kganttgraphicsscene.h b/src/KGantt/kganttgraphicsscene.h index 194d82a..fce721b 100644 --- a/src/KGantt/kganttgraphicsscene.h +++ b/src/KGantt/kganttgraphicsscene.h @@ -1,138 +1,138 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KGantt library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KGANTTGRAPHICSSCENE_H #define KGANTTGRAPHICSSCENE_H #include #include #include #include #include "kganttglobal.h" QT_BEGIN_NAMESPACE class QAbstractProxyModel; class QItemSelectionModel; class QPrinter; QT_END_NAMESPACE namespace KGantt { class AbstractGrid; class AbstractRowController; class GraphicsItem; class Constraint; class ConstraintModel; class ConstraintGraphicsItem; class ItemDelegate; class KGANTT_EXPORT GraphicsScene : public QGraphicsScene { Q_OBJECT KGANTT_DECLARE_PRIVATE_BASE_POLYMORPHIC( GraphicsScene ) public: explicit GraphicsScene( QObject* parent = nullptr ); virtual ~GraphicsScene(); //qreal dateTimeToSceneX( const QDateTime& dt ) const; //QDateTime sceneXtoDateTime( qreal x ) const; static QModelIndex mainIndex( const QModelIndex& idx ); static QModelIndex dataIndex( const QModelIndex& idx ); QAbstractItemModel* model() const; QAbstractProxyModel* summaryHandlingModel() const; QModelIndex rootIndex() const; ConstraintModel* constraintModel() const; QItemSelectionModel* selectionModel() const; void insertItem( const QPersistentModelIndex&, GraphicsItem* ); void removeItem( const QModelIndex& ); using QGraphicsScene::removeItem; GraphicsItem* findItem( const QModelIndex& ) const; GraphicsItem* findItem( const QPersistentModelIndex& ) const; void updateItems(); void clearItems(); void deleteSubtree( const QModelIndex& ); ConstraintGraphicsItem* findConstraintItem( const Constraint& ) const; QList findConstraintItems( const QModelIndex& idx ) const; void setItemDelegate( ItemDelegate* ); ItemDelegate* itemDelegate() const; void setRowController( AbstractRowController* rc ); AbstractRowController* rowController() const; void setGrid( AbstractGrid* grid ); AbstractGrid* grid() const; bool isReadOnly() const; void updateRow( const QModelIndex& idx ); GraphicsItem* createItem( ItemType type ) const; /* used by GraphicsItem */ void itemEntered( const QModelIndex& ); void itemPressed( const QModelIndex& ); void itemClicked( const QModelIndex& ); void itemDoubleClicked( const QModelIndex& ); void setDragSource( GraphicsItem* item ); GraphicsItem* dragSource() const; /* Printing */ void print( QPrinter* printer, bool drawRowLabels = true, bool drawColumnLabels = true ); void print( QPrinter* printer, qreal start, qreal end, bool drawRowLabels = true, bool drawColumnLabels = true ); void print( QPainter* painter, const QRectF& target = QRectF(), bool drawRowLabels=true, bool drawColumnLabels = true ); void print( QPainter* painter, qreal start, qreal end, const QRectF& target = QRectF(), bool drawRowLabels=true, bool drawColumnLabels = true ); Q_SIGNALS: void gridChanged(); void clicked( const QModelIndex & index ); void qrealClicked( const QModelIndex & index ); void entered( const QModelIndex & index ); void pressed( const QModelIndex & index ); protected: - /*reimp*/ void helpEvent( QGraphicsSceneHelpEvent *helpEvent ) Q_DECL_OVERRIDE; - /*reimp*/ void drawBackground( QPainter* painter, const QRectF& rect ) Q_DECL_OVERRIDE; - /*reimp*/ void drawForeground( QPainter* painter, const QRectF& rect ) Q_DECL_OVERRIDE; + /*reimp*/ void helpEvent( QGraphicsSceneHelpEvent *helpEvent ) override; + /*reimp*/ void drawBackground( QPainter* painter, const QRectF& rect ) override; + /*reimp*/ void drawForeground( QPainter* painter, const QRectF& rect ) override; public Q_SLOTS: void setModel( QAbstractItemModel* ); void setSummaryHandlingModel( QAbstractProxyModel* ); void setConstraintModel( ConstraintModel* ); void setRootIndex( const QModelIndex& idx ); void setSelectionModel( QItemSelectionModel* selectionmodel ); void setReadOnly( bool ); private Q_SLOTS: /* slots for ConstraintModel */ void slotConstraintAdded( const KGantt::Constraint& ); void slotConstraintRemoved( const KGantt::Constraint& ); void slotGridChanged(); private: void doPrint( QPainter* painter, const QRectF& targetRect, qreal start, qreal end, QPrinter* printer, bool drawRowLabels, bool drawColumnLabels ); }; } #endif /* KGANTTGRAPHICSSCENE_H */ diff --git a/src/KGantt/kganttgraphicsview.h b/src/KGantt/kganttgraphicsview.h index e77c5d1..f50b843 100644 --- a/src/KGantt/kganttgraphicsview.h +++ b/src/KGantt/kganttgraphicsview.h @@ -1,133 +1,133 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KGantt library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KGANTTGRAPHICSVIEW_H #define KGANTTGRAPHICSVIEW_H #include #include "kganttglobal.h" QT_BEGIN_NAMESPACE class QPrinter; class QModelIndex; class QAbstractItemModel; class QAbstractProxyModel; class QItemSelectionModel; QT_END_NAMESPACE namespace KGantt { class AbstractRowController; class AbstractGrid; class GraphicsItem; class ConstraintModel; class ItemDelegate; class KGANTT_EXPORT GraphicsView : public QGraphicsView { Q_OBJECT KGANTT_DECLARE_PRIVATE_BASE_POLYMORPHIC(GraphicsView) Q_PROPERTY( bool readOnly READ isReadOnly WRITE setReadOnly ) Q_PRIVATE_SLOT( d, void slotGridChanged() ) Q_PRIVATE_SLOT( d, void slotHorizontalScrollValueChanged( int ) ) Q_PRIVATE_SLOT( d, void slotHeaderContextMenuRequested( const QPoint& ) ) /* slots for QAbstractItemModel signals */ Q_PRIVATE_SLOT( d, void slotColumnsInserted( const QModelIndex& parent, int start, int end ) ) Q_PRIVATE_SLOT( d, void slotColumnsRemoved( const QModelIndex& parent, int start, int end ) ) Q_PRIVATE_SLOT( d, void slotDataChanged( const QModelIndex& topLeft, const QModelIndex& bottomRight ) ) Q_PRIVATE_SLOT( d, void slotLayoutChanged() ) Q_PRIVATE_SLOT( d, void slotModelReset() ) Q_PRIVATE_SLOT( d, void slotRowsInserted( const QModelIndex& parent, int start, int end ) ) Q_PRIVATE_SLOT( d, void slotRowsAboutToBeRemoved( const QModelIndex& parent, int start, int end ) ) Q_PRIVATE_SLOT( d, void slotRowsRemoved( const QModelIndex& parent, int start, int end ) ) Q_PRIVATE_SLOT( d, void slotItemClicked( const QModelIndex& idx ) ) Q_PRIVATE_SLOT( d, void slotItemDoubleClicked( const QModelIndex& idx ) ) public: explicit GraphicsView( QWidget* parent = nullptr ); virtual ~GraphicsView(); QAbstractItemModel* model() const; QAbstractProxyModel* summaryHandlingModel() const; ConstraintModel* constraintModel() const; QModelIndex rootIndex() const; QItemSelectionModel* selectionModel() const; AbstractRowController* rowController() const; AbstractGrid* grid() const; ItemDelegate* itemDelegate() const; bool isReadOnly() const; void setHeaderContextMenuPolicy( Qt::ContextMenuPolicy ); Qt::ContextMenuPolicy headerContextMenuPolicy() const; QModelIndex indexAt( const QPoint& pos ) const; virtual void addConstraint( const QModelIndex& from, const QModelIndex& to, Qt::KeyboardModifiers modifiers ); void updateRow( const QModelIndex& ); void updateScene(); public Q_SLOTS: void updateSceneRect(); public: void deleteSubtree( const QModelIndex& ); void print( QPrinter* printer, bool drawRowLabels = true, bool drawColumnLabels = true ); void print( QPrinter* printer, qreal start, qreal end, bool drawRowLabels = true, bool drawColumnLabels = true ); void print( QPainter* painter, const QRectF& target = QRectF(), bool drawRowLabels = true, bool drawColumnLabels = true ); void print( QPainter* painter, qreal start, qreal end, const QRectF& target = QRectF(), bool drawRowLabels = true, bool drawColumnLabels = true ); public Q_SLOTS: void setModel( QAbstractItemModel* ); void setSummaryHandlingModel( QAbstractProxyModel* model ); void setConstraintModel( ConstraintModel* ); void setRootIndex( const QModelIndex& ); void setSelectionModel( QItemSelectionModel* ); void setRowController( AbstractRowController* ); void setGrid( AbstractGrid* ); void setItemDelegate( ItemDelegate* delegate ); void setReadOnly( bool ); Q_SIGNALS: void activated( const QModelIndex & index ); void clicked( const QModelIndex & index ); void qrealClicked( const QModelIndex & index ); void entered( const QModelIndex & index ); void pressed( const QModelIndex & index ); void headerContextMenuRequested( const QPoint& pt ); protected: void clearItems(); - /*reimp*/void resizeEvent( QResizeEvent* ) Q_DECL_OVERRIDE; + /*reimp*/void resizeEvent( QResizeEvent* ) override; private: friend class View; GraphicsItem* createItem( ItemType type ) const; }; } #endif /* KGANTTGRAPHICSVIEW_H */ diff --git a/src/KGantt/kganttgraphicsview_p.h b/src/KGantt/kganttgraphicsview_p.h index 137b709..31680cb 100644 --- a/src/KGantt/kganttgraphicsview_p.h +++ b/src/KGantt/kganttgraphicsview_p.h @@ -1,83 +1,83 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KGantt library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KGANTTGRAPHICSVIEW_P_H #define KGANTTGRAPHICSVIEW_P_H #include "kganttgraphicsview.h" #include "kganttgraphicsscene.h" #include "kganttdatetimegrid.h" #include namespace KGantt { class HeaderWidget : public QWidget { Q_OBJECT public: explicit HeaderWidget( GraphicsView* parent ); virtual ~HeaderWidget(); GraphicsView* view() const { return qobject_cast( parent() );} public Q_SLOTS: void scrollTo( int ); protected: - /*reimp*/ bool event( QEvent* ev ) Q_DECL_OVERRIDE; - /*reimp*/ void paintEvent( QPaintEvent* ev ) Q_DECL_OVERRIDE; - /*reimp*/ void contextMenuEvent( QContextMenuEvent* ev ) Q_DECL_OVERRIDE; + /*reimp*/ bool event( QEvent* ev ) override; + /*reimp*/ void paintEvent( QPaintEvent* ev ) override; + /*reimp*/ void contextMenuEvent( QContextMenuEvent* ev ) override; private: qreal m_offset; }; class Q_DECL_HIDDEN GraphicsView::Private { Q_DISABLE_COPY( Private ) public: explicit Private(GraphicsView* _q); void updateHeaderGeometry(); void slotGridChanged(); void slotHorizontalScrollValueChanged( int val ); /* slots for QAbstractItemModel signals */ void slotColumnsInserted( const QModelIndex& parent, int start, int end ); void slotColumnsRemoved( const QModelIndex& parent, int start, int end ); void slotDataChanged( const QModelIndex& topLeft, const QModelIndex& bottomRight ); void slotLayoutChanged(); void slotModelReset(); void slotRowsInserted( const QModelIndex& parent, int start, int end ); void slotRowsAboutToBeRemoved( const QModelIndex& parent, int start, int end ); void slotRowsRemoved( const QModelIndex& parent, int start, int end ); void slotItemClicked( const QModelIndex& idx ); void slotItemDoubleClicked( const QModelIndex& idx ); void slotHeaderContextMenuRequested( const QPoint& pt ); void removeConstraintsRecursive( QAbstractProxyModel *summaryModel, const QModelIndex& index ); GraphicsView* q; AbstractRowController* rowcontroller; HeaderWidget headerwidget; GraphicsScene scene; }; } #endif /* KGANTTGRAPHICSVIEW_P_H */ diff --git a/src/KGantt/kganttlegend.h b/src/KGantt/kganttlegend.h index 5652fa8..2818d55 100644 --- a/src/KGantt/kganttlegend.h +++ b/src/KGantt/kganttlegend.h @@ -1,67 +1,67 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KGantt library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KGANTTLEGEND_H #define KGANTTLEGEND_H #include #include "kganttglobal.h" #include "kganttstyleoptionganttitem.h" namespace KGantt { class KGANTT_EXPORT Legend : public QAbstractItemView { Q_OBJECT KGANTT_DECLARE_PRIVATE_BASE_POLYMORPHIC( Legend ) public: explicit Legend( QWidget* parent = nullptr ); virtual ~Legend(); - /*reimp*/ QModelIndex indexAt( const QPoint& point ) const Q_DECL_OVERRIDE; - /*reimp*/ QRect visualRect( const QModelIndex& index ) const Q_DECL_OVERRIDE; + /*reimp*/ QModelIndex indexAt( const QPoint& point ) const override; + /*reimp*/ QRect visualRect( const QModelIndex& index ) const override; - /*reimp*/ void scrollTo( const QModelIndex&, ScrollHint = EnsureVisible ) Q_DECL_OVERRIDE {} + /*reimp*/ void scrollTo( const QModelIndex&, ScrollHint = EnsureVisible ) override {} - /*reimp*/ QSize sizeHint() const Q_DECL_OVERRIDE; - /*reimp*/ QSize minimumSizeHint() const Q_DECL_OVERRIDE; + /*reimp*/ QSize sizeHint() const override; + /*reimp*/ QSize minimumSizeHint() const override; - /*reimp*/ void setModel( QAbstractItemModel* model ) Q_DECL_OVERRIDE; + /*reimp*/ void setModel( QAbstractItemModel* model ) override; protected: virtual QRect drawItem( QPainter* painter, const QModelIndex& index, const QPoint& pos = QPoint() ) const; virtual QSize measureItem( const QModelIndex& index, bool recursive = true ) const; virtual StyleOptionGanttItem getStyleOption( const QModelIndex& index ) const; - /*reimp*/ void paintEvent( QPaintEvent* event ) Q_DECL_OVERRIDE; + /*reimp*/ void paintEvent( QPaintEvent* event ) override; - /*reimp*/ int horizontalOffset() const Q_DECL_OVERRIDE { return 0; } - /*reimp*/ bool isIndexHidden( const QModelIndex& ) const Q_DECL_OVERRIDE { return false; } - /*reimp*/ QModelIndex moveCursor( CursorAction, Qt::KeyboardModifiers ) Q_DECL_OVERRIDE { return QModelIndex(); } - /*reimp*/ void setSelection( const QRect&, QItemSelectionModel::SelectionFlags ) Q_DECL_OVERRIDE {} - /*reimp*/ int verticalOffset() const Q_DECL_OVERRIDE { return 0; } - /*reimp*/ QRegion visualRegionForSelection( const QItemSelection& ) const Q_DECL_OVERRIDE { return QRegion(); } + /*reimp*/ int horizontalOffset() const override { return 0; } + /*reimp*/ bool isIndexHidden( const QModelIndex& ) const override { return false; } + /*reimp*/ QModelIndex moveCursor( CursorAction, Qt::KeyboardModifiers ) override { return QModelIndex(); } + /*reimp*/ void setSelection( const QRect&, QItemSelectionModel::SelectionFlags ) override {} + /*reimp*/ int verticalOffset() const override { return 0; } + /*reimp*/ QRegion visualRegionForSelection( const QItemSelection& ) const override { return QRegion(); } protected Q_SLOTS: virtual void modelDataChanged(); }; } #endif diff --git a/src/KGantt/kganttlistviewrowcontroller.h b/src/KGantt/kganttlistviewrowcontroller.h index 4829f49..6020913 100644 --- a/src/KGantt/kganttlistviewrowcontroller.h +++ b/src/KGantt/kganttlistviewrowcontroller.h @@ -1,50 +1,50 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KGantt library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KGANTTLISTVIEWROWCONTROLLER_H #define KGANTTLISTVIEWROWCONTROLLER_H #include "kganttabstractrowcontroller.h" QT_BEGIN_NAMESPACE class QAbstractProxyModel; class QListView; QT_END_NAMESPACE namespace KGantt { class KGANTT_EXPORT ListViewRowController : public AbstractRowController { KGANTT_DECLARE_PRIVATE_BASE_POLYMORPHIC(ListViewRowController) public: ListViewRowController( QListView* lv, QAbstractProxyModel* proxy ); ~ListViewRowController(); - /*reimp*/ int headerHeight() const Q_DECL_OVERRIDE; - /*reimp*/ int maximumItemHeight() const Q_DECL_OVERRIDE; - /*reimp*/ int totalHeight() const Q_DECL_OVERRIDE; - /*reimp*/ bool isRowVisible( const QModelIndex& idx ) const Q_DECL_OVERRIDE; - /*reimp*/ bool isRowExpanded( const QModelIndex& idx ) const Q_DECL_OVERRIDE; - /*reimp*/ Span rowGeometry( const QModelIndex& idx ) const Q_DECL_OVERRIDE; - /*reimp*/ QModelIndex indexAt( int height ) const Q_DECL_OVERRIDE; - /*reimp*/ QModelIndex indexAbove( const QModelIndex& idx ) const Q_DECL_OVERRIDE; - /*reimp*/ QModelIndex indexBelow( const QModelIndex& idx ) const Q_DECL_OVERRIDE; + /*reimp*/ int headerHeight() const override; + /*reimp*/ int maximumItemHeight() const override; + /*reimp*/ int totalHeight() const override; + /*reimp*/ bool isRowVisible( const QModelIndex& idx ) const override; + /*reimp*/ bool isRowExpanded( const QModelIndex& idx ) const override; + /*reimp*/ Span rowGeometry( const QModelIndex& idx ) const override; + /*reimp*/ QModelIndex indexAt( int height ) const override; + /*reimp*/ QModelIndex indexAbove( const QModelIndex& idx ) const override; + /*reimp*/ QModelIndex indexBelow( const QModelIndex& idx ) const override; }; } #endif /* KGANTTLISTVIEWROWCONTROLLER_H */ diff --git a/src/KGantt/kganttproxymodel.h b/src/KGantt/kganttproxymodel.h index be616ea..92b78ac 100644 --- a/src/KGantt/kganttproxymodel.h +++ b/src/KGantt/kganttproxymodel.h @@ -1,59 +1,59 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KGantt library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KGANTTPROXYMODEL_H #define KGANTTPROXYMODEL_H #include "kganttforwardingproxymodel.h" namespace KGantt { class KGANTT_EXPORT ProxyModel : public ForwardingProxyModel { Q_OBJECT Q_DISABLE_COPY(ProxyModel) KGANTT_DECLARE_PRIVATE_BASE_POLYMORPHIC( ProxyModel ) public: explicit ProxyModel( QObject* parent = nullptr ); virtual ~ProxyModel(); void setColumn( int ganttrole, int col ); void removeColumn( int ganttrole ); void setRole( int ganttrole, int role ); void removeRole( int ganttrole ); int column( int ganttrole ) const; int role( int ganttrole ) const; #if 0 void setCalendarMode( bool enable ); bool calendarMode() const; #endif - /*reimp*/ QModelIndex mapFromSource( const QModelIndex& idx) const Q_DECL_OVERRIDE; - /*reimp*/ QModelIndex mapToSource( const QModelIndex& proxyIdx ) const Q_DECL_OVERRIDE; + /*reimp*/ QModelIndex mapFromSource( const QModelIndex& idx) const override; + /*reimp*/ QModelIndex mapToSource( const QModelIndex& proxyIdx ) const override; - /*reimp*/ int rowCount( const QModelIndex& idx ) const Q_DECL_OVERRIDE; - /*reimp*/ int columnCount( const QModelIndex& idx ) const Q_DECL_OVERRIDE; + /*reimp*/ int rowCount( const QModelIndex& idx ) const override; + /*reimp*/ int columnCount( const QModelIndex& idx ) const override; - /*reimp*/ QVariant data( const QModelIndex& idx, int role = Qt::DisplayRole ) const Q_DECL_OVERRIDE; - /*reimp*/ bool setData( const QModelIndex& idx, const QVariant& value, int role=Qt::EditRole ) Q_DECL_OVERRIDE; + /*reimp*/ QVariant data( const QModelIndex& idx, int role = Qt::DisplayRole ) const override; + /*reimp*/ bool setData( const QModelIndex& idx, const QVariant& value, int role=Qt::EditRole ) override; }; } #endif /* KGANTTPROXYMODEL_H */ diff --git a/src/KGantt/kganttsummaryhandlingproxymodel.h b/src/KGantt/kganttsummaryhandlingproxymodel.h index eb7ba20..610e485 100644 --- a/src/KGantt/kganttsummaryhandlingproxymodel.h +++ b/src/KGantt/kganttsummaryhandlingproxymodel.h @@ -1,52 +1,52 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KGantt library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KGANTTSUMMARYHANDLINGPROXYMODEL_H #define KGANTTSUMMARYHANDLINGPROXYMODEL_H #include "kganttforwardingproxymodel.h" namespace KGantt { class KGANTT_EXPORT SummaryHandlingProxyModel : public ForwardingProxyModel { Q_OBJECT KGANTT_DECLARE_PRIVATE_BASE_POLYMORPHIC( SummaryHandlingProxyModel ) public: explicit SummaryHandlingProxyModel( QObject* parent = nullptr ); virtual ~SummaryHandlingProxyModel(); - /*reimp*/ void setSourceModel( QAbstractItemModel* model ) Q_DECL_OVERRIDE; + /*reimp*/ void setSourceModel( QAbstractItemModel* model ) override; - /*reimp*/ QVariant data( const QModelIndex& proxyIndex, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; - /*reimp*/ bool setData( const QModelIndex& index, const QVariant& value, int role = Qt::EditRole ) Q_DECL_OVERRIDE; + /*reimp*/ QVariant data( const QModelIndex& proxyIndex, int role = Qt::DisplayRole) const override; + /*reimp*/ bool setData( const QModelIndex& index, const QVariant& value, int role = Qt::EditRole ) override; - /*reimp*/ Qt::ItemFlags flags( const QModelIndex& idx ) const Q_DECL_OVERRIDE; + /*reimp*/ Qt::ItemFlags flags( const QModelIndex& idx ) const override; protected: - /*reimp*/ void sourceModelReset() Q_DECL_OVERRIDE; - /*reimp*/ void sourceLayoutChanged() Q_DECL_OVERRIDE; - /*reimp*/ void sourceDataChanged( const QModelIndex& from, const QModelIndex& to ) Q_DECL_OVERRIDE; - /*reimp*/ void sourceColumnsAboutToBeInserted( const QModelIndex& idx, int start, int end ) Q_DECL_OVERRIDE; - /*reimp*/ void sourceColumnsAboutToBeRemoved( const QModelIndex& idx, int start, int end ) Q_DECL_OVERRIDE; - /*reimp*/ void sourceRowsAboutToBeInserted( const QModelIndex& idx, int start, int end ) Q_DECL_OVERRIDE; - /*reimp*/ void sourceRowsAboutToBeRemoved( const QModelIndex&, int start, int end ) Q_DECL_OVERRIDE; + /*reimp*/ void sourceModelReset() override; + /*reimp*/ void sourceLayoutChanged() override; + /*reimp*/ void sourceDataChanged( const QModelIndex& from, const QModelIndex& to ) override; + /*reimp*/ void sourceColumnsAboutToBeInserted( const QModelIndex& idx, int start, int end ) override; + /*reimp*/ void sourceColumnsAboutToBeRemoved( const QModelIndex& idx, int start, int end ) override; + /*reimp*/ void sourceRowsAboutToBeInserted( const QModelIndex& idx, int start, int end ) override; + /*reimp*/ void sourceRowsAboutToBeRemoved( const QModelIndex&, int start, int end ) override; }; } #endif /* KGANTTSUMMARYHANDLINGPROXYMODEL_H */ diff --git a/src/KGantt/kgantttreeviewrowcontroller.h b/src/KGantt/kgantttreeviewrowcontroller.h index 7221c1b..04ecf9b 100644 --- a/src/KGantt/kgantttreeviewrowcontroller.h +++ b/src/KGantt/kgantttreeviewrowcontroller.h @@ -1,50 +1,50 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KGantt library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KGANTTTREEVIEWROWCONTROLLER_H #define KGANTTTREEVIEWROWCONTROLLER_H #include "kganttabstractrowcontroller.h" QT_BEGIN_NAMESPACE class QAbstractProxyModel; class QTreeView; QT_END_NAMESPACE namespace KGantt { class KGANTT_EXPORT TreeViewRowController : public AbstractRowController { KGANTT_DECLARE_PRIVATE_BASE_POLYMORPHIC(TreeViewRowController) public: TreeViewRowController( QTreeView* tv, QAbstractProxyModel* proxy ); virtual ~TreeViewRowController(); - /*reimp*/ int headerHeight() const Q_DECL_OVERRIDE; - /*reimp*/ int maximumItemHeight() const Q_DECL_OVERRIDE; - /*reimp*/ int totalHeight() const Q_DECL_OVERRIDE; - /*reimp*/ bool isRowVisible( const QModelIndex& idx ) const Q_DECL_OVERRIDE; - /*reimp*/ bool isRowExpanded( const QModelIndex& idx ) const Q_DECL_OVERRIDE; - /*reimp*/ Span rowGeometry( const QModelIndex& idx ) const Q_DECL_OVERRIDE; - /*reimp*/ QModelIndex indexAt( int height ) const Q_DECL_OVERRIDE; - /*reimp*/ QModelIndex indexAbove( const QModelIndex& idx ) const Q_DECL_OVERRIDE; - /*reimp*/ QModelIndex indexBelow( const QModelIndex& idx ) const Q_DECL_OVERRIDE; + /*reimp*/ int headerHeight() const override; + /*reimp*/ int maximumItemHeight() const override; + /*reimp*/ int totalHeight() const override; + /*reimp*/ bool isRowVisible( const QModelIndex& idx ) const override; + /*reimp*/ bool isRowExpanded( const QModelIndex& idx ) const override; + /*reimp*/ Span rowGeometry( const QModelIndex& idx ) const override; + /*reimp*/ QModelIndex indexAt( int height ) const override; + /*reimp*/ QModelIndex indexAbove( const QModelIndex& idx ) const override; + /*reimp*/ QModelIndex indexBelow( const QModelIndex& idx ) const override; }; } #endif /* KGANTTTREEVIEWROWCONTROLLER_H */ diff --git a/src/KGantt/kganttview.cpp b/src/KGantt/kganttview.cpp index 94df6b4..72d2710 100644 --- a/src/KGantt/kganttview.cpp +++ b/src/KGantt/kganttview.cpp @@ -1,665 +1,665 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KGantt library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "kganttview.h" #include "kganttview_p.h" #include "kganttitemdelegate.h" #include "kganttgraphicsitem.h" #include "kganttsummaryhandlingproxymodel.h" #include #include #include #include #include #include #include #include #include #if defined KDAB_EVAL #include "../evaldialog/evaldialog.h" #endif using namespace KGantt; namespace { class HeaderView : public QHeaderView { public: explicit HeaderView( QWidget* parent=nullptr ) : QHeaderView( Qt::Horizontal, parent ) { } - QSize sizeHint() const Q_DECL_OVERRIDE { QSize s = QHeaderView::sizeHint(); s.rheight() *= 2; return s; } + QSize sizeHint() const override { QSize s = QHeaderView::sizeHint(); s.rheight() *= 2; return s; } }; } KGanttTreeView::KGanttTreeView( QAbstractProxyModel* proxy, QWidget* parent ) : QTreeView( parent ), m_controller( this, proxy ) { setHeader( new HeaderView ); } KGanttTreeView::~KGanttTreeView() { } void KGanttTreeView::expandAll(QModelIndex index) { for (int i = 0; i < model()->rowCount(index); i++) { QModelIndex indexAt = model()->index(i, 0, index); if (model()->hasChildren(indexAt)) expandAll(indexAt); if (isExpanded(indexAt)) continue; expand(indexAt); } } void KGanttTreeView::collapseAll(QModelIndex index) { for (int i = 0; i < model()->rowCount(index); i++) { QModelIndex indexAt = model()->index(i, 0, index); if (model()->hasChildren(indexAt)) collapseAll(indexAt); if (!isExpanded(indexAt)) continue; collapse(indexAt); } } View::Private::Private(View* v) : q(v), splitter(v), rowController(nullptr), gfxview( new GraphicsView( &splitter ) ), model(nullptr) { //init(); } View::Private::~Private() { delete gfxview; } void View::Private::init() { KGanttTreeView* tw = new KGanttTreeView( &ganttProxyModel, &splitter ); tw->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); tw->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel ); q->setLeftView( tw ); q->setRowController( tw->rowController() ); //gfxview.setRenderHints( QPainter::Antialiasing ); tw->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); QVBoxLayout* layout = new QVBoxLayout(q); layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(&splitter); q->setLayout(layout); constraintProxy.setProxyModel( &ganttProxyModel ); constraintProxy.setDestinationModel( &mappedConstraintModel ); setupGraphicsView(); } void View::Private::setupGraphicsView() { gfxview->setParent( &splitter ); gfxview->setAlignment(Qt::AlignTop|Qt::AlignLeft); gfxview->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); gfxview->setSelectionModel( leftWidget->selectionModel() ); gfxview->setConstraintModel( &mappedConstraintModel ); q->setLeftView( leftWidget ); q->setRowController( rowController ); updateScene(); } void View::Private::updateScene() { gfxview->clearItems(); if ( !model) return; if ( QTreeView* tw = qobject_cast(leftWidget)) { QModelIndex idx = ganttProxyModel.mapFromSource( model->index( 0, 0, leftWidget->rootIndex() ) ); do { gfxview->updateRow( idx ); } while ( ( idx = tw->indexBelow( idx ) ) != QModelIndex() && gfxview->rowController()->isRowVisible(idx) ); gfxview->updateSceneRect(); } else { const QModelIndex rootidx = ganttProxyModel.mapFromSource( leftWidget->rootIndex() ); for ( int r = 0; r < ganttProxyModel.rowCount(rootidx); ++r ) { gfxview->updateRow( ganttProxyModel.index( r, 0, rootidx ) ); } } } void View::Private::slotCollapsed(const QModelIndex& _idx) { QTreeView* tw = qobject_cast(leftWidget); if (!tw) return; bool blocked = gfxview->blockSignals( true ); QModelIndex idx( _idx ); const QAbstractItemModel* model = leftWidget->model(); const QModelIndex pidx = ganttProxyModel.mapFromSource(idx); bool isMulti = false; for ( QModelIndex treewalkidx = pidx; treewalkidx.isValid(); treewalkidx = treewalkidx.parent() ) { if ( treewalkidx.data( ItemTypeRole ).toInt() == TypeMulti && !gfxview->rowController()->isRowExpanded( treewalkidx ) ) { isMulti = true; break; } } if ( !isMulti ) { for ( int i = 0; i < model->rowCount( idx ); ++i ) { gfxview->deleteSubtree( ganttProxyModel.index( i, 0, pidx ) ); } } else { gfxview->updateRow(pidx); } //qDebug() << "Looking to update from " << idx; while ( ( idx=tw->indexBelow( idx ) ) != QModelIndex() && gfxview->rowController()->isRowVisible( ganttProxyModel.mapFromSource(idx) ) ) { const QModelIndex proxyidx( ganttProxyModel.mapFromSource( idx ) ); gfxview->updateRow(proxyidx); } gfxview->blockSignals( blocked ); gfxview->updateSceneRect(); } void View::Private::slotExpanded(const QModelIndex& _idx) { QModelIndex idx( ganttProxyModel.mapFromSource( _idx ) ); do { //qDebug() << "Updating row" << idx << idx.data( Qt::DisplayRole ).toString(); gfxview->updateRow(idx); } while ( ( idx=gfxview->rowController()->indexBelow( idx ) ) != QModelIndex() && gfxview->rowController()->isRowVisible( idx ) ); gfxview->updateSceneRect(); } void View::Private::slotVerticalScrollValueChanged( int val ) { #if 0 qDebug() << "View::Private::slotVerticalScrollValueChanged("<verticalScrollBar()->singleStep(); #endif leftWidget->verticalScrollBar()->setValue( val/gfxview->verticalScrollBar()->singleStep() ); } void View::Private::slotLeftWidgetVerticalRangeChanged(int min, int max ) { //qDebug() << "View::Private::slotLeftWidgetVerticalRangeChanged("<verticalScrollBar()->setRange( min, max ); gfxview->updateSceneRect(); } } void View::Private::slotGfxViewVerticalRangeChanged( int min, int max ) { //qDebug() << "View::Private::slotGfxViewVerticalRangeChanged("<verticalScrollBar()->minimum(); int leftMax = leftWidget->verticalScrollBar()->maximum(); bool blocked = gfxview->verticalScrollBar()->blockSignals( true ); gfxview->verticalScrollBar()->setRange( qMax( min, leftMin ), qMax( max, leftMax ) ); gfxview->verticalScrollBar()->blockSignals( blocked ); } } /*!\class KGantt::View kganttview.h KGanttView * \ingroup KGantt * \brief This widget that consists of a QTreeView and a GraphicsView * * This is the easy to use, complete gantt chart widget. It * consists of a QTreeView on the left and a KGantt::GraphicsView * on the right separated by a QSplitter. The two views share the same * model. */ /*! Constructor. Creates a View with parent \a parent, * a DateTimeGrid as default grid implementaion and no model etc. */ View::View(QWidget* parent) : QWidget(parent), _d(new Private(this)) { #if defined KDAB_EVAL EvalDialog::checkEvalLicense( "KD Gantt" ); #endif _d->init(); } View::~View() { delete _d; } #define d d_func() /*! Replaces the left widget with a custom QAbstractItemView. * * \param aiv The view to be used to the left, instead of the default tree view * \sa setRowController() */ void View::setLeftView( QAbstractItemView* aiv ) { assert( aiv ); if ( aiv==d->leftWidget ) return; if ( !d->leftWidget.isNull() ) { d->leftWidget->disconnect( this ); d->leftWidget->hide(); d->leftWidget->verticalScrollBar()->disconnect( d->gfxview->verticalScrollBar() ); d->gfxview->verticalScrollBar()->disconnect( d->leftWidget->verticalScrollBar() ); } d->leftWidget = aiv; d->splitter.insertWidget( 0, d->leftWidget ); if ( qobject_cast(d->leftWidget) ) { connect( d->leftWidget, SIGNAL(collapsed(QModelIndex)), this, SLOT(slotCollapsed(QModelIndex)) ); connect( d->leftWidget, SIGNAL(expanded(QModelIndex)), this, SLOT(slotExpanded(QModelIndex)) ); } connect( d->gfxview->verticalScrollBar(), SIGNAL(valueChanged(int)), d->leftWidget->verticalScrollBar(), SLOT(setValue(int)) ); connect( d->leftWidget->verticalScrollBar(), SIGNAL(valueChanged(int)), d->gfxview->verticalScrollBar(), SLOT(setValue(int)) ); connect( d->leftWidget->verticalScrollBar(), SIGNAL(rangeChanged(int,int)), this, SLOT(slotLeftWidgetVerticalRangeChanged(int,int)) ); connect( d->gfxview->verticalScrollBar(), SIGNAL(rangeChanged(int,int)), this, SLOT(slotGfxViewVerticalRangeChanged(int,int)) ); } /*! Sets \a ctrl to be the rowcontroller used by this View. * The default rowcontroller is owned by KGantt::View and is * suitable for the default treeview in the left part of the view. * You probably only want to change this if you replace the treeview. */ void View::setRowController( AbstractRowController* ctrl ) { if ( ctrl == d->rowController && d->gfxview->rowController() == ctrl ) return; d->rowController = ctrl; d->gfxview->setRowController( d->rowController ); } /*! \returns a pointer to the current rowcontroller. * \see AbstractRowController */ AbstractRowController* View::rowController() { return d->rowController; } /*! \overload AbstractRowController* KGantt::View::rowController() */ const AbstractRowController* View::rowController() const { return d->rowController; } /*! * \returns a pointer to the QAbstractItemView in the left * part of the widget. * */ const QAbstractItemView* View::leftView() const { return d->leftWidget; } /*! * \overload const QAbstractItemView* KGantt::View::leftView() const */ QAbstractItemView* View::leftView() { return d->leftWidget; } /*! Set the GraphicsView to be used for this View. It only makes sense to call this * if you need to subclass GraphicsView. * * NOTE: _Only_ call this right after creating the View, before setting a model or any other * attributes. */ void View::setGraphicsView( GraphicsView* gv ) { if ( gv != d->gfxview ) { GraphicsView* old = d->gfxview; d->gfxview = gv; d->gfxview->setModel(old->model()); // use the old ForwardingProxyModel d->setupGraphicsView(); d->gfxview->setGrid( old->grid() ); delete old; } } /*! * \returns a pointer to the GraphicsView */ const GraphicsView* View::graphicsView() const { return d->gfxview; } /*! * \overload const GraphicsView* KGantt::View::graphicsView() const */ GraphicsView* View::graphicsView() { return d->gfxview; } /*! * \returns a pointer to the QSplitter that manages the left view and graphicsView */ const QSplitter* View::splitter() const { return &d->splitter; } /*! * \overload const QSplitter* KGantt::View::splitter() const */ QSplitter* View::splitter() { return &d->splitter; } /*! \returns the current model displayed by this view */ QAbstractItemModel* View::model() const { return leftView()->model(); } /*! Sets the QAbstractItemModel to be displayed in this view * to \a model. * * \see GraphicsView::setModel */ void View::setModel( QAbstractItemModel* model ) { leftView()->setModel( model ); d->ganttProxyModel.setSourceModel( model ); d->gfxview->setModel( &d->ganttProxyModel ); } /*! \returns the QItemSelectionModel used by this view */ QItemSelectionModel* View::selectionModel() const { return leftView()->selectionModel(); } /*! Sets the QItemSelectionModel used by this view to manage * selections. Similar to QAbstractItemView::setSelectionModel */ void View::setSelectionModel( QItemSelectionModel* smodel ) { leftView()->setSelectionModel( smodel ); d->gfxview->setSelectionModel( new QItemSelectionModel( &( d->ganttProxyModel ),this ) ); } /*! Sets the AbstractGrid for this view. The grid is an * object that controls how QModelIndexes are mapped * to and from the view and how the background and header * is rendered. \see AbstractGrid and DateTimeGrid. */ void View::setGrid( AbstractGrid* grid ) { d->gfxview->setGrid( grid ); } void View::expandAll( QModelIndex index ) { // FIXME: // It is legal to call setLeftView() with any QAbstractItemView, // so expandAll should be reimplemented to work with that. KGanttTreeView* tw = qobject_cast(leftView()); if (tw) { tw->expandAll(index); } } void View::collapseAll( QModelIndex index ) { // FIXME: // It is legal to call setLeftView() with any QAbstractItemView, // so expandAll should be reimplemented to work with that. KGanttTreeView* tw = qobject_cast(leftView()); if (tw) { tw->collapseAll(index); } } /*! \returns the AbstractGrid used by this view. */ AbstractGrid* View::grid() const { return d->gfxview->grid(); } /*! \returns the rootindex for this view. */ QModelIndex View::rootIndex() const { return leftView()->rootIndex(); } /*! Sets the root index of the model displayed by this view. * Similar to QAbstractItemView::setRootIndex, default is QModelIndex(). */ void View::setRootIndex( const QModelIndex& idx ) { leftView()->setRootIndex( idx ); d->gfxview->setRootIndex( idx ); } /*! \returns the ItemDelegate used by this view to render items */ ItemDelegate* View::itemDelegate() const { return d->gfxview->itemDelegate(); } /*! Sets the KGantt::ItemDelegate used for rendering items on this * view. \see ItemDelegate and QAbstractItemDelegate. */ void View::setItemDelegate( ItemDelegate* delegate ) { leftView()->setItemDelegate( delegate ); d->gfxview->setItemDelegate( delegate ); } /*! Sets the constraintmodel displayed by this view. * \see KGantt::ConstraintModel. */ void View::setConstraintModel( ConstraintModel* cm ) { d->constraintProxy.setSourceModel( cm ); d->gfxview->setConstraintModel( &d->mappedConstraintModel ); } /*! \returns the KGantt::ConstraintModel displayed by this view. */ ConstraintModel* View::constraintModel() const { return d->constraintProxy.sourceModel(); } const QAbstractProxyModel* View::ganttProxyModel() const { return &( d->ganttProxyModel ); } QAbstractProxyModel* View::ganttProxyModel() { return &( d->ganttProxyModel ); } void View::ensureVisible(const QModelIndex& index) { QGraphicsView* view = graphicsView(); KGantt::GraphicsScene* scene = static_cast(view->scene()); if (!scene) return; KGantt::SummaryHandlingProxyModel* model = static_cast(scene->summaryHandlingModel()); const QModelIndex pidx = d->ganttProxyModel.mapFromSource(index); const QModelIndex idx = model->mapFromSource( pidx ); QGraphicsItem* item = scene->findItem(idx); view->ensureVisible(item); } void View::resizeEvent(QResizeEvent*ev) { QWidget::resizeEvent(ev); } /*!\returns The QModelIndex for the item located at * position \a pos in the view or an invalid index * if no item was present at that position. * * \see GraphicsView::indexAt */ QModelIndex View::indexAt( const QPoint& pos ) const { return d->gfxview->indexAt( pos ); } /*! Print the Gantt chart using \a printer. If \a drawRowLabels * is true (the default), each row will have it's label printed * on the left side. If \a drawColumnLabels is true (the * default), each column will have it's label printed at the * top side. * * This version of print() will print multiple pages. */ void View::print( QPrinter* printer, bool drawRowLabels, bool drawColumnLabels ) { graphicsView()->print( printer, drawRowLabels, drawColumnLabels ); } /*! Print part of the Gantt chart from \a start to \a end using \a printer. * If \a drawRowLabels is true (the default), each row will have it's * label printed on the left side. If \a drawColumnLabels is true (the * default), each column will have it's label printed at the * top side. * * This version of print() will print multiple pages. * * To print a certain range of a chart with a DateTimeGrid, use * qreal DateTimeGrid::mapFromDateTime( const QDateTime& dt) const * to figure out the values for \a start and \a end. */ void View::print( QPrinter* printer, qreal start, qreal end, bool drawRowLabels, bool drawColumnLabels ) { graphicsView()->print( printer, start, end, drawRowLabels, drawColumnLabels ); } /*! Render the GanttView inside the rectangle \a target using the painter \a painter. * If \a drawRowLabels is true (the default), each row will have it's * label printed on the left side. If \a drawColumnLabels is true (the * default), each column will have it's label printed at the * top side. */ void View::print( QPainter* painter, const QRectF& target, bool drawRowLabels, bool drawColumnLabels) { d->gfxview->print( painter, target, drawRowLabels, drawColumnLabels); } /*! Render the GanttView inside the rectangle \a target using the painter \a painter. * If \a drawRowLabels is true (the default), each row will have it's * label printed on the left side. If \a drawColumnLabels is true (the * default), each column will have it's label printed at the * top side. * * To print a certain range of a chart with a DateTimeGrid, use * qreal DateTimeGrid::mapFromDateTime( const QDateTime& dt) const * to figure out the values for \a start and \a end. */ void View::print( QPainter* painter, qreal start, qreal end, const QRectF& target, bool drawRowLabels, bool drawColumnLabels) { d->gfxview->print( painter, start, end, target, drawRowLabels, drawColumnLabels); } #include "moc_kganttview.cpp" #ifndef KDAB_NO_UNIT_TESTS #include "unittest/test.h" #include "kganttlistviewrowcontroller.h" #include #include #include #include KDAB_SCOPED_UNITTEST_SIMPLE( KGantt, View, "test" ) { View view( nullptr ); #if 0 // GUI tests do not work well on the server QTimer::singleShot( 1000, qApp, SLOT(quit()) ); view.show(); qApp->exec(); QPixmap screenshot1 = QPixmap::grabWidget( &view ); QTreeView* tv = new QTreeView; view.setLeftView( tv ); view.setRowController( new TreeViewRowController(tv,view.ganttProxyModel()) ); QTimer::singleShot( 1000, qApp, SLOT(quit()) ); qApp->exec(); QPixmap screenshot2 = QPixmap::grabWidget( &view ); assertEqual( screenshot1.toImage(), screenshot2.toImage() ); QListView* lv = new QListView; view.setLeftView(lv); view.setRowController( new ListViewRowController(lv,view.ganttProxyModel())); view.show(); QTimer::singleShot( 1000, qApp, SLOT(quit()) ); qApp->exec(); #endif } #endif /* KDAB_NO_UNIT_TESTS */ diff --git a/src/KGantt/kganttview.h b/src/KGantt/kganttview.h index caecd5c..b3df4f9 100644 --- a/src/KGantt/kganttview.h +++ b/src/KGantt/kganttview.h @@ -1,107 +1,107 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KGantt library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KGANTTVIEW_H #define KGANTTVIEW_H #include #include #include "kganttglobal.h" QT_BEGIN_NAMESPACE class QAbstractItemModel; class QAbstractProxyModel; class QAbstractItemView; class QItemSelectionModel; class QPrinter; class QSplitter; QT_END_NAMESPACE namespace KGantt { class ItemDelegate; class Constraint; class ConstraintModel; class AbstractGrid; class GraphicsView; class AbstractRowController; class KGANTT_EXPORT View : public QWidget { Q_OBJECT KGANTT_DECLARE_PRIVATE_BASE_POLYMORPHIC_QWIDGET(View) Q_PRIVATE_SLOT( d, void slotCollapsed(const QModelIndex&) ) Q_PRIVATE_SLOT( d, void slotExpanded(const QModelIndex&) ) Q_PRIVATE_SLOT( d, void slotVerticalScrollValueChanged( int ) ) Q_PRIVATE_SLOT( d, void slotLeftWidgetVerticalRangeChanged( int, int ) ) Q_PRIVATE_SLOT( d, void slotGfxViewVerticalRangeChanged( int, int ) ) public: explicit View(QWidget* parent = nullptr); virtual ~View(); QAbstractItemModel* model() const; QItemSelectionModel* selectionModel() const; ItemDelegate* itemDelegate() const; ConstraintModel* constraintModel() const; AbstractGrid* grid() const; QModelIndex rootIndex() const; QModelIndex indexAt( const QPoint& pos ) const; void setLeftView( QAbstractItemView* ); const QAbstractItemView* leftView() const; QAbstractItemView* leftView(); const QSplitter* splitter() const; QSplitter* splitter(); void setRowController( AbstractRowController* ); AbstractRowController* rowController(); const AbstractRowController* rowController() const; void setGraphicsView( GraphicsView* ); const GraphicsView* graphicsView() const; GraphicsView* graphicsView(); const QAbstractProxyModel* ganttProxyModel() const; QAbstractProxyModel* ganttProxyModel(); void ensureVisible(const QModelIndex& index); void print( QPrinter* printer, bool drawRowLabels=true, bool drawColumnLabels=true ); void print( QPrinter* printer, qreal start, qreal end, bool drawRowLabels=true, bool drawColumnLabels=true ); void print( QPainter* painter, const QRectF& target = QRectF(), bool drawRowLabels=true, bool drawColumnLabels=true); void print( QPainter* painter, qreal start, qreal end, const QRectF& target = QRectF(), bool drawRowLabels=true, bool drawColumnLabels=true); public Q_SLOTS: void setModel(QAbstractItemModel* model); void setRootIndex( const QModelIndex& idx ); void setSelectionModel( QItemSelectionModel* smodel ); void setItemDelegate( ItemDelegate* ); void setConstraintModel( ConstraintModel* ); void setGrid( AbstractGrid* ); void expandAll( QModelIndex index = QModelIndex() ); void collapseAll( QModelIndex index = QModelIndex() ); protected: - /*reimp*/ void resizeEvent(QResizeEvent*) Q_DECL_OVERRIDE; + /*reimp*/ void resizeEvent(QResizeEvent*) override; }; } #endif /* KGANTTVIEW_H */ diff --git a/src/KGantt/unittest/test.h b/src/KGantt/unittest/test.h index 5fe888f..496b77e 100644 --- a/src/KGantt/unittest/test.h +++ b/src/KGantt/unittest/test.h @@ -1,200 +1,200 @@ /* * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KGantt library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef __KDAB__UNITTEST__TEST_H__ #define __KDAB__UNITTEST__TEST_H__ #ifndef KDAB_NO_UNIT_TESTS #include "kganttglobal.h" #include #include #include namespace KDAB { namespace UnitTest { #define assertNotNull( x ) _assertNotNull( ( x ), #x, __FILE__, __LINE__ ) #define assertNull( x ) _assertNull( ( x ), #x, __FILE__, __LINE__ ) #define assertTrue( x ) _assertTrue( (x), #x, __FILE__, __LINE__ ) #define assertFalse( x ) _assertFalse( (x), #x, __FILE__, __LINE__ ) #define assertEqual( x, y ) _assertEqual( (x), (y), #x, #y, __FILE__, __LINE__ ) #define assertNotEqual( x, y ) _assertNotEqual( (x), (y), #x, #y, __FILE__, __LINE__ ) // to be phased out: #define assertNearEqual( x, y, z ) #define assertEqualWithEpsilons( x, y, z ) _assertEqualWithEpsilons( (x), (y), (z), #x, #y, #z, __FILE__, __LINE__ ) #if 0 #define assertIsNaN( x ) _assertIsNaN( (x), #x, __FILE__, __LINE__ ) #define assertIsNotNaN( x ) _assertIsNotNaN( (x), #x, __FILE__, __LINE__ ) #endif #define assertThrowsExceptionWithCode( x, E, code ) \ do { \ try { \ x; \ fail( __FILE__, __LINE__ ) \ << "\"" #x "\" didn't throw \"" #E "\"" << std::endl; \ } catch ( E & ppq_ut_thrown ) { \ success(); \ ( void )ppq_ut_thrown; \ code; \ } catch ( ... ) { \ fail( __FILE__, __LINE__ ) \ << "\"" #x "\" threw something, but it wasn't \"" #E "\"" << std::endl; \ } \ } while ( false ) #define assertThrowsException( x, E ) assertThrowsExceptionWithCode( x, E, do{}while (0) ) #define assertDoesNotThrowException( x, E ) \ do { \ try { \ x; \ success(); \ } catch ( E & ) { \ fail( __FILE__, __LINE__ ) \ << "\"" #x "\" threw \"" #E "\", but shouldn't" << std::endl; \ } catch ( ... ) { \ fail( __FILE__, __LINE__ ) \ << "\"" #x "\" threw something, but it wasn't \"" #E "\"" << std::endl; \ } \ } while ( false ) class Test { const std::string mName; unsigned int mFailed, mSucceeded; public: Test( const std::string & name ); virtual ~Test() {} const std::string & name() const { return mName; } unsigned int failed() const { return mFailed; } unsigned int succeeded() const { return mSucceeded; } virtual void run() = 0; protected: void _assertNotNull( const void * x, const char * expression, const char * file, unsigned int line ); void _assertNull( const void * x, const char * expression, const char * file, unsigned int line ); #if 0 void _assertIsNaN( qreal v, const char * expression, const char * file, unsigned int line ); void _assertIsNotNaN( qreal v, const char * expression, const char * file, unsigned int line ); #endif void _assertTrue( bool x, const char * expression, const char * file, unsigned int line ); void _assertFalse( bool x, const char * expression, const char * file, unsigned int line ); void _assertEqualWithEpsilons( float x1, float x2, int prec, const char * expr1, const char * expr2, const char * exprPrec, const char * file, unsigned int line ); void _assertEqualWithEpsilons( qreal x1, qreal x2, int prec, const char * expr1, const char * expr2, const char * exprPrec, const char * file, unsigned int line ); void _assertEqualWithEpsilons( long double x1, long double x2, int prec, const char * expr1, const char * expr2, const char * exprPrec, const char * file, unsigned int line ); template void _assertEqual( const T & x1, const S & x2, const char * expr1, const char * expr2, const char * file, unsigned int line ) { if ( x1 == x2 ) this->success(); else { this->fail( file, line ) << '"' << expr1 << "\" yielded " << x1 << "; expected: " << x2 << "(\"" << expr2 << "\")" << std::endl; } } template void _assertNotEqual( const T & x1, const S & x2, const char * expr1, const char * expr2, const char * file, unsigned int line ) { if ( x1 != x2 ) this->success(); else { this->fail( file, line ) << '"' << expr1 << "\" yielded " << x1 << "; expected something not equal to: " << x2 << "(\"" << expr2 << "\")" << std::endl; } } protected: std::ostream & fail( const char * file, unsigned int line ); void success() { ++mSucceeded; } }; class TestFactory { public: virtual ~TestFactory() {} virtual Test * create() const = 0; }; } } #include "testregistry.h" namespace KDAB { namespace UnitTest { template class GenericFactory : public TestFactory { public: GenericFactory( const char * group = nullptr ) { TestRegistry::instance()->registerTestFactory( this, group ); } - Test * create() const Q_DECL_OVERRIDE { return new T_Test(); } + Test * create() const override { return new T_Test(); } }; } } #include "libutil.h" // Use these macros to export your UnitTest class so that it gets executed by the test runner. // Use the second macro if your class is within a namespace. // Arguments : // - Namespace (unquoted) : the namespace in which the test class in contained // - Class (unquoted) : the test class, without namespace // - Group (quoted) : the name of the group this unit test belongs to #define KDAB_EXPORT_UNITTEST( Class, Group ) \ static const KDAB::UnitTest::GenericFactory< Class > __##Class##_unittest( Group ); \ KDAB_EXPORT_STATIC_SYMBOLS( Class ) #define KDAB_EXPORT_SCOPED_UNITTEST( Namespace, Class, Group ) \ static const KDAB::UnitTest::GenericFactory< Namespace::Class > __##Class##_unittest( Group ); \ KDAB_EXPORT_STATIC_SYMBOLS( Class ) // Use this macro to import the test explicitly (for windows static libs only) #define KDAB_IMPORT_UNITTEST( Class ) KDAB_IMPORT_STATIC_SYMBOLS( Class ) // Convenience macros that create a simple test class for a single test and export it. // Usage : KDAB_UNITTEST_SIMPLE( MyClass, "mygroup" ) { doSomething(); assertEqual(...); } #define KDAB_UNITTEST_SIMPLE( Class, Group ) \ class Class##Test : public KDAB::UnitTest::Test { \ public: \ Class##Test() : Test( #Class ) {} \ void run(); \ }; \ KDAB_EXPORT_UNITTEST( Class##Test, Group ) \ void Class##Test::run() #define KDAB_SCOPED_UNITTEST_SIMPLE( Namespace, Class, Group ) \ namespace Namespace { \ class Class##Test : public KDAB::UnitTest::Test { \ public: \ Class##Test() : Test( #Namespace "::" #Class ) {} \ - void run() Q_DECL_OVERRIDE; \ + void run() override; \ }; \ } \ KDAB_EXPORT_SCOPED_UNITTEST( Namespace, Class##Test, Group ) \ void Namespace::Class##Test::run() #endif // KDAB_NO_UNIT_TESTS #endif // __KDAB__UNITTEST__TEST_H__ diff --git a/tests/Gantt/apireview/entrydelegate.h b/tests/Gantt/apireview/entrydelegate.h index 2150d59..8291f81 100644 --- a/tests/Gantt/apireview/entrydelegate.h +++ b/tests/Gantt/apireview/entrydelegate.h @@ -1,42 +1,42 @@ /** * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KGantt library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ENTRYDELEGATE_H #define ENTRYDELEGATE_H #include namespace KGantt { class ConstraintModel; } class EntryDelegate : public QItemDelegate { public: EntryDelegate( KGantt::ConstraintModel* constraintModel, QObject* parent = nullptr ); - bool editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ) Q_DECL_OVERRIDE; + bool editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ) override; private: void addConstraint(const QModelIndex & index1, const QModelIndex & index2); void setReadOnly(const QModelIndex & index, bool readOnly); KGantt::ConstraintModel* constraintModel; }; #endif /* ENTRYDELEGATE_H */ diff --git a/tests/Gantt/customconstraints/main.cpp b/tests/Gantt/customconstraints/main.cpp index 001f7d9..e57cb8a 100644 --- a/tests/Gantt/customconstraints/main.cpp +++ b/tests/Gantt/customconstraints/main.cpp @@ -1,136 +1,136 @@ /** * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KGantt library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class MyGraphicsView : public KGantt::GraphicsView { Q_OBJECT public: MyGraphicsView( QWidget* parent = nullptr ) : KGantt::GraphicsView( parent ) { } /*reimp*/void addConstraint( const QModelIndex& from, const QModelIndex& to, - Qt::KeyboardModifiers modifiers ) Q_DECL_OVERRIDE + Qt::KeyboardModifiers modifiers ) override { qDebug() << "MyGraphicsView::addConstraint()"; if ( isReadOnly() ) return; KGantt::ConstraintModel* cmodel = constraintModel(); KGantt::Constraint c( from, to, ( modifiers&Qt::ShiftModifier )?KGantt::Constraint::TypeHard:KGantt::Constraint::TypeSoft ); c.setData( KGantt::Constraint::ValidConstraintPen, QPen( QColor( Qt::green ), 3, Qt::DashLine ) ); c.setData( KGantt::Constraint::InvalidConstraintPen, QPen( QColor( Qt::blue ), 3, Qt::DashLine ) ); if ( cmodel->hasConstraint( c ) ) cmodel->removeConstraint( c ); else cmodel->addConstraint( c ); } }; class MyStandardItem : public QStandardItem { public: MyStandardItem( const QVariant& v ) : QStandardItem() { setData( v, Qt::DisplayRole ); } MyStandardItem( const QString& v ) : QStandardItem() { setData( v, Qt::DisplayRole ); } MyStandardItem( const QDateTime& dt, int role ) : QStandardItem() { setData( QVariant::fromValue( dt ), role ); } }; class MyWidget : public QWidget { Q_OBJECT public: MyWidget() : QWidget( nullptr ) { view.setGraphicsView( new MyGraphicsView ); qDebug() << "Building data"; //proxyModel.setSourceModel( &model ); for ( int h = 0; h < 2; ++h ) { QList items; items << new MyStandardItem( QString::fromLatin1( "Item %1" ).arg( h ) ) << new MyStandardItem( KGantt::TypeTask ) << new MyStandardItem( QDateTime::currentDateTime().addDays( h ), KGantt::StartTimeRole ) << new MyStandardItem( QDateTime::currentDateTime().addDays( h+1 ), KGantt::EndTimeRole ) << new MyStandardItem( 50 ); model.appendRow( items ); } qDebug() << "Creating view"; slider.setOrientation( Qt::Horizontal ); slider.setRange( 1, 10000 ); slider.setValue( 100 ); QVBoxLayout* l = new QVBoxLayout( this ); l->addWidget( &view ); l->addWidget( &slider ); grid.setStartDateTime( QDateTime::currentDateTime().addDays( -3 ) ); grid.setDayWidth( 100 ); //grid.setNoInformationBrush( Qt::NoBrush ); view.setGrid( &grid ); view.setModel(&model); connect( &slider, SIGNAL(valueChanged(int)), this, SLOT(slotZoom(int)) ); } public slots: void slotZoom( int z ) { grid.setDayWidth( z ); } private: KGantt::View view; KGantt::DateTimeGrid grid; QSlider slider; QStandardItemModel model; }; int main( int argc, char** argv ) { QApplication app( argc, argv ); //QPixmapCache::setCacheLimit( 30*1024 ); MyWidget w; w.show(); return app.exec(); } #include "main.moc" diff --git a/tests/Gantt/gfxview/main.cpp b/tests/Gantt/gfxview/main.cpp index 6462478..af98568 100644 --- a/tests/Gantt/gfxview/main.cpp +++ b/tests/Gantt/gfxview/main.cpp @@ -1,151 +1,151 @@ /** * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KGantt library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include class MyRowController : public KGantt::AbstractRowController { private: static const int ROW_HEIGHT; QPointer m_model; public: MyRowController() { } void setModel( QAbstractItemModel* model ) { m_model = model; } - /*reimp*/int headerHeight() const Q_DECL_OVERRIDE { return 40; } + /*reimp*/int headerHeight() const override { return 40; } - /*reimp*/ bool isRowVisible( const QModelIndex& ) const Q_DECL_OVERRIDE { return true;} - /*reimp*/ bool isRowExpanded( const QModelIndex& ) const Q_DECL_OVERRIDE { return false; } - /*reimp*/ KGantt::Span rowGeometry( const QModelIndex& idx ) const Q_DECL_OVERRIDE + /*reimp*/ bool isRowVisible( const QModelIndex& ) const override { return true;} + /*reimp*/ bool isRowExpanded( const QModelIndex& ) const override { return false; } + /*reimp*/ KGantt::Span rowGeometry( const QModelIndex& idx ) const override { qDebug() << "rowGeometry(" << idx.row()<<")"; return KGantt::Span( idx.row()*ROW_HEIGHT, ROW_HEIGHT ); } - /*reimp*/ int maximumItemHeight() const Q_DECL_OVERRIDE { + /*reimp*/ int maximumItemHeight() const override { return ROW_HEIGHT/2; } - /*reimp*/ int totalHeight() const Q_DECL_OVERRIDE { + /*reimp*/ int totalHeight() const override { return m_model.isNull()?0:m_model->rowCount()*ROW_HEIGHT; } - /*reimp*/ QModelIndex indexAt( int height ) const Q_DECL_OVERRIDE { + /*reimp*/ QModelIndex indexAt( int height ) const override { return m_model->index( height/ROW_HEIGHT, 0 ); } - /*reimp*/ QModelIndex indexBelow( const QModelIndex& idx ) const Q_DECL_OVERRIDE { + /*reimp*/ QModelIndex indexBelow( const QModelIndex& idx ) const override { if ( !idx.isValid() )return QModelIndex(); return idx.model()->index( idx.row()+1, idx.column(), idx.parent() ); } - /*reimp*/ QModelIndex indexAbove( const QModelIndex& idx ) const Q_DECL_OVERRIDE { + /*reimp*/ QModelIndex indexAbove( const QModelIndex& idx ) const override { if ( !idx.isValid() )return QModelIndex(); return idx.model()->index( idx.row()-1, idx.column(), idx.parent() ); } }; const int MyRowController::ROW_HEIGHT = 30; class MyStandardItemModel : public QStandardItemModel { public: - /*reimp*/bool setData( const QModelIndex& idx, const QVariant& value, int role ) Q_DECL_OVERRIDE + /*reimp*/bool setData( const QModelIndex& idx, const QVariant& value, int role ) override { //qDebug() << "MyStandardItemModel::setData("<setReadOnly(true); view->setRowController( rowController ); view->show(); MyStandardItemModel model; for ( int i = 0; i < 10; ++i ) { QList items; for ( int j = 0; j < 10; ++j ) { QStandardItem* item = new QStandardItem; //for ( int col = 0; col < 5; ++col ) { // QStandardItem* colitem = new QStandardItem; item->setText( QString::fromLatin1( "Item %1" ).arg( i ) ); item->setData( KGantt::TypeTask, KGantt::ItemTypeRole ); item->setData( QDateTime::currentDateTime().addDays( 2*j ).addMSecs( 100000*i ), KGantt::StartTimeRole ); item->setData( QDateTime::currentDateTime().addDays( 2*j+1 ).addMSecs( 100000*i ), KGantt::EndTimeRole ); item->setData( QVariant::fromValue( random_alignment() ), Qt::TextAlignmentRole ); item->setData( QVariant::fromValue( random_position()), KGantt::TextPositionRole ); item->setFlags( item->flags() & ~Qt::ItemIsSelectable ); // item->appendColumn( QList() << colitem ); //} items.push_back( item ); } model.appendRow( items ); } qDebug() << &model; rowController->setModel( &model ); view->setModel( &model ); #if 0 QPushButton* pb = new QPushButton( QObject::tr( "Reset" ) ); QObject::connect( pb, SIGNAL(clicked()), &model, SIGNAL(modelReset()) ); pb->show(); #endif return app.exec(); //return 0; } diff --git a/tests/Gantt/headers/main.cpp b/tests/Gantt/headers/main.cpp index e3bb6e6..6b4cd5f 100644 --- a/tests/Gantt/headers/main.cpp +++ b/tests/Gantt/headers/main.cpp @@ -1,117 +1,117 @@ /** * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KGantt library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include #include using namespace KGantt; /* A custom formatter that displays tabs for every 10 minutes. */ class MyDateTimeScaleFormatter : public DateTimeScaleFormatter { public: MyDateTimeScaleFormatter(); - /*reimp*/QDateTime nextRangeBegin( const QDateTime& datetime ) const Q_DECL_OVERRIDE; - /*reimp*/QDateTime currentRangeBegin( const QDateTime& datetime ) const Q_DECL_OVERRIDE; + /*reimp*/QDateTime nextRangeBegin( const QDateTime& datetime ) const override; + /*reimp*/QDateTime currentRangeBegin( const QDateTime& datetime ) const override; - /*reimp*/QString text( const QDateTime& dt ) const Q_DECL_OVERRIDE; + /*reimp*/QString text( const QDateTime& dt ) const override; }; MyDateTimeScaleFormatter::MyDateTimeScaleFormatter() : DateTimeScaleFormatter( Hour, "hh" ) { } QDateTime MyDateTimeScaleFormatter::nextRangeBegin( const QDateTime& datetime ) const { return currentRangeBegin( datetime ).addSecs( 60*10 ); } QDateTime MyDateTimeScaleFormatter::currentRangeBegin( const QDateTime& datetime ) const { QDateTime dt( datetime ); dt.setTime( QTime( dt.time().hour(), ( dt.time().minute()/10 ) * 10, 0, 0 ) ); return dt; } QString MyDateTimeScaleFormatter::text( const QDateTime& dt ) const { return QObject::tr( ":%1\nXX" ).arg( dt.time().toString( "mm" ) ); } /* A custom headerview that is taller than standard * so we can fit more lines into it on the graphicsview * side. */ class MyHeaderView : public QHeaderView { public: explicit MyHeaderView( QWidget* parent = nullptr ) : QHeaderView( Qt::Horizontal, parent ) { } - /*reimp*/QSize sizeHint() const Q_DECL_OVERRIDE { + /*reimp*/QSize sizeHint() const override { QSize s = QHeaderView::sizeHint(); s.rheight() *= 3; return s; } }; int main( int argc, char** argv ) { QApplication app( argc, argv ); QStandardItemModel model( 1, 1 ); model.setHeaderData( 0, Qt::Horizontal, QObject::tr( "Task" ) ); /*** A view with some alternative header labels ***/ View view1; DateTimeGrid grid1; grid1.setUserDefinedUpperScale( new DateTimeScaleFormatter( DateTimeScaleFormatter::Year, QString::fromLatin1( "yyyy" ), QString::fromLatin1( "In the year %1." ), Qt::AlignLeft ) ); grid1.setUserDefinedLowerScale( new DateTimeScaleFormatter( DateTimeScaleFormatter::Month, QString::fromLatin1( "MMMM" ), QString::fromLatin1( "In the month %1." ), Qt::AlignRight ) ); grid1.setScale( DateTimeGrid::ScaleUserDefined ); grid1.setDayWidth( 6. ); view1.setGrid( &grid1 ); view1.setModel( &model ); view1.show(); /*** A view with header and vertical grid lines for every 10 minutes */ View view2; QTreeView* tw = qobject_cast( view2.leftView() ); if ( tw ) tw->setHeader( new MyHeaderView ); DateTimeGrid grid2; grid2.setDayWidth( 5000 ); grid2.setUserDefinedUpperScale( new DateTimeScaleFormatter( DateTimeScaleFormatter::Hour, QString::fromLatin1( "hh" ) ) ); grid2.setUserDefinedLowerScale( new MyDateTimeScaleFormatter ); grid2.setScale( DateTimeGrid::ScaleUserDefined ); view2.setGrid( &grid2 ); view2.setModel( &model ); view2.show(); return app.exec(); } diff --git a/tests/Gantt/reorder/main.cpp b/tests/Gantt/reorder/main.cpp index 8a2fd29..0077766 100644 --- a/tests/Gantt/reorder/main.cpp +++ b/tests/Gantt/reorder/main.cpp @@ -1,173 +1,173 @@ /** * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. * * This file is part of the KGantt library. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include #include /* Test model that uses beginMoveRows() */ class MyTaskModel : public QAbstractTableModel { struct Task { QString title; QDateTime start, end; }; QList m_tasks; public: MyTaskModel( QObject* parent = nullptr ) : QAbstractTableModel( parent ) { Task task; task.title = tr( "Item 1" ); task.start = QDateTime::currentDateTime(); task.end = task.start.addDays( 1 ); m_tasks.push_back( task ); task.title = tr( "Item 2" ); task.start = QDateTime::currentDateTime().addDays( 2 ); task.end = task.start.addDays( 1 ); m_tasks.push_back( task ); task.title = tr( "Item 3" ); task.start = QDateTime::currentDateTime().addDays( 4 ); task.end = task.start.addDays( 1 ); m_tasks.push_back( task ); task.title = tr( "Item 4" ); task.start = QDateTime::currentDateTime().addDays( 6 ); task.end = task.start.addDays( 1 ); m_tasks.push_back( task ); } - /*reimp*/int rowCount( const QModelIndex& index = QModelIndex() ) const Q_DECL_OVERRIDE { + /*reimp*/int rowCount( const QModelIndex& index = QModelIndex() ) const override { return index.isValid()?0:m_tasks.size(); } - /*reimp*/int columnCount( const QModelIndex& index = QModelIndex() ) const Q_DECL_OVERRIDE { + /*reimp*/int columnCount( const QModelIndex& index = QModelIndex() ) const override { return index.isValid()?0:4; } - /*reimp*/QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const Q_DECL_OVERRIDE + /*reimp*/QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const override { if ( index.isValid() && index.row() < rowCount() && index.column() < columnCount() ) { switch ( index.column() ) { case 0: return ( role == Qt::DisplayRole ) ?QVariant::fromValue( m_tasks[index.row()].title ) :QVariant(); case 1: return ( role == Qt::DisplayRole ) ?QVariant::fromValue( ( int )KGantt::TypeTask ) :QVariant(); case 2: return ( role == KGantt::StartTimeRole || role == Qt::DisplayRole ) ?QVariant::fromValue( m_tasks[index.row()].start ) :QVariant(); case 3: return ( role == KGantt::EndTimeRole || role == Qt::DisplayRole) ?QVariant::fromValue( m_tasks[index.row()].end ) :QVariant(); } } return QVariant(); } void moveRow( int from, int to ) { if ( from == to ) return; if ( from >= m_tasks.size() || to >= m_tasks.size()+1 ) return; if ( beginMoveRows( QModelIndex(), from, from, QModelIndex(), to ) ) { m_tasks.move( from, to ); endMoveRows(); } else { assert( 0 ); } } }; /* Test class to see the effect of moving rows */ class MoveHelper : public QObject { public: MoveHelper( MyTaskModel* model, KGantt::ConstraintModel*, KGantt::View*, #if 0 KGantt::ConstraintModel* constraints, KGantt::View* view, #endif int row1, int row2 ) : QObject( model ), m_model( model ), #if 0 m_constraints( constraints ), m_view( view ), #endif m_row1( row1 ), m_row2( row2 ) { } void showContraints( const QString& /*pfx*/ ) { #if 0 qDebug() << pfx << *m_constraints; qDebug() << "0:" << m_constraints->constraintsForIndex( m_model->index( 0, 0 ) ); qDebug() << "1:"<< m_constraints->constraintsForIndex( m_model->index( 1, 0 ) ); qDebug() << "2:"<< m_constraints->constraintsForIndex( m_model->index( 2, 0 ) ); qDebug() << "3:"<< m_constraints->constraintsForIndex( m_model->index( 3, 0 ) ); #endif } ~MoveHelper() { qDebug() << "Moving row" << m_row1 << "to" << m_row2; showContraints( "Before:" ); m_model->moveRow( m_row1, m_row2 ); showContraints( "After:" ); // Hack until KGantt supports this: //m_view->setConstraintModel( m_constraints ); } private: MyTaskModel* m_model; #if 0 KGantt::ConstraintModel* m_constraints; KGantt::View* m_view; #endif int m_row1, m_row2; }; int main( int argc, char** argv ) { QApplication app( argc, argv ); KGantt::View* view = new KGantt::View; MyTaskModel model; KGantt::ConstraintModel constraints; constraints.addConstraint( KGantt::Constraint( model.index( 0, 0 ), model.index( 1, 0 ) ) ); constraints.addConstraint( KGantt::Constraint( model.index( 0, 0 ), model.index( 2, 0 ) ) ); constraints.addConstraint( KGantt::Constraint( model.index( 1, 0 ), model.index( 3, 0 ) ) ); view->setModel( &model ); view->setConstraintModel( &constraints ); view->show(); /* After 5 seconds, move row 1 to pos 0: */ QTimer::singleShot( 5000, new MoveHelper( &model, &constraints, view, 1, 0 ), SLOT(deleteLater()) ); return app.exec(); }