~showard314/ubuntu/natty/qtiplot/Python2.7_fix

« back to all changes in this revision

Viewing changes to qtiplot/src/MultiLayer.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Gudjon I. Gudjonsson
  • Date: 2007-03-25 12:06:27 UTC
  • Revision ID: james.westby@ubuntu.com-20070325120627-5pvdufddr7i0r74x
Tags: upstream-0.9~rc2
ImportĀ upstreamĀ versionĀ 0.9~rc2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
    File                 : MultiLayer.cpp
 
3
    Project              : QtiPlot
 
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
 
8
 
 
9
 ***************************************************************************/
 
10
 
 
11
/***************************************************************************
 
12
 *                                                                         *
 
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.                                    *
 
17
 *                                                                         *
 
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.                           *
 
22
 *                                                                         *
 
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                                           *
 
27
 *                                                                         *
 
28
 ***************************************************************************/
 
29
#include <QVector>
 
30
#include <QWidgetList>
 
31
#include <QPrinter>
 
32
#include <QPrintDialog>
 
33
#include <QDateTime>
 
34
#include <QApplication>
 
35
#include <QMessageBox>
 
36
#include <QBitmap>
 
37
#include <QImageWriter>
 
38
#include <QPainter>
 
39
#include <QPicture>
 
40
#include <QClipboard>
 
41
 
 
42
#if QT_VERSION >= 0x040300
 
43
        #include <QSvgGenerator>
 
44
#endif
 
45
 
 
46
#include <qwt_plot.h>
 
47
#include <qwt_plot_canvas.h>
 
48
#include <qwt_plot_layout.h>
 
49
#include <qwt_scale_widget.h>
 
50
#include <qwt_text_label.h>
 
51
 
 
52
#include "MultiLayer.h"
 
53
#include "Plot.h"
 
54
#include "LegendMarker.h"
 
55
#include "SelectionMoveResizer.h"
 
56
 
 
57
#include <gsl/gsl_vector.h>
 
58
 
 
59
LayerButton::LayerButton(const QString& text, QWidget* parent)
 
60
: QPushButton(text, parent)
 
61
{
 
62
        int btn_size = 20;
 
63
 
 
64
        setToggleButton(true);
 
65
        setOn(true);
 
66
        setMaximumWidth(btn_size);
 
67
        setMaximumHeight(btn_size);
 
68
}
 
69
 
 
70
void LayerButton::mousePressEvent( QMouseEvent *event )
 
71
{
 
72
        if (event->button() == Qt::LeftButton && !isOn())
 
73
                emit clicked(this);
 
74
}
 
75
 
 
76
void LayerButton::mouseDoubleClickEvent ( QMouseEvent * )
 
77
{
 
78
        emit showCurvesDialog();
 
79
}
 
80
 
 
81
MultiLayer::MultiLayer(const QString& label, QWidget* parent, const char* name, Qt::WFlags f)
 
82
: MyWidget(label,parent,name,f)
 
83
{
 
84
        if ( !name )
 
85
                setName( "multilayer plot" );
 
86
 
 
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));
 
91
        setPalette(pal);
 
92
 
 
93
        QDateTime dt = QDateTime::currentDateTime ();
 
94
        setBirthDate(dt.toString(Qt::LocalDate));
 
95
 
 
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;
 
103
        active_graph = 0;
 
104
        addTextOn = false;
 
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;
 
110
 
 
111
        layerButtonsBox = new QHBoxLayout();
 
112
        QHBoxLayout *hbox = new QHBoxLayout();
 
113
        hbox->addLayout(layerButtonsBox);
 
114
        hbox->addStretch();
 
115
 
 
116
        canvas = new QWidget();
 
117
        canvas->installEventFilter(this);
 
118
 
 
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);
 
126
}
 
127
 
 
128
Graph *MultiLayer::layer(int num)
 
129
{
 
130
        return (Graph*) graphsList.at(num-1);
 
131
}
 
132
 
 
133
LayerButton* MultiLayer::addLayerButton()
 
134
{
 
135
        for (int i=0;i<buttonsList.count();i++)
 
136
        {
 
137
                LayerButton *btn=(LayerButton*) buttonsList.at(i);
 
138
                btn->setOn(false);
 
139
        }
 
140
 
 
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()));
 
144
 
 
145
        buttonsList.append(button);
 
146
    layerButtonsBox->addWidget(button);
 
147
        return button;
 
148
}
 
149
 
 
150
Graph* MultiLayer::addLayer(int x, int y, int width, int height)
 
151
{
 
152
        addLayerButton();
 
153
        if (!width && !height)
 
154
        {
 
155
                width = graph_width;
 
156
                height = graph_height;
 
157
        }
 
158
 
 
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);
 
164
 
 
165
        active_graph = g;
 
166
        g->show();
 
167
        connectLayer(g);
 
168
        return g;
 
169
}
 
170
 
 
171
void MultiLayer::adjustSize()
 
172
{
 
173
    canvas->resize(size().width(), size().height() - LayerButton::btnSize());
 
174
}
 
175
 
 
176
void MultiLayer::activateGraph(LayerButton* button)
 
177
{
 
178
        for (int i=0;i<buttonsList.count();i++)
 
179
        {
 
180
                LayerButton *btn=(LayerButton*)buttonsList.at(i);
 
181
                if (btn->isOn())
 
182
                        btn->setOn(false);
 
183
 
 
184
                if (btn == button)
 
185
                {
 
186
                        active_graph = (Graph*) graphsList.at(i);
 
187
                        active_graph->setFocus();
 
188
                        active_graph->raise();//raise layer on top of the layers stack
 
189
                        button->setOn(true);
 
190
                }
 
191
        }
 
192
}
 
