You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

493 lines
14 KiB

/***************************************************************************
qsplotview.h
-------------------
begin : 01-January-2000
copyright : (C) 2000 by Kamil Dobkowski
email : kamildobk@poczta.onet.pl
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QSPLOTVIEW_H
#define QSPLOTVIEW_H
#include "qscoord.h"
#include "qsaxes.h"
#include "qsaxis.h"
#include "qsctool.h"
#include "qsworkbook.h"
#include <qdatetime.h>
#include <qcstring.h>
#include <qwidget.h>
#include <qscrollbar.h>
#include <qintdict.h>
#include <qptrlist.h>
class QTimer;
class QPixmap;
class QSRuler;
class QSRangeScrollBar;
class QPushButton;
class QTabBar;
class QPopupMenu;
class QScrollBar;
class QGridLayout;
class QEvent;
class QSlider;
class QSPlotView;
/**
* \brief Holds a list of selected objects for QSPlotView
*
* Notice that selection doesn't own its objects, so QSCObject::colection() doesn't return selection but some
* other collection ( QSPage::objects() for example ) which the object belongs to.
* Only object which belongs to the same collection can be selected at one time.
* Before an object from another collection is added selection is cleared.
*/
class QSSelection : public QSCObjectCollection
{
friend class QSPlotView;
Q_OBJECT
public:
/**
* Constructor
*/
QSSelection( QObject *parent=NULL );
/**
* Destructor
*/
virtual ~QSSelection();
/**
* Returns the selection default collection.
*/
QSCObjectCollection *collection() const { return m_curr_collection; }
/**
* Returns the selection default collection.
*/
QSCObjectCollection *rootCollection() const { return m_root_collection; }
/**
* Set selection to this object.
*/
void set( QSCObject *object );
/**
* Adds a new object to the selection or removes selected object.
*/
void turn( QSCObject *object );
/**
* Adds object to a selection
*/
virtual void insert( int position, QSCObject *object );
/**
* Removes selected object from the selection
*/
virtual void remove( int index );
private:
QSWorkbook *m_workbook;
QSCObjectCollection *m_curr_collection;
QSCObjectCollection *m_root_collection;
void set_workbook( QSWorkbook *workbook );
void set_collection( QSCObject *object );
private slots:
void slot_object_removed(QSCObjectCollection*,QSCObject*);
void slot_page_removed( QSPage *page );
};
//-----------------------------------------------------------------//
/**
* \brief View class for QSWorkbook document
*
* Just call setWorkbook(). View updates itself
* automatically when workbook changes. It also manages
* canvas tools, see setTool(). Some object in the workbook can
* be selected, see selection().
* @author Kamil Dobkowski
*/
class QSPlotView : public QWidget {
Q_OBJECT
public:
/**
* See bindScrollBar()
*/
enum ScrollBarType { HorizontalBar = 0, VerticalBar = 1 };
/**
* See bindSlider()
*/
enum SliderType { HorizontalSlider = 0, VerticalSlider = 1, AdditionalSlider = 2 };
/**
* Constructor.
*/
QSPlotView(QWidget *parent=0, const char *name=0);
/**
* Destructor.
*/
virtual ~QSPlotView();
/**
* Sets a workbook.
*/
void setWorkbook( QSWorkbook *workbook );
/**
* Returns a default workbook.
*/
QSWorkbook *workbook() const { return m_workbook; }
/**
* Returns pointer to the current page. See slot setCurrentPage().
*/
QSPage *currentPage() const { return m_curr_page; }
/**
* Returns selection
*/
QSSelection *selection() const { return m_selection; }
/**
* Enables/disables pixmap buffering.
*/
void setPixmapBuffering( bool enabled );
/**
* Returns if pixmap buffering is on
*/
bool pixmapBuffering() const { return m_screen_buffering; }
/**
* Sets a new tool.
*/
void setTool( QSTool *t );
/**
* Turns on/off the full page mode.
*/
void setFullPage( bool enabled );
/**
* Sets a zoom value. Currently accepts values between 0.1 and 5.0.
*/
void setZoom( double zoom );
/**
* Sets grid spacing
*/
void setGridSpacing( int x_mm, int y_mm );
/**
* Shows/hides grid
*/
void setGridVisible( bool visible );
/**
* Shows/hides rulers
*/
void setRulersVisible( bool visible );
/**
* Shows/hides sliders and scrollbars
*/
void setSlidersVisible( bool visible );
/**
* Shows/hides page margin
*/
void setPageMarginsVisible( bool visible );
/**
* Returns the currently active object. If selection contains
* only one object - it becames active object, active object is
* NULL if selection contains more than a one object.
*/
QSCObject *activeObject() const { return m_active_object; }
/**
* Returns the active axes or NULL.( active means a parent axes of the selected object ).
*/
QSAxes *activeAxes() const { return m_active_axes; }
/**
* Default parent collection for newly created objects.
* If QSGroup s selected this is QSCGroup, if not this is QSPage or NULL.
*/
QSCObjectCollection *activeCollection() const;
/**
* Returns a grid spacing
*/
int gridSpacingX() const { return m_grid_x; }
/**
* Returns a grid spacing
*/
int gridSpacingY() const { return m_grid_y; }
/**
* Is grid visible.
*/
bool gridVisible() const { return m_grid_visible; }
/**
* Are rulers visible.
*/
bool rulersVisible() const { return m_rulers_visible; }
/**
* Returns the current 'slider' state.
*/
bool slidersVisible() const { return m_sliders_visible; }
/**
* Is page margin visible.
*/
bool pageMarginsVisible() const { return m_page_margins_visible; }
/**
* Returns a full page setting.
*/
bool fullPage() const { return m_full_page; }
/**
* Return zoom value
*/
double zoom() const { return m_zoom; }
/**
* Current dpi of the canvas. It is calculated as follows: zoom*72.0
*/
double dpi() const { return m_full_page ? m_zoom * 72.0 : 72.0; }
/**
* Designates a scrollbar to set a range on the given axis.
* This applies only to the active axes object.
* Only bounded scrollbars are visible. To unbind call this
* function with axis = UnknownAxisType. Those settings are valid even
* after plot object has changed.
*/
void bindScrollBar( ScrollBarType t, QSAxis::AxisType axisType );
/**
* Designates a slider to set a given property of an active axes.
* To unbind call this function with 'property' set to QSCString::null.
*/
void bindSlider( SliderType t, const char *property, int min, int max );
/**
* A bumber of axis or UnknownAxisType.
*/
QSAxis::AxisType scrollBarAxis( ScrollBarType t ) const { return m_scrollbars[t].type; }
/**
* Returns a property name or null.
*/
QCString sliderProperty( SliderType t ) const { return m_sliders[t].property; }
/**
* Returns a min value or 0.
*/
int sliderMin( SliderType t ) const { return m_sliders[t].min; }
/**
* Returns a max value or 0.
*/
int sliderMax( SliderType t ) const { return m_sliders[t].max; }
/**
* Returns the currently selected tool
*/
QSTool *tool() const { return m_ctool; }
/**
* Returns a canvas.
*/
QWidget *canvasWidget() const { return m_canvas; }
/**
* Returns object at position 'pos' or NULL. if 'recursive' is
* true it digs through all QSCGroups.
*/
QSCObject *objectAt( const QPoint& pos, bool recursive = true );
/**
* Shows a user message. Emits message() signal.
*/
void showUserMessage( const QString& msg );
/**
* Reimplemented
*/
bool eventFilter( QObject *, QEvent* );
public slots:
/**
* Sets the current ( displayed ) page
*/
void setCurrentPage( int index );
/**
* Updates canvas. There should be no need to call this directly.
* It is always called when the current page changes.
*/
void updateCanvas();
signals:
/**
* Status messages. Emmited mainly by tools during their work.
*/
void message( const QString& msg );
/**
* Emitted when a selected object changes.
*/
void sigActiveObjectChanged();
/**
* Emitted when an active object changes,
* Notice that an active axes can change in this case too.
*/
void sigActiveAxesChanged();
/**
* Added removed reordered.
*/
void sigActiveAxesDatasetsChanged();
/**
* Current page was changed - see: setCurrentPage() .
*/
void sigCurrentPageChanged();
/**
* Current page title has changed
*/
void sigCurrentPageTitleChanged( const QString& newTitle );
/**
* Current page object list was changed.
*/
void sigCurrentPageObjectListChanged();
/**
* Mouse right-button click over page bar.
*/
void sigPageBarClicked();
/**
* Slider pressed
*/
void sigSliderPressed();
/**
* Slider released
*/
void sigSliderReleased();
/**
* Scrollbar pressed
*/
void sigScrollBarPressed();
/**
* Scrollbar released
*/
void sigScrollBarReleased();
private:
QSWorkbook *m_workbook;
QSPage *m_curr_page;
QSSelection *m_selection;
bool m_full_page;
QSAxes *m_active_axes;
QGridLayout *m_layout;
QWidget *m_canvas;
QWidget *m_shadow;
QWidget *m_interior;
QSTool *m_ctool;
bool m_tool_activated;
bool m_tool_activating;
QSCObject *m_active_object;
double m_zoom;
int m_grid_x;
int m_grid_y;
bool m_grid_visible;
bool m_page_margins_visible;
bool m_screen_buffering;
bool m_screen_buffer_valid;
QPixmap *m_screen_buffer;
QTimer *m_refresh_buffer;
QTime m_perf_monitor;
bool m_rulers_visible;
QSRuler *m_hruler;
QSRuler *m_vruler;
bool m_sliders_visible;
QScrollBar *m_hscrollbar;
QScrollBar *m_vscrollbar;
QTabBar *m_page_list;
QIntDict<QSPage> m_pages;
struct slider_data_t {
QSlider *slider;
int min;
int max;
QCString property;
} m_sliders[3];
struct scrollbar_data_t {
QSRangeScrollBar *scrollbar;
QSAxis::AxisType type;
} m_scrollbars[2];
void set_backstore_internal( bool enabled );
bool backstore_internal();
void recreate_gui();
void recreate_rulers();
void recreate_parameter_scrollbars();
void recreate_parameter_sliders();
void recreate_canvas_scrollbars();
void recreate_page_bar();
void update_rulers();
void update_parameter_scrollbars();
void update_parameter_sliders();
void update_canvas_scrollbars();
void update_page_bar();
void init();
void clean();
void activate_tool();
void deactivate_tool();
void set_active_object( QSCObject *o, bool tool = false );
void set_active_axes( QSAxes *axes );
void draw_tool();
void draw_page();
void draw_grid( QPainter *p );
void draw_full_page( QPaintDevice *paint_device );
void draw_single_view( QPaintDevice *paint_device );
void show_page_popup();
bool confirm( const QString& message );
private slots:
void slot_selection_changed();
void adjust_canvas_size();
void slot_page_removed( QSPage *page );
void slot_page_added( QSPage *page );
void slot_page_order();
void slot_curr_page_object_list_changed();
void slot_page_tab_selected(int);
void slot_active_axes_modified();
void slot_active_axes_ranges_changed();
void slot_active_axes_changed(QSData*);
void slot_active_axes_order();
void slot_update_canvas_pos(int);
void slot_object_removed( QSCObject *object );
void slot_hslider_moved( int );
void slot_vslider_moved( int );
void slot_aslider_moved( int );
void slot_slider_pressed();
void slot_slider_released();
void slot_scrollbar_pressed();
void slot_scrollbar_released();
void slot_hscrollbar_moved( int );
void slot_vscrollbar_moved( int );
void slot_page_list_changed();
void slot_refresh_screen_buffer();
void slot_page_draw_ends();
void slot_axes_draw_ends();
void slot_curr_page_title_changed( const QString& new_title );
};
//-------------------------------------------------------------//
class QSRangeScrollBar : public QScrollBar
{
Q_OBJECT
public:
QSRangeScrollBar( QWidget *parent );
virtual ~QSRangeScrollBar();
void setAxes( QSAxes *axes, QSAxis::AxisType type );
void updateScrollbar();
void updateRange();
private:
QSAxes *m_axes;
QSAxis::AxisType m_type;
bool m_updating_range;
bool m_updating_scrollbars;
double m_min;
double m_max;
};
#endif