00001
00002 #include <QTableWidget>
00003 #include <QPrinter>
00004 #include <QPrintDialog>
00005 #include <QMenu>
00006 #include <QFileDialog>
00007
00008 #include <qwt_plot.h>
00009 #include <qwt_plot_zoomer.h>
00010 #include <qwt_plot_panner.h>
00011 #include <qwt_plot_curve.h>
00012 #include <qwt_plot_layout.h>
00013 #include <qwt_legend.h>
00014
00015 #include "simplegraphcontroller.h"
00016 #include "qsedataset.h"
00017 #include "qsedataexport.h"
00018 #include "qseaveragerrole.h"
00019 #include "coloredtableitem.h"
00020
00021 SimpleGraphController::SimpleGraphController
00022 (QseDataSet *f, QwtPlot *qp, QTableWidget *scans, QTableWidget *cols, QseAveragerRole* rl, QObject *parent)
00023 : QObject(parent),
00024 m_DataSet(f),
00025 m_CurrentScan(-1),
00026 m_Plot(qp),
00027 m_ScansTable(scans),
00028 m_ColumnsTable(cols),
00029 m_Role(rl),
00030 m_Zoomer(NULL),
00031 m_Panner(NULL),
00032 m_Legend(NULL),
00033 m_LegendShown(true)
00034 {
00035 m_Plot->setCanvasBackground(QColor(Qt::white));
00036
00037 m_Zoomer = new QwtPlotZoomer(QwtPlot::xBottom, QwtPlot::yLeft, qp->canvas());
00038 m_Zoomer -> setSelectionFlags(QwtPicker::DragSelection | QwtPicker::CornerToCorner);
00039 m_Zoomer -> setTrackerMode(QwtPicker::ActiveOnly);
00040 m_Zoomer -> setRubberBand(QwtPicker::RectRubberBand);
00041
00042 m_Pens[0].setColor(Qt::black);
00043 m_Pens[1].setColor(Qt::red);
00044 m_Pens[2].setColor(Qt::green);
00045 m_Pens[3].setColor(Qt::blue);
00046 m_Pens[4].setColor(Qt::cyan);
00047 m_Pens[5].setColor(Qt::magenta);
00048 m_Pens[6].setColor(Qt::darkYellow);
00049 m_Pens[7].setColor(Qt::darkRed);
00050 m_Pens[8].setColor(Qt::darkGreen);
00051 m_Pens[9].setColor(Qt::darkBlue);
00052 m_Pens[10].setColor(Qt::darkCyan);
00053 m_Pens[11].setColor(Qt::darkMagenta);
00054
00055
00056
00057
00058 #if QT_VERSION < 0x040000
00059
00060 m_Zoomer -> setMousePattern(QwtEventPattern::MouseSelect2,
00061 Qt::LeftButton, Qt::ControlButton | Qt::ShiftButton);
00062 #else
00063
00064 m_Zoomer -> setMousePattern(QwtEventPattern::MouseSelect2,
00065 Qt::LeftButton, Qt::ControlModifier | Qt::ShiftModifier);
00066 #endif
00067
00068 m_Zoomer -> setMousePattern(QwtEventPattern::MouseSelect3,
00069 Qt::LeftButton, Qt::ControlModifier);
00070
00071 m_Panner = new QwtPlotPanner(qp->canvas());
00072 m_Panner -> setMouseButton(Qt::MidButton);
00073 m_Panner -> setEnabled(true);
00074
00075 m_Legend = new QwtLegend;
00076 m_Legend -> setFrameStyle(QFrame::Box|QFrame::Sunken);
00077 m_Legend -> setItemMode(QwtLegend::CheckableItem);
00078
00079 m_Plot -> insertLegend(m_Legend, QwtPlot::BottomLegend);
00080
00081 connect(m_Plot, SIGNAL(legendChecked(QwtPlotItem*,bool)),
00082 this, SLOT(legendChecked(QwtPlotItem*,bool)));
00083
00084 m_Plot -> canvas() -> setContextMenuPolicy(Qt::CustomContextMenu);
00085 connect(m_Plot -> canvas(), SIGNAL(customContextMenuRequested(const QPoint &)),
00086 this, SLOT(graphContextMenu(const QPoint&)));
00087
00088 if (m_ColumnsTable) {
00089 m_ColumnsTable->setContextMenuPolicy(Qt::CustomContextMenu);
00090
00091 connect(m_ColumnsTable, SIGNAL(customContextMenuRequested(const QPoint &)),
00092 this, SLOT(columnsTableContextMenu(const QPoint &)));
00093
00094 connect(m_DataSet, SIGNAL(dataChanged()),
00095 this, SLOT(updateColumnsTable()));
00096 }
00097
00098 if (m_ScansTable) {
00099 m_ScansTable->setContextMenuPolicy(Qt::CustomContextMenu);
00100
00101 connect(m_ScansTable, SIGNAL(customContextMenuRequested(const QPoint &)),
00102 this, SLOT(scansTableContextMenu(const QPoint &)));
00103
00104 connect(m_ScansTable, SIGNAL(itemSelectionChanged()), this, SLOT(updateGraph()));
00105
00106 connect(m_DataSet, SIGNAL(dataChanged()),
00107 this, SLOT(updateScansTable()));
00108 }
00109
00110 }
00111
00112 SimpleGraphController::~SimpleGraphController()
00113 {
00114 }
00115
00116 QseScan* SimpleGraphController::currentScan()
00117 {
00118 return m_DataSet->scan(m_CurrentScan);
00119 }
00120
00121 void SimpleGraphController::setCurrentScan(int n)
00122 {
00123 if (n != m_CurrentScan) {
00124 m_CurrentScan = n;
00125
00126 if (m_ColumnsTable) {
00127 updateColumnsTable();
00128 }
00129
00130 updateGraph();
00131 }
00132 }
00133
00134 void SimpleGraphController::setAutoScale()
00135 {
00136 m_Plot -> setAxisAutoScale(QwtPlot::xBottom);
00137 m_Plot -> setAxisAutoScale(QwtPlot::yLeft);
00138 m_Plot -> replot();
00139
00140 m_Zoomer -> setZoomBase();
00141 }
00142
00143 void SimpleGraphController::showLegend()
00144 {
00145 m_LegendShown = true;
00146
00147 QwtPlotItem *item;
00148 const QwtPlotItemList &items = m_Plot->itemList();
00149
00150 foreach (item, items) {
00151 item->setItemAttribute(QwtPlotItem::Legend, true);
00152 }
00153
00154 m_Plot -> updateLayout();
00155 }
00156
00157 void SimpleGraphController::hideLegend()
00158 {
00159 m_LegendShown = false;
00160
00161 QwtPlotItem *item;
00162 const QwtPlotItemList &items = m_Plot->itemList();
00163
00164 foreach (item, items) {
00165 item->setItemAttribute(QwtPlotItem::Legend, false);
00166 }
00167
00168 m_Plot -> updateLayout();
00169 }
00170
00171 void SimpleGraphController::printGraph()
00172 {
00173 QPrinter printer;
00174
00175 printer.setCreator("Spec EXAFS Processor");
00176
00177
00178 QPrintDialog dialog(&printer);
00179
00180 if (dialog.exec()) {
00181 QwtPlotPrintFilter filter;
00182
00183 if ( printer.colorMode() == QPrinter::GrayScale ) {
00184 filter.setOptions(QwtPlotPrintFilter::PrintAll & ~QwtPlotPrintFilter::PrintCanvasBackground);
00185 }
00186
00187 m_Plot -> print(printer, filter);
00188 }
00189 }
00190
00191 void SimpleGraphController::legendChecked(QwtPlotItem *it, bool checked)
00192 {
00193 if (it) {
00194 QwtPlotCurve *pc = dynamic_cast<QwtPlotCurve*>(it);
00195
00196 if (pc) {
00197 QPen p = pc->pen();
00198 if (checked) {
00199 p.setWidth(3);
00200 } else {
00201 p.setWidth(0);
00202 }
00203
00204 if (m_Plot) {
00205 pc->setPen(p);
00206 m_Plot->replot();
00207 }
00208 }
00209 }
00210 }
00211
00212 void SimpleGraphController::setDataSet(QseDataSet *ds)
00213 {
00214 m_DataSet = ds;
00215 }
00216
00217 void SimpleGraphController::updateScansTable()
00218 {
00219 return;
00220
00221 Q_ASSERT(m_ScansTable);
00222
00223 int ns = m_DataSet -> scanCount();
00224
00225 m_ScansTable -> setUpdatesEnabled(false);
00226
00227 m_ScansTable -> setRowCount(ns);
00228 m_ScansTable -> setColumnCount(2);
00229
00230 m_ScansTable -> setHorizontalHeaderItem(0, new ColoredTableItem(Qt::black, false, "Scan"));
00231 m_ScansTable -> setHorizontalHeaderItem(1, new ColoredTableItem(Qt::black, false, "#Points"));
00232
00233 for (int i=0; i<ns; i++) {
00234 QseScan *s = m_DataSet -> scan(i);
00235
00236 if (s) {
00237 m_ScansTable->setItem(i,0, new ColoredTableItem(Qt::black, false, s->scanCommand()));
00238 int nr = s->maxRowCount();
00239 m_ScansTable->setItem(i,1, new ColoredTableItem(Qt::black, false, QString("%1").arg(nr)));
00240 }
00241 }
00242
00243 m_ScansTable -> resizeColumnsToContents();
00244 m_ScansTable -> resizeRowsToContents();
00245
00246 m_ScansTable -> setUpdatesEnabled(true);
00247 m_ScansTable -> repaint();
00248 }
00249
00250 void SimpleGraphController::updateColumnsTable()
00251 {
00252 return;
00253
00254 Q_ASSERT(m_ColumnsTable);
00255
00256 QseScan *s = currentScan();
00257
00258 if (s) {
00259 int nc = s->columnCount();
00260
00261 m_ColumnsTable->setUpdatesEnabled(false);
00262 m_ColumnsTable->setRowCount(nc);
00263 m_ColumnsTable->setColumnCount(1);
00264 m_ColumnsTable->setHorizontalHeaderItem(0, new ColoredTableItem(Qt::black, false, "Column"));
00265
00266 for (int i = 0; i < nc; i++) {
00267 QseColumn *col = s->column(i);
00268
00269 if (col) {
00270 m_ColumnsTable-> setItem(i, 0, m_Role -> styledColumnItem(col));
00271 }
00272 }
00273
00274 m_ColumnsTable -> resizeColumnsToContents();
00275 m_ColumnsTable -> resizeRowsToContents();
00276
00277 m_ColumnsTable->setUpdatesEnabled(true);
00278 m_ColumnsTable->repaint();
00279 }
00280 }
00281
00282 void SimpleGraphController::updateGraph()
00283 {
00284 m_Plot -> clear();
00285
00286 if (m_ScansTable) {
00287
00288 int pnnum = 0;
00289
00290 QList<QTableWidgetSelectionRange> selections = m_ScansTable -> selectedRanges();
00291 QTableWidgetSelectionRange selection;
00292
00293 foreach(selection, selections) {
00294 int r0 = selection.topRow();
00295 int r1 = selection.bottomRow();
00296
00297 for (int i = r0; i<=r1; i++) {
00298 QseScan *s = m_DataSet -> scan(i);
00299
00300 if (s) {
00301 int nc = s->columnCount();
00302
00303 if (nc >= 5) {
00304 QseColumn *xc = s->column(0);
00305 int nr = xc->rowCount();
00306
00307 QseColumn *yc = s->column(4);
00308 QwtPlotCurve *pc = new QwtPlotCurve(s->scanCommand());
00309
00310 pc->setData(xc->data(), yc->data(), nr);
00311 pc->setPen(m_Pens[pnnum]);
00312 pnnum = (pnnum + 1) % NPENS;
00313 pc->setItemAttribute(QwtPlotItem::Legend, m_LegendShown);
00314 pc->attach(m_Plot);
00315 }
00316 }
00317 }
00318 }
00319 } else if (m_ColumnsTable == NULL) {
00320 QseScan *s = currentScan();
00321 if (s) {
00322 int nc = s->columnCount();
00323
00324 if (nc >= 5) {
00325 QseColumn *xc = s->column(0);
00326 int nr = xc->rowCount();
00327
00328 QseColumn *yc = s->column(4);
00329 QwtPlotCurve *pc = new QwtPlotCurve(s->scanCommand());
00330
00331 pc->setData(xc->data(), yc->data(), nr);
00332 pc->setPen(m_Pens[0]);
00333 pc->setItemAttribute(QwtPlotItem::Legend, m_LegendShown);
00334 pc->attach(m_Plot);
00335 }
00336 }
00337 } else if (m_ColumnsTable && m_Role) {
00338 QseScan *s = currentScan();
00339
00340 if (s) {
00341 m_Plot->setTitle(s->scanCommand());
00342
00343 QseColumn *xc = NULL;
00344 int nc = s->columnCount();
00345
00346 for (int i = 0; i < nc; i++) {
00347 QseColumn *col = s->column(i);
00348 if (col && m_Role->matchesEnergyColumn(col)) {
00349 xc = col;
00350 break;
00351 }
00352 }
00353
00354 if (xc) {
00355 int nr = xc->rowCount();
00356 int pnnum = 0;
00357
00358 for (int i = 0; i < nc; i++) {
00359 QseColumn *yc = s->column(i);
00360
00361 if (yc && m_Role->matchesDetectorColumn(yc)) {
00362 QwtPlotCurve *pc = new QwtPlotCurve(yc->name());
00363 pc->setData(xc->data(), yc->data(), nr);
00364 pc->setPen(m_Pens[pnnum]);
00365 pnnum = (pnnum + 1) % NPENS;
00366 pc->setItemAttribute(QwtPlotItem::Legend, m_LegendShown);
00367 pc->attach(m_Plot);
00368 }
00369 }
00370 }
00371 }
00372 }
00373
00374 m_Plot -> replot();
00375
00376 if (m_Zoomer -> zoomRectIndex() == 0) {
00377 m_Zoomer -> setZoomBase();
00378 }
00379
00380
00381 }
00382
00383 void SimpleGraphController::addContextMenuAction(QAction *action)
00384 {
00385 m_Actions.append(action);
00386 }
00387
00391 void SimpleGraphController::columnsTableContextMenu(const QPoint & pos)
00392 {
00393 int col = m_ColumnsTable -> columnAt(pos.x());
00394
00395 if (col == 0) {
00396 QseScan *s = currentScan();
00397
00398 if (s) {
00399 QList<QTableWidgetSelectionRange> selections = m_ColumnsTable -> selectedRanges();
00400 QTableWidgetSelectionRange selection;
00401
00402
00403 QMenu menu(NULL, NULL);
00404
00405 QAction* revertItem = menu.addAction(QString("Revert column(s) to Default Usage"));
00406 QAction* unusedItem = menu.addAction(QString("Do Not Use column(s)"));
00407 QAction* detectorItem = menu.addAction(QString("Use column(s) as a signal channel"));
00408 QAction* normalizationItem = menu.addAction(QString("Use column(s) as a normalization channel"));
00409 QAction* energyItem = menu.addAction(QString("Use column(s) as Energy (X Value)"));
00410 QAction* secondsItem = menu.addAction(QString("Use column(s) as counting time"));
00411
00412 QAction* init = revertItem;
00413 QseColumn::QseColumnRole newrole = QseColumn::UnspecifiedRole;
00414
00415 menu.setMouseTracking(TRUE);
00416
00417 QAction* id = menu.exec(QCursor::pos() + QPoint( -40, -10), init);
00418
00419 if (id == revertItem) {
00420 newrole = QseColumn::UnspecifiedRole;
00421 } else if (id == unusedItem) {
00422 newrole = QseColumn::NotUsedRole;
00423 } else if (id == detectorItem) {
00424 newrole = QseColumn::DetectorRole;
00425 } else if (id == normalizationItem) {
00426 newrole = QseColumn::NormalizationRole;
00427 } else if (id == energyItem) {
00428 newrole = QseColumn::EnergyRole;
00429 } else if (id == secondsItem) {
00430 newrole = QseColumn::SecondsRole;
00431 }
00432
00433 if (id) {
00434 foreach (selection, selections) {
00435 int minrow = selection.topRow();
00436 int maxrow = selection.bottomRow();
00437
00438 int nchanged = 0;
00439
00440 for (int row = minrow; row <= maxrow; row++) {
00441 QseColumn *c = s->column(row);
00442 if (c) {
00443 nchanged++;
00444 c->setColumnRole(newrole);
00445 }
00446 }
00447
00448 if (nchanged) {
00449 emit columnRangeRolesChanged(m_CurrentScan, m_CurrentScan, minrow, maxrow);
00450 }
00451 }
00452 }
00453 }
00454 }
00455 }
00456
00460 void SimpleGraphController::scansTableContextMenu(const QPoint & pos)
00461 {
00462 QMenu menu(NULL, NULL);
00463 QAction *action;
00464
00465 foreach (action, m_Actions) {
00466 menu.addAction(action);
00467 }
00468
00469 QAction* saveItem = menu.addAction(QString("Save selected scans"));
00470 QAction* removeItem = menu.addAction(QString("Remove selected scans"));
00471
00472 menu.setMouseTracking(TRUE);
00473
00474 QAction* id = menu.exec(QCursor::pos() + QPoint( -40, -10), saveItem);
00475
00476 if (id == saveItem) {
00477 saveSelectedScans();
00478 } else if (id == removeItem) {
00479 removeSelectedScans();
00480 }
00481 }
00482
00483 void SimpleGraphController::graphContextMenu(const QPoint &pos)
00484 {
00485 QMenu menu(NULL, NULL);
00486 QAction *action;
00487
00488 foreach (action, m_Actions) {
00489 menu.addAction(action);
00490 }
00491
00492 QAction* autoscaleItem = menu.addAction(QString("Autoscale Graph"));
00493 QAction* printItem = menu.addAction(QString("Print Graph..."));
00494
00495 QAction* showLegendItem = NULL;
00496 QAction* hideLegendItem = NULL;
00497
00498 if (m_LegendShown) {
00499 hideLegendItem = menu.addAction(QString("Hide Legend"));
00500 } else {
00501 showLegendItem = menu.addAction(QString("Display Legend"));
00502 }
00503
00504 QAction* saveItem = NULL;
00505 QAction* removeItem = NULL;
00506
00507 if (m_ScansTable) {
00508 saveItem = menu.addAction(QString("Save selected scans"));
00509 removeItem = menu.addAction(QString("Remove selected scans"));
00510 }
00511
00512 menu.setMouseTracking(TRUE);
00513
00514 QAction* id = menu.exec(QCursor::pos() + QPoint( -40, -10), saveItem);
00515
00516 if (id == autoscaleItem) {
00517 setAutoScale();
00518 } else if (id == printItem) {
00519 printGraph();
00520 } else if (id == showLegendItem) {
00521 showLegend();
00522 } else if (id == hideLegendItem) {
00523 hideLegend();
00524 } else if (m_ScansTable && (id == saveItem)) {
00525 saveSelectedScans();
00526 } else if (m_ScansTable && (id == removeItem)) {
00527 removeSelectedScans();
00528 }
00529 }
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570 void SimpleGraphController::saveSelectedScans()
00571 {
00572 QList<QTableWidgetSelectionRange> selections = m_ScansTable -> selectedRanges();
00573 QTableWidgetSelectionRange selection;
00574 QList<int> selectedScans;
00575
00576 foreach (selection, selections) {
00577 int r0 = selection.topRow();
00578 int r1 = selection.bottomRow();
00579
00580 for (int i = r0; i <= r1; i++) {
00581 selectedScans.append(i);
00582 }
00583 }
00584
00585 QseDataExport::exportSelectedData("export/data", m_DataSet, selectedScans);
00586 }
00587
00588 void SimpleGraphController::removeSelectedScans()
00589 {
00590 QList<QTableWidgetSelectionRange> selections = m_ScansTable -> selectedRanges();
00591 QTableWidgetSelectionRange selection;
00592 int ns = m_DataSet->scanCount();
00593
00594 QVector<int> toRemove;
00595 toRemove.resize(ns);
00596
00597 foreach (selection, selections) {
00598 int r0 = selection.topRow();
00599 int r1 = selection.bottomRow();
00600
00601 for (int i = r0; i <= r1; i++) {
00602 if (i >= 0 && i < ns) {
00603 toRemove[i] = 1;
00604 }
00605 }
00606 }
00607
00608 for (int i = ns-1; i >= 0; i--) {
00609 if (toRemove[i]) {
00610 m_ScansTable -> removeRow(i);
00611 m_DataSet -> removeScan(i);
00612 }
00613 }
00614
00615 updateGraph();
00616 }
00617