@@ -31,8 +31,9 DrilldownChart::DrilldownChart(QGraphicsItem *parent, Qt::WindowFlags wFlags) | |||||
31 |
|
31 | |||
32 | void DrilldownChart::changeSeries(QAbstractSeries *series) |
|
32 | void DrilldownChart::changeSeries(QAbstractSeries *series) | |
33 | { |
|
33 | { | |
34 | if (m_currentSeries) |
|
34 | if (m_currentSeries) { | |
35 | removeSeries(m_currentSeries); |
|
35 | removeSeries(m_currentSeries); | |
|
36 | } | |||
36 | m_currentSeries = series; |
|
37 | m_currentSeries = series; | |
37 | addSeries(series); |
|
38 | addSeries(series); | |
38 | setTitle(series->name()); |
|
39 | setTitle(series->name()); |
@@ -3,7 +3,6 DEPENDPATH += $$PWD | |||||
3 |
|
3 | |||
4 | SOURCES += \ |
|
4 | SOURCES += \ | |
5 | $$PWD/bar.cpp \ |
|
5 | $$PWD/bar.cpp \ | |
6 | $$PWD/barchartmodel.cpp \ |
|
|||
7 | $$PWD/barchartitem.cpp \ |
|
6 | $$PWD/barchartitem.cpp \ | |
8 | $$PWD/percentbarchartitem.cpp \ |
|
7 | $$PWD/percentbarchartitem.cpp \ | |
9 | $$PWD/qbarseries.cpp \ |
|
8 | $$PWD/qbarseries.cpp \ | |
@@ -15,7 +14,6 SOURCES += \ | |||||
15 |
|
14 | |||
16 | PRIVATE_HEADERS += \ |
|
15 | PRIVATE_HEADERS += \ | |
17 | $$PWD/bar_p.h \ |
|
16 | $$PWD/bar_p.h \ | |
18 | $$PWD/barchartmodel_p.h \ |
|
|||
19 | $$PWD/barchartitem_p.h \ |
|
17 | $$PWD/barchartitem_p.h \ | |
20 | $$PWD/percentbarchartitem_p.h \ |
|
18 | $$PWD/percentbarchartitem_p.h \ | |
21 | $$PWD/stackedbarchartitem_p.h \ |
|
19 | $$PWD/stackedbarchartitem_p.h \ |
@@ -47,7 +47,6 public: | |||||
47 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); |
|
47 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); | |
48 | QRectF boundingRect() const; |
|
48 | QRectF boundingRect() const; | |
49 |
|
49 | |||
50 | // TODO: Consider the domain for layoutChanged. May be use case, may not be. If it is, then the derived classes need to implement it |
|
|||
51 | virtual void dataChanged(); // data of series has changed -> need to recalculate bar sizes |
|
50 | virtual void dataChanged(); // data of series has changed -> need to recalculate bar sizes | |
52 |
|
51 | |||
53 | virtual QVector<QRectF> calculateLayout(); |
|
52 | virtual QVector<QRectF> calculateLayout(); | |
@@ -65,7 +64,6 public Q_SLOTS: | |||||
65 |
|
64 | |||
66 | protected: |
|
65 | protected: | |
67 |
|
66 | |||
68 | // TODO: consider these. |
|
|||
69 | qreal m_domainMinX; |
|
67 | qreal m_domainMinX; | |
70 | qreal m_domainMaxX; |
|
68 | qreal m_domainMaxX; | |
71 | qreal m_domainMinY; |
|
69 | qreal m_domainMinY; |
@@ -22,7 +22,6 | |||||
22 | #include "qbarseries_p.h" |
|
22 | #include "qbarseries_p.h" | |
23 | #include "qbarset.h" |
|
23 | #include "qbarset.h" | |
24 | #include "qbarset_p.h" |
|
24 | #include "qbarset_p.h" | |
25 | #include "barchartmodel_p.h" |
|
|||
26 | #include "domain_p.h" |
|
25 | #include "domain_p.h" | |
27 | #include "legendmarker_p.h" |
|
26 | #include "legendmarker_p.h" | |
28 | #include "chartdataset_p.h" |
|
27 | #include "chartdataset_p.h" | |
@@ -112,7 +111,7 QAbstractSeries::QSeriesType QBarSeries::type() const | |||||
112 | void QBarSeries::appendBarSet(QBarSet *set) |
|
111 | void QBarSeries::appendBarSet(QBarSet *set) | |
113 | { |
|
112 | { | |
114 | Q_D(QBarSeries); |
|
113 | Q_D(QBarSeries); | |
115 |
d->m_ |
|
114 | d->m_barSets.append(set); | |
116 | QObject::connect(set->d_ptr.data(), SIGNAL(valueChanged()), d, SLOT(barsetChanged())); |
|
115 | QObject::connect(set->d_ptr.data(), SIGNAL(valueChanged()), d, SLOT(barsetChanged())); | |
117 | emit d->restructuredBars(); |
|
116 | emit d->restructuredBars(); | |
118 | } |
|
117 | } | |
@@ -125,8 +124,10 void QBarSeries::appendBarSet(QBarSet *set) | |||||
125 | void QBarSeries::removeBarSet(QBarSet *set) |
|
124 | void QBarSeries::removeBarSet(QBarSet *set) | |
126 | { |
|
125 | { | |
127 | Q_D(QBarSeries); |
|
126 | Q_D(QBarSeries); | |
128 | d->m_internalModel->removeBarSet(set); |
|
127 | if (d->m_barSets.contains(set)) { | |
129 | emit d->restructuredBars(); |
|
128 | d->m_barSets.removeOne(set); | |
|
129 | emit d->restructuredBars(); | |||
|
130 | } | |||
130 | } |
|
131 | } | |
131 |
|
132 | |||
132 | /*! |
|
133 | /*! | |
@@ -138,11 +139,10 void QBarSeries::appendBarSets(QList<QBarSet* > sets) | |||||
138 | { |
|
139 | { | |
139 | Q_D(QBarSeries); |
|
140 | Q_D(QBarSeries); | |
140 | foreach (QBarSet* barset, sets) { |
|
141 | foreach (QBarSet* barset, sets) { | |
141 |
d->m_ |
|
142 | d->m_barSets.append(barset); | |
142 | QObject::connect(barset, SIGNAL(valueChanged()), this, SLOT(barsetChanged())); |
|
143 | QObject::connect(barset, SIGNAL(valueChanged()), this, SLOT(barsetChanged())); | |
143 | } |
|
144 | } | |
144 | emit d->restructuredBars(); |
|
145 | emit d->restructuredBars(); | |
145 |
|
||||
146 | } |
|
146 | } | |
147 |
|
147 | |||
148 | /*! |
|
148 | /*! | |
@@ -155,7 +155,9 void QBarSeries::removeBarSets(QList<QBarSet* > sets) | |||||
155 | Q_D(QBarSeries); |
|
155 | Q_D(QBarSeries); | |
156 |
|
156 | |||
157 | foreach (QBarSet* barset, sets) { |
|
157 | foreach (QBarSet* barset, sets) { | |
158 | d->m_internalModel->removeBarSet(barset); |
|
158 | if (d->m_barSets.contains(barset)) { | |
|
159 | d->m_barSets.removeOne(barset); | |||
|
160 | } | |||
159 | } |
|
161 | } | |
160 | emit d->restructuredBars(); |
|
162 | emit d->restructuredBars(); | |
161 | } |
|
163 | } | |
@@ -167,7 +169,7 void QBarSeries::removeBarSets(QList<QBarSet* > sets) | |||||
167 | void QBarSeries::insertBarSet(int i, QBarSet *set) |
|
169 | void QBarSeries::insertBarSet(int i, QBarSet *set) | |
168 | { |
|
170 | { | |
169 | Q_D(QBarSeries); |
|
171 | Q_D(QBarSeries); | |
170 |
d->m_ |
|
172 | d->m_barSets.insert(i,set); | |
171 | emit d->barsetChanged(); |
|
173 | emit d->barsetChanged(); | |
172 | } |
|
174 | } | |
173 |
|
175 | |||
@@ -177,7 +179,7 void QBarSeries::insertBarSet(int i, QBarSet *set) | |||||
177 | int QBarSeries::barsetCount() const |
|
179 | int QBarSeries::barsetCount() const | |
178 | { |
|
180 | { | |
179 | Q_D(const QBarSeries); |
|
181 | Q_D(const QBarSeries); | |
180 |
return d->m_ |
|
182 | return d->m_barSets.count(); | |
181 | } |
|
183 | } | |
182 |
|
184 | |||
183 | /*! |
|
185 | /*! | |
@@ -186,7 +188,7 int QBarSeries::barsetCount() const | |||||
186 | int QBarSeries::categoryCount() const |
|
188 | int QBarSeries::categoryCount() const | |
187 | { |
|
189 | { | |
188 | Q_D(const QBarSeries); |
|
190 | Q_D(const QBarSeries); | |
189 |
return d->m_ |
|
191 | return d->m_categories.count(); | |
190 | } |
|
192 | } | |
191 |
|
193 | |||
192 | /*! |
|
194 | /*! | |
@@ -195,7 +197,7 int QBarSeries::categoryCount() const | |||||
195 | QList<QBarSet*> QBarSeries::barSets() const |
|
197 | QList<QBarSet*> QBarSeries::barSets() const | |
196 | { |
|
198 | { | |
197 | Q_D(const QBarSeries); |
|
199 | Q_D(const QBarSeries); | |
198 |
return d->m_ |
|
200 | return d->m_barSets; | |
199 | } |
|
201 | } | |
200 |
|
202 | |||
201 | /*! |
|
203 | /*! | |
@@ -228,14 +230,7 void QBarSeries::setModelMapping(int categories, int bottomBoundary, int topBoun | |||||
228 | QBarCategories QBarSeries::categories() const |
|
230 | QBarCategories QBarSeries::categories() const | |
229 | { |
|
231 | { | |
230 | Q_D(const QBarSeries); |
|
232 | Q_D(const QBarSeries); | |
231 |
|
233 | return d->m_categories; | ||
232 | QBarCategories categories; |
|
|||
233 | int count = d->m_internalModel->categoryCount(); |
|
|||
234 | for (int i=1; i <= count; i++) { |
|
|||
235 | categories.insert(i, d->m_internalModel->categoryName(i - 1)); |
|
|||
236 | } |
|
|||
237 | return categories; |
|
|||
238 |
|
||||
239 | } |
|
234 | } | |
240 |
|
235 | |||
241 | /*! |
|
236 | /*! | |
@@ -252,7 +247,7 void QBarSeries::setLabelsVisible(bool visible) | |||||
252 |
|
247 | |||
253 | QBarSeriesPrivate::QBarSeriesPrivate(QBarCategories categories, QBarSeries *q) : |
|
248 | QBarSeriesPrivate::QBarSeriesPrivate(QBarCategories categories, QBarSeries *q) : | |
254 | QAbstractSeriesPrivate(q), |
|
249 | QAbstractSeriesPrivate(q), | |
255 | m_internalModel(new BarChartModel(categories,this)), |
|
250 | m_categories(categories), | |
256 | m_model(0), |
|
251 | m_model(0), | |
257 | m_mapCategories(-1), |
|
252 | m_mapCategories(-1), | |
258 | m_mapBarBottom(-1), |
|
253 | m_mapBarBottom(-1), | |
@@ -263,52 +258,115 QBarSeriesPrivate::QBarSeriesPrivate(QBarCategories categories, QBarSeries *q) : | |||||
263 |
|
258 | |||
264 | QBarSet* QBarSeriesPrivate::barsetAt(int index) |
|
259 | QBarSet* QBarSeriesPrivate::barsetAt(int index) | |
265 | { |
|
260 | { | |
266 |
return m_ |
|
261 | return m_barSets.at(index); | |
267 | } |
|
262 | } | |
268 |
|
263 | |||
269 | QString QBarSeriesPrivate::categoryName(int category) |
|
264 | QString QBarSeriesPrivate::categoryName(int category) | |
270 | { |
|
265 | { | |
271 |
return m_ |
|
266 | return m_categories.at(category); | |
272 | } |
|
267 | } | |
273 |
|
268 | |||
274 | qreal QBarSeriesPrivate::min() |
|
269 | qreal QBarSeriesPrivate::min() | |
275 | { |
|
270 | { | |
276 | return m_internalModel->min(); |
|
271 | if (m_barSets.count() <= 0) { | |
|
272 | return 0; | |||
|
273 | } | |||
|
274 | qreal min = INT_MAX; | |||
|
275 | ||||
|
276 | for (int i = 0; i < m_barSets.count(); i++) { | |||
|
277 | int categoryCount = m_barSets.at(i)->count(); | |||
|
278 | for (int j = 0; j < categoryCount; j++) { | |||
|
279 | qreal temp = m_barSets.at(i)->at(j); | |||
|
280 | if (temp < min) | |||
|
281 | min = temp; | |||
|
282 | } | |||
|
283 | } | |||
|
284 | return min; | |||
277 | } |
|
285 | } | |
278 |
|
286 | |||
279 | qreal QBarSeriesPrivate::max() |
|
287 | qreal QBarSeriesPrivate::max() | |
280 | { |
|
288 | { | |
281 | return m_internalModel->max(); |
|
289 | if (m_barSets.count() <= 0) { | |
|
290 | return 0; | |||
|
291 | } | |||
|
292 | qreal max = INT_MIN; | |||
|
293 | ||||
|
294 | for (int i = 0; i < m_barSets.count(); i++) { | |||
|
295 | int categoryCount = m_barSets.at(i)->count(); | |||
|
296 | for (int j = 0; j < categoryCount; j++) { | |||
|
297 | qreal temp = m_barSets.at(i)->at(j); | |||
|
298 | if (temp > max) | |||
|
299 | max = temp; | |||
|
300 | } | |||
|
301 | } | |||
|
302 | ||||
|
303 | return max; | |||
282 | } |
|
304 | } | |
283 |
|
305 | |||
284 | qreal QBarSeriesPrivate::valueAt(int set, int category) |
|
306 | qreal QBarSeriesPrivate::valueAt(int set, int category) | |
285 | { |
|
307 | { | |
286 | return m_internalModel->valueAt(set, category); |
|
308 | if ((set < 0) || (set >= m_barSets.count())) { | |
|
309 | // No set, no value. | |||
|
310 | return 0; | |||
|
311 | } else if ((category < 0) || (category >= m_barSets.at(set)->count())) { | |||
|
312 | // No category, no value. | |||
|
313 | return 0; | |||
|
314 | } | |||
|
315 | ||||
|
316 | return m_barSets.at(set)->at(category); | |||
287 | } |
|
317 | } | |
288 |
|
318 | |||
289 | qreal QBarSeriesPrivate::percentageAt(int set, int category) |
|
319 | qreal QBarSeriesPrivate::percentageAt(int set, int category) | |
290 | { |
|
320 | { | |
291 | return m_internalModel->percentageAt(set, category); |
|
321 | if ((set < 0) || (set >= m_barSets.count())) { | |
|
322 | // No set, no value. | |||
|
323 | return 0; | |||
|
324 | } else if ((category < 0) || (category >= m_barSets.at(set)->count())) { | |||
|
325 | // No category, no value. | |||
|
326 | return 0; | |||
|
327 | } | |||
|
328 | ||||
|
329 | qreal value = m_barSets.at(set)->at(category); | |||
|
330 | qreal sum = categorySum(category); | |||
|
331 | if ( qFuzzyIsNull(sum) ) { | |||
|
332 | return 0; | |||
|
333 | } | |||
|
334 | ||||
|
335 | return value / sum; | |||
292 | } |
|
336 | } | |
293 |
|
337 | |||
294 | qreal QBarSeriesPrivate::categorySum(int category) |
|
338 | qreal QBarSeriesPrivate::categorySum(int category) | |
295 | { |
|
339 | { | |
296 | return m_internalModel->categorySum(category); |
|
340 | qreal sum(0); | |
|
341 | int count = m_barSets.count(); // Count sets | |||
|
342 | for (int set = 0; set < count; set++) { | |||
|
343 | if (category < m_barSets.at(set)->count()) | |||
|
344 | sum += m_barSets.at(set)->at(category); | |||
|
345 | } | |||
|
346 | return sum; | |||
297 | } |
|
347 | } | |
298 |
|
348 | |||
299 | qreal QBarSeriesPrivate::absoluteCategorySum(int category) |
|
349 | qreal QBarSeriesPrivate::absoluteCategorySum(int category) | |
300 | { |
|
350 | { | |
301 | return m_internalModel->absoluteCategorySum(category); |
|
351 | qreal sum(0); | |
|
352 | int count = m_barSets.count(); // Count sets | |||
|
353 | for (int set = 0; set < count; set++) { | |||
|
354 | if (category < m_barSets.at(set)->count()) | |||
|
355 | sum += qAbs(m_barSets.at(set)->at(category)); | |||
|
356 | } | |||
|
357 | return sum; | |||
302 | } |
|
358 | } | |
303 |
|
359 | |||
304 | qreal QBarSeriesPrivate::maxCategorySum() |
|
360 | qreal QBarSeriesPrivate::maxCategorySum() | |
305 | { |
|
361 | { | |
306 | return m_internalModel->maxCategorySum(); |
|
362 | qreal max = INT_MIN; | |
307 | } |
|
363 | int count = m_categories.count(); | |
308 |
|
364 | for (int i = 0; i < count; i++) { | ||
309 | BarChartModel& QBarSeriesPrivate::modelInternal() |
|
365 | qreal sum = categorySum(i); | |
310 | { |
|
366 | if (sum > max) | |
311 | return *m_internalModel; |
|
367 | max = sum; | |
|
368 | } | |||
|
369 | return max; | |||
312 | } |
|
370 | } | |
313 |
|
371 | |||
314 | bool QBarSeriesPrivate::setModel(QAbstractItemModel *model) |
|
372 | bool QBarSeriesPrivate::setModel(QAbstractItemModel *model) | |
@@ -353,12 +411,11 void QBarSeriesPrivate::setModelMapping(int categories, int bottomBoundry, int t | |||||
353 | this, SLOT(modelUpdated(QModelIndex,QModelIndex))); |
|
411 | this, SLOT(modelUpdated(QModelIndex,QModelIndex))); | |
354 |
|
412 | |||
355 | // create the initial bars |
|
413 | // create the initial bars | |
356 | delete m_internalModel; |
|
414 | m_categories.clear(); | |
357 | if (m_mapOrientation == Qt::Vertical) { |
|
415 | if (m_mapOrientation == Qt::Vertical) { | |
358 | QStringList categories; |
|
416 | for (int k = 0; k < m_model->rowCount(); k++) { | |
359 | for (int k = 0; k < m_model->rowCount(); k++) |
|
417 | m_categories << m_model->data(m_model->index(k, m_mapCategories), Qt::DisplayRole).toString(); | |
360 | categories << m_model->data(m_model->index(k, m_mapCategories), Qt::DisplayRole).toString(); |
|
418 | } | |
361 | m_internalModel = new BarChartModel(categories, this); |
|
|||
362 |
|
419 | |||
363 | for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) { |
|
420 | for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) { | |
364 | QBarSet* barSet = new QBarSet(QString("Column: %1").arg(i + 1)); |
|
421 | QBarSet* barSet = new QBarSet(QString("Column: %1").arg(i + 1)); | |
@@ -367,10 +424,9 void QBarSeriesPrivate::setModelMapping(int categories, int bottomBoundry, int t | |||||
367 | q->appendBarSet(barSet); |
|
424 | q->appendBarSet(barSet); | |
368 | } |
|
425 | } | |
369 | } else { |
|
426 | } else { | |
370 | QStringList categories; |
|
427 | for (int k = 0; k < m_model->columnCount(); k++) { | |
371 | for (int k = 0; k < m_model->columnCount(); k++) |
|
428 | m_categories << m_model->data(m_model->index(m_mapCategories, k), Qt::DisplayRole).toString(); | |
372 | categories << m_model->data(m_model->index(m_mapCategories, k), Qt::DisplayRole).toString(); |
|
429 | } | |
373 | m_internalModel = new BarChartModel(categories, this); |
|
|||
374 |
|
430 | |||
375 | for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) { |
|
431 | for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) { | |
376 | QBarSet* barSet = new QBarSet(QString("Row: %1").arg(i + 1)); |
|
432 | QBarSet* barSet = new QBarSet(QString("Row: %1").arg(i + 1)); | |
@@ -413,7 +469,7 void QBarSeriesPrivate::scaleDomain(Domain& domain) | |||||
413 | int tickXCount(domain.tickXCount()); |
|
469 | int tickXCount(domain.tickXCount()); | |
414 | int tickYCount(domain.tickYCount()); |
|
470 | int tickYCount(domain.tickYCount()); | |
415 |
|
471 | |||
416 |
qreal x = m_ |
|
472 | qreal x = m_categories.count(); | |
417 | qreal y = max(); |
|
473 | qreal y = max(); | |
418 | minX = qMin(minX, x); |
|
474 | minX = qMin(minX, x); | |
419 | minY = qMin(minY, y); |
|
475 | minY = qMin(minY, y); |
@@ -31,7 +31,6 QTCOMMERCIALCHART_BEGIN_NAMESPACE | |||||
31 | typedef QStringList QBarCategories; |
|
31 | typedef QStringList QBarCategories; | |
32 |
|
32 | |||
33 | class QBarSet; |
|
33 | class QBarSet; | |
34 | class BarChartModel; |
|
|||
35 | class BarCategory; |
|
34 | class BarCategory; | |
36 | class QBarSeriesPrivate; |
|
35 | class QBarSeriesPrivate; | |
37 |
|
36 |
@@ -33,7 +33,6 public: | |||||
33 | qreal categorySum(int category); |
|
33 | qreal categorySum(int category); | |
34 | qreal absoluteCategorySum(int category); |
|
34 | qreal absoluteCategorySum(int category); | |
35 | qreal maxCategorySum(); |
|
35 | qreal maxCategorySum(); | |
36 | BarChartModel& modelInternal(); |
|
|||
37 |
|
36 | |||
38 | Q_SIGNALS: |
|
37 | Q_SIGNALS: | |
39 | void clicked(QBarSet *barset, QString category, Qt::MouseButtons button); |
|
38 | void clicked(QBarSet *barset, QString category, Qt::MouseButtons button); | |
@@ -47,7 +46,9 private Q_SLOTS: | |||||
47 | void barsetChanged(); |
|
46 | void barsetChanged(); | |
48 |
|
47 | |||
49 | protected: |
|
48 | protected: | |
50 | BarChartModel *m_internalModel; // TODO: this may change... current "2 models" situation doesn't look good. |
|
49 | QList<QBarSet *> m_barSets; | |
|
50 | QBarCategories m_categories; | |||
|
51 | ||||
51 | QAbstractItemModel* m_model; |
|
52 | QAbstractItemModel* m_model; | |
52 | int m_mapCategories; |
|
53 | int m_mapCategories; | |
53 | int m_mapBarBottom; |
|
54 | int m_mapBarBottom; |
@@ -21,7 +21,6 | |||||
21 | #include "qstackedbarseries.h" |
|
21 | #include "qstackedbarseries.h" | |
22 | #include "qstackedbarseries_p.h" |
|
22 | #include "qstackedbarseries_p.h" | |
23 | #include "stackedbarchartitem_p.h" |
|
23 | #include "stackedbarchartitem_p.h" | |
24 | #include "barchartmodel_p.h" |
|
|||
25 | #include "chartdataset_p.h" |
|
24 | #include "chartdataset_p.h" | |
26 | #include "charttheme_p.h" |
|
25 | #include "charttheme_p.h" | |
27 | #include "chartanimator_p.h" |
|
26 | #include "chartanimator_p.h" | |
@@ -79,7 +78,7 void QStackedBarSeriesPrivate::scaleDomain(Domain& domain) | |||||
79 | int tickXCount(domain.tickXCount()); |
|
78 | int tickXCount(domain.tickXCount()); | |
80 | int tickYCount(domain.tickYCount()); |
|
79 | int tickYCount(domain.tickYCount()); | |
81 |
|
80 | |||
82 |
qreal x = m_ |
|
81 | qreal x = m_categories.count(); | |
83 | qreal y = maxCategorySum(); |
|
82 | qreal y = maxCategorySum(); | |
84 | minX = qMin(minX, x); |
|
83 | minX = qMin(minX, x); | |
85 | minY = qMin(minY, y); |
|
84 | minY = qMin(minY, y); |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now