193
 
 
194
void MultiLayer::setActiveGraph(Graph* g)
 
195
{
 
196
        if (!g || active_graph == g)
 
197
                return;
 
198
 
 
199
        active_graph = g;
 
200
        active_graph->setFocus();
 
201
 
 
202
        if (d_layers_selector)
 
203
                delete d_layers_selector;
 
204
 
 
205
        active_graph->raise();//raise layer on top of the layers stack
 
206
 
 
207
        for (int i=0;i<(int)graphsList.count();i++)
 
208
        {
 
209
                Graph *gr = (Graph *)graphsList.at(i);
 
210
                LayerButton *btn = (LayerButton *)buttonsList.at(i);
 
211
                if (gr == g)
 
212
                        btn->setOn(true);
 
213
                else
 
214
                        btn->setOn(false);
 
215
        }
 
216
}
 
217
 
 
218
void MultiLayer::contextMenuEvent(QContextMenuEvent *e)
 
219
{
 
220
        emit showWindowContextMenu();
 
221
        e->accept();
 
222
}
 
223
 
 
224
void MultiLayer::resizeLayers (const QResizeEvent *re)
 
225
{
 
226
        QSize oldSize = re->oldSize();
 
227
        QSize size = re->size();
 
228
 
 
229
    if (d_open_maximized == 1)
 
230
    {// 2 resize events are triggered for maximized windows: this hack allows to ignore the first one!
 
231
        d_open_maximized++;
 
232
        return;
 
233
    }
 
234
    else if (d_open_maximized == 2)
 
235
    {
 
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);
 
241
        //return;
 
242
    }
 
243
 
 
244
    if(!oldSize.isValid())
 
245
        return;
 
246
 
 
247
    resizeLayers(size, oldSize, false);
 
248
}
 
249
 
 
250
void MultiLayer::resizeLayers (const QSize& size, const QSize& oldSize, bool scaleFonts)
 
251
{
 
252
        QApplication::setOverrideCursor(Qt::waitCursor);
 
253
 
 
254
        double w_ratio = (double)size.width()/(double)oldSize.width();
 
255
        double h_ratio = (double)(size.height())/(double)(oldSize.height());
 
256
 
 
257
        for (int i=0;i<graphsList.count();i++)
 
258
        {
 
259
                Graph *gr = (Graph *)graphsList.at(i);
 
260
                if (gr && !gr->ignoresResizeEvents())
 
261
                {
 
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);
 
266
 
 
267
                        gr->setGeometry(QRect(gx, gy, gw, gh));
 
268
                        gr->plotWidget()->resize(QSize(gw, gh));
 
269
 
 
270
            if (scaleFonts)
 
271
                gr->scaleFonts(h_ratio);
 
272
                }
 
273
        }
 
274
 
 
275
        emit modifiedPlot();
 
276
        emit resizedWindow(this);
 
277
        QApplication::restoreOverrideCursor();
 
278
}
 
279
 
 
280
void MultiLayer::confirmRemoveLayer()
 
281
{
 
282
        if (graphs>1)
 
283
        {
 
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"),
 
288
                                        0, 2) )
 
289
                {
 
290
                        case 0:
 
291
                                removeLayer();
 
292
                                arrangeLayers(true, false);
 
293
                                break;
 
294
 
 
295
                        case 1:
 
296
                                removeLayer();
 
297
                                break;
 
298
 
 
299
                        case 2:
 
300
                                return;
 
301
                                break;
 
302
                }
 
303
        }
 
304
        else
 
305
                removeLayer();
 
306
}
 
307
 
 
308
void MultiLayer::removeLayer()
 
309
{
 
310
        //remove corresponding button
 
311
        LayerButton *btn=0;
 
312
        int i;
 
313
        for (i=0;i<buttonsList.count();i++)
 
314
        {
 
315
                btn=(LayerButton*)buttonsList.at(i);
 
316
                if (btn->isOn())
 
317
                {
 
318
                        buttonsList.removeAll(btn);
 
319
                        btn->close(true);
 
320
                        break;
 
321
                }
 
322
        }
 
323
 
 
324
        //update the texts of the buttons
 
325
        for (i=0;i<buttonsList.count();i++)
 
326
        {
 
327
                btn=(LayerButton*)buttonsList.at(i);
 
328
                btn->setText(QString::number(i+1));
 
329
        }
 
330
 
 
331
        if (active_graph->zoomOn() || active_graph->activeTool())
 
332
                emit setPointerCursor();
 
333
 
 
334
        int index = graphsList.indexOf(active_graph);
 
335
        graphsList.removeAt(index);
 
336
        active_graph->close();
 
337
        graphs--;
 
338
        if(index >= graphsList.count())
 
339
                index--;
 
340
 
 
341
        if (graphs == 0)
 
342
        {
 
343
                active_graph = 0;
 
344
                return;
 
345
        }
 
346
 
 
347
        active_graph=(Graph*) graphsList.at(index);
 
348
 
 
349
        for (i=0;i<(int)graphsList.count();i++)
 
350
        {
 
351
                Graph *gr=(Graph *)graphsList.at(i);
 
352
                if (gr == active_graph)
 
353
                {
 
354
                        LayerButton *button=(LayerButton *)buttonsList.at(i);
 
355
                        button->setOn(TRUE);
 
356
                        break;
 
357
                }
 
358
        }
 
359
 
 
360
        emit modifiedPlot();
 
361
}
 
362
 
 
363
void MultiLayer::setGraphGeometry(int x, int y, int w, int h)
 
