1
/***************************************************************************
4
--------------------------------------------------------------------
5
Copyright : (C) 2006 by Ion Vasilief, Tilman Hoener zu Siederdissen
6
Email (use @ for *) : ion_vasilief*yahoo.fr, thzs*gmx.net
7
Description : Multi layer widget
9
***************************************************************************/
11
/***************************************************************************
13
* This program is free software; you can redistribute it and/or modify *
14
* it under the terms of the GNU General Public License as published by *
15
* the Free Software Foundation; either version 2 of the License, or *
16
* (at your option) any later version. *
18
* This program is distributed in the hope that it will be useful, *
19
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
20
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
21
* GNU General Public License for more details. *
23
* You should have received a copy of the GNU General Public License *
24
* along with this program; if not, write to the Free Software *
25
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
26
* Boston, MA 02110-1301 USA *
28
***************************************************************************/
30
#include <QWidgetList>
32
#include <QPrintDialog>
34
#include <QApplication>
35
#include <QMessageBox>
37
#include <QImageWriter>
42
#if QT_VERSION >= 0x040300
43
#include <QSvgGenerator>
47
#include <qwt_plot_canvas.h>
48
#include <qwt_plot_layout.h>
49
#include <qwt_scale_widget.h>
50
#include <qwt_text_label.h>
52
#include "MultiLayer.h"
54
#include "LegendMarker.h"
55
#include "SelectionMoveResizer.h"
57
#include <gsl/gsl_vector.h>
59
LayerButton::LayerButton(const QString& text, QWidget* parent)
60
: QPushButton(text, parent)
64
setToggleButton(true);
66
setMaximumWidth(btn_size);
67
setMaximumHeight(btn_size);
70
void LayerButton::mousePressEvent( QMouseEvent *event )
72
if (event->button() == Qt::LeftButton && !isOn())
76
void LayerButton::mouseDoubleClickEvent ( QMouseEvent * )
78
emit showCurvesDialog();
81
MultiLayer::MultiLayer(const QString& label, QWidget* parent, const char* name, Qt::WFlags f)
82
: MyWidget(label,parent,name,f)
85
setName( "multilayer plot" );
87
QPalette pal = palette();
88
pal.setColor(QPalette::Active, QPalette::Window, QColor(Qt::white));
89
pal.setColor(QPalette::Inactive, QPalette::Window, QColor(Qt::white));
90
pal.setColor(QPalette::Disabled, QPalette::Window, QColor(Qt::white));
93
QDateTime dt = QDateTime::currentDateTime ();
94
setBirthDate(dt.toString(Qt::LocalDate));
96
graphs=0; cols=1; rows=1;
97
graph_width=500; graph_height=400;
98
colsSpace=5; rowsSpace=5;
99
left_margin = 5; right_margin = 5;
100
top_margin = 5; bottom_margin = 5;
101
l_canvas_width = 400; l_canvas_height = 300;
102
hor_align = HCenter; vert_align = VCenter;
105
d_open_maximized = 0;
106
d_max_size = QSize();
107
d_normal_size = QSize();
108
d_scale_on_print = true;
109
d_print_cropmarks = false;
111
layerButtonsBox = new QHBoxLayout();
112
QHBoxLayout *hbox = new QHBoxLayout();
113
hbox->addLayout(layerButtonsBox);
116
canvas = new QWidget();
117
canvas->installEventFilter(this);
119
QVBoxLayout* layout = new QVBoxLayout(this);
120
layout->addLayout(hbox);
121
layout->addWidget(canvas);
122
layout->setMargin(0);
123
layout->setSpacing(0);
124
setGeometry(QRect( 0, 0, graph_width, graph_height ));
125
setFocusPolicy(Qt::StrongFocus);
128
Graph *MultiLayer::layer(int num)
130
return (Graph*) graphsList.at(num-1);
133
LayerButton* MultiLayer::addLayerButton()
135
for (int i=0;i<buttonsList.count();i++)
137
LayerButton *btn=(LayerButton*) buttonsList.at(i);
141
LayerButton *button = new LayerButton(QString::number(++graphs));
142
connect (button, SIGNAL(clicked(LayerButton*)),this, SLOT(activateGraph(LayerButton*)));
143
connect (button, SIGNAL(showCurvesDialog()),this, SIGNAL(showCurvesDialog()));
145
buttonsList.append(button);
146
layerButtonsBox->addWidget(button);
150
Graph* MultiLayer::addLayer(int x, int y, int width, int height)
153
if (!width && !height)
156
height = graph_height;
159
Graph* g = new Graph(canvas);
160
g->setAttribute(Qt::WA_DeleteOnClose);
161
g->setGeometry(x, y, width, height);
162
g->plotWidget()->resize(QSize(width, height));
163
graphsList.append(g);
171
void MultiLayer::adjustSize()
173
canvas->resize(size().width(), size().height() - LayerButton::btnSize());
176
void MultiLayer::activateGraph(LayerButton* button)
178
for (int i=0;i<buttonsList.count();i++)
180
LayerButton *btn=(LayerButton*)buttonsList.at(i);
186
active_graph = (Graph*) graphsList.at(i);
187
active_graph->setFocus();
188
active_graph->raise();//raise layer on top of the layers stack
194
void MultiLayer::setActiveGraph(Graph* g)
196
if (!g || active_graph == g)
200
active_graph->setFocus();
202
if (d_layers_selector)
203
delete d_layers_selector;
205
active_graph->raise();//raise layer on top of the layers stack
207
for (int i=0;i<(int)graphsList.count();i++)
209
Graph *gr = (Graph *)graphsList.at(i);
210
LayerButton *btn = (LayerButton *)buttonsList.at(i);
218
void MultiLayer::contextMenuEvent(QContextMenuEvent *e)
220
emit showWindowContextMenu();
224
void MultiLayer::resizeLayers (const QResizeEvent *re)
226
QSize oldSize = re->oldSize();
227
QSize size = re->size();
229
if (d_open_maximized == 1)
230
{// 2 resize events are triggered for maximized windows: this hack allows to ignore the first one!
234
else if (d_open_maximized == 2)
236
d_open_maximized = 0;
237
//TODO: for maximized windows, the size of the layers should be saved in % of the workspace area in order to restore
238
//the layers properly! For the moment just resize the layers to occupy the whole canvas, although the restored geometry might be altered!
239
oldSize = QSize(canvas->childrenRect().width() + left_margin + right_margin,
240
canvas->childrenRect().height() + top_margin + bottom_margin);
244
if(!oldSize.isValid())
247
resizeLayers(size, oldSize, false);
250
void MultiLayer::resizeLayers (const QSize& size, const QSize& oldSize, bool scaleFonts)
252
QApplication::setOverrideCursor(Qt::waitCursor);
254
double w_ratio = (double)size.width()/(double)oldSize.width();
255
double h_ratio = (double)(size.height())/(double)(oldSize.height());
257
for (int i=0;i<graphsList.count();i++)
259
Graph *gr = (Graph *)graphsList.at(i);
260
if (gr && !gr->ignoresResizeEvents())
262
int gx = qRound(gr->x()*w_ratio);
263
int gy = qRound(gr->y()*h_ratio);
264
int gw = qRound(gr->width()*w_ratio);
265
int gh = qRound(gr->height()*h_ratio);
267
gr->setGeometry(QRect(gx, gy, gw, gh));
268
gr->plotWidget()->resize(QSize(gw, gh));
271
gr->scaleFonts(h_ratio);
276
emit resizedWindow(this);
277
QApplication::restoreOverrideCursor();
280
void MultiLayer::confirmRemoveLayer()
284
switch(QMessageBox::information(this,
285
tr("QtiPlot - Guess best layout?"),
286
tr("Do you want QtiPlot to rearrange the remaining layers?"),
287
tr("&Yes"), tr("&No"), tr("&Cancel"),
292
arrangeLayers(true, false);
308
void MultiLayer::removeLayer()
310
//remove corresponding button
313
for (i=0;i<buttonsList.count();i++)
315
btn=(LayerButton*)buttonsList.at(i);
318
buttonsList.removeAll(btn);
324
//update the texts of the buttons
325
for (i=0;i<buttonsList.count();i++)
327
btn=(LayerButton*)buttonsList.at(i);
328
btn->setText(QString::number(i+1));
331
if (active_graph->zoomOn() || active_graph->activeTool())
332
emit setPointerCursor();
334
int index = graphsList.indexOf(active_graph);
335
graphsList.removeAt(index);
336
active_graph->close();
338
if(index >= graphsList.count())
347
active_graph=(Graph*) graphsList.at(index);
349
for (i=0;i<(int)graphsList.count();i++)
351
Graph *gr=(Graph *)graphsList.at(i);
352
if (gr == active_graph)
354
LayerButton *button=(LayerButton *)buttonsList.at(i);
363
void MultiLayer::setGraphGeometry(int x, int y, int w, int h)
365
if (active_graph->pos() == QPoint (x,y) &&
366
active_graph->size() == QSize (w,h))
369
active_graph->setGeometry(QRect(QPoint(x,y),QSize(w,h)));
370
active_graph->plotWidget()->resize(QSize(w, h));
374
QSize MultiLayer::arrangeLayers(bool userSize)
376
const QRect rect = canvas->geometry();
378
gsl_vector *xTopR = gsl_vector_calloc (graphs);//ratio between top axis + title and canvas height
379
gsl_vector *xBottomR = gsl_vector_calloc (graphs); //ratio between bottom axis and canvas height
380
gsl_vector *yLeftR = gsl_vector_calloc (graphs);
381
gsl_vector *yRightR = gsl_vector_calloc (graphs);
382
gsl_vector *maxXTopHeight = gsl_vector_calloc (rows);//maximum top axis + title height in a row
383
gsl_vector *maxXBottomHeight = gsl_vector_calloc (rows);//maximum bottom axis height in a row
384
gsl_vector *maxYLeftWidth = gsl_vector_calloc (cols);//maximum left axis width in a column
385
gsl_vector *maxYRightWidth = gsl_vector_calloc (cols);//maximum right axis width in a column
386
gsl_vector *Y = gsl_vector_calloc (rows);
387
gsl_vector *X = gsl_vector_calloc (cols);
390
for (i=0; i<graphs; i++)
391
{//calculate scales/canvas dimensions reports for each layer and stores them in the above vectors
392
Graph *gr=(Graph *)graphsList.at(i);
393
QwtPlot *plot=gr->plotWidget();
394
QwtPlotLayout *plotLayout=plot->plotLayout();
395
QRect cRect=plotLayout->canvasRect();
396
double ch = (double) cRect.height();
397
double cw = (double) cRect.width();
399
QRect tRect=plotLayout->titleRect ();
400
QwtScaleWidget *scale=(QwtScaleWidget *) plot->axisWidget (QwtPlot::xTop);
404
topHeight += tRect.height() + plotLayout->spacing();
407
QRect sRect=plotLayout->scaleRect (QwtPlot::xTop);
408
topHeight += sRect.height();
410
gsl_vector_set (xTopR, i, double(topHeight)/ch);
412
scale=(QwtScaleWidget *) plot->axisWidget (QwtPlot::xBottom);
415
QRect sRect = plotLayout->scaleRect (QwtPlot::xBottom);
416
gsl_vector_set (xBottomR, i, double(sRect.height())/ch);
419
scale=(QwtScaleWidget *) plot->axisWidget (QwtPlot::yLeft);
422
QRect sRect = plotLayout->scaleRect (QwtPlot::yLeft);
423
gsl_vector_set (yLeftR, i, double(sRect.width())/cw);
426
scale=(QwtScaleWidget *) plot->axisWidget (QwtPlot::yRight);
429
QRect sRect = plotLayout->scaleRect (QwtPlot::yRight);
430
gsl_vector_set (yRightR, i, double(sRect.width())/cw);
433
//calculate max scales/canvas dimensions ratio for each line and column and stores them to vectors
440
double aux = gsl_vector_get(xTopR, i);
441
double old_max = gsl_vector_get(maxXTopHeight, row);
443
gsl_vector_set(maxXTopHeight, row, aux);
445
aux = gsl_vector_get(xBottomR, i) ;
446
if (aux >= gsl_vector_get(maxXBottomHeight, row))
447
gsl_vector_set(maxXBottomHeight, row, aux);
449
aux = gsl_vector_get(yLeftR, i);
450
if (aux >= gsl_vector_get(maxYLeftWidth, col))
451
gsl_vector_set(maxYLeftWidth, col, aux);
453
aux = gsl_vector_get(yRightR, i);
454
if (aux >= gsl_vector_get(maxYRightWidth, col))
455
gsl_vector_set(maxYRightWidth, col, aux);
458
double c_heights = 0.0;
459
for (i=0; i<rows; i++)
461
gsl_vector_set (Y, i, c_heights);
462
c_heights += 1 + gsl_vector_get(maxXTopHeight, i) + gsl_vector_get(maxXBottomHeight, i);
465
double c_widths = 0.0;
466
for (i=0; i<cols; i++)
468
gsl_vector_set (X, i, c_widths);
469
c_widths += 1 + gsl_vector_get(maxYLeftWidth, i) + gsl_vector_get(maxYRightWidth, i);
474
l_canvas_width = int((rect.width()-(cols-1)*colsSpace - right_margin - left_margin)/c_widths);
475
l_canvas_height = int((rect.height()-(rows-1)*rowsSpace - top_margin - bottom_margin)/c_heights);
478
QSize size = QSize(l_canvas_width, l_canvas_height);
480
for (i=0; i<graphs; i++)
488
//calculate sizes and positions for layers
489
const int w = int (l_canvas_width*(1 + gsl_vector_get(yLeftR, i) + gsl_vector_get(yRightR, i)));
490
const int h = int (l_canvas_height*(1 + gsl_vector_get(xTopR, i) + gsl_vector_get(xBottomR, i)));
492
int x = left_margin + col*colsSpace;
493
if (hor_align == HCenter)
494
x += int (l_canvas_width*(gsl_vector_get(X, col) + gsl_vector_get(maxYLeftWidth, col) - gsl_vector_get(yLeftR, i)));
495
else if (hor_align == Left)
496
x += int(l_canvas_width*gsl_vector_get(X, col));
497
else if (hor_align == Right)
498
x += int(l_canvas_width*(gsl_vector_get(X, col) + gsl_vector_get(maxYLeftWidth, col) - gsl_vector_get(yLeftR, i)+
499
gsl_vector_get(maxYRightWidth, col) - gsl_vector_get(yRightR, i)));
501
int y = top_margin + row*rowsSpace;
502
if (vert_align == VCenter)
503
y += int(l_canvas_height*(gsl_vector_get(Y, row) + gsl_vector_get(maxXTopHeight, row) - gsl_vector_get(xTopR, i)));
504
else if (vert_align == Top)
505
y += int(l_canvas_height*gsl_vector_get(Y, row));
506
else if (vert_align == Bottom)
507
y += int(l_canvas_height*(gsl_vector_get(Y, row) + gsl_vector_get(maxXTopHeight, row) - gsl_vector_get(xTopR, i)+
508
+ gsl_vector_get(maxXBottomHeight, row) - gsl_vector_get(xBottomR, i)));
510
//resizes and moves layers
511
Graph *gr = (Graph *)graphsList.at(i);
512
bool autoscaleFonts = false;
514
{//When the user specifies the layer canvas size, the window is resized
515
//and the fonts must be scaled accordingly. If the size is calculated
516
//automatically we don't rescale the fonts in order to prevent problems
517
//with too small fonts when the user adds new layers or when removing layers
519
autoscaleFonts = gr->autoscaleFonts();//save user settings
520
gr->setAutoscaleFonts(false);
523
gr->setGeometry(QRect(x, y, w, h));
524
gr->plotWidget()->resize(QSize(w, h));
527
gr->setAutoscaleFonts(autoscaleFonts);//restore user settings
531
gsl_vector_free (maxXTopHeight); gsl_vector_free (maxXBottomHeight);
532
gsl_vector_free (maxYLeftWidth); gsl_vector_free (maxYRightWidth);
533
gsl_vector_free (xTopR); gsl_vector_free (xBottomR);
534
gsl_vector_free (yLeftR); gsl_vector_free (yRightR);
535
gsl_vector_free (X); gsl_vector_free (Y);
539
void MultiLayer::findBestLayout(int &rows, int &cols)
542
if(NumGraph%2==0) // NumGraph is an even number
554
else if(NumGraph%2!=0) // NumGraph is an odd number
570
void MultiLayer::arrangeLayers(bool fit, bool userSize)
575
QApplication::setOverrideCursor(Qt::waitCursor);
577
if(d_layers_selector)
578
delete d_layers_selector;
581
findBestLayout(rows, cols);
583
//the canvas sizes of all layers become equal only after several
584
//resize iterations, due to the way Qwt handles the plot layout
586
QSize size = arrangeLayers(userSize);
587
QSize canvas_size = QSize(1,1);
588
while (canvas_size != size && iterations < 10)
592
size = arrangeLayers(userSize);
597
bool ignoreResize = active_graph->ignoresResizeEvents();
598
for (int i=0; i<(int)graphsList.count(); i++)
600
Graph *gr = (Graph *)graphsList.at(i);
601
gr->setIgnoreResizeEvents(true);
605
QSize size = canvas->childrenRect().size();
606
this->resize(QSize(size.width() + right_margin,
607
size.height() + bottom_margin + LayerButton::btnSize()));
609
for (int i=0; i<(int)graphsList.count(); i++)
611
Graph *gr = (Graph *)graphsList.at(i);
612
gr->setIgnoreResizeEvents(ignoreResize);
617
QApplication::restoreOverrideCursor();
620
void MultiLayer::setCols(int c)
626
void MultiLayer::setRows(int r)
632
QPixmap MultiLayer::canvasPixmap()
634
return QPixmap::grabWidget(canvas);
637
void MultiLayer::exportToFile(const QString& fileName)
639
if ( fileName.isEmpty() )
641
QMessageBox::critical(0, tr("QtiPlot - Error"), tr("Please provide a valid file name!"));
645
if (fileName.contains(".eps") || fileName.contains(".pdf") || fileName.contains(".ps"))
647
exportVector(fileName);
652
QList<QByteArray> list = QImageWriter::supportedImageFormats();
653
for(int i=0 ; i<list.count() ; i++)
655
if (fileName.contains( "." + list[i].toLower()))
657
exportImage(fileName);
661
QMessageBox::critical(this, tr("QtiPlot - Error"), tr("File format not handled, operation aborted!"));
665
void MultiLayer::exportImage(const QString& fileName, int quality, bool transparent)
667
QPixmap pic = canvasPixmap();
670
QBitmap mask(pic.size());
671
mask.fill(Qt::color1);
674
p.setPen(Qt::color0);
676
QColor background = QColor (Qt::white);
677
QRgb backgroundPixel = background.rgb ();
679
QImage image = pic.convertToImage();
680
for (int y=0; y<image.height(); y++)
682
for ( int x=0; x<image.width(); x++ )
684
QRgb rgb = image.pixel(x, y);
685
if (rgb == backgroundPixel) // we want the frame transparent
692
pic.save(fileName, 0, quality);
695
void MultiLayer::exportPDF(const QString& fname)
700
void MultiLayer::exportVector(const QString& fileName, int res, bool color)
702
if ( fileName.isEmpty() )
704
QMessageBox::critical(this, tr("QtiPlot - Error"),
705
tr("Please provide a valid file name!"));
710
printer.setDocName (this->name());
711
printer.setCreator("QtiPlot");
712
printer.setFullPage(true);
713
printer.setOutputFileName(fileName);
714
if (fileName.contains(".eps"))
715
printer.setOutputFormat(QPrinter::PostScriptFormat);
718
printer.setResolution(res);
720
QRect canvasRect = canvas->rect();
721
printer.setPageSize(Graph::minPageSize(printer, canvasRect));
723
double aspect = double(canvasRect.width())/double(canvasRect.height());
725
printer.setOrientation(QPrinter::Portrait);
727
printer.setOrientation(QPrinter::Landscape);
730
printer.setColorMode(QPrinter::Color);
732
printer.setColorMode(QPrinter::GrayScale);
734
QRect paperRect = printer.paperRect();
735
int x_margin = (paperRect.width() - canvasRect.width())/2;
736
int y_margin = (paperRect.height() - canvasRect.height())/2;
738
QPainter paint(&printer);
739
for (int i=0; i<(int)graphsList.count(); i++)
741
Graph *gr = (Graph *)graphsList.at(i);
742
Plot *myPlot = (Plot *)gr->plotWidget();
744
QPoint pos = gr->pos();
745
pos = QPoint(x_margin + pos.x(), y_margin + pos.y());
746
myPlot->print(&paint, QRect(pos, myPlot->size()));
750
void MultiLayer::exportSVG(const QString& fname)
752
#if QT_VERSION >= 0x040300
753
QSvgGenerator generator;
754
generator.setFileName(fname);
755
generator.setSize(canvas->size());
757
QPainter p(&generator);
758
for (int i=0; i<(int)graphsList.count(); i++)
760
Graph *gr = (Graph *)graphsList.at(i);
761
Plot *myPlot = (Plot *)gr->plotWidget();
763
QPoint pos = QPoint(gr->pos().x(), gr->pos().y());
764
myPlot->print(&p, QRect(pos, myPlot->size()));
770
void MultiLayer::copyAllLayers()
772
QPixmap pic = canvasPixmap();
773
QImage image= pic.convertToImage();
774
QApplication::clipboard()->setImage(image);
777
void MultiLayer::printActiveLayer()
781
active_graph->setScaleOnPrint(d_scale_on_print);
782
active_graph->printCropmarks(d_print_cropmarks);
783
active_graph->print();
787
void MultiLayer::print()
790
printer.setColorMode (QPrinter::Color);
791
printer.setFullPage(true);
792
QRect canvasRect = canvas->rect();
793
double aspect = double(canvasRect.width())/double(canvasRect.height());
795
printer.setOrientation(QPrinter::Portrait);
797
printer.setOrientation(QPrinter::Landscape);
799
QPrintDialog printDialog(&printer);
800
if (printDialog.exec() == QDialog::Accepted)
802
QPainter paint(&printer);
803
printAllLayers(&paint);
808
void MultiLayer::printAllLayers(QPainter *painter)
813
QPrinter *printer = (QPrinter *)painter->device();
814
QRect paperRect = ((QPrinter *)painter->device())->paperRect();
815
QRect canvasRect = canvas->rect();
816
QRect pageRect = printer->pageRect();
817
QRect cr = canvasRect; // cropmarks rectangle
819
if (d_scale_on_print)
821
int margin = (int)((1/2.54)*printer->logicalDpiY()); // 1 cm margins
822
double scaleFactorX=(double)(paperRect.width()-2*margin)/(double)canvasRect.width();
823
double scaleFactorY=(double)(paperRect.height()-2*margin)/(double)canvasRect.height();
825
if (d_print_cropmarks)
827
cr.moveTo(QPoint(margin + int(cr.x()*scaleFactorX),
828
margin + int(cr.y()*scaleFactorY)));
829
cr.setWidth(int(cr.width()*scaleFactorX));
830
cr.setHeight(int(cr.height()*scaleFactorX));
833
for (int i=0; i<(int)graphsList.count(); i++)
835
Graph *gr=(Graph *)graphsList.at(i);
836
Plot *myPlot= gr->plotWidget();
838
QPoint pos=gr->pos();
839
pos=QPoint(margin + int(pos.x()*scaleFactorX), margin + int(pos.y()*scaleFactorY));
841
int width=int(myPlot->frameGeometry().width()*scaleFactorX);
842
int height=int(myPlot->frameGeometry().height()*scaleFactorY);
844
myPlot->print(painter, QRect(pos, QSize(width,height)));
849
int x_margin = (pageRect.width() - canvasRect.width())/2;
850
int y_margin = (pageRect.height() - canvasRect.height())/2;
852
if (d_print_cropmarks)
853
cr.moveTo(x_margin, y_margin);
855
for (int i=0; i<(int)graphsList.count(); i++)
857
Graph *gr = (Graph *)graphsList.at(i);
858
Plot *myPlot = (Plot *)gr->plotWidget();
860
QPoint pos = gr->pos();
861
pos = QPoint(x_margin + pos.x(), y_margin + pos.y());
862
myPlot->print(painter, QRect(pos, myPlot->size()));
865
if (d_print_cropmarks)
867
cr.addCoords(-1, -1, 2, 2);
869
painter->setPen(QPen(QColor(Qt::black), 0.5, Qt::DashLine));
870
painter->drawLine(paperRect.left(), cr.top(), paperRect.right(), cr.top());
871
painter->drawLine(paperRect.left(), cr.bottom(), paperRect.right(), cr.bottom());
872
painter->drawLine(cr.left(), paperRect.top(), cr.left(), paperRect.bottom());
873
painter->drawLine(cr.right(), paperRect.top(), cr.right(), paperRect.bottom());
879
void MultiLayer::setFonts(const QFont& titleFnt, const QFont& scaleFnt,
880
const QFont& numbersFnt, const QFont& legendFnt)
882
for (int i=0;i<(int)graphsList.count();i++)
884
Graph *gr=(Graph *)graphsList.at(i);
885
QwtPlot *plot=gr->plotWidget();
887
QwtText text = plot->title();
888
text.setFont(titleFnt);
889
plot->setTitle(text);
890
for (int j= 0;j<QwtPlot::axisCnt;j++)
892
plot->setAxisFont (j,numbersFnt);
894
text = plot->axisTitle(j );
895
text.setFont(scaleFnt);
896
plot->setAxisTitle(j, text);
899
QVector<int> keys=gr->textMarkerKeys();
900
for (int k=0;k<(int)keys.size();k++)
902
LegendMarker* mrk=(LegendMarker*)gr->textMarker(keys[k]);
904
mrk->setFont(legendFnt);
911
void MultiLayer::connectLayer(Graph *g)
913
connect (g,SIGNAL(drawLineEnded(bool)), this, SIGNAL(drawLineEnded(bool)));
914
connect (g,SIGNAL(drawTextOff()),this,SIGNAL(drawTextOff()));
915
connect (g,SIGNAL(showPlotDialog(int)),this,SIGNAL(showPlotDialog(int)));
916
connect (g,SIGNAL(createTable(const QString&,int,int,const QString&)),
917
this,SIGNAL(createTable(const QString&,int,int,const QString&)));
918
connect (g,SIGNAL(viewLineDialog()),this,SIGNAL(showLineDialog()));
919
connect (g,SIGNAL(showContextMenu()),this,SIGNAL(showGraphContextMenu()));
920
connect (g,SIGNAL(showAxisDialog(int)),this,SIGNAL(showAxisDialog(int)));
921
connect (g,SIGNAL(axisDblClicked(int)),this,SIGNAL(showScaleDialog(int)));
922
connect (g,SIGNAL(xAxisTitleDblClicked()),this,SIGNAL(showXAxisTitleDialog()));
923
connect (g,SIGNAL(yAxisTitleDblClicked()),this,SIGNAL(showYAxisTitleDialog()));
924
connect (g,SIGNAL(rightAxisTitleDblClicked()),this,SIGNAL(showRightAxisTitleDialog()));
925
connect (g,SIGNAL(topAxisTitleDblClicked()),this,SIGNAL(showTopAxisTitleDialog()));
926
connect (g,SIGNAL(showMarkerPopupMenu()),this,SIGNAL(showMarkerPopupMenu()));
927
connect (g,SIGNAL(showCurveContextMenu(int)),this,SIGNAL(showCurveContextMenu(int)));
928
connect (g,SIGNAL(cursorInfo(const QString&)),this,SIGNAL(cursorInfo(const QString&)));
929
connect (g,SIGNAL(viewImageDialog()),this,SIGNAL(showImageDialog()));
930
connect (g,SIGNAL(viewTitleDialog()),this,SIGNAL(viewTitleDialog()));
931
connect (g,SIGNAL(modifiedGraph()),this,SIGNAL(modifiedPlot()));
932
connect (g,SIGNAL(selectedGraph(Graph*)),this, SLOT(setActiveGraph(Graph*)));
933
connect (g,SIGNAL(viewTextDialog()),this,SIGNAL(showTextDialog()));
934
connect (g,SIGNAL(createIntensityTable(const QString&)),
935
this,SIGNAL(createIntensityTable(const QString&)));
938
void MultiLayer::addTextLayer(int f, const QFont& font,
939
const QColor& textCol, const QColor& backgroundCol)
941
defaultTextMarkerFont = font;
942
defaultTextMarkerFrame = f;
943
defaultTextMarkerColor = textCol;
944
defaultTextMarkerBackground = backgroundCol;
947
QApplication::setOverrideCursor(Qt::IBeamCursor);
951
void MultiLayer::addTextLayer(const QPoint& pos)
956
QVector<bool> axesOn(4);
957
for (int j=0;j<4;j++)
959
g->enableAxes(axesOn);
960
g->setIgnoreResizeEvents(true);
961
g->setTextMarkerDefaults(defaultTextMarkerFrame, defaultTextMarkerFont,
962
defaultTextMarkerColor, defaultTextMarkerBackground);
963
LegendMarker *mrk = g->newLegend(tr("enter your text here"));
964
QSize size = mrk->rect().size();
965
setGraphGeometry(pos.x(), pos.y(), size.width()+10, size.height()+10);
966
g->setIgnoreResizeEvents(false);
968
QApplication::restoreOverrideCursor();
969
canvas->releaseMouse();
975
bool MultiLayer::eventFilter(QObject *object, QEvent *e)
977
if(e->type() == QEvent::MouseButtonPress && object == (QObject *)canvas)
979
const QMouseEvent *me = (const QMouseEvent *)e;
980
if (me->button()==Qt::LeftButton && addTextOn)
981
addTextLayer(me->pos());
985
else if(e->type() == QEvent::Resize && object == (QObject *)canvas)
987
resizeLayers((const QResizeEvent *)e);
989
else if (e->type()==QEvent::ContextMenu && object == titleBar)
991
emit showTitleBarMenu();
992
((QContextMenuEvent*)e)->accept();
995
return MyWidget::eventFilter(object, e);
998
void MultiLayer::keyPressEvent(QKeyEvent * e)
1000
if (e->key() == Qt::Key_F12)
1002
if (d_layers_selector)
1003
delete d_layers_selector;
1004
int index = graphsList.indexOf((QWidget *)active_graph) + 1;
1005
if (index >= graphsList.size())
1007
Graph *g=(Graph *)graphsList.at(index);
1013
if (e->key() == Qt::Key_F10)
1015
if (d_layers_selector)
1016
delete d_layers_selector;
1017
int index=graphsList.indexOf((QWidget *)active_graph) - 1;
1019
index = graphsList.size() - 1;
1020
Graph *g=(Graph *)graphsList.at(index);
1026
if (e->key() == Qt::Key_F11)
1028
emit showWindowContextMenu();
1033
void MultiLayer::wheelEvent ( QWheelEvent * e )
1035
QApplication::setOverrideCursor(Qt::waitCursor);
1040
Graph *resize_graph = 0;
1041
// Get the position of the mouse
1044
for (int i=0;i<(int)graphsList.count();i++)
1046
Graph *gr=(Graph *)graphsList.at(i);
1047
intSize=gr->plotWidget()->size();
1049
if(xMouse>aux.x() && xMouse<(aux.x()+intSize.width()))
1051
if(yMouse>aux.y() && yMouse<(aux.y()+intSize.height()))
1058
if(resize && (e->state()==Qt::AltButton || e->state()==Qt::ControlButton || e->state()==Qt::ShiftButton))
1060
intSize=resize_graph->plotWidget()->size();
1061
// If alt is pressed then change the width
1062
if(e->state()==Qt::AltButton)
1066
intSize.rwidth()+=5;
1068
else if(e->delta()<0)
1070
intSize.rwidth()-=5;
1073
// If crt is pressed then changed the height
1074
else if(e->state()==Qt::ControlButton)
1078
intSize.rheight()+=5;
1080
else if(e->delta()<0)
1082
intSize.rheight()-=5;
1085
// If shift is pressed then resize
1086
else if(e->state()==Qt::ShiftButton)
1090
intSize.rwidth()+=5;
1091
intSize.rheight()+=5;
1093
else if(e->delta()<0)
1095
intSize.rwidth()-=5;
1096
intSize.rheight()-=5;
1100
aux=resize_graph->pos();
1101
resize_graph->setGeometry(QRect(QPoint(aux.x(),aux.y()),intSize));
1102
resize_graph->plotWidget()->resize(intSize);
1104
emit modifiedPlot();
1106
QApplication::restoreOverrideCursor();
1109
bool MultiLayer::isEmpty ()
1117
QString MultiLayer::saveToString(const QString& geometry)
1119
QString s="<multiLayer>\n";
1120
s+=QString(name())+"\t";
1121
s+=QString::number(cols)+"\t";
1122
s+=QString::number(rows)+"\t";
1123
s+=birthDate()+"\n";
1125
s+="WindowLabel\t" + windowLabel() + "\t" + QString::number(captionPolicy()) + "\n";
1126
s+="Margins\t"+QString::number(left_margin)+"\t"+QString::number(right_margin)+"\t"+
1127
QString::number(top_margin)+"\t"+QString::number(bottom_margin)+"\n";
1128
s+="Spacing\t"+QString::number(rowsSpace)+"\t"+QString::number(colsSpace)+"\n";
1129
s+="LayerCanvasSize\t"+QString::number(l_canvas_width)+"\t"+QString::number(l_canvas_height)+"\n";
1130
s+="Alignement\t"+QString::number(hor_align)+"\t"+QString::number(vert_align)+"\n";
1132
for (int i=0;i<(int)graphsList.count();i++)
1134
Graph* ag=(Graph*)graphsList.at(i);
1135
s+=ag->saveToString();
1137
return s+"</multiLayer>\n";
1140
QString MultiLayer::saveAsTemplate(const QString& geometryInfo)
1142
QString s="<multiLayer>\t";
1143
s+=QString::number(rows)+"\t";
1144
s+=QString::number(cols)+"\n";
1146
s+="Margins\t"+QString::number(left_margin)+"\t"+QString::number(right_margin)+"\t"+
1147
QString::number(top_margin)+"\t"+QString::number(bottom_margin)+"\n";
1148
s+="Spacing\t"+QString::number(rowsSpace)+"\t"+QString::number(colsSpace)+"\n";
1149
s+="LayerCanvasSize\t"+QString::number(l_canvas_width)+"\t"+QString::number(l_canvas_height)+"\n";
1150
s+="Alignement\t"+QString::number(hor_align)+"\t"+QString::number(vert_align)+"\n";
1152
for (int i=0;i<(int)graphsList.count();i++)
1154
Graph* ag=(Graph*)graphsList.at(i);
1155
s += ag->saveToString(true);
1160
void MultiLayer::mousePressEvent ( QMouseEvent * e )
1163
QPoint pos = canvas->mapFromParent(e->pos());
1164
// iterate backwards, so layers on top are preferred for selection
1165
QList<QWidget*>::iterator i = graphsList.end();
1166
while (i!=graphsList.begin()) {
1168
QRect igeo = (*i)->frameGeometry();
1169
igeo.addCoords(-margin, -margin, margin, margin);
1170
if (igeo.contains(pos)) {
1171
if (e->modifiers() & Qt::ShiftModifier) {
1172
if (d_layers_selector)
1173
d_layers_selector->add(*i);
1175
d_layers_selector = new SelectionMoveResizer(*i);
1176
connect(d_layers_selector, SIGNAL(targetsChanged()), this, SIGNAL(modifiedPlot()));
1179
setActiveGraph((Graph*) (*i));
1180
active_graph->raise();
1181
if (!d_layers_selector) {
1182
d_layers_selector = new SelectionMoveResizer(*i);
1183
connect(d_layers_selector, SIGNAL(targetsChanged()), this, SIGNAL(modifiedPlot()));
1189
if (d_layers_selector)
1190
delete d_layers_selector;
1193
void MultiLayer::setMargins (int lm, int rm, int tm, int bm)
1195
if (left_margin != lm)
1197
if (right_margin != rm)
1199
if (top_margin != tm)
1201
if (bottom_margin != bm)
1205
void MultiLayer::setSpacing (int rgap, int cgap)
1207
if (rowsSpace != rgap)
1209
if (colsSpace != cgap)
1213
void MultiLayer::setLayerCanvasSize (int w, int h)
1215
if (l_canvas_width != w)
1217
if (l_canvas_height != h)
1218
l_canvas_height = h;
1221
void MultiLayer::setAlignement (int ha, int va)
1223
if (hor_align != ha)
1226
if (vert_align != va)
1230
void MultiLayer::setLayersNumber(int n)
1235
int dn = graphs - n;
1238
for (int i = 0; i < dn; i++)
1239
{//remove layer buttons
1240
LayerButton *btn=(LayerButton*)buttonsList.last();
1244
buttonsList.removeLast();
1247
Graph *g = (Graph *)graphsList.last();
1250
if (g->zoomOn() || g->activeTool())
1254
graphsList.removeLast();
1264
// check whether the active Graph.has been deleted
1265
if(graphsList.indexOf(active_graph) == -1)
1266
active_graph=(Graph*) graphsList.last();
1267
for (int j=0;j<(int)graphsList.count();j++)
1269
Graph *gr=(Graph *)graphsList.at(j);
1270
if (gr == active_graph)
1272
LayerButton *button=(LayerButton *)buttonsList.at(j);
1273
button->setOn(TRUE);
1280
for (int i = 0; i < abs(dn); i++)
1284
emit modifiedPlot();
1287
void MultiLayer::copy(MultiLayer* ml)
1289
setSpacing(ml->rowsSpacing(), ml->colsSpacing());
1290
setAlignement(ml->horizontalAlignement(), ml->verticalAlignement());
1291
setMargins(ml->leftMargin(), ml->rightMargin(), ml->topMargin(), ml->bottomMargin());
1293
QWidgetList graphsList = ml->graphPtrs();
1294
for (int i=0; i<graphsList.count(); i++)
1296
Graph* g = (Graph*)graphsList.at(i);
1297
Graph* g2 = addLayer(g->pos().x(), g->pos().y(), g->width(), g->height());
1299
g2->setIgnoreResizeEvents(g->ignoresResizeEvents());
1300
g2->setAutoscaleFonts(g->autoscaleFonts());
1304
bool MultiLayer::focusNextPrevChild ( bool next )
1309
return active_graph->focusNextPrevChild(next);
1312
void MultiLayer::changeEvent(QEvent *event)
1314
if (event->type() == QEvent::WindowStateChange) {
1315
if ( windowState() & Qt::WindowMaximized )
1316
d_max_size = QSize(width(), height() - LayerButton::btnSize());
1317
else if ( windowState() & Qt::WindowMinimized )
1319
if (((QWindowStateChangeEvent*)event)->oldState() == Qt::WindowMaximized)
1320
resizeLayers(d_normal_size, d_max_size, true);
1322
else if ( windowState() == Qt::WindowNoState )
1323
d_normal_size = QSize(width(), height() - LayerButton::btnSize());
1325
MyWidget::changeEvent(event);
1328
void MultiLayer::setHidden()
1330
if (status() == MyWidget::Maximized)
1331
resizeLayers(d_normal_size, d_max_size, false);
1333
MyWidget::setHidden();