##// END OF EJS Templates
Add dialog of chartwidgettest now remembers selections
Tero Ahola -
r376:173abb78cc61
parent child
Show More
@@ -1,145 +1,165
1 #include "dataseriedialog.h"
1 #include "dataseriedialog.h"
2 #include <QDialogButtonBox>
2 #include <QDialogButtonBox>
3 #include <QGridLayout>
3 #include <QGridLayout>
4 #include <QCheckBox>
4 #include <QCheckBox>
5 #include <QPushButton>
5 #include <QPushButton>
6 #include <QGroupBox>
6 #include <QGroupBox>
7 #include <QRadioButton>
7 #include <QRadioButton>
8 #include <QLabel>
8 #include <QLabel>
9 #include <QDebug>
9 #include <QDebug>
10
10
11 DataSerieDialog::DataSerieDialog(QString defaultType, QWidget *parent) :
11 DataSerieDialog::DataSerieDialog(QWidget *parent) :
12 QDialog(parent)
12 QDialog(parent)
13 {
13 {
14 QDialogButtonBox *addSeriesBox = new QDialogButtonBox(Qt::Horizontal);
14 QDialogButtonBox *addSeriesBox = new QDialogButtonBox(Qt::Horizontal);
15 QPushButton *b = addSeriesBox->addButton(QDialogButtonBox::Ok);
15 QPushButton *b = addSeriesBox->addButton(QDialogButtonBox::Ok);
16 connect(b, SIGNAL(clicked()), this, SLOT(accept()));
16 connect(b, SIGNAL(clicked()), this, SLOT(accept()));
17 b = addSeriesBox->addButton(QDialogButtonBox::Cancel);
17 b = addSeriesBox->addButton(QDialogButtonBox::Cancel);
18 connect(b, SIGNAL(clicked()), this, SLOT(reject()));
18 connect(b, SIGNAL(clicked()), this, SLOT(reject()));
19
19
20 QGridLayout *grid = new QGridLayout();
20 QGridLayout *grid = new QGridLayout();
21
21
22 m_seriesTypeSelector = seriesTypeSelector();
22 m_seriesTypeSelector = seriesTypeSelector();
23 m_columnCountSelector = columnCountSelector();
23 m_columnCountSelector = columnCountSelector();
24 m_rowCountSelector = rowCountSelector();
24 m_rowCountSelector = rowCountSelector();
25 m_dataCharacteristicsSelector = dataCharacteristicsSelector();
25 m_dataCharacteristicsSelector = dataCharacteristicsSelector();
26
26
27 grid->addWidget(m_seriesTypeSelector, 0, 0);
27 grid->addWidget(m_seriesTypeSelector, 0, 0);
28 grid->addWidget(m_columnCountSelector, 0, 1);
28 grid->addWidget(m_columnCountSelector, 0, 1);
29 grid->addWidget(m_rowCountSelector, 1, 1);
29 grid->addWidget(m_rowCountSelector, 1, 1);
30 grid->addWidget(m_dataCharacteristicsSelector, 1, 0);
30 grid->addWidget(m_dataCharacteristicsSelector, 1, 0);
31 m_labelsSelector = new QCheckBox("Labels defined");
31 m_labelsSelector = new QCheckBox("Labels defined");
32 m_labelsSelector->setChecked(true);
32 m_labelsSelector->setChecked(true);
33 grid->addWidget(m_labelsSelector, 2, 0);
33 grid->addWidget(m_labelsSelector, 2, 0);
34 grid->addWidget(addSeriesBox, 3, 1);
34 grid->addWidget(addSeriesBox, 3, 1);
35
35
36 setLayout(grid);
36 setLayout(grid);
37 }
37 }
38
38
39 QGroupBox *DataSerieDialog::seriesTypeSelector()
39 QGroupBox *DataSerieDialog::seriesTypeSelector()
40 {
40 {
41 QVBoxLayout *layout = new QVBoxLayout();
41 QVBoxLayout *layout = new QVBoxLayout();
42
42
43 QRadioButton *line = new QRadioButton("Line");
43 QRadioButton *line = new QRadioButton("Line");
44 line->setChecked(true);
44 line->setChecked(true);
45 layout->addWidget(line);
45 layout->addWidget(line);
46 layout->addWidget(new QRadioButton("Area"));
46 layout->addWidget(new QRadioButton("Area"));
47 layout->addWidget(new QRadioButton("Pie"));
47 layout->addWidget(new QRadioButton("Pie"));
48 layout->addWidget(new QRadioButton("Bar"));
48 layout->addWidget(new QRadioButton("Bar"));
49 layout->addWidget(new QRadioButton("Stacked bar"));
49 layout->addWidget(new QRadioButton("Stacked bar"));
50 layout->addWidget(new QRadioButton("Percent bar"));
50 layout->addWidget(new QRadioButton("Percent bar"));
51 layout->addWidget(new QRadioButton("Scatter"));
51 layout->addWidget(new QRadioButton("Scatter"));
52 layout->addWidget(new QRadioButton("Spline"));
52 layout->addWidget(new QRadioButton("Spline"));
53
53
54 QGroupBox *groupBox = new QGroupBox("Series type");
54 QGroupBox *groupBox = new QGroupBox("Series type");
55 groupBox->setLayout(layout);
55 groupBox->setLayout(layout);
56 selectRadio(groupBox, 0);
56
57
57 return groupBox;
58 return groupBox;
58 }
59 }
59
60
60 QGroupBox *DataSerieDialog::columnCountSelector()
61 QGroupBox *DataSerieDialog::columnCountSelector()
61 {
62 {
62 QVBoxLayout *layout = new QVBoxLayout();
63 QVBoxLayout *layout = new QVBoxLayout();
63
64
64 QRadioButton *radio = new QRadioButton("1");
65 QRadioButton *radio = new QRadioButton("1");
65 radio->setChecked(true);
66 radio->setChecked(true);
66 layout->addWidget(radio);
67 layout->addWidget(radio);
67 layout->addWidget(new QRadioButton("2"));
68 layout->addWidget(new QRadioButton("2"));
68 layout->addWidget(new QRadioButton("3"));
69 layout->addWidget(new QRadioButton("3"));
69 layout->addWidget(new QRadioButton("5"));
70 layout->addWidget(new QRadioButton("5"));
70 layout->addWidget(new QRadioButton("10"));
71 layout->addWidget(new QRadioButton("10"));
71 layout->addWidget(new QRadioButton("100"));
72 layout->addWidget(new QRadioButton("100"));
72
73
73 QGroupBox *groupBox = new QGroupBox("Column count");
74 QGroupBox *groupBox = new QGroupBox("Column count");
74 groupBox->setLayout(layout);
75 groupBox->setLayout(layout);
76 selectRadio(groupBox, 0);
75
77
76 return groupBox;
78 return groupBox;
77 }
79 }
78
80
79 QGroupBox *DataSerieDialog::rowCountSelector()
81 QGroupBox *DataSerieDialog::rowCountSelector()
80 {
82 {
81 QVBoxLayout *layout = new QVBoxLayout();
83 QVBoxLayout *layout = new QVBoxLayout();
82
84
83 layout->addWidget(new QRadioButton("1"));
85 layout->addWidget(new QRadioButton("1"));
84 QRadioButton *radio = new QRadioButton("10");
86 QRadioButton *radio = new QRadioButton("10");
85 radio->setChecked(true);
87 radio->setChecked(true);
86 layout->addWidget(radio);
88 layout->addWidget(radio);
87 layout->addWidget(new QRadioButton("50"));
89 layout->addWidget(new QRadioButton("50"));
88 layout->addWidget(new QRadioButton("100"));
90 layout->addWidget(new QRadioButton("100"));
89 layout->addWidget(new QRadioButton("10000"));
91 layout->addWidget(new QRadioButton("10000"));
90 layout->addWidget(new QRadioButton("1000000"));
92 layout->addWidget(new QRadioButton("1000000"));
91
93
92 QGroupBox *groupBox = new QGroupBox("Row count");
94 QGroupBox *groupBox = new QGroupBox("Row count");
93 groupBox->setLayout(layout);
95 groupBox->setLayout(layout);
96 selectRadio(groupBox, 0);
94
97
95 return groupBox;
98 return groupBox;
96 }
99 }
97
100
98 QGroupBox *DataSerieDialog::dataCharacteristicsSelector()
101 QGroupBox *DataSerieDialog::dataCharacteristicsSelector()
99 {
102 {
100 QVBoxLayout *layout = new QVBoxLayout();
103 QVBoxLayout *layout = new QVBoxLayout();
101
104
102 QRadioButton *radio1 = new QRadioButton("Linear");
105 layout->addWidget(new QRadioButton("Linear"));
103 radio1->setChecked(true);
104 layout->addWidget(radio1);
105 layout->addWidget(new QRadioButton("Constant"));
106 layout->addWidget(new QRadioButton("Constant"));
106 layout->addWidget(new QRadioButton("Random"));
107 layout->addWidget(new QRadioButton("Random"));
107 layout->addWidget(new QRadioButton("Sin"));
108 layout->addWidget(new QRadioButton("Sin"));
108 layout->addWidget(new QRadioButton("Sin + random"));
109 layout->addWidget(new QRadioButton("Sin + random"));
109
110
110 QGroupBox *groupBox = new QGroupBox("Data Characteristics");
111 QGroupBox *groupBox = new QGroupBox("Data Characteristics");
111 groupBox->setLayout(layout);
112 groupBox->setLayout(layout);
113 selectRadio(groupBox, 0);
112
114
113 return groupBox;
115 return groupBox;
114 }
116 }
115
117
116 void DataSerieDialog::accept()
118 void DataSerieDialog::accept()
117 {
119 {
118 accepted(radioSelection(m_seriesTypeSelector),
120 accepted(radioSelection(m_seriesTypeSelector),
119 radioSelection(m_columnCountSelector).toInt(),
121 radioSelection(m_columnCountSelector).toInt(),
120 radioSelection(m_rowCountSelector).toInt(),
122 radioSelection(m_rowCountSelector).toInt(),
121 radioSelection(m_dataCharacteristicsSelector),
123 radioSelection(m_dataCharacteristicsSelector),
122 m_labelsSelector->isChecked());
124 m_labelsSelector->isChecked());
123 QDialog::accept();
125 QDialog::accept();
124 }
126 }
125
127
128 void DataSerieDialog::selectRadio(QGroupBox *groupBox, int defaultSelection)
129 {
130 QVBoxLayout *layout = qobject_cast<QVBoxLayout *>(groupBox->layout());
131 Q_ASSERT(layout);
132 Q_ASSERT(layout->count());
133
134 QLayoutItem *item = 0;
135 if (defaultSelection == -1) {
136 item = layout->itemAt(0);
137 } else if (layout->count() > defaultSelection) {
138 item = layout->itemAt(defaultSelection);
139 }
140 Q_ASSERT(item);
141 QRadioButton *radio = qobject_cast<QRadioButton *>(item->widget());
142 Q_ASSERT(radio);
143 radio->setChecked(true);
144 }
145
126 QString DataSerieDialog::radioSelection(QGroupBox *groupBox)
146 QString DataSerieDialog::radioSelection(QGroupBox *groupBox)
127 {
147 {
128 QString selection;
148 QString selection;
129 QVBoxLayout *layout = qobject_cast<QVBoxLayout *>(groupBox->layout());
149 QVBoxLayout *layout = qobject_cast<QVBoxLayout *>(groupBox->layout());
130 Q_ASSERT(layout);
150 Q_ASSERT(layout);
131
151
132 for (int i(0); i < layout->count(); i++) {
152 for (int i(0); i < layout->count(); i++) {
133 QLayoutItem *item = layout->itemAt(i);
153 QLayoutItem *item = layout->itemAt(i);
134 Q_ASSERT(item);
154 Q_ASSERT(item);
135 QRadioButton *radio = qobject_cast<QRadioButton *>(item->widget());
155 QRadioButton *radio = qobject_cast<QRadioButton *>(item->widget());
136 Q_ASSERT(radio);
156 Q_ASSERT(radio);
137 if (radio->isChecked()) {
157 if (radio->isChecked()) {
138 selection = radio->text();
158 selection = radio->text();
139 break;
159 break;
140 }
160 }
141 }
161 }
142
162
143 qDebug() << "radioSelection: " << selection;
163 qDebug() << "radioSelection: " << selection;
144 return selection;
164 return selection;
145 }
165 }
@@ -1,34 +1,35
1 #ifndef DATASERIEDIALOG_H
1 #ifndef DATASERIEDIALOG_H
2 #define DATASERIEDIALOG_H
2 #define DATASERIEDIALOG_H
3
3
4 #include <QDialog>
4 #include <QDialog>
5
5
6 class QGroupBox;
6 class QGroupBox;
7 class QCheckBox;
7 class QCheckBox;
8
8
9 class DataSerieDialog : public QDialog
9 class DataSerieDialog : public QDialog
10 {
10 {
11 Q_OBJECT
11 Q_OBJECT
12 public:
12 public:
13 explicit DataSerieDialog(QString defaultType, QWidget *parent = 0);
13 explicit DataSerieDialog(QWidget *parent = 0);
14
14
15 signals:
15 signals:
16 void accepted(QString series, int columnCount, int rowCount, QString dataCharacteristics, bool labelsDefined);
16 void accepted(QString series, int columnCount, int rowCount, QString dataCharacteristics, bool labelsDefined);
17
17
18 public slots:
18 public slots:
19 void accept();
19 void accept();
20
20
21 private:
21 private:
22 QGroupBox *seriesTypeSelector();
22 QGroupBox *seriesTypeSelector();
23 QGroupBox *columnCountSelector();
23 QGroupBox *columnCountSelector();
24 QGroupBox *rowCountSelector();
24 QGroupBox *rowCountSelector();
25 QGroupBox *dataCharacteristicsSelector();
25 QGroupBox *dataCharacteristicsSelector();
26 void selectRadio(QGroupBox *groupBox, int defaultSelection);
26 QString radioSelection(QGroupBox *groupBox);
27 QString radioSelection(QGroupBox *groupBox);
27 QGroupBox *m_seriesTypeSelector;
28 QGroupBox *m_seriesTypeSelector;
28 QGroupBox *m_columnCountSelector;
29 QGroupBox *m_columnCountSelector;
29 QGroupBox *m_rowCountSelector;
30 QGroupBox *m_rowCountSelector;
30 QCheckBox *m_labelsSelector;
31 QCheckBox *m_labelsSelector;
31 QGroupBox *m_dataCharacteristicsSelector;
32 QGroupBox *m_dataCharacteristicsSelector;
32 };
33 };
33
34
34 #endif // DATASERIEDIALOG_H
35 #endif // DATASERIEDIALOG_H
@@ -1,371 +1,375
1 #include "mainwidget.h"
1 #include "mainwidget.h"
2 #include "dataseriedialog.h"
2 #include "dataseriedialog.h"
3 #include "qpieseries.h"
3 #include "qpieseries.h"
4 #include "qscatterseries.h"
4 #include "qscatterseries.h"
5 #include <qlineseries.h>
5 #include <qlineseries.h>
6 #include <qbarset.h>
6 #include <qbarset.h>
7 #include <qbarcategory.h>
7 #include <qbarcategory.h>
8 #include <qbarseries.h>
8 #include <qbarseries.h>
9 #include <qstackedbarseries.h>
9 #include <qstackedbarseries.h>
10 #include <qpercentbarseries.h>
10 #include <qpercentbarseries.h>
11 #include <QPushButton>
11 #include <QPushButton>
12 #include <QComboBox>
12 #include <QComboBox>
13 #include <QSpinBox>
13 #include <QSpinBox>
14 #include <QCheckBox>
14 #include <QCheckBox>
15 #include <QGridLayout>
15 #include <QGridLayout>
16 #include <QHBoxLayout>
16 #include <QHBoxLayout>
17 #include <QLabel>
17 #include <QLabel>
18 #include <QSpacerItem>
18 #include <QSpacerItem>
19 #include <QMessageBox>
19 #include <QMessageBox>
20 #include <cmath>
20 #include <cmath>
21 #include <QDebug>
21 #include <QDebug>
22 #include <QStandardItemModel>
22 #include <QStandardItemModel>
23
23
24
24
25 QTCOMMERCIALCHART_USE_NAMESPACE
25 QTCOMMERCIALCHART_USE_NAMESPACE
26
26
27 MainWidget::MainWidget(QWidget *parent) :
27 MainWidget::MainWidget(QWidget *parent) :
28 QWidget(parent)
28 QWidget(parent),
29 m_addSerieDialog(0),
30 m_chartWidget(0)
29 {
31 {
30 m_chartWidget = new QChartView(this);
32 m_chartWidget = new QChartView(this);
31 m_chartWidget->setRubberBandPolicy(QChartView::HorizonalRubberBand);
33 m_chartWidget->setRubberBandPolicy(QChartView::HorizonalRubberBand);
32
34
33 // Grid layout for the controls for configuring the chart widget
35 // Grid layout for the controls for configuring the chart widget
34 QGridLayout *grid = new QGridLayout();
36 QGridLayout *grid = new QGridLayout();
35 QPushButton *addSeriesButton = new QPushButton("Add series");
37 QPushButton *addSeriesButton = new QPushButton("Add series");
36 connect(addSeriesButton, SIGNAL(clicked()), this, SLOT(addSeries()));
38 connect(addSeriesButton, SIGNAL(clicked()), this, SLOT(addSeries()));
37 grid->addWidget(addSeriesButton, 0, 1);
39 grid->addWidget(addSeriesButton, 0, 1);
38 initBackroundCombo(grid);
40 initBackroundCombo(grid);
39 initScaleControls(grid);
41 initScaleControls(grid);
40 initThemeCombo(grid);
42 initThemeCombo(grid);
41 QCheckBox *zoomCheckBox = new QCheckBox("Drag'n drop Zoom");
43 QCheckBox *zoomCheckBox = new QCheckBox("Drag'n drop Zoom");
42 connect(zoomCheckBox, SIGNAL(toggled(bool)), m_chartWidget, SLOT(setZoomEnabled(bool)));
44 connect(zoomCheckBox, SIGNAL(toggled(bool)), m_chartWidget, SLOT(setZoomEnabled(bool)));
43 zoomCheckBox->setChecked(true);
45 zoomCheckBox->setChecked(true);
44 grid->addWidget(zoomCheckBox, grid->rowCount(), 0);
46 grid->addWidget(zoomCheckBox, grid->rowCount(), 0);
45 // add row with empty label to make all the other rows static
47 // add row with empty label to make all the other rows static
46 grid->addWidget(new QLabel(""), grid->rowCount(), 0);
48 grid->addWidget(new QLabel(""), grid->rowCount(), 0);
47 grid->setRowStretch(grid->rowCount() - 1, 1);
49 grid->setRowStretch(grid->rowCount() - 1, 1);
48
50
49 // Another grid layout as a main layout
51 // Another grid layout as a main layout
50 QGridLayout *mainLayout = new QGridLayout();
52 QGridLayout *mainLayout = new QGridLayout();
51 mainLayout->addLayout(grid, 0, 0);
53 mainLayout->addLayout(grid, 0, 0);
52
54
53 // Init series type specific controls
55 // Init series type specific controls
54 initPieControls();
56 initPieControls();
55 mainLayout->addLayout(m_pieLayout, 2, 0);
57 mainLayout->addLayout(m_pieLayout, 2, 0);
56 // Scatter series specific settings
58 // Scatter series specific settings
57 // m_scatterLayout = new QGridLayout();
59 // m_scatterLayout = new QGridLayout();
58 // m_scatterLayout->addWidget(new QLabel("scatter"), 0, 0);
60 // m_scatterLayout->addWidget(new QLabel("scatter"), 0, 0);
59 // m_scatterLayout->setEnabled(false);
61 // m_scatterLayout->setEnabled(false);
60 // mainLayout->addLayout(m_scatterLayout, 1, 0);
62 // mainLayout->addLayout(m_scatterLayout, 1, 0);
61
63
62 // Add layouts and the chart widget to the main layout
64 // Add layouts and the chart widget to the main layout
63 mainLayout->addWidget(m_chartWidget, 0, 1, 3, 1);
65 mainLayout->addWidget(m_chartWidget, 0, 1, 3, 1);
64 setLayout(mainLayout);
66 setLayout(mainLayout);
65 }
67 }
66
68
67 // Combo box for selecting the chart's background
69 // Combo box for selecting the chart's background
68 void MainWidget::initBackroundCombo(QGridLayout *grid)
70 void MainWidget::initBackroundCombo(QGridLayout *grid)
69 {
71 {
70 QComboBox *backgroundCombo = new QComboBox(this);
72 QComboBox *backgroundCombo = new QComboBox(this);
71 backgroundCombo->addItem("Color");
73 backgroundCombo->addItem("Color");
72 backgroundCombo->addItem("Gradient");
74 backgroundCombo->addItem("Gradient");
73 backgroundCombo->addItem("Image");
75 backgroundCombo->addItem("Image");
74 connect(backgroundCombo, SIGNAL(currentIndexChanged(int)),
76 connect(backgroundCombo, SIGNAL(currentIndexChanged(int)),
75 this, SLOT(backgroundChanged(int)));
77 this, SLOT(backgroundChanged(int)));
76
78
77 grid->addWidget(new QLabel("Background:"), grid->rowCount(), 0);
79 grid->addWidget(new QLabel("Background:"), grid->rowCount(), 0);
78 grid->addWidget(backgroundCombo, grid->rowCount() - 1, 1);
80 grid->addWidget(backgroundCombo, grid->rowCount() - 1, 1);
79 }
81 }
80
82
81 // Scale related controls (auto-scale vs. manual min-max values)
83 // Scale related controls (auto-scale vs. manual min-max values)
82 void MainWidget::initScaleControls(QGridLayout *grid)
84 void MainWidget::initScaleControls(QGridLayout *grid)
83 {
85 {
84 m_autoScaleCheck = new QCheckBox("Automatic scaling");
86 m_autoScaleCheck = new QCheckBox("Automatic scaling");
85 connect(m_autoScaleCheck, SIGNAL(stateChanged(int)), this, SLOT(autoScaleChanged(int)));
87 connect(m_autoScaleCheck, SIGNAL(stateChanged(int)), this, SLOT(autoScaleChanged(int)));
86 // Allow setting also non-sense values (like -2147483648 and 2147483647)
88 // Allow setting also non-sense values (like -2147483648 and 2147483647)
87 m_xMinSpin = new QSpinBox();
89 m_xMinSpin = new QSpinBox();
88 m_xMinSpin->setMinimum(INT_MIN);
90 m_xMinSpin->setMinimum(INT_MIN);
89 m_xMinSpin->setMaximum(INT_MAX);
91 m_xMinSpin->setMaximum(INT_MAX);
90 m_xMinSpin->setValue(0);
92 m_xMinSpin->setValue(0);
91 connect(m_xMinSpin, SIGNAL(valueChanged(int)), this, SLOT(xMinChanged(int)));
93 connect(m_xMinSpin, SIGNAL(valueChanged(int)), this, SLOT(xMinChanged(int)));
92 m_xMaxSpin = new QSpinBox();
94 m_xMaxSpin = new QSpinBox();
93 m_xMaxSpin->setMinimum(INT_MIN);
95 m_xMaxSpin->setMinimum(INT_MIN);
94 m_xMaxSpin->setMaximum(INT_MAX);
96 m_xMaxSpin->setMaximum(INT_MAX);
95 m_xMaxSpin->setValue(10);
97 m_xMaxSpin->setValue(10);
96 connect(m_xMaxSpin, SIGNAL(valueChanged(int)), this, SLOT(xMaxChanged(int)));
98 connect(m_xMaxSpin, SIGNAL(valueChanged(int)), this, SLOT(xMaxChanged(int)));
97 m_yMinSpin = new QSpinBox();
99 m_yMinSpin = new QSpinBox();
98 m_yMinSpin->setMinimum(INT_MIN);
100 m_yMinSpin->setMinimum(INT_MIN);
99 m_yMinSpin->setMaximum(INT_MAX);
101 m_yMinSpin->setMaximum(INT_MAX);
100 m_yMinSpin->setValue(0);
102 m_yMinSpin->setValue(0);
101 connect(m_yMinSpin, SIGNAL(valueChanged(int)), this, SLOT(yMinChanged(int)));
103 connect(m_yMinSpin, SIGNAL(valueChanged(int)), this, SLOT(yMinChanged(int)));
102 m_yMaxSpin = new QSpinBox();
104 m_yMaxSpin = new QSpinBox();
103 m_yMaxSpin->setMinimum(INT_MIN);
105 m_yMaxSpin->setMinimum(INT_MIN);
104 m_yMaxSpin->setMaximum(INT_MAX);
106 m_yMaxSpin->setMaximum(INT_MAX);
105 m_yMaxSpin->setValue(10);
107 m_yMaxSpin->setValue(10);
106 connect(m_yMaxSpin, SIGNAL(valueChanged(int)), this, SLOT(yMaxChanged(int)));
108 connect(m_yMaxSpin, SIGNAL(valueChanged(int)), this, SLOT(yMaxChanged(int)));
107
109
108 grid->addWidget(m_autoScaleCheck, grid->rowCount(), 0);
110 grid->addWidget(m_autoScaleCheck, grid->rowCount(), 0);
109 grid->addWidget(new QLabel("x min:"), grid->rowCount(), 0);
111 grid->addWidget(new QLabel("x min:"), grid->rowCount(), 0);
110 grid->addWidget(m_xMinSpin, grid->rowCount() - 1, 1);
112 grid->addWidget(m_xMinSpin, grid->rowCount() - 1, 1);
111 grid->addWidget(new QLabel("x max:"), grid->rowCount(), 0);
113 grid->addWidget(new QLabel("x max:"), grid->rowCount(), 0);
112 grid->addWidget(m_xMaxSpin, grid->rowCount() - 1, 1);
114 grid->addWidget(m_xMaxSpin, grid->rowCount() - 1, 1);
113 grid->addWidget(new QLabel("y min:"), grid->rowCount(), 0);
115 grid->addWidget(new QLabel("y min:"), grid->rowCount(), 0);
114 grid->addWidget(m_yMinSpin, grid->rowCount() - 1, 1);
116 grid->addWidget(m_yMinSpin, grid->rowCount() - 1, 1);
115 grid->addWidget(new QLabel("y max:"), grid->rowCount(), 0);
117 grid->addWidget(new QLabel("y max:"), grid->rowCount(), 0);
116 grid->addWidget(m_yMaxSpin, grid->rowCount() - 1, 1);
118 grid->addWidget(m_yMaxSpin, grid->rowCount() - 1, 1);
117
119
118 m_autoScaleCheck->setChecked(true);
120 m_autoScaleCheck->setChecked(true);
119 }
121 }
120
122
121 // Combo box for selecting theme
123 // Combo box for selecting theme
122 void MainWidget::initThemeCombo(QGridLayout *grid)
124 void MainWidget::initThemeCombo(QGridLayout *grid)
123 {
125 {
124 QComboBox *chartTheme = new QComboBox();
126 QComboBox *chartTheme = new QComboBox();
125 chartTheme->addItem("Default");
127 chartTheme->addItem("Default");
126 chartTheme->addItem("Vanilla");
128 chartTheme->addItem("Vanilla");
127 chartTheme->addItem("Icy");
129 chartTheme->addItem("Icy");
128 chartTheme->addItem("Grayscale");
130 chartTheme->addItem("Grayscale");
129 chartTheme->addItem("Scientific");
131 chartTheme->addItem("Scientific");
130 chartTheme->addItem("Unnamed1");
132 chartTheme->addItem("Unnamed1");
131 connect(chartTheme, SIGNAL(currentIndexChanged(int)),
133 connect(chartTheme, SIGNAL(currentIndexChanged(int)),
132 this, SLOT(changeChartTheme(int)));
134 this, SLOT(changeChartTheme(int)));
133 grid->addWidget(new QLabel("Chart theme:"), 8, 0);
135 grid->addWidget(new QLabel("Chart theme:"), 8, 0);
134 grid->addWidget(chartTheme, 8, 1);
136 grid->addWidget(chartTheme, 8, 1);
135 }
137 }
136
138
137 void MainWidget::initPieControls()
139 void MainWidget::initPieControls()
138 {
140 {
139 // Pie series specific settings
141 // Pie series specific settings
140 // Pie size factory
142 // Pie size factory
141 QDoubleSpinBox *pieSizeSpin = new QDoubleSpinBox();
143 QDoubleSpinBox *pieSizeSpin = new QDoubleSpinBox();
142 pieSizeSpin->setMinimum(LONG_MIN);
144 pieSizeSpin->setMinimum(LONG_MIN);
143 pieSizeSpin->setMaximum(LONG_MAX);
145 pieSizeSpin->setMaximum(LONG_MAX);
144 pieSizeSpin->setValue(1.0);
146 pieSizeSpin->setValue(1.0);
145 pieSizeSpin->setSingleStep(0.1);
147 pieSizeSpin->setSingleStep(0.1);
146 connect(pieSizeSpin, SIGNAL(valueChanged(double)), this, SLOT(setPieSizeFactor(double)));
148 connect(pieSizeSpin, SIGNAL(valueChanged(double)), this, SLOT(setPieSizeFactor(double)));
147 // Pie position
149 // Pie position
148 QComboBox *piePosCombo = new QComboBox(this);
150 QComboBox *piePosCombo = new QComboBox(this);
149 piePosCombo->addItem("Maximized");
151 piePosCombo->addItem("Maximized");
150 piePosCombo->addItem("Top left");
152 piePosCombo->addItem("Top left");
151 piePosCombo->addItem("Top right");
153 piePosCombo->addItem("Top right");
152 piePosCombo->addItem("Bottom left");
154 piePosCombo->addItem("Bottom left");
153 piePosCombo->addItem("Bottom right");
155 piePosCombo->addItem("Bottom right");
154 connect(piePosCombo, SIGNAL(currentIndexChanged(int)),
156 connect(piePosCombo, SIGNAL(currentIndexChanged(int)),
155 this, SLOT(setPiePosition(int)));
157 this, SLOT(setPiePosition(int)));
156 m_pieLayout = new QGridLayout();
158 m_pieLayout = new QGridLayout();
157 m_pieLayout->setEnabled(false);
159 m_pieLayout->setEnabled(false);
158 m_pieLayout->addWidget(new QLabel("Pie size factor"), 0, 0);
160 m_pieLayout->addWidget(new QLabel("Pie size factor"), 0, 0);
159 m_pieLayout->addWidget(pieSizeSpin, 0, 1);
161 m_pieLayout->addWidget(pieSizeSpin, 0, 1);
160 m_pieLayout->addWidget(new QLabel("Pie position"), 1, 0);
162 m_pieLayout->addWidget(new QLabel("Pie position"), 1, 0);
161 m_pieLayout->addWidget(piePosCombo, 1, 1);
163 m_pieLayout->addWidget(piePosCombo, 1, 1);
162 }
164 }
163
165
164 void MainWidget::addSeries()
166 void MainWidget::addSeries()
165 {
167 {
166 DataSerieDialog dialog(m_defaultSeriesName, this);
168 if (!m_addSerieDialog) {
167 connect(&dialog, SIGNAL(accepted(QString, int, int, QString, bool)),
169 m_addSerieDialog = new DataSerieDialog(this);
170 connect(m_addSerieDialog, SIGNAL(accepted(QString, int, int, QString, bool)),
168 this, SLOT(addSeries(QString, int, int, QString, bool)));
171 this, SLOT(addSeries(QString, int, int, QString, bool)));
169 dialog.exec();
172 }
173 m_addSerieDialog->exec();
170 }
174 }
171
175
172 QList<RealList> MainWidget::generateTestData(int columnCount, int rowCount, QString dataCharacteristics)
176 QList<RealList> MainWidget::generateTestData(int columnCount, int rowCount, QString dataCharacteristics)
173 {
177 {
174 // TODO: dataCharacteristics
178 // TODO: dataCharacteristics
175 QList<RealList> testData;
179 QList<RealList> testData;
176 for (int j(0); j < columnCount; j++) {
180 for (int j(0); j < columnCount; j++) {
177 QList <qreal> newColumn;
181 QList <qreal> newColumn;
178 for (int i(0); i < rowCount; i++) {
182 for (int i(0); i < rowCount; i++) {
179 if (dataCharacteristics == "Sin") {
183 if (dataCharacteristics == "Sin") {
180 newColumn.append(abs(sin(3.14159265358979 / 50 * i) * 100));
184 newColumn.append(abs(sin(3.14159265358979 / 50 * i) * 100));
181 } else if (dataCharacteristics == "Sin + random") {
185 } else if (dataCharacteristics == "Sin + random") {
182 newColumn.append(abs(sin(3.14159265358979 / 50 * i) * 100) + (rand() % 5));
186 newColumn.append(abs(sin(3.14159265358979 / 50 * i) * 100) + (rand() % 5));
183 } else if (dataCharacteristics == "Random") {
187 } else if (dataCharacteristics == "Random") {
184 newColumn.append(rand() % 5);
188 newColumn.append(rand() % 5);
185 } else if (dataCharacteristics == "Linear") {
189 } else if (dataCharacteristics == "Linear") {
186 //newColumn.append(i * (j + 1.0));
190 //newColumn.append(i * (j + 1.0));
187 // TODO: temporary hack to make pie work; prevent zero values:
191 // TODO: temporary hack to make pie work; prevent zero values:
188 newColumn.append(i * (j + 1.0) + 0.1);
192 newColumn.append(i * (j + 1.0) + 0.1);
189 } else { // "constant"
193 } else { // "constant"
190 newColumn.append((j + 1.0));
194 newColumn.append((j + 1.0));
191 }
195 }
192 }
196 }
193 testData.append(newColumn);
197 testData.append(newColumn);
194 }
198 }
195 return testData;
199 return testData;
196 }
200 }
197
201
198 QStringList MainWidget::generateLabels(int count)
202 QStringList MainWidget::generateLabels(int count)
199 {
203 {
200 QStringList result;
204 QStringList result;
201 for (int i(0); i < count; i++)
205 for (int i(0); i < count; i++)
202 result.append("label" + QString::number(i));
206 result.append("label" + QString::number(i));
203 return result;
207 return result;
204 }
208 }
205
209
206 void MainWidget::addSeries(QString seriesName, int columnCount, int rowCount, QString dataCharacteristics, bool labelsEnabled)
210 void MainWidget::addSeries(QString seriesName, int columnCount, int rowCount, QString dataCharacteristics, bool labelsEnabled)
207 {
211 {
208 qDebug() << "addSeries: " << seriesName
212 qDebug() << "addSeries: " << seriesName
209 << " columnCount: " << columnCount
213 << " columnCount: " << columnCount
210 << " rowCount: " << rowCount
214 << " rowCount: " << rowCount
211 << " dataCharacteristics: " << dataCharacteristics
215 << " dataCharacteristics: " << dataCharacteristics
212 << " labels enabled: " << labelsEnabled;
216 << " labels enabled: " << labelsEnabled;
213 m_defaultSeriesName = seriesName;
217 m_defaultSeriesName = seriesName;
214
218
215 QList<RealList> data = generateTestData(columnCount, rowCount, dataCharacteristics);
219 QList<RealList> data = generateTestData(columnCount, rowCount, dataCharacteristics);
216
220
217 // Line series and scatter series use similar data
221 // Line series and scatter series use similar data
218 if (seriesName.contains("line", Qt::CaseInsensitive)) {
222 if (seriesName.contains("line", Qt::CaseInsensitive)) {
219 for (int j(0); j < data.count(); j ++) {
223 for (int j(0); j < data.count(); j ++) {
220 QList<qreal> column = data.at(j);
224 QList<qreal> column = data.at(j);
221 QLineSeries *series = new QLineSeries();
225 QLineSeries *series = new QLineSeries();
222 for (int i(0); i < column.count(); i++) {
226 for (int i(0); i < column.count(); i++) {
223 series->add(i, column.at(i));
227 series->add(i, column.at(i));
224 }
228 }
225 m_chartWidget->addSeries(series);
229 m_chartWidget->addSeries(series);
226 setCurrentSeries(series);
230 setCurrentSeries(series);
227 }
231 }
228 } else if (seriesName.contains("scatter", Qt::CaseInsensitive)) {
232 } else if (seriesName.contains("scatter", Qt::CaseInsensitive)) {
229 for (int j(0); j < data.count(); j++) {
233 for (int j(0); j < data.count(); j++) {
230 QList<qreal> column = data.at(j);
234 QList<qreal> column = data.at(j);
231 QScatterSeries *series = new QScatterSeries();
235 QScatterSeries *series = new QScatterSeries();
232 for (int i(0); i < column.count(); i++) {
236 for (int i(0); i < column.count(); i++) {
233 (*series) << QPointF(i, column.at(i));
237 (*series) << QPointF(i, column.at(i));
234 }
238 }
235 m_chartWidget->addSeries(series);
239 m_chartWidget->addSeries(series);
236 setCurrentSeries(series);
240 setCurrentSeries(series);
237 }
241 }
238 } else if (seriesName.contains("pie", Qt::CaseInsensitive)) {
242 } else if (seriesName.contains("pie", Qt::CaseInsensitive)) {
239 QStringList labels = generateLabels(rowCount);
243 QStringList labels = generateLabels(rowCount);
240 for (int j(0); j < data.count(); j++) {
244 for (int j(0); j < data.count(); j++) {
241 QPieSeries *series = new QPieSeries();
245 QPieSeries *series = new QPieSeries();
242 QList<qreal> column = data.at(j);
246 QList<qreal> column = data.at(j);
243 for (int i(0); i < column.count(); i++) {
247 for (int i(0); i < column.count(); i++) {
244 series->add(column.at(i), labels.at(i));
248 series->add(column.at(i), labels.at(i));
245 }
249 }
246 m_chartWidget->addSeries(series);
250 m_chartWidget->addSeries(series);
247 setCurrentSeries(series);
251 setCurrentSeries(series);
248 }
252 }
249 } else if (seriesName == "Bar"
253 } else if (seriesName == "Bar"
250 || seriesName == "Stacked bar"
254 || seriesName == "Stacked bar"
251 || seriesName == "Percent bar") {
255 || seriesName == "Percent bar") {
252 // TODO: replace QBarCategory with QStringList?
256 // TODO: replace QBarCategory with QStringList?
253 QBarCategory *category = new QBarCategory;
257 QBarCategory *category = new QBarCategory;
254 QStringList labels = generateLabels(rowCount);
258 QStringList labels = generateLabels(rowCount);
255 foreach(QString label, labels)
259 foreach(QString label, labels)
256 *category << label;
260 *category << label;
257 QBarSeries* series = 0;
261 QBarSeries* series = 0;
258 if (seriesName == "Bar")
262 if (seriesName == "Bar")
259 series = new QBarSeries(category, this);
263 series = new QBarSeries(category, this);
260 else if (seriesName == "Stacked bar")
264 else if (seriesName == "Stacked bar")
261 series = new QStackedBarSeries(category, this);
265 series = new QStackedBarSeries(category, this);
262 else
266 else
263 series = new QPercentBarSeries(category, this);
267 series = new QPercentBarSeries(category, this);
264
268
265 for (int j(0); j < data.count(); j++) {
269 for (int j(0); j < data.count(); j++) {
266 QList<qreal> column = data.at(j);
270 QList<qreal> column = data.at(j);
267 QBarSet *set = new QBarSet("set" + QString::number(j));
271 QBarSet *set = new QBarSet("set" + QString::number(j));
268 for (int i(0); i < column.count(); i++) {
272 for (int i(0); i < column.count(); i++) {
269 *set << column.at(i);
273 *set << column.at(i);
270 }
274 }
271 series->addBarSet(set);
275 series->addBarSet(set);
272 }
276 }
273 series->setFloatingValuesEnabled(true);
277 series->setFloatingValuesEnabled(true);
274 series->setToolTipEnabled(true);
278 series->setToolTipEnabled(true);
275 series->setSeparatorsEnabled(false);
279 series->setSeparatorsEnabled(false);
276 m_chartWidget->addSeries(series);
280 m_chartWidget->addSeries(series);
277 setCurrentSeries(series);
281 setCurrentSeries(series);
278 }
282 }
279
283
280 // TODO: spline and area
284 // TODO: spline and area
281 }
285 }
282
286
283 void MainWidget::setCurrentSeries(QSeries *series)
287 void MainWidget::setCurrentSeries(QSeries *series)
284 {
288 {
285 if (series) {
289 if (series) {
286 m_currentSeries = series;
290 m_currentSeries = series;
287 switch (m_currentSeries->type()) {
291 switch (m_currentSeries->type()) {
288 case QSeries::SeriesTypeLine:
292 case QSeries::SeriesTypeLine:
289 break;
293 break;
290 case QSeries::SeriesTypeScatter:
294 case QSeries::SeriesTypeScatter:
291 break;
295 break;
292 case QSeries::SeriesTypePie:
296 case QSeries::SeriesTypePie:
293 break;
297 break;
294 case QSeries::SeriesTypeBar:
298 case QSeries::SeriesTypeBar:
295 qDebug() << "setCurrentSeries (bar)";
299 qDebug() << "setCurrentSeries (bar)";
296 break;
300 break;
297 case QSeries::SeriesTypeStackedBar:
301 case QSeries::SeriesTypeStackedBar:
298 qDebug() << "setCurrentSeries (Stackedbar)";
302 qDebug() << "setCurrentSeries (Stackedbar)";
299 break;
303 break;
300 case QSeries::SeriesTypePercentBar:
304 case QSeries::SeriesTypePercentBar:
301 qDebug() << "setCurrentSeries (Percentbar)";
305 qDebug() << "setCurrentSeries (Percentbar)";
302 break;
306 break;
303 default:
307 default:
304 Q_ASSERT(false);
308 Q_ASSERT(false);
305 break;
309 break;
306 }
310 }
307 }
311 }
308 }
312 }
309
313
310 void MainWidget::backgroundChanged(int itemIndex)
314 void MainWidget::backgroundChanged(int itemIndex)
311 {
315 {
312 qDebug() << "backgroundChanged: " << itemIndex;
316 qDebug() << "backgroundChanged: " << itemIndex;
313 }
317 }
314
318
315 void MainWidget::autoScaleChanged(int value)
319 void MainWidget::autoScaleChanged(int value)
316 {
320 {
317 if (value) {
321 if (value) {
318 // TODO: enable auto scaling
322 // TODO: enable auto scaling
319 } else {
323 } else {
320 // TODO: set scaling manually (and disable auto scaling)
324 // TODO: set scaling manually (and disable auto scaling)
321 }
325 }
322
326
323 m_xMinSpin->setEnabled(!value);
327 m_xMinSpin->setEnabled(!value);
324 m_xMaxSpin->setEnabled(!value);
328 m_xMaxSpin->setEnabled(!value);
325 m_yMinSpin->setEnabled(!value);
329 m_yMinSpin->setEnabled(!value);
326 m_yMaxSpin->setEnabled(!value);
330 m_yMaxSpin->setEnabled(!value);
327 }
331 }
328
332
329 void MainWidget::xMinChanged(int value)
333 void MainWidget::xMinChanged(int value)
330 {
334 {
331 qDebug() << "xMinChanged: " << value;
335 qDebug() << "xMinChanged: " << value;
332 }
336 }
333
337
334 void MainWidget::xMaxChanged(int value)
338 void MainWidget::xMaxChanged(int value)
335 {
339 {
336 qDebug() << "xMaxChanged: " << value;
340 qDebug() << "xMaxChanged: " << value;
337 }
341 }
338
342
339 void MainWidget::yMinChanged(int value)
343 void MainWidget::yMinChanged(int value)
340 {
344 {
341 qDebug() << "yMinChanged: " << value;
345 qDebug() << "yMinChanged: " << value;
342 }
346 }
343
347
344 void MainWidget::yMaxChanged(int value)
348 void MainWidget::yMaxChanged(int value)
345 {
349 {
346 qDebug() << "yMaxChanged: " << value;
350 qDebug() << "yMaxChanged: " << value;
347 }
351 }
348
352
349 void MainWidget::changeChartTheme(int themeIndex)
353 void MainWidget::changeChartTheme(int themeIndex)
350 {
354 {
351 qDebug() << "changeChartTheme: " << themeIndex;
355 qDebug() << "changeChartTheme: " << themeIndex;
352 m_chartWidget->setChartTheme((QChart::ChartTheme) themeIndex);
356 m_chartWidget->setChartTheme((QChart::ChartTheme) themeIndex);
353 //TODO: remove this hack. This is just to make it so that theme change is seen immediately.
357 //TODO: remove this hack. This is just to make it so that theme change is seen immediately.
354 QSize s = size();
358 QSize s = size();
355 s.setWidth(s.width()+1);
359 s.setWidth(s.width()+1);
356 resize(s);
360 resize(s);
357 }
361 }
358
362
359 void MainWidget::setPieSizeFactor(double size)
363 void MainWidget::setPieSizeFactor(double size)
360 {
364 {
361 QPieSeries *pie = qobject_cast<QPieSeries *>(m_currentSeries);
365 QPieSeries *pie = qobject_cast<QPieSeries *>(m_currentSeries);
362 if (pie)
366 if (pie)
363 pie->setSizeFactor(qreal(size));
367 pie->setSizeFactor(qreal(size));
364 }
368 }
365
369
366 void MainWidget::setPiePosition(int position)
370 void MainWidget::setPiePosition(int position)
367 {
371 {
368 QPieSeries *pie = qobject_cast<QPieSeries *>(m_currentSeries);
372 QPieSeries *pie = qobject_cast<QPieSeries *>(m_currentSeries);
369 if (pie)
373 if (pie)
370 pie->setPosition((QPieSeries::PiePosition) position);
374 pie->setPosition((QPieSeries::PiePosition) position);
371 }
375 }
@@ -1,59 +1,61
1 #ifndef MAINWIDGET_H
1 #ifndef MAINWIDGET_H
2 #define MAINWIDGET_H
2 #define MAINWIDGET_H
3
3
4 #include <qchartglobal.h>
4 #include <qchartglobal.h>
5 #include <qchartview.h>
5 #include <qchartview.h>
6 #include <QWidget>
6 #include <QWidget>
7
7
8 class QSpinBox;
8 class QSpinBox;
9 class QCheckBox;
9 class QCheckBox;
10 class QGridLayout;
10 class QGridLayout;
11
11
12 QTCOMMERCIALCHART_USE_NAMESPACE
12 QTCOMMERCIALCHART_USE_NAMESPACE
13
13
14 #define RealList QList<qreal>
14 #define RealList QList<qreal>
15 class DataSerieDialog;
15
16
16 class MainWidget : public QWidget
17 class MainWidget : public QWidget
17 {
18 {
18 Q_OBJECT
19 Q_OBJECT
19 public:
20 public:
20 explicit MainWidget(QWidget *parent = 0);
21 explicit MainWidget(QWidget *parent = 0);
21
22
22 signals:
23 signals:
23
24
24 private:
25 private:
25 void initBackroundCombo(QGridLayout *grid);
26 void initBackroundCombo(QGridLayout *grid);
26 void initScaleControls(QGridLayout *grid);
27 void initScaleControls(QGridLayout *grid);
27 void initThemeCombo(QGridLayout *grid);
28 void initThemeCombo(QGridLayout *grid);
28 void initPieControls();
29 void initPieControls();
29
30
30 private slots:
31 private slots:
31 void addSeries();
32 void addSeries();
32 void addSeries(QString series, int columnCount, int rowCount, QString dataCharacteristics, bool labelsEnabled);
33 void addSeries(QString series, int columnCount, int rowCount, QString dataCharacteristics, bool labelsEnabled);
33 void backgroundChanged(int itemIndex);
34 void backgroundChanged(int itemIndex);
34 void autoScaleChanged(int value);
35 void autoScaleChanged(int value);
35 void xMinChanged(int value);
36 void xMinChanged(int value);
36 void xMaxChanged(int value);
37 void xMaxChanged(int value);
37 void yMinChanged(int value);
38 void yMinChanged(int value);
38 void yMaxChanged(int value);
39 void yMaxChanged(int value);
39 void setCurrentSeries(QSeries *series);
40 void setCurrentSeries(QSeries *series);
40 void changeChartTheme(int themeIndex);
41 void changeChartTheme(int themeIndex);
41 void setPieSizeFactor(double margin);
42 void setPieSizeFactor(double margin);
42 void setPiePosition(int position);
43 void setPiePosition(int position);
43 QList<RealList> generateTestData(int columnCount, int rowCount, QString dataCharacteristics);
44 QList<RealList> generateTestData(int columnCount, int rowCount, QString dataCharacteristics);
44 QStringList generateLabels(int count);
45 QStringList generateLabels(int count);
45
46
46 private:
47 private:
48 DataSerieDialog *m_addSerieDialog;
47 QChartView *m_chartWidget;
49 QChartView *m_chartWidget;
48 QCheckBox *m_autoScaleCheck;
50 QCheckBox *m_autoScaleCheck;
49 QSpinBox *m_xMinSpin;
51 QSpinBox *m_xMinSpin;
50 QSpinBox *m_xMaxSpin;
52 QSpinBox *m_xMaxSpin;
51 QSpinBox *m_yMinSpin;
53 QSpinBox *m_yMinSpin;
52 QSpinBox *m_yMaxSpin;
54 QSpinBox *m_yMaxSpin;
53 QString m_defaultSeriesName;
55 QString m_defaultSeriesName;
54 QSeries *m_currentSeries;
56 QSeries *m_currentSeries;
55 QGridLayout *m_scatterLayout;
57 QGridLayout *m_scatterLayout;
56 QGridLayout *m_pieLayout;
58 QGridLayout *m_pieLayout;
57 };
59 };
58
60
59 #endif // MAINWIDGET_H
61 #endif // MAINWIDGET_H
General Comments 0
You need to be logged in to leave comments. Login now