364
{
 
365
        if (active_graph->pos() == QPoint (x,y) &&
 
366
                active_graph->size() == QSize (w,h))
 
367
                return;
 
368
 
 
369
        active_graph->setGeometry(QRect(QPoint(x,y),QSize(w,h)));
 
370
    active_graph->plotWidget()->resize(QSize(w, h));
 
371
        emit modifiedPlot();
 
372
}
 
373
 
 
374
QSize MultiLayer::arrangeLayers(bool userSize)
 
375
{
 
376
        const QRect rect = canvas->geometry();
 
377
 
 
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);
 
388
 
 
389
        int i;
 
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();
 
398
 
 
399
                QRect tRect=plotLayout->titleRect ();
 
400
                QwtScaleWidget *scale=(QwtScaleWidget *) plot->axisWidget (QwtPlot::xTop);
 
401
 
 
402
                int topHeight = 0;
 
403
                if (!tRect.isNull())
 
404
                        topHeight += tRect.height() + plotLayout->spacing();
 
405
                if (scale)
 
406
                {
 
407
                        QRect sRect=plotLayout->scaleRect (QwtPlot::xTop);
 
408
                        topHeight += sRect.height();
 
409
                }
 
410
                gsl_vector_set (xTopR, i, double(topHeight)/ch);
 
411
 
 
412
                scale=(QwtScaleWidget *) plot->axisWidget (QwtPlot::xBottom);
 
413
                if (scale)
 
414
                {
 
415
                        QRect sRect = plotLayout->scaleRect (QwtPlot::xBottom);
 
416
                        gsl_vector_set (xBottomR, i, double(sRect.height())/ch);
 
417
                }
 
418
 
 
419
                scale=(QwtScaleWidget *) plot->axisWidget (QwtPlot::yLeft);
 
420
                if (scale)
 
421
                {
 
422
                        QRect sRect = plotLayout->scaleRect (QwtPlot::yLeft);
 
423
                        gsl_vector_set (yLeftR, i, double(sRect.width())/cw);
 
424
                }
 
425
 
 
426
                scale=(QwtScaleWidget *) plot->axisWidget (QwtPlot::yRight);
 
427
                if (scale)
 
428
                {
 
429
                        QRect sRect = plotLayout->scaleRect (QwtPlot::yRight);
 
430
                        gsl_vector_set (yRightR, i, double(sRect.width())/cw);
 
431
                }
 
432
 
 
433
                //calculate max scales/canvas dimensions ratio for each line and column and stores them to vectors
 
434
                int row = i / cols;
 
435
                if (row >= rows )
 
436
                        row = rows - 1;
 
437
 
 
438
                int col = i % cols;
 
439
 
 
440
                double aux = gsl_vector_get(xTopR, i);
 
441
                double old_max = gsl_vector_get(maxXTopHeight, row);
 
442
                if (aux >= old_max)
 
443
                        gsl_vector_set(maxXTopHeight, row,  aux);
 
444
 
 
445
                aux = gsl_vector_get(xBottomR, i) ;
 
446
                if (aux >= gsl_vector_get(maxXBottomHeight, row))
 
447
                        gsl_vector_set(maxXBottomHeight, row,  aux);
 
448
 
 
449
                aux = gsl_vector_get(yLeftR, i);
 
450
                if (aux >= gsl_vector_get(maxYLeftWidth, col))
 
451
                        gsl_vector_set(maxYLeftWidth, col, aux);
 
452
 
 
453
                aux = gsl_vector_get(yRightR, i);
 
454
                if (aux >= gsl_vector_get(maxYRightWidth, col))
 
455
                        gsl_vector_set(maxYRightWidth, col, aux);
 
456
        }
 
457
 
 
458
        double c_heights = 0.0;
 
459
        for (i=0; i<rows; i++)
 
460
        {
 
461
                gsl_vector_set (Y, i, c_heights);
 
462
                c_heights += 1 + gsl_vector_get(maxXTopHeight, i) + gsl_vector_get(maxXBottomHeight, i);
 
463
        }
 
464
 
 
465
        double c_widths = 0.0;
 
466
        for (i=0; i<cols; i++)
 
467
        {
 
468
                gsl_vector_set (X, i, c_widths);
 
469
                c_widths += 1 + gsl_vector_get(maxYLeftWidth, i) + gsl_vector_get(maxYRightWidth, i);
 
470
        }
 
471
 
 
472
        if (!userSize)
 
473
        {
 
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);
 
476
        }
 
477
 
 
478
        QSize size = QSize(l_canvas_width, l_canvas_height);
 
479
 
 
480
        for (i=0; i<graphs; i++)
 
481
        {
 
482
                int row = i / cols;
 
483
                if (row >= rows )
 
484
                        row = rows - 1;
 
485
 
 
486
                int col = i % cols;
 
487
 
 
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)));
 
491
 
 
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)));
 
500
 
 
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)));
 
509
 
 
510
                //resizes and moves layers
 
511
                Graph *gr = (Graph *)graphsList.at(i);
 
512
                bool autoscaleFonts = false;
 
513
                if (!userSize)
 
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
 
518
 
 
519
                        autoscaleFonts = gr->autoscaleFonts();//save user settings
 
520
                        gr->setAutoscaleFonts(false);
 
521
                }
 
522
 
 
523
                gr->setGeometry(QRect(x, y, w, h));
 
524
                gr->plotWidget()->resize(QSize(w, h));
 
525
 
 
526
                if (!userSize)
 
527
                        gr->setAutoscaleFonts(autoscaleFonts);//restore user settings
 
528
        }
 
529
 
 
530
        //free memory
 
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);
 
536
        return size;
 
