File indexing completed on 2024-06-16 04:09:00

0001 /**
0002  * SPDX-FileCopyrightText: 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved.
0003  *
0004  * This file is part of the KD Chart library.
0005  *
0006  * SPDX-License-Identifier: GPL-2.0-or-later
0007  */
0008 
0009 #include "mainwindow.h"
0010 
0011 #include <KChartChart>
0012 #include <KChartLegend>
0013 #include <KChartPosition>
0014 #include <KChartLineDiagram>
0015 #include <KChartTextAttributes>
0016 #include <QComboBox>
0017 #include <QLineEdit>
0018 
0019 class LegendItem : public QTreeWidgetItem
0020 {
0021 public:
0022     LegendItem( KChart::Legend* legend, QTreeWidget* parent ) :
0023         QTreeWidgetItem( parent ), m_legend( legend ) {}
0024 
0025     KChart::Legend* legend() const { return m_legend; }
0026 
0027 private:
0028     KChart::Legend* m_legend;
0029 };
0030 
0031 
0032 MainWindow::MainWindow( QWidget* parent ) :
0033     QWidget( parent )
0034 {
0035     setupUi( this );
0036 
0037     QHBoxLayout* chartLayout = new QHBoxLayout( chartFrame );
0038     m_chart = new KChart::Chart();
0039     chartLayout->addWidget( m_chart );
0040 
0041     m_model.loadFromCSV( ":/data" );
0042 
0043     // Set up the diagram
0044     m_lines = new KChart::LineDiagram();
0045     m_lines->setModel( &m_model );
0046     m_chart->coordinatePlane()->replaceDiagram( m_lines );
0047 
0048     QPen pen = QPen( m_lines->pen(0).color(), 2 );
0049     pen.setStyle( Qt::DashLine );
0050     m_lines->setPen( 0, pen );
0051     pen = QPen( m_lines->pen(2).color(), 2 );
0052     pen.setStyle( Qt::DashDotDotLine );
0053     m_lines->setPen( 2, pen );
0054 
0055     // Add at least one legend for starters
0056     KChart::Legend* legend = new KChart::Legend( m_lines, m_chart );
0057     legend->setPosition( KChart::Position::North );
0058     legend->setAlignment( Qt::AlignCenter );
0059     legend->setShowLines( false );
0060     legend->setTitleText( tr( "Legend" ) );
0061     legend->setOrientation( Qt::Vertical );
0062     m_chart->addLegend( legend );
0063     legend->show();
0064 
0065     LegendItem* newItem = new LegendItem( legend, legendsTV );
0066     newItem->setText( 0, tr( "North" ) );
0067     newItem->setText( 1, tr( "no" ) );
0068     newItem->setText( 2, tr( "Legend" ) );
0069     newItem->setText( 3, tr( "Vertical" ) );
0070     newItem->setText( 4, tr( "Center") );
0071     newItem->setText( 5, tr( "MarkersOnly" ) );
0072 
0073     alignmentMap[ Qt::AlignTop     | Qt::AlignLeft]    = tr("Top + Left");
0074     alignmentMap[ Qt::AlignTop     | Qt::AlignHCenter] = tr("Top + HCenter");
0075     alignmentMap[ Qt::AlignTop     | Qt::AlignRight]   = tr("Top + Right");
0076     alignmentMap[ Qt::AlignVCenter | Qt::AlignRight]   = tr("VCenter + Right");
0077     alignmentMap[ Qt::AlignBottom  | Qt::AlignRight]   = tr("Bottom + Right");
0078     alignmentMap[ Qt::AlignBottom  | Qt::AlignHCenter] = tr("Bottom + HCenter");
0079     alignmentMap[ Qt::AlignBottom  | Qt::AlignLeft]    = tr("Bottom + Left");
0080     alignmentMap[ Qt::AlignVCenter | Qt::AlignLeft]    = tr("VCenter + Left");
0081     alignmentMap[ Qt::AlignCenter]                     = tr("Center");
0082 
0083     m_chart->update();
0084 }
0085 
0086 
0087 void MainWindow::initAddLegendDialog( DerivedAddLegendDialog& conf,
0088                                       Qt::Alignment alignment ) const
0089 {
0090     conf.titleTextED->setFocus();
0091 
0092     // Note: Legend position can be Floating but it can not be Center
0093     const QStringList labels = KChart::Position::printableNames( KChart::Position::IncludeFloating );
0094     const QList<QByteArray> names = KChart::Position::names( KChart::Position::IncludeFloating );
0095 
0096 
0097     for ( int i = 0, end = qMin( labels.size(), names.size() ) ; i != end ; ++i )
0098         conf.positionCO->addItem( labels[i], names[i] );
0099 
0100     QMap<Qt::Alignment, QString>::const_iterator it = alignmentMap.constBegin();
0101     while (it != alignmentMap.constEnd()) {
0102         conf.alignmentCO->addItem( it.value() );
0103         ++it;
0104     }
0105     const int idx = conf.alignmentCO->findText( alignmentMap[ alignment ] );
0106     if ( idx > -1 )
0107         conf.alignmentCO->setCurrentIndex( idx );
0108 }
0109 
0110 void MainWindow::on_addLegendPB_clicked()
0111 {
0112     DerivedAddLegendDialog conf;
0113     initAddLegendDialog( conf, Qt::AlignCenter );
0114     if ( conf.exec() == QDialog::Accepted ) {
0115         KChart::Legend* legend = new KChart::Legend( m_lines, m_chart );
0116         m_chart->addLegend( legend );
0117         legend->setPosition(
0118             KChart::Position::fromName( conf.positionCO->itemData( conf.positionCO->currentIndex() ).toByteArray() ) );
0119         // get the alignment
0120         Qt::Alignment alignment = Qt::AlignCenter;
0121         const QString selectedAlignment( conf.alignmentCO->currentText() );
0122         QMap<Qt::Alignment, QString>::const_iterator i = alignmentMap.constBegin();
0123         while ( i != alignmentMap.constEnd() ) {
0124             if ( i.value() == selectedAlignment ) {
0125                 alignment = i.key();
0126                 break;
0127             }
0128             ++i;
0129         }
0130         legend->setAlignment( alignment );
0131         legend->setShowLines( conf.showLinesCB->isChecked() );
0132         legend->setTitleText( conf.titleTextED->text() );
0133         legend->setOrientation( ( conf.orientationCO->currentIndex() == 0 ) ? Qt::Vertical : Qt::Horizontal );
0134 
0135         switch ( conf.styleCO->currentIndex() )
0136         {
0137         case 0:
0138             legend->setLegendStyle( KChart::Legend::MarkersOnly );
0139             break;
0140         case 1:
0141             legend->setLegendStyle( KChart::Legend::LinesOnly );
0142             break;
0143         case 2:
0144             legend->setLegendStyle(KChart::Legend::MarkersAndLines );
0145             break;
0146         default:
0147             legend->setLegendStyle( KChart::Legend::MarkersOnly );
0148             break;
0149         }
0150 
0151         LegendItem* newItem = new LegendItem( legend, legendsTV );
0152         newItem->setText( 0, conf.positionCO->currentText() );
0153         newItem->setText( 1, conf.showLinesCB->isChecked() ? tr( "yes" ) : tr( "no" ) );
0154         newItem->setText( 2, conf.titleTextED->text() );
0155         newItem->setText( 3, conf.orientationCO->currentText() );
0156         newItem->setText( 4, selectedAlignment );
0157         newItem->setText( 5, conf.styleCO->currentText() );
0158         m_chart->update();
0159     }
0160 }
0161 
0162 
0163 void MainWindow::on_editLegendPB_clicked()
0164 {
0165     if ( legendsTV->selectedItems().size() == 0 ) return;
0166     LegendItem* item = static_cast<LegendItem*>( legendsTV->selectedItems().first() );
0167     KChart::Legend* legend = item->legend();
0168     DerivedAddLegendDialog conf;
0169     initAddLegendDialog( conf, legend->alignment() );
0170     conf.showLinesCB->setChecked( legend->showLines() );
0171     conf.titleTextED->setText( legend->titleText() );
0172     legend->setLegendSymbolAlignment(Qt::AlignBottom);
0173 
0174     // In this example we are using legend position names, that match
0175     // exactly the names in KChart::Legend::LegendPosition,
0176     // so we can use a shortcut here, to set the respective name in
0177     // the dialog's list, and we need no error checking for findText():
0178     conf.positionCO->setCurrentIndex(
0179             conf.positionCO->findText( legend->position().printableName() ) );
0180     conf.orientationCO->setCurrentIndex( ( legend->orientation() == Qt::Vertical ) ? 0 : 1 );
0181     conf.styleCO->setCurrentIndex( legend->legendStyle() );
0182 
0183     if ( conf.exec() == QDialog::Accepted ) {
0184         //legend->setPosition( (KChart::Legend::LegendPosition)conf.positionCO->currentIndex() );
0185         legend->setPosition(
0186             KChart::Position::fromName( conf.positionCO->itemData( conf.positionCO->currentIndex() ).toByteArray() ) );
0187         // get the alignment
0188         Qt::Alignment alignment = Qt::AlignCenter;
0189         const QString selectedAlignment( conf.alignmentCO->currentText() );
0190         QMap<Qt::Alignment, QString>::const_iterator i = alignmentMap.constBegin();
0191         while ( i != alignmentMap.constEnd() ) {
0192             if ( i.value() == selectedAlignment ) {
0193                 alignment = i.key();
0194                 break;
0195             }
0196             ++i;
0197         }
0198         legend->setAlignment( alignment );
0199         legend->setShowLines( conf.showLinesCB->isChecked() );
0200         legend->setTitleText( conf.titleTextED->text() );
0201         legend->setOrientation( ( conf.orientationCO->currentIndex() == 0 ) ? Qt::Vertical : Qt::Horizontal );
0202 
0203         switch ( conf.styleCO->currentIndex() )
0204         {
0205         case 0:
0206             legend->setLegendStyle( KChart::Legend::MarkersOnly );
0207             break;
0208         case 1:
0209             legend->setLegendStyle( KChart::Legend::LinesOnly );
0210             break;
0211         case 2:
0212             legend->setLegendStyle(KChart::Legend::MarkersAndLines );
0213             break;
0214         default:
0215             legend->setLegendStyle( KChart::Legend::MarkersOnly );
0216             break;
0217         }
0218 
0219         item->setText( 0, conf.positionCO->currentText() );
0220         item->setText( 1, conf.showLinesCB->isChecked() ? tr("yes") : tr("no") );
0221         item->setText( 2, conf.titleTextED->text() );
0222         item->setText( 3, conf.orientationCO->currentText() );
0223         item->setText( 4, selectedAlignment );
0224         item->setText( 5, conf.styleCO->currentText() );
0225         m_chart->update();
0226     }
0227 }
0228 
0229 
0230 
0231 void MainWindow::on_removeLegendPB_clicked()
0232 {
0233     if ( legendsTV->selectedItems().size() == 0 ) return;
0234     QList<QTreeWidgetItem*> items = legendsTV->selectedItems();
0235     for ( QList<QTreeWidgetItem*>::iterator it = items.begin();
0236          it != items.end(); ++it )
0237     {
0238         KChart::Legend* legend = static_cast<LegendItem*>( (*it) )->legend();
0239 #if 0
0240         // Note: Despite it being owned by the Chart, you *can* just delete
0241         //       the legend: KD Chart will notice that and adjust its layout ...
0242         delete legend;
0243 #else
0244         // ... but the correct way is to first take it, so the Chart is no longer owning it:
0245         m_chart->takeLegend( legend );
0246         // ... and then delete it:
0247         delete legend;
0248 #endif
0249         delete (*it);
0250     }
0251     m_chart->update();
0252 }
0253 
0254 void MainWindow::on_legendsTV_itemSelectionChanged()
0255 {
0256     removeLegendPB->setEnabled( legendsTV->selectedItems().count() > 0 );
0257     removeLegendPB->setEnabled( legendsTV->selectedItems().count() == 1 );
0258 }