1 
2 /***************************************************************************
3  *                                                                         *
4  *   copyright : (C) 2007 The University of Toronto                        *
5  *                   netterfield@astro.utoronto.ca                         *
6  *                                                                         *
7  *   This program is free software; you can redistribute it and/or modify  *
8  *   it under the terms of the GNU General Public License as published by  *
9  *   the Free Software Foundation; either version 2 of the License, or     *
10  *   (at your option) any later version.                                   *
11  *                                                                         *
12  ***************************************************************************/
13 
14 #include "view.h"
15 #include "scene.h"
16 #include "viewitem.h"
17 #include "layoutboxitem.h"
18 #include "mainwindow.h"
19 #include "application.h"
20 #include "applicationsettings.h"
21 #include "viewdialog.h"
22 #include "viewgridlayout.h"
23 #include "document.h"
24 #include "plotitemmanager.h"
25 #include "plotitem.h"
26 #include "plotaxis.h"
27 #include "dialogdefaults.h"
28 #include "datacollection.h"
29 
30 #include <math.h>
31 
32 #include <QDebug>
33 #include <QTimer>
34 #include <QUndoStack>
35 #include <QResizeEvent>
36 #include <QMenu>
37 #include <QWidgetAction>
38 #include <QGraphicsItem>
39 #include <QGraphicsScene>
40 #include <QGraphicsSceneMouseEvent>
41 #include <QInputDialog>
42 #include <QKeyEvent>
43 #include <QtCore/qmath.h>
44 
45 namespace Kst {
46 
View()47 View::View() : QGraphicsView(kstApp->mainWindow())
48 {
49   init();
50 }
51 
View(QWidget * parent)52 View::View(QWidget* parent) : QGraphicsView(parent)
53 {
54   init();
55 }
56 
57 
init()58 void View::init()
59 {
60   _viewMode = Data;
61   _mouseMode = Default;
62   _layoutBoxItem = 0;
63   _gridSpacing = QSizeF(20,20);
64   _showGrid = false;
65   _snapToGridHorizontal = false;
66   _snapToGridVertical = false;
67   _plotBordersDirty = false;
68   _printing = false;
69   _dataMode = false;
70   _fontRescale = 1.0;
71   _childMaximized = false;
72   _undoStack = new QUndoStack(this);
73   _referenceFontSizeToView = true;
74   setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
75   setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
76   setScene(new Scene(this));
77   scene()->setSceneRect(rect());
78   scene()->installEventFilter(this);
79   setInteractive(true);
80   setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
81   setFrameStyle(QFrame::NoFrame);
82 
83   setContextMenuPolicy(Qt::DefaultContextMenu);
84 
85   setViewportUpdateMode(QGraphicsView::MinimalViewportUpdate);
86   setViewport(0);
87 
88   connect(ApplicationSettings::self(), SIGNAL(modified()), this, SLOT(updateSettings()));
89   loadSettings();
90 
91   _editAction = new QAction(tr("Edit"), this);
92   //_editAction->setShortcut(Qt::Key_E);
93 //   registerShortcut(_editAction);
94   connect(_editAction, SIGNAL(triggered()), this, SLOT(edit()));
95 
96   _autoLayoutAction = new QAction(tr("Automatic"), this);
97   //_autoLayoutAction->setShortcut(Qt::Key_U);
98   //registerShortcut(_autoLayoutAction);
99   connect(_autoLayoutAction, SIGNAL(triggered()), this, SLOT(createUnprotectedLayout()));
100 
101   _protectedLayoutAction = new QAction(tr("Protect Layout"), this);
102   connect(_protectedLayoutAction, SIGNAL(triggered()), this, SLOT(createLayout()));
103 
104   _customLayoutAction = new QAction(tr("Columns"), this);
105   connect(_customLayoutAction, SIGNAL(triggered()), this, SLOT(createCustomLayout()));
106 
107   connect(this, SIGNAL(viewModeChanged(View::ViewMode)), PlotItemManager::self(), SLOT(clearFocusedPlots()));
108 
109   applyDialogDefaultsFill();
110 }
111 
112 
~View()113 View::~View() {
114   // PlotItems are QGraphicsItems and managed by Qt's graphic view
115   delete _undoStack;
116   delete _layoutBoxItem;
117 }
118 
undoStack() const119 QUndoStack *View::undoStack() const {
120   return _undoStack;
121 }
122 
123 
selectedViewItem() const124 ViewItem *View::selectedViewItem() const {
125   QList<QGraphicsItem*> items = scene()->selectedItems();
126   if (items.isEmpty())
127     return 0;
128 
129   //return the first item
130   return dynamic_cast<ViewItem*>(items.first());
131 }
132 
applyDialogDefaultsFill()133 void View::applyDialogDefaultsFill() {
134   //set the brush
135   QBrush brush;
136   brush = dialogDefaultsBrush(staticDefaultsGroupName());
137   setBackgroundBrush(brush);
138 }
139 
save(QXmlStreamWriter & xml)140 void View::save(QXmlStreamWriter &xml) {
141   QList<QGraphicsItem*> items = scene()->items(Qt::AscendingOrder);
142   xml.writeAttribute("width", QVariant(sceneRect().width()).toString());
143   xml.writeAttribute("height", QVariant(sceneRect().height()).toString());
144   xml.writeAttribute("color", backgroundBrush().color().name());
145   xml.writeAttribute("style", QVariant((int)backgroundBrush().style()).toString());
146   if (backgroundBrush().gradient()) {
147     QString stopList;
148     foreach(const QGradientStop &stop, backgroundBrush().gradient()->stops()) {
149       qreal point = (qreal)stop.first;
150       QColor color = (QColor)stop.second;
151 
152       stopList += QString::number(point);
153       stopList += ',';
154       stopList += color.name();
155       stopList += ',';
156     }
157     xml.writeAttribute("gradient", stopList);
158   }
159 
160   foreach(QGraphicsItem* viewItem, items) {
161     if (!viewItem->parentItem()) {
162       dynamic_cast<ViewItem*>(viewItem)->save(xml);
163     }
164   }
165 }
166 
167 
viewMode() const168 View::ViewMode View::viewMode() const {
169   return _viewMode;
170 }
171 
172 
setViewMode(ViewMode mode)173 void View::setViewMode(ViewMode mode) {
174   ViewMode oldMode = _viewMode;
175   _viewMode = mode;
176   emit viewModeChanged(oldMode);
177 }
178 
179 
mouseMode() const180 View::MouseMode View::mouseMode() const {
181   return _mouseMode;
182 }
183 
184 
setMouseMode(MouseMode mode)185 void View::setMouseMode(MouseMode mode) {
186 
187   //Clear the creation polygons if we're currently
188   //in Create mouse mode.
189   MouseMode oldMode = _mouseMode;
190 
191   if (oldMode == Create) {
192     _creationPolygonPress.clear();
193     _creationPolygonRelease.clear();
194     _creationPolygonMove.clear();
195   }
196 
197   _mouseMode = mode;
198 
199   if (_mouseMode != Create) {
200     setCursor(Qt::ArrowCursor);
201     setDragMode(QGraphicsView::RubberBandDrag);
202   } else {
203     setDragMode(QGraphicsView::NoDrag);
204   }
205 
206   emit mouseModeChanged(oldMode);
207 }
208 
setZoomOnly(ZoomOnlyMode zoomMode)209 void View::setZoomOnly(ZoomOnlyMode zoomMode)
210 {
211   QList<PlotItem*> plots = PlotItemManager::plotsForView(this);
212   foreach (PlotItem* plot, plots) {
213    plot->setZoomOnly(zoomMode);
214    // should we overload setZoomOnly?
215    QList<PlotRenderItem*> renderers = plot->renderItems();
216    foreach (PlotRenderItem* renderer, renderers) {
217      renderer->setZoomOnly(zoomMode);
218    }
219   }
220 }
221 
creationPolygon(CreationEvents events) const222 QPolygonF View::creationPolygon(CreationEvents events) const {
223   if (events == View::MousePress)
224      return _creationPolygonPress;
225   if (events == View::MouseRelease)
226      return _creationPolygonRelease;
227   if (events == View::MouseMove)
228      return _creationPolygonMove;
229   return QPolygonF();
230 }
231 
232 
setShowGrid(bool showGrid)233 void View::setShowGrid(bool showGrid) {
234   //Don't repaint unless absolutely necessary
235   if (_showGrid == showGrid)
236     return;
237 
238   _showGrid = showGrid;
239   invalidateScene(sceneRect(), QGraphicsScene::BackgroundLayer);
240 }
241 
242 
setGridSpacing(const QSizeF & gridSpacing)243 void View::setGridSpacing(const QSizeF &gridSpacing) {
244   //Don't repaint unless absolutely necessary
245   if (_gridSpacing == gridSpacing)
246     return;
247 
248   _gridSpacing = gridSpacing;
249   invalidateScene(sceneRect(), QGraphicsScene::BackgroundLayer);
250 }
251 
252 
snapPoint(const QPointF & point)253 QPointF View::snapPoint(const QPointF &point) {
254   qreal x = point.x();
255   qreal y = point.y();
256   if (_snapToGridHorizontal && gridSpacing().width() > 0)
257     x -= fmod(point.x(), gridSpacing().width());
258 
259   if (_snapToGridVertical && gridSpacing().height() > 0)
260     y -= fmod(point.y(), gridSpacing().height());
261 
262   return QPointF(x, y);
263 }
264 
265 
event(QEvent * event)266 bool View::event(QEvent *event) {
267   if (event->type() == QEvent::Shortcut) {
268     QShortcutEvent *e = static_cast<QShortcutEvent*>(event);
269 
270     QPointF mousePos = mapToScene(mapFromGlobal(QCursor::pos()));
271     QList<QGraphicsItem*> list = scene()->items(mousePos);
272     if (list.isEmpty()) {
273       if (e->key() == _editAction->shortcut()) {
274         _editAction->trigger();
275       }
276     } else {
277       foreach (QGraphicsItem *item, list) {
278         ViewItem *viewItem = dynamic_cast<ViewItem*>(item);
279         if (!viewItem)
280           continue;
281 
282         // Qt bug: http://bugreports.qt.nokia.com/browse/QTBUG-8188
283         // also see PlotRenderItem::hoverEnterEvent, there is a workaround.
284         //if (viewItem                         && viewItem->tryShortcut(e->key())) {
285         if (viewItem && viewItem->hasFocus() && viewItem->tryShortcut(e->key())) {
286           return true;
287         }
288       }
289     }
290   }
291 //  } else if (event->type() == QEvent::MouseButtonPress) {
292 //    QMouseEvent *e = static_cast<QMouseEvent*>(event);
293 //    if (e->button() == Qt::RightButton) {
294 //      //contextMenuEvent();
295 //      //return true;
296 //    }
297 //  }
298 
299   return QGraphicsView::event(event);
300 }
301 
302 
eventFilter(QObject * obj,QEvent * event)303 bool View::eventFilter(QObject *obj, QEvent *event) {
304   if (obj != scene() || _mouseMode != Create)
305     return QGraphicsView::eventFilter(obj, event);
306 
307   switch (event->type()) {
308   case QEvent::GraphicsSceneMousePress:
309     {
310       QGraphicsSceneMouseEvent *e = static_cast<QGraphicsSceneMouseEvent*>(event);
311       if (e->button() == Qt::LeftButton) {
312         _creationPolygonPress << snapPoint(e->buttonDownScenePos(Qt::LeftButton));
313         emit creationPolygonChanged(MousePress);
314         return true; //filter this otherwise something can grab our mouse...
315       }
316     }
317   case QEvent::GraphicsSceneMouseRelease:
318     {
319       QGraphicsSceneMouseEvent *e = static_cast<QGraphicsSceneMouseEvent*>(event);
320       if (e->button() != Qt::LeftButton) break;
321       _creationPolygonRelease << snapPoint(e->scenePos());
322       emit creationPolygonChanged(MouseRelease);
323       break;
324     }
325   case QEvent::GraphicsSceneMouseMove:
326     {
327       QGraphicsSceneMouseEvent *e = static_cast<QGraphicsSceneMouseEvent*>(event);
328       _creationPolygonMove << snapPoint(e->scenePos());
329       emit creationPolygonChanged(MouseMove);
330       break;
331     }
332   case QEvent::KeyPress:
333     {
334       QKeyEvent *e = static_cast<QKeyEvent*>(event);
335       if (e->key() == Qt::Key_Escape) {
336         emit creationPolygonChanged(EscapeEvent);
337       }
338     }
339   default:
340     break;
341   }
342 
343   return QGraphicsView::eventFilter(obj, event);
344 }
345 
346 
createCustomLayout()347 void View::createCustomLayout() {
348   bool ok;
349   int default_cols = qMax(1,int(sqrt((qreal)Data::self()->plotList().count())));
350   int columns = QInputDialog::getInt(this, tr("Kst: Column Layout"),
351                                       tr("Layout in columns in order of creation.\nSelect number of columns:"),default_cols, 1,
352                                       15, 1, &ok);
353   if (ok) {
354     createLayout(false, columns);
355   }
356 }
357 
358 
createLayout(bool preserve,int columns)359 void View::createLayout(bool preserve, int columns) {
360   PlotItemManager::self()->clearFocusedPlots();
361 
362   LayoutCommand *layout = new LayoutCommand(new LayoutBoxItem(this));
363   layout->createLayout(preserve, columns);
364 
365   if (_layoutBoxItem) {
366     _layoutBoxItem->setEnabled(false);
367     delete _layoutBoxItem;
368     _layoutBoxItem = 0;
369   }
370 }
371 
372 
appendToLayout(CurvePlacement::Layout layout,ViewItem * item,int columns)373 void View::appendToLayout(CurvePlacement::Layout layout, ViewItem* item, int columns) {
374   AppendLayoutCommand *appendlayout = new AppendLayoutCommand(new LayoutBoxItem(this));
375   appendlayout->appendLayout(layout, item, columns);
376   if (_layoutBoxItem) {
377     LayoutBoxItem *layoutBox = _layoutBoxItem;
378     _layoutBoxItem->setEnabled(false);
379     delete layoutBox;
380   }
381 
382 }
383 
processResize(QSize size)384 void View::processResize(QSize size) {
385 
386   setPlotBordersDirty(true);
387   if (size != sceneRect().size()) {
388     QRectF oldSceneRect = sceneRect();
389 
390     viewport()->resize(size);
391 
392     setSceneRect(QRectF(0.0, 0.0, size.width() - 1.0, size.height() - 1.0));
393 
394     setCacheMode(QGraphicsView::CacheBackground);
395 
396     foreach (QGraphicsItem *item, items()) {
397       if (item->parentItem())
398         continue;
399 
400       ViewItem *viewItem = dynamic_cast<ViewItem*>(item);
401       Q_ASSERT(viewItem);
402 
403       viewItem->updateChildGeometry(oldSceneRect, sceneRect());
404     }
405   }
406 }
407 
resizeEvent(QResizeEvent * event)408 void View::resizeEvent(QResizeEvent *event) {
409   if (event) {
410     QGraphicsView::resizeEvent(event);
411   }
412   setPlotBordersDirty(true);
413   if (size() != sceneRect().size()) {
414     QRectF oldSceneRect = sceneRect();
415 
416     setSceneRect(QRectF(0.0, 0.0, width() - 1.0, height() - 1.0));
417 
418     setCacheMode(QGraphicsView::CacheBackground);
419 
420     foreach (QGraphicsItem *item, items()) {
421       if (item->parentItem())
422         continue;
423 
424       ViewItem *viewItem = dynamic_cast<ViewItem*>(item);
425       Q_ASSERT(viewItem);
426 
427       viewItem->updateChildGeometry(oldSceneRect, sceneRect());
428     }
429   }
430 }
431 
432 
forceChildResize(QRectF oldRect,QRectF newRect)433 void View::forceChildResize(QRectF oldRect, QRectF newRect) {
434   foreach (QGraphicsItem *item, items()) {
435     if (item->parentItem())
436       continue;
437 
438     ViewItem *viewItem = dynamic_cast<ViewItem*>(item);
439     Q_ASSERT(viewItem);
440 
441     viewItem->updateChildGeometry(oldRect, newRect);
442   }
443 }
444 
445 
drawBackground(QPainter * painter,const QRectF & rect)446 void View::drawBackground(QPainter *painter, const QRectF &rect) {
447   if (isPrinting()) {
448     QBrush currentBrush(backgroundBrush());
449     setBackgroundBrush(Qt::white);
450     QGraphicsView::drawBackground(painter, rect);
451     setBackgroundBrush(currentBrush);
452     return;
453   }
454 
455   QGraphicsView::drawBackground(painter, rect);
456 
457   if (!showGrid())
458     return;
459 
460   painter->save();
461   QColor c = Qt::gray;
462   c.setAlphaF(c.alphaF() * 0.2);
463   painter->setPen(c);
464   // http://techbase.kde.org/Development/Tutorials/Graphics/Performance says
465   // setOpacity turns off hardware acceleration.
466   // they suggest setting alpha in the color instead, which
467   // we have done, above.
468   //painter->setOpacity(0.2);
469 
470   const QRectF r = sceneRect();
471   qreal spacing = gridSpacing().width();
472 
473   //FIXME We should probably only draw those lines that intercept rect
474 
475   //vertical lines
476   qreal x = r.left() + spacing;
477   while (x < r.right() && spacing > 0) {
478     QLineF line(QPointF(x, r.top()), QPointF(x, r.bottom()));
479     painter->drawLine(line);
480     x += spacing;
481   }
482 
483   spacing = gridSpacing().height();
484 
485   //horizontal lines
486   qreal y = r.top() + spacing;
487   while (y < r.bottom() && spacing > 0) {
488     QLineF line(QPointF(r.left(), y), QPointF(r.right(), y));
489     painter->drawLine(line);
490     y += spacing;
491   }
492 
493   painter->restore();
494 }
495 
496 
updateSettings()497 void View::updateSettings() {
498   setShowGrid(ApplicationSettings::self()->showGrid());
499 
500   setSnapToGrid(ApplicationSettings::self()->snapToGrid());
501 
502   setGridSpacing(QSizeF(ApplicationSettings::self()->gridHorizontalSpacing(),
503                         ApplicationSettings::self()->gridVerticalSpacing()));
504 
505   //FIXME: only if reference size changed...
506   forceChildResize(sceneRect(), sceneRect());
507   //FIXME: should trigger a paint.
508 }
509 
510 
loadSettings()511 void View::loadSettings() {
512   setShowGrid(ApplicationSettings::self()->showGrid());
513 
514   setSnapToGrid(ApplicationSettings::self()->snapToGrid());
515 
516   setGridSpacing(QSizeF(ApplicationSettings::self()->gridHorizontalSpacing(),
517                         ApplicationSettings::self()->gridVerticalSpacing()));
518 
519 }
520 
521 
updateChildGeometry(const QRectF & oldSceneRect)522 void View::updateChildGeometry(const QRectF &oldSceneRect) {
523   foreach (QGraphicsItem *item, items()) {
524     if (item->parentItem())
525       continue;
526 
527     ViewItem *viewItem = dynamic_cast<ViewItem*>(item);
528     Q_ASSERT(viewItem);
529 
530     viewItem->updateChildGeometry(oldSceneRect, sceneRect());
531   }
532 }
533 
534 // returns the size of a font, rescaled by the size of the paint device
535 // relative to the reference window size.
scaledFontSize(qreal pointSize,const QPaintDevice & p) const536 qreal View::scaledFontSize(qreal pointSize, const QPaintDevice &p) const {
537   qreal fontSize;
538 
539   qreal height_inch = qreal(height())/qreal(p.logicalDpiY());
540   qreal width_inch = qreal(width())/qreal(p.logicalDpiX());
541 
542   qreal scale =  2.54*(width_inch + height_inch)/(ApplicationSettings::self()->referenceViewHeightCM() +
543                                       ApplicationSettings::self()->referenceViewWidthCM());
544 
545   fontSize = pointSize * scale * _fontRescale;
546 
547   /*
548   if (!_printing) {
549       fontSize = (qreal)(height() + width()) /
550               (ApplicationSettings::self()->referenceViewHeight() +
551                ApplicationSettings::self()->referenceViewWidth()) *
552               pointSize * _fontRescale;
553   } else {
554       fontSize = (qreal)(p.heightMM() + p.widthMM()) * 0.1 /
555               (ApplicationSettings::self()->referenceViewHeightCM() +
556                ApplicationSettings::self()->referenceViewWidthCM()) *
557               pointSize * _fontRescale;
558   }
559 */
560 
561   if (fontSize < ApplicationSettings::self()->minimumFontSize()) {
562       fontSize = ApplicationSettings::self()->minimumFontSize();
563   }
564 
565   if (fontSize < 0)
566     return 1;
567 
568 #ifdef Q_OS_WIN
569   // On Windows more and more memory gets allocated when fontsize
570   // is too detailed, somewhere some strange caching happens.
571   const qreal fontPrecision = 4;
572   fontSize = floor(fontSize * fontPrecision + 0.5) / fontPrecision;
573 #endif
574 
575   return fontSize;
576 }
577 
578 
579 
580 // Set the font sizes of all plots in the view to a default size, scaled
581 // by the default global font scale, and the application minimum font scale.
resetPlotFontSizes(PlotItem * plot)582 double View::resetPlotFontSizes(PlotItem* plot) {
583   QList<PlotItem*> plots;
584   plots.append(plot);
585   return resetPlotFontSizes(plots);
586 }
587 
resetPlotFontSizes(QList<PlotItem * > new_plots)588 double View::resetPlotFontSizes(QList<PlotItem*> new_plots) {
589   QList<PlotItem*> plots(new_plots);
590   plots.append(PlotItemManager::self()->plotsForView(this));
591   qreal pointSize = dialogDefaults().value("plot/globalFontScale",16.0).toDouble();
592 
593   // the 4 in the line below is a magic number that impedes scaling until you
594   // have more than a couple of rows/columns.  A 1 would make it scale more
595   // aggressively.  The behavior looks pretty good to me with 4.
596   qreal count = qMax(plots.count()-1, 1);
597 
598   //qreal newPointSize = qMax(pointSize/qSqrt(count) , ApplicationSettings::self()->minimumFontSize());
599 
600   qreal newPointSize = (pointSize - ApplicationSettings::self()->minimumFontSize())/qSqrt(count) + ApplicationSettings::self()->minimumFontSize();
601 
602   if (newPointSize<pointSize) {
603     pointSize = newPointSize;
604   }
605   qreal legendPointSize = qMax(pointSize*qreal(0.6), ApplicationSettings::self()->minimumFontSize());
606   foreach(PlotItem* plotItem, plots) {
607     plotItem->setGlobalFontScale(pointSize);
608     plotItem->rightLabelDetails()->setFontScale(pointSize);
609     plotItem->leftLabelDetails()->setFontScale(pointSize);
610     plotItem->bottomLabelDetails()->setFontScale(pointSize);
611     plotItem->topLabelDetails()->setFontScale(pointSize);
612     plotItem->numberLabelDetails()->setFontScale(pointSize);
613     if (plotItem->showLegend()) {
614       plotItem->legend()->setFontScale(legendPointSize);
615     }
616   }
617   return pointSize;
618 }
619 
620 // copy the font settings of the first plotItem in the view into
621 // plot, then break.
configurePlotFontDefaults(PlotItem * plot)622 void View::configurePlotFontDefaults(PlotItem *plot) {
623   if (plot) {
624     foreach(PlotItem* plotItem, PlotItemManager::self()->plotsForView(this)) {
625       if (plot != plotItem) {
626         plot->setGlobalFont(plotItem->globalFont());
627         plot->setGlobalFontScale(plotItem->globalFontScale());
628         plot->setGlobalFontColor(plotItem->globalFontColor());
629 
630         plot->leftLabelDetails()->setFontUseGlobal(plotItem->leftLabelDetails()->fontUseGlobal());
631         plot->leftLabelDetails()->setFont(plotItem->leftLabelDetails()->font());
632         plot->leftLabelDetails()->setFontScale(plotItem->leftLabelDetails()->fontScale());
633         plot->leftLabelDetails()->setFontColor(plotItem->leftLabelDetails()->fontColor());
634 
635         plot->rightLabelDetails()->setFontUseGlobal(plotItem->rightLabelDetails()->fontUseGlobal());
636         plot->rightLabelDetails()->setFont(plotItem->rightLabelDetails()->font());
637         plot->rightLabelDetails()->setFontScale(plotItem->rightLabelDetails()->fontScale());
638         plot->rightLabelDetails()->setFontColor(plotItem->rightLabelDetails()->fontColor());
639 
640         plot->topLabelDetails()->setFontUseGlobal(plotItem->topLabelDetails()->fontUseGlobal());
641         plot->topLabelDetails()->setFont(plotItem->topLabelDetails()->font());
642         plot->topLabelDetails()->setFontScale(plotItem->topLabelDetails()->fontScale());
643         plot->topLabelDetails()->setFontColor(plotItem->topLabelDetails()->fontColor());
644 
645         plot->bottomLabelDetails()->setFontUseGlobal(plotItem->bottomLabelDetails()->fontUseGlobal());
646         plot->bottomLabelDetails()->setFont(plotItem->bottomLabelDetails()->font());
647         plot->bottomLabelDetails()->setFontScale(plotItem->bottomLabelDetails()->fontScale());
648         plot->bottomLabelDetails()->setFontColor(plotItem->bottomLabelDetails()->fontColor());
649 
650         plot->numberLabelDetails()->setFontUseGlobal(plotItem->numberLabelDetails()->fontUseGlobal());
651         plot->numberLabelDetails()->setFont(plotItem->numberLabelDetails()->font());
652         plot->numberLabelDetails()->setFontScale(plotItem->numberLabelDetails()->fontScale());
653         plot->numberLabelDetails()->setFontColor(plotItem->numberLabelDetails()->fontColor());
654 
655         plot->setItemPen(plotItem->storedPen());
656         plot->setItemBrush(plotItem->brush());
657         plot->xAxis()->copyProperties(plotItem->xAxis());
658         plot->yAxis()->copyProperties(plotItem->yAxis());
659 
660         break;
661       }
662     }
663   }
664 }
665 
666 
viewContextMenuEvent()667 void View::viewContextMenuEvent() {
668   QMenu menu;
669 
670   addTitle(&menu);
671   menu.addAction(_editAction);
672 
673   QMenu layoutMenu;
674   layoutMenu.setTitle(tr("Cleanup Layout"));
675   layoutMenu.addAction(_autoLayoutAction);
676   //layoutMenu.addAction(_protectedLayoutAction);
677   layoutMenu.addAction(_customLayoutAction);
678   menu.addMenu(&layoutMenu);
679 
680   menu.exec(QCursor::pos());
681 }
682 
683 
addTitle(QMenu * menu) const684 void View::addTitle(QMenu *menu) const {
685   QWidgetAction *action = new QWidgetAction(menu);
686   action->setEnabled(false);
687 
688   QLabel *label = new QLabel(tr("View Menu"), menu);
689   label->setAlignment(Qt::AlignCenter);
690   label->setStyleSheet("QLabel {"
691                        "border-bottom: 2px solid lightGray;"
692                        "font: bold large;"
693                        "padding: 3px;"
694                        "margin: 1px;"
695                        "}");
696   action->setDefaultWidget(label);
697   menu->addAction(action);
698 }
699 
700 
edit()701 void View::edit() {
702   ViewDialog *editDialog = new ViewDialog(this, kstApp->mainWindow());
703   editDialog->show();
704 }
705 
706 
viewChanged()707 void View::viewChanged() {
708   //kstApp->mainWindow()->document()->setChanged(true);
709 }
710 
711 
layoutableViewItems()712 QList<ViewItem*> View::layoutableViewItems() {
713   QList<QGraphicsItem*> graphics_items = scene()->items();
714   QList<ViewItem *> layoutable_view_items;
715 
716   foreach(QGraphicsItem* graphics_item, graphics_items) {
717     ViewItem *item = dynamic_cast<ViewItem*>(graphics_item);
718     if (item && (!item->hasStaticGeometry()) &&
719         item->isVisible() &&
720         item->allowsLayout() &&
721         ((dynamic_cast<LayoutBoxItem*>(item->parentViewItem())!=0) || (!item->parentViewItem()))) {
722       layoutable_view_items.append(item);
723     }
724   }
725 
726   qSort(layoutable_view_items.begin(), layoutable_view_items.end(), shortNameLessThan);
727 
728   return layoutable_view_items;
729 
730 }
731 
732 }
733 
734 // vim: ts=2 sw=2 et
735