537
}
 
538
 
 
539
void MultiLayer::findBestLayout(int &rows, int &cols)
 
540
{
 
541
        int NumGraph=graphs;
 
542
        if(NumGraph%2==0) // NumGraph is an even number
 
543
        {
 
544
                if(NumGraph<=2)
 
545
                        cols=NumGraph/2+1;
 
546
                else if(NumGraph>2)
 
547
                        cols=NumGraph/2;
 
548
 
 
549
                if(NumGraph<8)
 
550
                        rows=NumGraph/4+1;
 
551
                if(NumGraph>=8)
 
552
                        rows=NumGraph/4;
 
553
        }
 
554
        else if(NumGraph%2!=0) // NumGraph is an odd number
 
555
        {
 
556
                int Num=NumGraph+1;
 
557
 
 
558
                if(Num<=2)
 
559
                        cols=1;
 
560
                else if(Num>2)
 
561
                        cols=Num/2;
 
562
 
 
563
                if(Num<8)
 
564
                        rows=Num/4+1;
 
565
                if(Num>=8)
 
566
                        rows=Num/4;
 
567
        }
 
568
}
 
569
 
 
570
void MultiLayer::arrangeLayers(bool fit, bool userSize)
 
571
{
 
572
        if (!graphs)
 
573
                return;
 
574
 
 
575
        QApplication::setOverrideCursor(Qt::waitCursor);
 
576
 
 
577
        if(d_layers_selector)
 
578
                delete d_layers_selector;
 
579
 
 
580
        if (fit)
 
581
                findBestLayout(rows, cols);
 
582
 
 
583
        //the canvas sizes of all layers become equal only after several
 
584
        //resize iterations, due to the way Qwt handles the plot layout
 
585
        int iterations = 0;
 
586
        QSize size = arrangeLayers(userSize);
 
587
        QSize canvas_size = QSize(1,1);
 
588
        while (canvas_size != size && iterations < 10)
 
589
        {
 
590
                iterations++;
 
591
                canvas_size = size;
 
592
                size = arrangeLayers(userSize);
 
593
        }
 
594
 
 
595
        if (userSize)
 
596
        {//resize window
 
597
                bool ignoreResize = active_graph->ignoresResizeEvents();
 
598
                for (int i=0; i<(int)graphsList.count(); i++)
 
599
                {
 
600
                        Graph *gr = (Graph *)graphsList.at(i);
 
601
                        gr->setIgnoreResizeEvents(true);
 
602
                }
 
603
 
 
604
                this->showNormal();
 
605
                QSize size = canvas->childrenRect().size();
 
606
                this->resize(QSize(size.width() + right_margin,
 
607
                                        size.height() + bottom_margin + LayerButton::btnSize()));
 
608
 
 
609
                for (int i=0; i<(int)graphsList.count(); i++)
 
610
                {
 
611
                        Graph *gr = (Graph *)graphsList.at(i);
 
612
                        gr->setIgnoreResizeEvents(ignoreResize);
 
613
                }
 
614
        }
 
615
 
 
616
        emit modifiedPlot();
 
617
        QApplication::restoreOverrideCursor();
 
618
}
 
619
 
 
620
void MultiLayer::setCols(int c)
 
621
{
 
622
        if (cols != c)
 
623
                cols=c;
 
624
}
 
625
 
 
626
void MultiLayer::setRows(int r)
 
627
{
 
628
        if (rows != r)
 
629
                rows=r;
 
630
}
 
631
 
 
632
QPixmap MultiLayer::canvasPixmap()
 
633
{
 
634
    return QPixmap::grabWidget(canvas);
 
635
}
 
636
 
 
637
void MultiLayer::exportToFile(const QString& fileName)
 
638
{
 
639
        if ( fileName.isEmpty() )
 
640
        {
 
641
                QMessageBox::critical(0, tr("QtiPlot - Error"), tr("Please provide a valid file name!"));
 
642
        return;
 
643
        }
 
644
 
 
645
        if (fileName.contains(".eps") || fileName.contains(".pdf") || fileName.contains(".ps"))
 
646
        {
 
647
                exportVector(fileName);
 
648
                return;
 
649
        }
 
650
        else
 
651
        {
 
652
                QList<QByteArray> list = QImageWriter::supportedImageFormats();
 
653
        for(int i=0 ; i<list.count() ; i++)
 
654
                {
 
655
                        if (fileName.contains( "." + list[i].toLower()))
 
656
                        {
 
657
                                exportImage(fileName);
 
658
                                return;
 
659
                        }
 
660
                }
 
661
        QMessageBox::critical(this, tr("QtiPlot - Error"), tr("File format not handled, operation aborted!"));
 
662
        }
 
663
}
 
664
 
 
665
void MultiLayer::exportImage(const QString& fileName, int quality, bool transparent)
 
666
{
 
667
        QPixmap pic = canvasPixmap();
 
668
        if (transparent)
 
669
        {
 
670
                QBitmap mask(pic.size());
 
671
                mask.fill(Qt::color1);
 
672
                QPainter p;
 
673
                p.begin(&mask);
 
674
                p.setPen(Qt::color0);
 
675
 
 
676
                QColor background = QColor (Qt::white);
 
677
                QRgb backgroundPixel = background.rgb ();
 
678
 
 
679
                QImage image = pic.convertToImage();
 
680
                for (int y=0; y<image.height(); y++)
 
681
                {
 
682
                        for ( int x=0; x<image.width(); x++ )
 
683
                        {
 
684
                                QRgb rgb = image.pixel(x, y);
 
685
                                if (rgb == backgroundPixel) // we want the frame transparent
 
686
                                        p.drawPoint( x, y );
 
687
                        }
 
688
                }
 
689
                p.end();
 
690
                pic.setMask(mask);
 
691
        }
 
692
        pic.save(fileName, 0, quality);
 
693
}
 
694
 
 
695
void MultiLayer::exportPDF(const QString& fname)
 
696
{
 
697
        exportVector(fname);
 
698
}
 
699
 
 
700
void MultiLayer::exportVector(const QString& fileName, int res, bool color)
 
701
{
 
702
        if ( fileName.isEmpty() )
 
703
        {
 
704
                QMessageBox::critical(this, tr("QtiPlot - Error"),
 
705
                tr("Please provide a valid file name!"));
 
706
        return;
 
707
        }
 
708
 
 
709
        QPrinter printer;
 
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);
 
716
 
 
717
        if (res)
 
718
                printer.setResolution(res);
 
719
 
 
720
        QRect canvasRect = canvas->rect();
 
721
        printer.setPageSize(Graph::minPageSize(printer, canvasRect));
 
722
 
 
723
        double aspect = double(canvasRect.width())/double(canvasRect.height());
 
724
        if (aspect < 1)
 
725
                printer.setOrientation(QPrinter::Portrait);
 
726
        else
 
727
                printer.setOrientation(QPrinter::Landscape);
 
728
 
 
729
        if (color)
 
730
                printer.setColorMode(QPrinter::Color);
 
731
        else
 
732
                printer.setColorMode(QPrinter::GrayScale);
 
733
 
 
734
        QRect paperRect = printer.paperRect();
 
735
    int x_margin = (paperRect.width() - canvasRect.width())/2;
 
736
    int y_margin = (paperRect.height() - canvasRect.height())/2;
 
737
 
 
738
        QPainter paint(&printer);
 
739
        for (int i=0; i<(int)graphsList.count(); i++)
 
740
        {
 
741
                Graph *gr = (Graph *)graphsList.at(i);
 
742
                Plot *myPlot = (Plot *)gr->plotWidget();
 
743
 
 
744
                QPoint pos = gr->pos();
 
745
                pos = QPoint(x_margin + pos.x(), y_margin + pos.y());
 
746
                myPlot->print(&paint, QRect(pos, myPlot->size()));
 
747
        }
 
748
}
 
749
 
 
750
void MultiLayer::exportSVG(const QString& fname)
 
751
{
 
752
        #if QT_VERSION >= 0x040300
 
753
                QSvgGenerator generator;
 
754
        generator.setFileName(fname);
 
755
        generator.setSize(canvas->size());
 
756
        
 
757
                QPainter p(&generator);
 
758
        for (int i=0; i<(int)graphsList.count(); i++)
 
759
                {
 
760
                        Graph *gr = (Graph *)graphsList.at(i);
 
761
                        Plot *myPlot = (Plot *)gr->plotWidget();
 
762
 
 
763
                        QPoint pos = QPoint(gr->pos().x(), gr->pos().y());
 
764
                        myPlot->print(&p, QRect(pos, myPlot->size()));
 
765
                }
 
766
                p.end();
 
767
        #endif
 
768
}
 
769
 
 
770
void MultiLayer::copyAllLayers()
 
771
{
 
772
        QPixmap pic = canvasPixmap();
 
773
        QImage image= pic.convertToImage();
 
774
        QApplication::clipboard()->setImage(image);
 
775
}
 
776
 
 
777
void MultiLayer::printActiveLayer()
 
778
{
 
779
        if (active_graph)
 
780
        {
 
781
                active_graph->setScaleOnPrint(d_scale_on_print);
 
782
                active_graph->printCropmarks(d_print_cropmarks);
 
783
                active_graph->print();
 
784
        }
 
785
}
 
786
 
 
787
void MultiLayer::print()
 
788
{
 
789
        QPrinter printer;
 
790
        printer.setColorMode (QPrinter::Color);
 
791
        printer.setFullPage(true);
 
792
    QRect canvasRect = canvas->rect();
 
793
    double aspect = double(canvasRect.width())/double(canvasRect.height());
 
794
    if (aspect < 1)
 
795
        printer.setOrientation(QPrinter::Portrait);
 
796
    else
 
797
        printer.setOrientation(QPrinter::Landscape);
 
798
 
 
799
    QPrintDialog printDialog(&printer);
 
800
    if (printDialog.exec() == QDialog::Accepted)
 
801
        {
 
802
                QPainter paint(&printer);
 
803
                printAllLayers(&paint);
 
804
                paint.end();
 
805
        }
 
806
}
 
807
 
 
808
void MultiLayer::printAllLayers(QPainter *painter)
 
809
{
 
810
        if (!painter)
 
811
                return;
 
812
 
 
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
 
818
        
 
819
        if (d_scale_on_print)
 
820
        {
 
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();
 
824
 
 
825
        if (d_print_cropmarks)
 
826
        {
 
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));
 
831
        }
 
832
 
 
833
                for (int i=0; i<(int)graphsList.count(); i++)
 
834
                {
 
835
                        Graph *gr=(Graph *)graphsList.at(i);
 
836
                        Plot *myPlot= gr->plotWidget();
 
837
 
 
838
                        QPoint pos=gr->pos();
 
839
                        pos=QPoint(margin + int(pos.x()*scaleFactorX), margin + int(pos.y()*scaleFactorY));
 
840
 
 
841
                        int width=int(myPlot->frameGeometry().width()*scaleFactorX);
 
842
                        int height=int(myPlot->frameGeometry().height()*scaleFactorY);
 
843
 
 
844
                        myPlot->print(painter, QRect(pos, QSize(width,height)));
 
845
                }
 
846
        }
 
847
        else
 
848
        {
 
849
        int x_margin = (pageRect.width() - canvasRect.width())/2;
 
850
        int y_margin = (pageRect.height() - canvasRect.height())/2;
 
851
 
 
852
        if (d_print_cropmarks)
 
853
            cr.moveTo(x_margin, y_margin);
 
854
 
 
855
                for (int i=0; i<(int)graphsList.count(); i++)
 
856
                {
 
857
                        Graph *gr = (Graph *)graphsList.at(i);
 
858
                        Plot *myPlot = (Plot *)gr->plotWidget();
 
859
 
 
860
                        QPoint pos = gr->pos();
 
861
                        pos = QPoint(x_margin + pos.x(), y_margin + pos.y());
 
862
                        myPlot->print(painter, QRect(pos, myPlot->size()));
 
863
                }
 
864
        }
 
865
        if (d_print_cropmarks)
 
866
    {
 
867
                cr.addCoords(-1, -1, 2, 2);
 
868
        painter->save();
 
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()); 
 
874
                painter->restore();
 
875
        }
 
876
 
 
877
}
 
878
 
 
879
void MultiLayer::setFonts(const QFont& titleFnt, const QFont& scaleFnt,
 
880
                const QFont& numbersFnt, const QFont& legendFnt)
 
881
{
 
882
        for (int i=0;i<(int)graphsList.count();i++)
 
883
        {
 
884
                Graph *gr=(Graph *)graphsList.at(i);
 
885
                QwtPlot *plot=gr->plotWidget();
 
886
 
 
887
                QwtText text = plot->title();
 
888
            text.setFont(titleFnt);
 
889
            plot->setTitle(text);
 
890
                for (int j= 0;j<QwtPlot::axisCnt;j++)
 
891
                {
 
892
                        plot->setAxisFont (j,numbersFnt);
 
893
 
 
894
                        text = plot->axisTitle(j );
 
895
                text.setFont(scaleFnt);
 
896
                plot->setAxisTitle(j, text);
 
897
                }
 
898
 
 
899
                QVector<int> keys=gr->textMarkerKeys();
 
900
                for (int k=0;k<(int)keys.size();k++)
 
901
                {
 
902
                        LegendMarker* mrk=(LegendMarker*)gr->textMarker(keys[k]);
 
903
                        if (mrk)
 
904
                                mrk->setFont(legendFnt);
 
905
                }
 
906
                plot->replot();
 
907
        }
 
908
        emit modifiedPlot();
 
909
}
 
910
 
 
911
void MultiLayer::connectLayer(Graph *g)
 
912
{
 
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&)));
 
936
}
 
937
 
 
938
void MultiLayer::addTextLayer(int f, const QFont& font,
 
939
                const QColor& textCol, const QColor& backgroundCol)
 
940
{
 
941
        defaultTextMarkerFont = font;
 
942
        defaultTextMarkerFrame = f;
 
943
        defaultTextMarkerColor = textCol;
 
944
        defaultTextMarkerBackground = backgroundCol;
 
945
 
 
946
        addTextOn=TRUE;
 
947
        QApplication::setOverrideCursor(Qt::IBeamCursor);
 
948
        canvas->grabMouse();
 
949
}
 
950
 
 
951
void MultiLayer::addTextLayer(const QPoint& pos)
 
952
{
 
953
        Graph* g=addLayer();
 
954
        g->removeLegend();
 
955
        g->setTitle("");
 
956
        QVector<bool> axesOn(4);
 
957
        for (int j=0;j<4;j++)
 
958
                axesOn[j] = false;
 
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);
 
967
        g->show();
 
968
        QApplication::restoreOverrideCursor();
 
969
        canvas->releaseMouse();
 
970
        addTextOn=false;
 
971
        emit drawTextOff();
 
972
        emit modifiedPlot();
 
973
}
 
974
 
 
975
bool MultiLayer::eventFilter(QObject *object, QEvent *e)
 
976
{
 
977
        if(e->type() == QEvent::MouseButtonPress && object == (QObject *)canvas)
 
978
        {
 
979
                const QMouseEvent *me = (const QMouseEvent *)e;
 
980
                if (me->button()==Qt::LeftButton && addTextOn)
 
981
                        addTextLayer(me->pos());
 
982
 
 
983
                return false;
 
984
        }
 
985
        else if(e->type() == QEvent::Resize && object == (QObject *)canvas)
 
986
        {
 
987
                resizeLayers((const QResizeEvent *)e);
 
988
        }
 
989
        else if (e->type()==QEvent::ContextMenu && object == titleBar)
 
990
        {
 
991
                emit showTitleBarMenu();
 
992
                ((QContextMenuEvent*)e)->accept();
 
993
                return true;
 
994
        }
 
995
        return MyWidget::eventFilter(object, e);
 
996
}
 
997
 
 
998
void MultiLayer::keyPressEvent(QKeyEvent * e)
 
999
{
 
1000
        if (e->key() == Qt::Key_F12)
 
1001
        {
 
1002
                if (d_layers_selector)
 
1003
                        delete d_layers_selector;
 
1004
                int index = graphsList.indexOf((QWidget *)active_graph) + 1;
 
1005
                if (index >= graphsList.size())
 
1006
                        index = 0;
 
1007
                Graph *g=(Graph *)graphsList.at(index);
 
1008
                if (g)
 
1009
                        setActiveGraph(g);
 
1010
                return;
 
1011
        }
 
1012
 
 
1013
        if (e->key() == Qt::Key_F10)
 
1014
        {
 
1015
                if (d_layers_selector)
 
1016
                        delete d_layers_selector;
 
1017
                int index=graphsList.indexOf((QWidget *)active_graph) - 1;
 
1018
                if (index < 0)
 
1019
                        index = graphsList.size() - 1;
 
1020
                Graph *g=(Graph *)graphsList.at(index);
 
1021
                if (g)
 
1022
                        setActiveGraph(g);
 
1023
                return;
 
1024
        }
 
1025
 
 
1026
        if (e->key() == Qt::Key_F11)
 
1027
        {
 
1028
                emit showWindowContextMenu();
 
1029
                return;
 
1030
        }
 
1031
}
 
1032
 
 
1033
void MultiLayer::wheelEvent ( QWheelEvent * e )
 
1034
{
 
1035
        QApplication::setOverrideCursor(Qt::waitCursor);
 
1036
 
 
1037
        bool resize=false;
 
1038
        QPoint aux;
 
1039
        QSize intSize;
 
1040
        Graph *resize_graph = 0;
 
1041
        // Get the position of the mouse
 
1042
        int xMouse=e->x();
 
1043
        int yMouse=e->y();
 
1044
        for (int i=0;i<(int)graphsList.count();i++)
 
1045
        {
 
1046
                Graph *gr=(Graph *)graphsList.at(i);
 
1047
                intSize=gr->plotWidget()->size();
 
1048
                aux=gr->pos();
 
1049
                if(xMouse>aux.x() && xMouse<(aux.x()+intSize.width()))
 
1050
                {
 
1051
                        if(yMouse>aux.y() && yMouse<(aux.y()+intSize.height()))
 
1052
                        {
 
1053
                                resize_graph=gr;
 
1054
                                resize=TRUE;
 
1055
                        }
 
1056
                }
 
1057
        }
 
1058
        if(resize && (e->state()==Qt::AltButton || e->state()==Qt::ControlButton || e->state()==Qt::ShiftButton))
 
1059
        {
 
1060
                intSize=resize_graph->plotWidget()->size();
 
1061
                // If alt is pressed then change the width
 
1062
                if(e->state()==Qt::AltButton)
 
1063
                {
 
1064
                        if(e->delta()>0)
 
1065
                        {
 
1066
                                intSize.rwidth()+=5;
 
1067
                        }
 
1068
                        else if(e->delta()<0)
 
1069
                        {
 
1070
                                intSize.rwidth()-=5;
 
1071
                        }
 
1072
                }
 
1073
                // If crt is pressed then changed the height
 
1074
                else if(e->state()==Qt::ControlButton)
 
1075
                {
 
1076
                        if(e->delta()>0)
 
1077
                        {
 
1078
                                intSize.rheight()+=5;
 
1079
                        }
 
1080
                        else if(e->delta()<0)
 
1081
                        {
 
1082
                                intSize.rheight()-=5;
 
1083
                        }
 
1084
                }
 
1085
                // If shift is pressed then resize
 
1086
                else if(e->state()==Qt::ShiftButton)
 
1087
                {
 
1088
                        if(e->delta()>0)
 
1089
                        {
 
1090
                                intSize.rwidth()+=5;
 
1091
                                intSize.rheight()+=5;
 
1092
                        }
 
1093
                        else if(e->delta()<0)
 
1094
                        {
 
1095
                                intSize.rwidth()-=5;
 
1096
                                intSize.rheight()-=5;
 
1097
                        }
 
1098
                }
 
1099
 
 
1100
                aux=resize_graph->pos();
 
1101
                resize_graph->setGeometry(QRect(QPoint(aux.x(),aux.y()),intSize));
 
1102
                resize_graph->plotWidget()->resize(intSize);
 
1103
 
 
1104
                emit modifiedPlot();
 
1105
        }
 
1106
        QApplication::restoreOverrideCursor();
 
1107
}
 
1108
 
 
1109
bool MultiLayer::isEmpty ()
 
1110
{
 
1111
        if (graphs <= 0)
 
1112
                return true;
 
1113
        else
 
1114
                return false;
 
1115
}
 
1116
 
 
1117
QString MultiLayer::saveToString(const QString& geometry)
 
1118
{
 
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";
 
1124
        s+=geometry;
 
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";
 
1131
 
 
1132
        for (int i=0;i<(int)graphsList.count();i++)
 
1133
        {
 
1134
                Graph* ag=(Graph*)graphsList.at(i);
 
1135
                s+=ag->saveToString();
 
1136
        }
 
1137
        return s+"</multiLayer>\n";
 
1138
}
 
1139
 
 
1140
QString MultiLayer::saveAsTemplate(const QString& geometryInfo)
 
1141
{
 
1142
        QString s="<multiLayer>\t";
 
1143
        s+=QString::number(rows)+"\t";
 
1144
        s+=QString::number(cols)+"\n";
 
1145
        s+= geometryInfo;
 
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";
 
1151
 
 
1152
        for (int i=0;i<(int)graphsList.count();i++)
 
1153
        {
 
1154
                Graph* ag=(Graph*)graphsList.at(i);
 
1155
                s += ag->saveToString(true);
 
1156
        }
 
1157
        return s;
 
1158
}
 
1159
 
 
1160
void MultiLayer::mousePressEvent ( QMouseEvent * e )
 
1161
{
 
1162
        int margin = 5;
 
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()) {
 
1167
                --i;
 
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);
 
1174
                                else {
 
1175
                                        d_layers_selector = new SelectionMoveResizer(*i);
 
1176
                                        connect(d_layers_selector, SIGNAL(targetsChanged()), this, SIGNAL(modifiedPlot()));
 
1177
                                }
 
1178
                        } else {
 
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()));
 
1184
                                }
 
1185
                        }
 
1186
                        return;
 
1187
                }
 
1188
        }
 
1189
        if (d_layers_selector)
 
1190
                delete d_layers_selector;
 
1191
}
 
1192
 
 
1193
void MultiLayer::setMargins (int lm, int rm, int tm, int bm)
 
1194
{
 
1195
        if (left_margin != lm)
 
1196
                left_margin = lm;
 
1197
        if (right_margin != rm)
 
1198
                right_margin = rm;
 
1199
        if (top_margin != tm)
 
1200
                top_margin = tm;
 
1201
        if (bottom_margin != bm)
 
1202
                bottom_margin = bm;
 
1203
}
 
1204
 
 
1205
void MultiLayer::setSpacing (int rgap, int cgap)
 
1206
{
 
1207
        if (rowsSpace != rgap)
 
1208
                rowsSpace = rgap;
 
1209
        if (colsSpace != cgap)
 
1210
                colsSpace = cgap;
 
1211
}
 
1212
 
 
1213
void MultiLayer::setLayerCanvasSize (int w, int h)
 
1214
{
 
1215
        if (l_canvas_width != w)
 
1216
                l_canvas_width = w;
 
1217
        if (l_canvas_height != h)
 
1218
                l_canvas_height = h;
 
1219
}
 
1220
 
 
1221
void MultiLayer::setAlignement (int ha, int va)
 
1222
{
 
1223
        if (hor_align != ha)
 
1224
                hor_align = ha;
 
1225
 
 
1226
        if (vert_align != va)
 
1227
                vert_align = va;
 
1228
}
 
1229
 
 
1230
void MultiLayer::setLayersNumber(int n)
 
1231
{
 
1232
        if (graphs == n)
 
1233
                return;
 
1234
 
 
1235
        int dn = graphs - n;
 
1236
        if (dn > 0)
 
1237
        {
 
1238
                for (int i = 0; i < dn; i++)
 
1239
                {//remove layer buttons
 
1240
                        LayerButton *btn=(LayerButton*)buttonsList.last();
 
1241
                        if (btn)
 
1242
                        {
 
1243
                                btn->close();
 
1244
                                buttonsList.removeLast();
 
1245
                        }
 
1246
 
 
1247
                        Graph *g = (Graph *)graphsList.last();
 
1248
                        if (g)
 
1249
                        {//remove layers
 
1250
                                if (g->zoomOn() || g->activeTool())
 
1251
                                        setPointerCursor();
 
1252
 
 
1253
                                g->close();
 
1254
                                graphsList.removeLast();
 
1255
                        }
 
1256
                }
 
1257
                graphs = n;
 
1258
                if (!graphs)
 
1259
                {
 
1260
                        active_graph = 0;
 
1261
                        return;
 
1262
                }
 
1263
 
 
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++)
 
1268
                {
 
1269
                        Graph *gr=(Graph *)graphsList.at(j);
 
1270
                        if (gr == active_graph)
 
1271
                        {
 
1272
                                LayerButton *button=(LayerButton *)buttonsList.at(j);
 
1273
                                button->setOn(TRUE);
 
1274
                                break;
 
1275
                        }
 
1276
                }
 
1277
        }
 
1278
        else
 
1279
        {
 
1280
                for (int i = 0; i < abs(dn); i++)
 
1281
                        addLayer();
 
1282
        }
 
1283
 
 
1284
        emit modifiedPlot();
 
1285
}
 
1286
 
 
1287
void MultiLayer::copy(MultiLayer* ml)
 
1288
{
 
1289
        setSpacing(ml->rowsSpacing(), ml->colsSpacing());
 
1290
        setAlignement(ml->horizontalAlignement(), ml->verticalAlignement());
 
1291
        setMargins(ml->leftMargin(), ml->rightMargin(), ml->topMargin(), ml->bottomMargin());
 
1292
 
 
1293
        QWidgetList graphsList = ml->graphPtrs();
 
1294
        for (int i=0; i<graphsList.count(); i++)
 
1295
        {
 
1296
                Graph* g = (Graph*)graphsList.at(i);
 
1297
                Graph* g2 = addLayer(g->pos().x(), g->pos().y(), g->width(), g->height());
 
1298
                g2->copy(g);
 
1299
                g2->setIgnoreResizeEvents(g->ignoresResizeEvents());
 
1300
                g2->setAutoscaleFonts(g->autoscaleFonts());
 
1301
        }
 
1302
}
 
1303
 
 
1304
bool MultiLayer::focusNextPrevChild ( bool next )
 
1305
{
 
1306
        if (!active_graph)
 
1307
                return true;
 
1308
 
 
1309
        return active_graph->focusNextPrevChild(next);
 
1310
}
 
1311
 
 
1312
void MultiLayer::changeEvent(QEvent *event)
 
1313
{
 
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 )
 
1318
        {
 
1319
            if (((QWindowStateChangeEvent*)event)->oldState() == Qt::WindowMaximized)
 
1320
                resizeLayers(d_normal_size, d_max_size, true);
 
1321
        }
 
1322
        else if ( windowState() == Qt::WindowNoState )
 
1323
            d_normal_size = QSize(width(), height() - LayerButton::btnSize());
 
1324
        }
 
1325
        MyWidget::changeEvent(event);
 
1326
}
 
1327
 
 
1328
void MultiLayer::setHidden()
 
1329
{
 
1330
        if (status() == MyWidget::Maximized)
 
1331
                resizeLayers(d_normal_size, d_max_size, false);
 
1332
        
 
1333
        MyWidget::setHidden();
 
1334
}