2014-01-14 16:30:13 +00:00
# include "profilewidget2.h"
2014-01-15 14:00:23 +00:00
# include "diveplotdatamodel.h"
2014-01-15 14:23:40 +00:00
# include "helpers.h"
2014-01-15 15:34:55 +00:00
# include "profile.h"
2014-01-16 17:02:32 +00:00
# include "diveeventitem.h"
2014-01-21 12:48:26 +00:00
# include "divetextitem.h"
2014-02-05 16:34:45 +00:00
# include "divetooltipitem.h"
2014-02-17 22:15:40 +00:00
# include "planner.h"
2014-02-26 19:42:55 +00:00
# include "device.h"
2014-02-27 18:20:03 +00:00
# include "ruleritem.h"
2014-08-15 00:22:27 +00:00
# include "tankitem.h"
2014-04-16 20:03:44 +00:00
# include "pref.h"
2015-02-09 20:58:40 +00:00
# include "divepicturewidget.h"
2015-02-09 20:27:59 +00:00
# include "models.h"
2015-02-09 20:58:40 +00:00
# include "maintab.h"
2015-02-09 22:37:17 +00:00
# include "diveplanner.h"
2015-02-09 20:27:59 +00:00
2014-03-16 04:12:34 +00:00
# include <libdivecomputer/parser.h>
2014-02-04 23:47:50 +00:00
# include <QScrollBar>
2014-03-10 15:59:02 +00:00
# include <QtCore/qmath.h>
2014-03-16 04:12:34 +00:00
# include <QMessageBox>
2014-04-03 19:16:15 +00:00
# include <QInputDialog>
2015-01-17 15:02:03 +00:00
# include <QDebug>
2015-02-09 20:58:40 +00:00
# include <QWheelEvent>
2014-01-16 17:02:32 +00:00
2014-01-15 15:20:05 +00:00
# ifndef QT_NO_DEBUG
# include <QTableView>
# endif
2014-01-16 05:28:33 +00:00
# include "mainwindow.h"
2014-02-12 15:50:35 +00:00
# include <preferences.h>
2014-01-15 15:20:05 +00:00
2014-02-07 17:32:39 +00:00
/* This is the global 'Item position' variable.
* it should tell you where to position things up
* on the canvas .
*
* please , please , please , use this instead of
* hard coding the item on the scene with a random
* value .
*/
2014-02-28 04:09:57 +00:00
static struct _ItemPos {
struct _Pos {
2014-02-07 17:32:39 +00:00
QPointF on ;
QPointF off ;
} ;
2014-02-28 04:09:57 +00:00
struct _Axis {
_Pos pos ;
QLineF shrinked ;
QLineF expanded ;
2014-09-28 08:11:38 +00:00
QLineF intermediate ;
2014-02-07 17:32:39 +00:00
} ;
_Pos background ;
2014-02-07 23:17:14 +00:00
_Pos dcLabel ;
2014-08-15 13:30:31 +00:00
_Pos tankBar ;
2014-02-07 17:32:39 +00:00
_Axis depth ;
2014-02-11 18:55:07 +00:00
_Axis partialPressure ;
2014-09-28 08:11:38 +00:00
_Axis partialPressureTissue ;
2014-08-15 14:11:14 +00:00
_Axis partialPressureWithTankBar ;
2014-09-15 12:09:00 +00:00
_Axis percentage ;
2014-09-28 08:11:38 +00:00
_Axis percentageWithTankBar ;
2014-02-07 17:32:39 +00:00
_Axis time ;
_Axis cylinder ;
_Axis temperature ;
2014-11-02 18:41:41 +00:00
_Axis temperatureAll ;
2014-02-20 01:18:26 +00:00
_Axis heartBeat ;
2015-01-17 18:54:10 +00:00
_Axis heartBeatWithTankBar ;
2014-02-07 17:32:39 +00:00
} itemPos ;
2014-02-07 16:59:58 +00:00
2014-02-28 04:09:57 +00:00
ProfileWidget2 : : ProfileWidget2 ( QWidget * parent ) : QGraphicsView ( parent ) ,
2014-01-15 14:00:23 +00:00
currentState ( INVALID ) ,
2014-06-09 21:06:00 +00:00
dataModel ( new DivePlotDataModel ( this ) ) ,
2014-02-04 23:47:50 +00:00
zoomLevel ( 0 ) ,
2014-03-10 15:59:02 +00:00
zoomFactor ( 1.15 ) ,
2014-02-28 04:09:57 +00:00
background ( new DivePixmapItem ( ) ) ,
2014-06-09 21:06:00 +00:00
backgroundFile ( " :poster " ) ,
2014-02-05 16:34:45 +00:00
toolTipItem ( new ToolTipItem ( ) ) ,
2014-03-10 11:43:43 +00:00
isPlotZoomed ( prefs . zoomed_plot ) ,
2014-01-15 14:00:23 +00:00
profileYAxis ( new DepthAxis ( ) ) ,
2014-01-27 17:14:42 +00:00
gasYAxis ( new PartialGasPressureAxis ( ) ) ,
2014-01-16 23:30:47 +00:00
temperatureAxis ( new TemperatureAxis ( ) ) ,
2014-01-15 14:00:23 +00:00
timeAxis ( new TimeAxis ( ) ) ,
2014-02-07 16:14:36 +00:00
diveProfileItem ( new DiveProfileItem ( ) ) ,
temperatureItem ( new DiveTemperatureItem ( ) ) ,
2015-01-04 21:36:01 +00:00
meanDepthItem ( new DiveMeanDepthItem ( ) ) ,
2014-02-09 18:11:17 +00:00
cylinderPressureAxis ( new DiveCartesianAxis ( ) ) ,
2014-02-07 16:14:36 +00:00
gasPressureItem ( new DiveGasPressureItem ( ) ) ,
2014-01-21 16:59:19 +00:00
diveComputerText ( new DiveTextItem ( ) ) ,
2014-02-07 16:14:36 +00:00
diveCeiling ( new DiveCalculatedCeiling ( ) ) ,
2014-02-07 16:59:58 +00:00
reportedCeiling ( new DiveReportedCeiling ( ) ) ,
2014-02-28 04:09:57 +00:00
pn2GasItem ( new PartialPressureGasItem ( ) ) ,
pheGasItem ( new PartialPressureGasItem ( ) ) ,
po2GasItem ( new PartialPressureGasItem ( ) ) ,
2015-01-05 07:20:26 +00:00
o2SetpointGasItem ( new PartialPressureGasItem ( ) ) ,
2015-01-20 18:13:53 +00:00
ccrsensor1GasItem ( new PartialPressureGasItem ( ) ) ,
ccrsensor2GasItem ( new PartialPressureGasItem ( ) ) ,
ccrsensor3GasItem ( new PartialPressureGasItem ( ) ) ,
2014-02-20 01:18:26 +00:00
heartBeatAxis ( new DiveCartesianAxis ( ) ) ,
2014-02-27 15:39:53 +00:00
heartBeatItem ( new DiveHeartrateItem ( ) ) ,
2014-09-15 12:09:00 +00:00
percentageAxis ( new DiveCartesianAxis ( ) ) ,
ambPressureItem ( new DiveAmbPressureItem ( ) ) ,
gflineItem ( new DiveGFLineItem ( ) ) ,
2014-08-05 21:27:00 +00:00
mouseFollowerVertical ( new DiveLineItem ( ) ) ,
2014-08-06 17:54:37 +00:00
mouseFollowerHorizontal ( new DiveLineItem ( ) ) ,
2014-03-25 21:34:09 +00:00
rulerItem ( new RulerItem2 ( ) ) ,
2014-08-15 00:22:27 +00:00
tankItem ( new TankItem ( ) ) ,
2014-03-25 21:34:09 +00:00
isGrayscale ( false ) ,
2014-05-26 20:51:46 +00:00
printMode ( false ) ,
2014-06-30 22:08:16 +00:00
shouldCalculateMaxTime ( true ) ,
2014-07-09 20:09:52 +00:00
shouldCalculateMaxDepth ( true ) ,
fontPrintScale ( 1.0 )
2014-01-14 16:30:13 +00:00
{
2014-02-09 18:11:17 +00:00
memset ( & plotInfo , 0 , sizeof ( plotInfo ) ) ;
2014-02-07 16:59:58 +00:00
setupSceneAndFlags ( ) ;
setupItemSizes ( ) ;
setupItemOnScene ( ) ;
addItemsToScene ( ) ;
scene ( ) - > installEventFilter ( this ) ;
2014-02-12 15:50:35 +00:00
connect ( PreferencesDialog : : instance ( ) , SIGNAL ( settingsChanged ( ) ) , this , SLOT ( settingsChanged ( ) ) ) ;
2014-05-24 15:39:40 +00:00
QAction * action = NULL ;
# define ADD_ACTION(SHORTCUT, Slot) \
action = new QAction ( this ) ; \
action - > setShortcut ( SHORTCUT ) ; \
action - > setShortcutContext ( Qt : : WindowShortcut ) ; \
addAction ( action ) ; \
connect ( action , SIGNAL ( triggered ( bool ) ) , this , SLOT ( Slot ) ) ; \
actionsForKeys [ SHORTCUT ] = action ;
ADD_ACTION ( Qt : : Key_Escape , keyEscAction ( ) ) ;
ADD_ACTION ( Qt : : Key_Delete , keyDeleteAction ( ) ) ;
ADD_ACTION ( Qt : : Key_Up , keyUpAction ( ) ) ;
ADD_ACTION ( Qt : : Key_Down , keyDownAction ( ) ) ;
ADD_ACTION ( Qt : : Key_Left , keyLeftAction ( ) ) ;
ADD_ACTION ( Qt : : Key_Right , keyRightAction ( ) ) ;
# undef ADD_ACTION
2015-02-02 21:12:11 +00:00
# if !defined(QT_NO_DEBUG) && defined(SHOW_PLOT_INFO_TABLE)
2014-02-07 16:59:58 +00:00
QTableView * diveDepthTableView = new QTableView ( ) ;
diveDepthTableView - > setModel ( dataModel ) ;
2014-03-07 15:42:13 +00:00
diveDepthTableView - > show ( ) ;
2014-02-07 16:59:58 +00:00
# endif
}
2014-01-15 14:23:40 +00:00
2014-12-18 07:47:51 +00:00
ProfileWidget2 : : ~ ProfileWidget2 ( )
{
delete background ;
delete toolTipItem ;
delete profileYAxis ;
delete gasYAxis ;
delete temperatureAxis ;
delete timeAxis ;
delete diveProfileItem ;
delete temperatureItem ;
2015-01-02 00:28:37 +00:00
delete meanDepthItem ;
2014-12-18 07:47:51 +00:00
delete cylinderPressureAxis ;
delete gasPressureItem ;
delete diveComputerText ;
delete diveCeiling ;
delete reportedCeiling ;
delete pn2GasItem ;
delete pheGasItem ;
delete po2GasItem ;
2015-01-05 07:20:26 +00:00
delete o2SetpointGasItem ;
2015-01-20 18:13:53 +00:00
delete ccrsensor1GasItem ;
delete ccrsensor2GasItem ;
delete ccrsensor3GasItem ;
2014-12-18 07:47:51 +00:00
delete heartBeatAxis ;
delete heartBeatItem ;
delete percentageAxis ;
delete ambPressureItem ;
delete gflineItem ;
delete mouseFollowerVertical ;
delete mouseFollowerHorizontal ;
delete rulerItem ;
delete tankItem ;
}
2014-05-19 05:39:34 +00:00
# define SUBSURFACE_OBJ_DATA 1
# define SUBSURFACE_OBJ_DC_TEXT 0x42
2014-02-07 16:59:58 +00:00
void ProfileWidget2 : : addItemsToScene ( )
{
scene ( ) - > addItem ( background ) ;
scene ( ) - > addItem ( toolTipItem ) ;
scene ( ) - > addItem ( profileYAxis ) ;
scene ( ) - > addItem ( gasYAxis ) ;
scene ( ) - > addItem ( temperatureAxis ) ;
scene ( ) - > addItem ( timeAxis ) ;
scene ( ) - > addItem ( diveProfileItem ) ;
scene ( ) - > addItem ( cylinderPressureAxis ) ;
scene ( ) - > addItem ( temperatureItem ) ;
2015-01-02 00:28:37 +00:00
scene ( ) - > addItem ( meanDepthItem ) ;
2014-02-07 16:59:58 +00:00
scene ( ) - > addItem ( gasPressureItem ) ;
2014-05-19 05:39:34 +00:00
// I cannot seem to figure out if an object that I find with itemAt() on the scene
// is the object I am looking for - my guess is there's a simple way in Qt to do that
// but nothing I tried worked.
// so instead this adds a special magic key/value pair to the object to mark it
diveComputerText - > setData ( SUBSURFACE_OBJ_DATA , SUBSURFACE_OBJ_DC_TEXT ) ;
2014-02-07 16:59:58 +00:00
scene ( ) - > addItem ( diveComputerText ) ;
scene ( ) - > addItem ( diveCeiling ) ;
scene ( ) - > addItem ( reportedCeiling ) ;
scene ( ) - > addItem ( pn2GasItem ) ;
scene ( ) - > addItem ( pheGasItem ) ;
scene ( ) - > addItem ( po2GasItem ) ;
2015-01-05 07:20:26 +00:00
scene ( ) - > addItem ( o2SetpointGasItem ) ;
2015-01-20 18:13:53 +00:00
scene ( ) - > addItem ( ccrsensor1GasItem ) ;
scene ( ) - > addItem ( ccrsensor2GasItem ) ;
scene ( ) - > addItem ( ccrsensor3GasItem ) ;
2014-09-15 12:09:00 +00:00
scene ( ) - > addItem ( percentageAxis ) ;
2014-02-20 01:18:26 +00:00
scene ( ) - > addItem ( heartBeatAxis ) ;
scene ( ) - > addItem ( heartBeatItem ) ;
2014-02-27 18:20:03 +00:00
scene ( ) - > addItem ( rulerItem ) ;
scene ( ) - > addItem ( rulerItem - > sourceNode ( ) ) ;
scene ( ) - > addItem ( rulerItem - > destNode ( ) ) ;
2014-08-15 00:22:27 +00:00
scene ( ) - > addItem ( tankItem ) ;
2014-08-05 21:27:00 +00:00
scene ( ) - > addItem ( mouseFollowerHorizontal ) ;
scene ( ) - > addItem ( mouseFollowerVertical ) ;
2014-08-05 22:47:02 +00:00
QPen pen ( QColor ( Qt : : red ) . lighter ( ) ) ;
pen . setWidth ( 0 ) ;
mouseFollowerHorizontal - > setPen ( pen ) ;
mouseFollowerVertical - > setPen ( pen ) ;
2014-05-22 18:40:22 +00:00
Q_FOREACH ( DiveCalculatedTissue * tissue , allTissues ) {
2014-02-07 16:59:58 +00:00
scene ( ) - > addItem ( tissue ) ;
}
2014-09-15 12:09:00 +00:00
Q_FOREACH ( DivePercentageItem * percentage , allPercentages ) {
scene ( ) - > addItem ( percentage ) ;
}
scene ( ) - > addItem ( ambPressureItem ) ;
scene ( ) - > addItem ( gflineItem ) ;
2014-02-07 16:59:58 +00:00
}
2014-01-15 14:23:40 +00:00
2014-02-07 16:59:58 +00:00
void ProfileWidget2 : : setupItemOnScene ( )
{
2014-02-07 18:34:42 +00:00
background - > setZValue ( 9999 ) ;
2014-03-11 22:09:54 +00:00
toolTipItem - > setZValue ( 9998 ) ;
2014-02-07 16:59:58 +00:00
toolTipItem - > setTimeAxis ( timeAxis ) ;
2014-03-11 22:09:54 +00:00
rulerItem - > setZValue ( 9997 ) ;
2014-08-15 00:22:27 +00:00
tankItem - > setZValue ( 100 ) ;
2014-01-23 19:54:34 +00:00
2014-02-07 19:59:21 +00:00
profileYAxis - > setOrientation ( DiveCartesianAxis : : TopToBottom ) ;
profileYAxis - > setMinimum ( 0 ) ;
2014-02-28 04:09:57 +00:00
profileYAxis - > setTickInterval ( M_OR_FT ( 10 , 30 ) ) ;
2014-03-19 20:06:18 +00:00
profileYAxis - > setTickSize ( 0.5 ) ;
2014-02-16 00:43:27 +00:00
profileYAxis - > setLineSize ( 96 ) ;
2014-02-16 22:16:39 +00:00
timeAxis - > setLineSize ( 92 ) ;
2014-03-19 20:06:18 +00:00
timeAxis - > setTickSize ( - 0.5 ) ;
2014-02-07 19:59:21 +00:00
2014-01-23 19:54:34 +00:00
gasYAxis - > setOrientation ( DiveCartesianAxis : : BottomToTop ) ;
gasYAxis - > setTickInterval ( 1 ) ;
2014-02-07 21:42:47 +00:00
gasYAxis - > setTickSize ( 1 ) ;
2014-01-27 17:14:42 +00:00
gasYAxis - > setMinimum ( 0 ) ;
gasYAxis - > setModel ( dataModel ) ;
2014-02-15 19:15:57 +00:00
gasYAxis - > setFontLabelScale ( 0.7 ) ;
2014-02-16 00:43:27 +00:00
gasYAxis - > setLineSize ( 96 ) ;
2014-01-16 20:39:13 +00:00
2014-02-20 01:18:26 +00:00
heartBeatAxis - > setOrientation ( DiveCartesianAxis : : BottomToTop ) ;
2014-04-07 20:15:21 +00:00
heartBeatAxis - > setTickSize ( 0.2 ) ;
2014-02-20 01:18:26 +00:00
heartBeatAxis - > setTickInterval ( 10 ) ;
heartBeatAxis - > setFontLabelScale ( 0.7 ) ;
heartBeatAxis - > setLineSize ( 96 ) ;
2014-09-15 12:09:00 +00:00
percentageAxis - > setOrientation ( DiveCartesianAxis : : BottomToTop ) ;
percentageAxis - > setTickSize ( 0.2 ) ;
percentageAxis - > setTickInterval ( 10 ) ;
percentageAxis - > setFontLabelScale ( 0.7 ) ;
percentageAxis - > setLineSize ( 96 ) ;
2014-01-16 21:28:33 +00:00
temperatureAxis - > setOrientation ( DiveCartesianAxis : : BottomToTop ) ;
2014-01-16 20:39:13 +00:00
temperatureAxis - > setTickSize ( 2 ) ;
temperatureAxis - > setTickInterval ( 300 ) ;
2014-01-17 17:34:15 +00:00
cylinderPressureAxis - > setOrientation ( DiveCartesianAxis : : BottomToTop ) ;
2014-01-17 16:28:59 +00:00
cylinderPressureAxis - > setTickSize ( 2 ) ;
cylinderPressureAxis - > setTickInterval ( 30000 ) ;
2014-01-15 14:23:40 +00:00
2014-02-16 22:16:39 +00:00
diveComputerText - > setAlignment ( Qt : : AlignRight | Qt : : AlignTop ) ;
2014-03-25 21:34:10 +00:00
diveComputerText - > setBrush ( getColor ( TIME_TEXT , isGrayscale ) ) ;
2014-01-21 12:48:26 +00:00
2014-02-27 19:42:00 +00:00
rulerItem - > setAxis ( timeAxis , profileYAxis ) ;
2014-08-15 00:22:27 +00:00
tankItem - > setHorizontalAxis ( timeAxis ) ;
2014-02-27 19:42:00 +00:00
2014-02-07 16:14:36 +00:00
setupItem ( reportedCeiling , timeAxis , profileYAxis , dataModel , DivePlotDataModel : : CEILING , DivePlotDataModel : : TIME , 1 ) ;
setupItem ( diveCeiling , timeAxis , profileYAxis , dataModel , DivePlotDataModel : : CEILING , DivePlotDataModel : : TIME , 1 ) ;
2014-02-28 04:09:57 +00:00
for ( int i = 0 ; i < 16 ; i + + ) {
2014-01-23 17:02:12 +00:00
DiveCalculatedTissue * tissueItem = new DiveCalculatedTissue ( ) ;
2014-02-28 04:09:57 +00:00
setupItem ( tissueItem , timeAxis , profileYAxis , dataModel , DivePlotDataModel : : TISSUE_1 + i , DivePlotDataModel : : TIME , 1 + i ) ;
2014-01-23 17:02:12 +00:00
allTissues . append ( tissueItem ) ;
2014-09-15 12:09:00 +00:00
DivePercentageItem * percentageItem = new DivePercentageItem ( i ) ;
setupItem ( percentageItem , timeAxis , percentageAxis , dataModel , DivePlotDataModel : : PERCENTAGE_1 + i , DivePlotDataModel : : TIME , 1 + i ) ;
allPercentages . append ( percentageItem ) ;
2014-01-23 17:02:12 +00:00
}
2014-02-07 16:14:36 +00:00
setupItem ( gasPressureItem , timeAxis , cylinderPressureAxis , dataModel , DivePlotDataModel : : TEMPERATURE , DivePlotDataModel : : TIME , 1 ) ;
setupItem ( temperatureItem , timeAxis , temperatureAxis , dataModel , DivePlotDataModel : : TEMPERATURE , DivePlotDataModel : : TIME , 1 ) ;
2014-02-20 01:18:26 +00:00
setupItem ( heartBeatItem , timeAxis , heartBeatAxis , dataModel , DivePlotDataModel : : HEARTBEAT , DivePlotDataModel : : TIME , 1 ) ;
2014-09-15 12:09:00 +00:00
setupItem ( ambPressureItem , timeAxis , percentageAxis , dataModel , DivePlotDataModel : : AMBPRESSURE , DivePlotDataModel : : TIME , 1 ) ;
setupItem ( gflineItem , timeAxis , percentageAxis , dataModel , DivePlotDataModel : : GFLINE , DivePlotDataModel : : TIME , 1 ) ;
2014-02-07 16:14:36 +00:00
setupItem ( diveProfileItem , timeAxis , profileYAxis , dataModel , DivePlotDataModel : : DEPTH , DivePlotDataModel : : TIME , 0 ) ;
2015-01-02 00:28:37 +00:00
setupItem ( meanDepthItem , timeAxis , profileYAxis , dataModel , DivePlotDataModel : : INSTANT_MEANDEPTH , DivePlotDataModel : : TIME , 1 ) ;
2015-01-01 23:28:38 +00:00
2014-01-23 18:03:19 +00:00
2014-02-28 04:09:57 +00:00
# define CREATE_PP_GAS(ITEM, VERTICAL_COLUMN, COLOR, COLOR_ALERT, THRESHOULD_SETTINGS, VISIBILITY_SETTINGS) \
2014-02-07 16:14:36 +00:00
setupItem ( ITEM , timeAxis , gasYAxis , dataModel , DivePlotDataModel : : VERTICAL_COLUMN , DivePlotDataModel : : TIME , 0 ) ; \
2014-02-28 04:09:57 +00:00
ITEM - > setThreshouldSettingsKey ( THRESHOULD_SETTINGS ) ; \
ITEM - > setVisibilitySettingsKey ( VISIBILITY_SETTINGS ) ; \
2014-03-25 21:34:10 +00:00
ITEM - > setColors ( getColor ( COLOR , isGrayscale ) , getColor ( COLOR_ALERT , isGrayscale ) ) ; \
2014-05-22 18:40:22 +00:00
ITEM - > settingsChanged ( ) ; \
2014-02-16 01:01:20 +00:00
ITEM - > setZValue ( 99 ) ;
2014-01-27 17:14:42 +00:00
2014-11-01 16:22:07 +00:00
CREATE_PP_GAS ( pn2GasItem , PN2 , PN2 , PN2_ALERT , & prefs . pp_graphs . pn2_threshold , " pn2graph " ) ;
CREATE_PP_GAS ( pheGasItem , PHE , PHE , PHE_ALERT , & prefs . pp_graphs . phe_threshold , " phegraph " ) ;
CREATE_PP_GAS ( po2GasItem , PO2 , PO2 , PO2_ALERT , & prefs . pp_graphs . po2_threshold , " po2graph " ) ;
2015-01-05 07:20:26 +00:00
CREATE_PP_GAS ( o2SetpointGasItem , O2SETPOINT , PO2_ALERT , PO2_ALERT , & prefs . pp_graphs . po2_threshold , " po2graph " ) ;
2015-01-20 18:13:53 +00:00
CREATE_PP_GAS ( ccrsensor1GasItem , CCRSENSOR1 , CCRSENSOR1 , PO2_ALERT , & prefs . pp_graphs . po2_threshold , " ccrsensorgraph " ) ;
CREATE_PP_GAS ( ccrsensor2GasItem , CCRSENSOR2 , CCRSENSOR2 , PO2_ALERT , & prefs . pp_graphs . po2_threshold , " ccrsensorgraph " ) ;
CREATE_PP_GAS ( ccrsensor3GasItem , CCRSENSOR3 , CCRSENSOR3 , PO2_ALERT , & prefs . pp_graphs . po2_threshold , " ccrsensorgraph " ) ;
2014-01-27 17:14:42 +00:00
# undef CREATE_PP_GAS
2014-01-23 20:03:28 +00:00
2014-02-12 16:24:19 +00:00
temperatureAxis - > setTextVisible ( false ) ;
2014-02-16 00:54:41 +00:00
temperatureAxis - > setLinesVisible ( false ) ;
2014-02-12 16:24:19 +00:00
cylinderPressureAxis - > setTextVisible ( false ) ;
2014-02-16 00:54:41 +00:00
cylinderPressureAxis - > setLinesVisible ( false ) ;
timeAxis - > setLinesVisible ( true ) ;
profileYAxis - > setLinesVisible ( true ) ;
2014-02-28 04:09:57 +00:00
gasYAxis - > setZValue ( timeAxis - > zValue ( ) + 1 ) ;
2014-02-20 01:18:26 +00:00
heartBeatAxis - > setTextVisible ( true ) ;
heartBeatAxis - > setLinesVisible ( true ) ;
2014-09-15 12:09:00 +00:00
percentageAxis - > setTextVisible ( true ) ;
percentageAxis - > setLinesVisible ( true ) ;
2014-12-13 21:06:52 +00:00
replotEnabled = true ;
2014-02-07 16:59:58 +00:00
}
2014-01-15 15:01:29 +00:00
2014-03-09 13:59:31 +00:00
void ProfileWidget2 : : replot ( )
{
2014-12-13 21:06:52 +00:00
if ( ! replotEnabled )
return ;
2014-04-03 19:52:05 +00:00
dataModel - > clear ( ) ;
2014-07-09 18:19:08 +00:00
plotDive ( 0 , true ) ; // simply plot the displayed_dive again
2014-03-09 13:59:31 +00:00
}
2014-02-07 16:59:58 +00:00
void ProfileWidget2 : : setupItemSizes ( )
{
2014-02-07 19:38:00 +00:00
// Scene is *always* (double) 100 / 100.
// Background Config
/* Much probably a better math is needed here.
* good thing is that we only need to change the
* Axis and everything else is auto - adjusted . *
*/
2014-02-07 17:32:39 +00:00
itemPos . background . on . setX ( 0 ) ;
itemPos . background . on . setY ( 0 ) ;
itemPos . background . off . setX ( 0 ) ;
itemPos . background . off . setY ( 110 ) ;
2014-02-07 19:38:00 +00:00
//Depth Axis Config
itemPos . depth . pos . on . setX ( 3 ) ;
itemPos . depth . pos . on . setY ( 3 ) ;
itemPos . depth . pos . off . setX ( - 2 ) ;
itemPos . depth . pos . off . setY ( 3 ) ;
2014-02-28 04:09:57 +00:00
itemPos . depth . expanded . setP1 ( QPointF ( 0 , 0 ) ) ;
2014-09-28 08:11:38 +00:00
itemPos . depth . expanded . setP2 ( QPointF ( 0 , 85 ) ) ;
2014-02-28 04:09:57 +00:00
itemPos . depth . shrinked . setP1 ( QPointF ( 0 , 0 ) ) ;
2014-11-02 18:41:41 +00:00
itemPos . depth . shrinked . setP2 ( QPointF ( 0 , 55 ) ) ;
2014-09-28 08:11:38 +00:00
itemPos . depth . intermediate . setP1 ( QPointF ( 0 , 0 ) ) ;
2014-11-02 18:41:41 +00:00
itemPos . depth . intermediate . setP2 ( QPointF ( 0 , 65 ) ) ;
2014-02-07 19:38:00 +00:00
// Time Axis Config
itemPos . time . pos . on . setX ( 3 ) ;
2014-02-16 22:16:39 +00:00
itemPos . time . pos . on . setY ( 95 ) ;
2014-02-07 19:38:00 +00:00
itemPos . time . pos . off . setX ( 3 ) ;
itemPos . time . pos . off . setY ( 110 ) ;
2014-02-28 04:09:57 +00:00
itemPos . time . expanded . setP1 ( QPointF ( 0 , 0 ) ) ;
itemPos . time . expanded . setP2 ( QPointF ( 94 , 0 ) ) ;
2014-02-07 21:42:47 +00:00
// Partial Gas Axis Config
2014-02-11 18:55:07 +00:00
itemPos . partialPressure . pos . on . setX ( 97 ) ;
2014-09-28 08:11:38 +00:00
itemPos . partialPressure . pos . on . setY ( 75 ) ;
2014-02-11 18:55:07 +00:00
itemPos . partialPressure . pos . off . setX ( 110 ) ;
2014-02-16 01:01:20 +00:00
itemPos . partialPressure . pos . off . setY ( 63 ) ;
2014-02-28 04:09:57 +00:00
itemPos . partialPressure . expanded . setP1 ( QPointF ( 0 , 0 ) ) ;
2014-11-02 18:41:41 +00:00
itemPos . partialPressure . expanded . setP2 ( QPointF ( 0 , 19 ) ) ;
2014-08-15 14:11:14 +00:00
itemPos . partialPressureWithTankBar = itemPos . partialPressure ;
2014-09-28 08:11:38 +00:00
itemPos . partialPressureWithTankBar . expanded . setP2 ( QPointF ( 0 , 17 ) ) ;
itemPos . partialPressureTissue = itemPos . partialPressure ;
itemPos . partialPressureTissue . pos . on . setX ( 97 ) ;
2014-11-02 18:41:41 +00:00
itemPos . partialPressureTissue . pos . on . setY ( 65 ) ;
itemPos . partialPressureTissue . expanded . setP2 ( QPointF ( 0 , 16 ) ) ;
2014-02-07 21:42:47 +00:00
// cylinder axis config
itemPos . cylinder . pos . on . setX ( 3 ) ;
itemPos . cylinder . pos . on . setY ( 20 ) ;
itemPos . cylinder . pos . off . setX ( - 10 ) ;
itemPos . cylinder . pos . off . setY ( 20 ) ;
2014-02-28 04:09:57 +00:00
itemPos . cylinder . expanded . setP1 ( QPointF ( 0 , 15 ) ) ;
itemPos . cylinder . expanded . setP2 ( QPointF ( 0 , 50 ) ) ;
itemPos . cylinder . shrinked . setP1 ( QPointF ( 0 , 0 ) ) ;
itemPos . cylinder . shrinked . setP2 ( QPointF ( 0 , 20 ) ) ;
2014-09-28 08:11:38 +00:00
itemPos . cylinder . intermediate . setP1 ( QPointF ( 0 , 0 ) ) ;
itemPos . cylinder . intermediate . setP2 ( QPointF ( 0 , 20 ) ) ;
2014-02-07 23:17:14 +00:00
2014-02-16 22:16:39 +00:00
// Temperature axis config
2014-02-07 23:17:14 +00:00
itemPos . temperature . pos . on . setX ( 3 ) ;
2014-12-12 19:44:14 +00:00
itemPos . temperature . pos . on . setY ( 60 ) ;
2014-11-02 18:41:41 +00:00
itemPos . temperatureAll . pos . on . setY ( 51 ) ;
2014-02-07 23:17:14 +00:00
itemPos . temperature . pos . off . setX ( - 10 ) ;
itemPos . temperature . pos . off . setY ( 40 ) ;
2014-11-02 18:41:41 +00:00
itemPos . temperature . expanded . setP1 ( QPointF ( 0 , 20 ) ) ;
itemPos . temperature . expanded . setP2 ( QPointF ( 0 , 33 ) ) ;
itemPos . temperature . shrinked . setP1 ( QPointF ( 0 , 2 ) ) ;
itemPos . temperature . shrinked . setP2 ( QPointF ( 0 , 12 ) ) ;
itemPos . temperature . intermediate . setP1 ( QPointF ( 0 , 2 ) ) ;
itemPos . temperature . intermediate . setP2 ( QPointF ( 0 , 12 ) ) ;
2014-02-07 23:17:14 +00:00
2014-09-28 08:11:38 +00:00
// Heartbeat axis config
2014-02-20 01:18:26 +00:00
itemPos . heartBeat . pos . on . setX ( 3 ) ;
2015-01-17 18:54:10 +00:00
itemPos . heartBeat . pos . on . setY ( 82 ) ;
2014-02-28 04:09:57 +00:00
itemPos . heartBeat . expanded . setP1 ( QPointF ( 0 , 0 ) ) ;
2014-09-28 08:11:38 +00:00
itemPos . heartBeat . expanded . setP2 ( QPointF ( 0 , 10 ) ) ;
2015-01-17 18:54:10 +00:00
itemPos . heartBeatWithTankBar = itemPos . heartBeat ;
itemPos . heartBeatWithTankBar . expanded . setP2 ( QPointF ( 0 , 7 ) ) ;
2014-09-15 12:09:00 +00:00
2014-09-28 08:11:38 +00:00
// Percentage axis config
2014-09-15 12:09:00 +00:00
itemPos . percentage . pos . on . setX ( 3 ) ;
2014-09-28 08:11:38 +00:00
itemPos . percentage . pos . on . setY ( 80 ) ;
2014-09-15 12:09:00 +00:00
itemPos . percentage . expanded . setP1 ( QPointF ( 0 , 0 ) ) ;
2014-09-19 06:48:19 +00:00
itemPos . percentage . expanded . setP2 ( QPointF ( 0 , 15 ) ) ;
2014-09-28 08:11:38 +00:00
itemPos . percentageWithTankBar = itemPos . percentage ;
itemPos . percentageWithTankBar . expanded . setP2 ( QPointF ( 0 , 12 ) ) ;
2014-02-20 01:18:26 +00:00
2014-02-07 23:17:14 +00:00
itemPos . dcLabel . on . setX ( 3 ) ;
2014-02-16 22:16:39 +00:00
itemPos . dcLabel . on . setY ( 100 ) ;
2014-02-07 23:17:14 +00:00
itemPos . dcLabel . off . setX ( - 10 ) ;
2014-02-16 22:16:39 +00:00
itemPos . dcLabel . off . setY ( 100 ) ;
2014-08-15 13:30:31 +00:00
itemPos . tankBar . on . setX ( 0 ) ;
2014-09-28 08:11:38 +00:00
itemPos . tankBar . on . setY ( 91.5 ) ;
2014-01-14 16:30:13 +00:00
}
2014-02-07 16:59:58 +00:00
2014-07-21 21:22:44 +00:00
void ProfileWidget2 : : setupItem ( AbstractProfilePolygonItem * item , DiveCartesianAxis * hAxis ,
2015-01-02 00:28:37 +00:00
DiveCartesianAxis * vAxis , DivePlotDataModel * model ,
int vData , int hData , int zValue )
2014-02-07 16:14:36 +00:00
{
2014-02-07 16:59:58 +00:00
item - > setHorizontalAxis ( hAxis ) ;
item - > setVerticalAxis ( vAxis ) ;
item - > setModel ( model ) ;
item - > setVerticalDataColumn ( vData ) ;
item - > setHorizontalDataColumn ( hData ) ;
item - > setZValue ( zValue ) ;
2014-02-07 16:14:36 +00:00
}
2014-02-07 16:59:58 +00:00
void ProfileWidget2 : : setupSceneAndFlags ( )
{
2014-12-18 18:47:00 +00:00
setScene ( new QGraphicsScene ( this ) ) ;
2014-02-07 16:59:58 +00:00
scene ( ) - > setSceneRect ( 0 , 0 , 100 , 100 ) ;
setHorizontalScrollBarPolicy ( Qt : : ScrollBarAlwaysOff ) ;
setVerticalScrollBarPolicy ( Qt : : ScrollBarAlwaysOff ) ;
scene ( ) - > setItemIndexMethod ( QGraphicsScene : : NoIndex ) ;
setOptimizationFlags ( QGraphicsView : : DontSavePainterState ) ;
setViewportUpdateMode ( QGraphicsView : : BoundingRectViewportUpdate ) ;
setRenderHints ( QPainter : : Antialiasing | QPainter : : TextAntialiasing | QPainter : : SmoothPixmapTransform ) ;
setMouseTracking ( true ) ;
background - > setFlag ( QGraphicsItem : : ItemIgnoresTransformations ) ;
}
2014-01-14 16:30:13 +00:00
// Currently just one dive, but the plan is to enable All of the selected dives.
2014-07-09 18:19:08 +00:00
void ProfileWidget2 : : plotDive ( struct dive * d , bool force )
2014-01-14 16:30:13 +00:00
{
2014-03-11 21:54:28 +00:00
static bool firstCall = true ;
2014-06-04 20:41:50 +00:00
QTime measureDuration ; // let's measure how long this takes us (maybe we'll turn of TTL calculation later
measureDuration . start ( ) ;
2014-03-11 21:54:28 +00:00
2014-07-03 21:34:24 +00:00
if ( currentState ! = ADD & & currentState ! = PLAN ) {
if ( ! d ) {
if ( selected_dive = = - 1 )
return ;
d = current_dive ; // display the current dive
}
2014-01-15 15:34:55 +00:00
2014-07-03 21:34:24 +00:00
// No need to do this again if we are already showing the same dive
// computer of the same dive, so we check the unique id of the dive
// and the selected dive computer number against the ones we are
// showing (can't compare the dive pointers as those might change).
2014-07-09 18:19:08 +00:00
if ( d - > id = = displayed_dive . id & & dc_number = = dataModel - > dcShown ( ) & & ! force )
2014-07-03 21:34:24 +00:00
return ;
2014-07-03 03:00:57 +00:00
2014-07-03 21:34:24 +00:00
// this copies the dive and makes copies of all the relevant additional data
copy_dive ( d , & displayed_dive ) ;
} else {
2014-05-22 02:31:26 +00:00
DivePlannerPointsModel * plannerModel = DivePlannerPointsModel : : instance ( ) ;
plannerModel - > createTemporaryPlan ( ) ;
if ( ! plannerModel - > getDiveplan ( ) . dp ) {
plannerModel - > deleteTemporaryPlan ( ) ;
return ;
}
}
2014-07-03 03:00:57 +00:00
// special handling for the first time we display things
2014-07-21 22:10:31 +00:00
int animSpeedBackup = 0 ;
2014-04-03 19:52:05 +00:00
if ( firstCall & & MainWindow : : instance ( ) - > filesFromCommandLine ( ) ) {
2014-07-21 22:10:31 +00:00
animSpeedBackup = prefs . animation_speed ;
prefs . animation_speed = 0 ;
2014-03-11 21:54:28 +00:00
firstCall = false ;
}
2014-03-13 17:23:20 +00:00
// restore default zoom level
2014-03-10 15:59:02 +00:00
if ( zoomLevel ) {
const qreal defScale = 1.0 / qPow ( zoomFactor , ( qreal ) zoomLevel ) ;
scale ( defScale , defScale ) ;
zoomLevel = 0 ;
}
2014-03-25 21:34:12 +00:00
// reset some item visibility on printMode changes
2014-06-17 18:01:15 +00:00
toolTipItem - > setVisible ( ! printMode ) ;
2015-01-28 18:55:55 +00:00
rulerItem - > setVisible ( prefs . rulergraph & & ! printMode & & currentState ! = PLAN & & currentState ! = ADD ) ;
2014-03-25 21:34:12 +00:00
2014-05-13 00:26:12 +00:00
if ( currentState = = EMPTY )
setProfileState ( ) ;
2014-02-26 19:42:55 +00:00
// next get the dive computer structure - if there are no samples
// let's create a fake profile that's somewhat reasonable for the
// data that we have
2014-07-03 03:00:57 +00:00
struct divecomputer * currentdc = select_dc ( & displayed_dive ) ;
2014-01-15 15:34:55 +00:00
Q_ASSERT ( currentdc ) ;
2014-02-26 19:42:55 +00:00
if ( ! currentdc | | ! currentdc - > samples ) {
currentdc = fake_dc ( currentdc ) ;
}
2014-01-15 15:34:55 +00:00
2015-01-23 07:47:33 +00:00
bool setpointflag = ( currentdc - > divemode = = CCR ) & & prefs . pp_graphs . po2 & & current_dive ;
bool sensorflag = setpointflag & & prefs . show_ccr_sensors ;
o2SetpointGasItem - > setVisible ( setpointflag & & prefs . show_ccr_setpoint ) ;
ccrsensor1GasItem - > setVisible ( sensorflag ) ;
ccrsensor2GasItem - > setVisible ( sensorflag & & ( currentdc - > no_o2sensors > 1 ) ) ;
ccrsensor3GasItem - > setVisible ( sensorflag & & ( currentdc - > no_o2sensors > 2 ) ) ;
2015-01-05 07:20:26 +00:00
2014-01-15 15:34:55 +00:00
/* This struct holds all the data that's about to be plotted.
* I ' m not sure this is the best approach ( but since we are
* interpolating some points of the Dive , maybe it is . . . )
* The Calculation of the points should be done per graph ,
* so I ' ll * not * calculate everything if something is not being
* shown .
*/
2015-01-23 19:05:32 +00:00
plotInfo = calculate_max_limits_new ( & displayed_dive , currentdc ) ;
2014-12-04 15:42:00 +00:00
create_plot_info_new ( & displayed_dive , currentdc , & plotInfo , ! shouldCalculateMaxDepth ) ;
2015-01-02 00:28:37 +00:00
if ( shouldCalculateMaxTime )
2014-11-19 22:28:16 +00:00
maxtime = get_maxtime ( & plotInfo ) ;
2014-06-30 22:08:16 +00:00
/* Only update the max depth if it's bigger than the current ones
* when we are dragging the handler to plan / add dive .
* otherwhise , update normally .
*/
2014-11-19 22:28:16 +00:00
int newMaxDepth = get_maxdepth ( & plotInfo ) ;
2015-01-02 00:28:37 +00:00
if ( ! shouldCalculateMaxDepth ) {
2014-06-30 22:08:16 +00:00
if ( maxdepth < newMaxDepth ) {
maxdepth = newMaxDepth ;
}
} else {
maxdepth = newMaxDepth ;
}
2014-01-15 15:34:55 +00:00
2014-11-19 22:28:16 +00:00
dataModel - > setDive ( & displayed_dive , plotInfo ) ;
toolTipItem - > setPlotInfo ( plotInfo ) ;
2014-02-05 16:53:57 +00:00
2014-01-16 17:02:32 +00:00
// It seems that I'll have a lot of boilerplate setting the model / axis for
// each item, I'll mostly like to fix this in the future, but I'll keep at this for now.
2014-01-18 22:33:12 +00:00
profileYAxis - > setMaximum ( maxdepth ) ;
2014-01-15 15:34:55 +00:00
profileYAxis - > updateTicks ( ) ;
2014-02-07 19:59:21 +00:00
2014-11-19 22:28:16 +00:00
temperatureAxis - > setMinimum ( plotInfo . mintemp ) ;
2014-12-10 22:48:19 +00:00
temperatureAxis - > setMaximum ( plotInfo . maxtemp - plotInfo . mintemp > 2000 ? plotInfo . maxtemp : plotInfo . mintemp + 2000 ) ;
2014-02-20 01:18:26 +00:00
2014-11-19 22:28:16 +00:00
if ( plotInfo . maxhr ) {
heartBeatAxis - > setMinimum ( plotInfo . minhr ) ;
heartBeatAxis - > setMaximum ( plotInfo . maxhr ) ;
2014-07-21 22:32:46 +00:00
heartBeatAxis - > updateTicks ( HR_AXIS ) ; // this shows the ticks
2014-02-23 22:32:25 +00:00
}
2014-11-19 22:28:16 +00:00
heartBeatAxis - > setVisible ( prefs . hrgraph & & plotInfo . maxhr ) ;
2014-07-21 22:32:46 +00:00
2014-09-15 12:09:00 +00:00
percentageAxis - > setMinimum ( 0 ) ;
percentageAxis - > setMaximum ( 100 ) ;
percentageAxis - > setVisible ( false ) ;
percentageAxis - > updateTicks ( HR_AXIS ) ;
2014-01-15 20:03:58 +00:00
timeAxis - > setMaximum ( maxtime ) ;
2014-01-27 19:09:08 +00:00
int i , incr ;
2014-02-28 04:09:57 +00:00
static int increments [ 8 ] = { 10 , 20 , 30 , 60 , 5 * 60 , 10 * 60 , 15 * 60 , 30 * 60 } ;
2014-01-27 19:09:08 +00:00
/* Time markers: at most every 10 seconds, but no more than 12 markers.
* We start out with 10 seconds and increment up to 30 minutes ,
* depending on the dive time .
* This allows for 6 h dives - enough ( I hope ) for even the craziest
* divers - but just in case , for those 8 h depth - record - breaking dives ,
* we double the interval if this still doesn ' t get us to 12 or fewer
* time markers */
i = 0 ;
while ( i < 7 & & maxtime / increments [ i ] > 12 )
i + + ;
incr = increments [ i ] ;
while ( maxtime / incr > 12 )
incr * = 2 ;
timeAxis - > setTickInterval ( incr ) ;
2014-01-15 15:34:55 +00:00
timeAxis - > updateTicks ( ) ;
2014-11-19 22:28:16 +00:00
cylinderPressureAxis - > setMinimum ( plotInfo . minpressure ) ;
cylinderPressureAxis - > setMaximum ( plotInfo . maxpressure ) ;
2014-03-07 15:08:31 +00:00
2014-11-19 22:28:16 +00:00
rulerItem - > setPlotInfo ( plotInfo ) ;
tankItem - > setData ( dataModel , & plotInfo , & displayed_dive ) ;
2014-01-23 19:54:34 +00:00
2014-01-27 17:14:42 +00:00
dataModel - > emitDataChanged ( ) ;
2014-01-23 18:12:18 +00:00
// The event items are a bit special since we don't know how many events are going to
// exist on a dive, so I cant create cache items for that. that's why they are here
// while all other items are up there on the constructor.
2014-01-16 17:02:32 +00:00
qDeleteAll ( eventItems ) ;
eventItems . clear ( ) ;
struct event * event = currentdc - > events ;
while ( event ) {
DiveEventItem * item = new DiveEventItem ( ) ;
item - > setHorizontalAxis ( timeAxis ) ;
item - > setVerticalAxis ( profileYAxis ) ;
item - > setModel ( dataModel ) ;
item - > setEvent ( event ) ;
2014-01-19 22:16:08 +00:00
item - > setZValue ( 2 ) ;
2014-01-16 17:02:32 +00:00
scene ( ) - > addItem ( item ) ;
eventItems . push_back ( item ) ;
event = event - > next ;
}
2014-03-17 15:14:58 +00:00
// Only set visible the events that should be visible
2014-05-22 18:40:22 +00:00
Q_FOREACH ( DiveEventItem * event , eventItems ) {
2014-03-16 22:10:03 +00:00
event - > setVisible ( ! event - > shouldBeHidden ( ) ) ;
2014-02-23 16:33:58 +00:00
}
2014-06-29 15:31:37 +00:00
QString dcText = get_dc_nickname ( currentdc - > model , currentdc - > deviceid ) ;
2014-05-19 05:29:43 +00:00
int nr ;
2014-07-03 21:34:24 +00:00
if ( ( nr = number_of_computers ( & displayed_dive ) ) > 1 )
2014-05-19 05:29:43 +00:00
dcText + = tr ( " (#%1 of %2) " ) . arg ( dc_number + 1 ) . arg ( nr ) ;
2015-01-23 18:54:16 +00:00
if ( dcText . isEmpty ( ) )
dcText = tr ( " Unknown dive computer " ) ;
2014-05-19 05:29:43 +00:00
diveComputerText - > setText ( dcText ) ;
2014-07-21 22:10:31 +00:00
if ( MainWindow : : instance ( ) - > filesFromCommandLine ( ) & & animSpeedBackup ! = 0 ) {
prefs . animation_speed = animSpeedBackup ;
2014-03-11 21:54:28 +00:00
}
2014-05-22 02:31:26 +00:00
2014-05-25 20:49:26 +00:00
if ( currentState = = ADD | | currentState = = PLAN ) { // TODO: figure a way to move this from here.
2014-05-22 02:31:26 +00:00
repositionDiveHandlers ( ) ;
DivePlannerPointsModel * model = DivePlannerPointsModel : : instance ( ) ;
model - > deleteTemporaryPlan ( ) ;
}
2014-07-21 21:54:28 +00:00
plotPictures ( ) ;
2014-06-04 20:41:50 +00:00
// OK, how long did this take us? Anything above the second is way too long,
// so if we are calculation TTS / NDL then let's force that off.
if ( measureDuration . elapsed ( ) > 1000 & & prefs . calcndltts ) {
MainWindow : : instance ( ) - > turnOffNdlTts ( ) ;
2015-02-27 00:57:56 +00:00
MainWindow : : instance ( ) - > getNotificationWidget ( ) - > showNotification ( tr ( " Show NDL / TTS was disabled because of excessive processing time " ) , KMessageWidget : : Error ) ;
2014-06-04 20:41:50 +00:00
}
2014-01-14 16:30:13 +00:00
}
2015-01-30 10:16:55 +00:00
void ProfileWidget2 : : recalcCeiling ( )
{
diveCeiling - > recalc ( ) ;
}
2014-01-14 16:30:13 +00:00
void ProfileWidget2 : : settingsChanged ( )
{
2014-05-05 22:58:25 +00:00
// if we are showing calculated ceilings then we have to replot()
// because the GF could have changed; otherwise we try to avoid replot()
bool needReplot = prefs . calcceiling ;
2015-01-17 18:54:10 +00:00
if ( ( prefs . percentagegraph | | prefs . hrgraph ) & & PP_GRAPHS_ENABLED ) {
2014-02-12 15:50:35 +00:00
profileYAxis - > animateChangeLine ( itemPos . depth . shrinked ) ;
2014-11-02 18:41:41 +00:00
temperatureAxis - > setPos ( itemPos . temperatureAll . pos . on ) ;
2014-02-12 16:08:01 +00:00
temperatureAxis - > animateChangeLine ( itemPos . temperature . shrinked ) ;
2014-02-12 16:12:56 +00:00
cylinderPressureAxis - > animateChangeLine ( itemPos . cylinder . shrinked ) ;
2014-09-28 08:11:38 +00:00
if ( prefs . tankbar ) {
percentageAxis - > setPos ( itemPos . percentageWithTankBar . pos . on ) ;
percentageAxis - > animateChangeLine ( itemPos . percentageWithTankBar . expanded ) ;
2015-01-17 18:54:10 +00:00
heartBeatAxis - > setPos ( itemPos . heartBeatWithTankBar . pos . on ) ;
heartBeatAxis - > animateChangeLine ( itemPos . heartBeatWithTankBar . expanded ) ;
} else {
2014-09-28 08:11:38 +00:00
percentageAxis - > setPos ( itemPos . percentage . pos . on ) ;
2015-01-17 18:54:10 +00:00
percentageAxis - > animateChangeLine ( itemPos . percentage . expanded ) ;
heartBeatAxis - > setPos ( itemPos . heartBeat . pos . on ) ;
heartBeatAxis - > animateChangeLine ( itemPos . heartBeat . expanded ) ;
2014-09-28 08:11:38 +00:00
}
gasYAxis - > setPos ( itemPos . partialPressureTissue . pos . on ) ;
gasYAxis - > animateChangeLine ( itemPos . partialPressureTissue . expanded ) ;
2015-01-17 18:54:10 +00:00
2014-12-10 22:49:12 +00:00
} else if ( PP_GRAPHS_ENABLED | | prefs . hrgraph | | prefs . percentagegraph ) {
2014-09-28 08:11:38 +00:00
profileYAxis - > animateChangeLine ( itemPos . depth . intermediate ) ;
2014-11-02 18:41:41 +00:00
temperatureAxis - > setPos ( itemPos . temperature . pos . on ) ;
2014-09-28 08:11:38 +00:00
temperatureAxis - > animateChangeLine ( itemPos . temperature . intermediate ) ;
cylinderPressureAxis - > animateChangeLine ( itemPos . cylinder . intermediate ) ;
if ( prefs . tankbar ) {
percentageAxis - > setPos ( itemPos . percentageWithTankBar . pos . on ) ;
percentageAxis - > animateChangeLine ( itemPos . percentageWithTankBar . expanded ) ;
gasYAxis - > setPos ( itemPos . partialPressureWithTankBar . pos . on ) ;
gasYAxis - > setLine ( itemPos . partialPressureWithTankBar . expanded ) ;
2015-01-17 18:54:10 +00:00
heartBeatAxis - > setPos ( itemPos . heartBeatWithTankBar . pos . on ) ;
heartBeatAxis - > animateChangeLine ( itemPos . heartBeatWithTankBar . expanded ) ;
2014-12-10 22:49:12 +00:00
} else {
2014-09-28 08:11:38 +00:00
gasYAxis - > setPos ( itemPos . partialPressure . pos . on ) ;
gasYAxis - > animateChangeLine ( itemPos . partialPressure . expanded ) ;
percentageAxis - > setPos ( itemPos . percentage . pos . on ) ;
percentageAxis - > setLine ( itemPos . percentage . expanded ) ;
2015-01-17 18:54:10 +00:00
heartBeatAxis - > setPos ( itemPos . heartBeat . pos . on ) ;
heartBeatAxis - > animateChangeLine ( itemPos . heartBeat . expanded ) ;
2014-09-28 08:11:38 +00:00
}
2014-02-28 04:09:57 +00:00
} else {
2014-02-12 15:50:35 +00:00
profileYAxis - > animateChangeLine ( itemPos . depth . expanded ) ;
2014-12-12 19:44:14 +00:00
if ( prefs . tankbar ) {
temperatureAxis - > setPos ( itemPos . temperatureAll . pos . on ) ;
} else {
temperatureAxis - > setPos ( itemPos . temperature . pos . on ) ;
}
2014-02-12 16:08:01 +00:00
temperatureAxis - > animateChangeLine ( itemPos . temperature . expanded ) ;
2014-02-12 16:12:56 +00:00
cylinderPressureAxis - > animateChangeLine ( itemPos . cylinder . expanded ) ;
2014-02-12 15:50:35 +00:00
}
2014-09-28 08:11:38 +00:00
2014-08-21 12:52:14 +00:00
tankItem - > setVisible ( prefs . tankbar ) ;
2014-04-16 20:03:44 +00:00
if ( prefs . zoomed_plot ! = isPlotZoomed ) {
isPlotZoomed = prefs . zoomed_plot ;
2014-05-05 22:58:25 +00:00
needReplot = true ;
2014-02-27 15:39:53 +00:00
}
2014-05-05 22:58:25 +00:00
if ( needReplot )
replot ( ) ;
2014-01-14 16:30:13 +00:00
}
2014-02-28 04:09:57 +00:00
void ProfileWidget2 : : resizeEvent ( QResizeEvent * event )
2014-01-14 16:30:13 +00:00
{
2014-02-11 04:45:08 +00:00
QGraphicsView : : resizeEvent ( event ) ;
2014-01-15 14:55:33 +00:00
fitInView ( sceneRect ( ) , Qt : : IgnoreAspectRatio ) ;
2014-02-07 18:34:42 +00:00
fixBackgroundPos ( ) ;
2014-01-15 14:55:33 +00:00
}
2014-05-26 20:51:46 +00:00
void ProfileWidget2 : : mousePressEvent ( QMouseEvent * event )
{
2015-03-11 01:23:45 +00:00
if ( zoomLevel )
return ;
2014-05-26 20:51:46 +00:00
QGraphicsView : : mousePressEvent ( event ) ;
2015-01-02 00:28:37 +00:00
if ( currentState = = PLAN )
2014-05-26 20:51:46 +00:00
shouldCalculateMaxTime = false ;
}
2014-06-30 22:08:16 +00:00
void ProfileWidget2 : : divePlannerHandlerClicked ( )
{
2015-03-11 01:23:45 +00:00
if ( zoomLevel )
return ;
2014-06-30 22:08:16 +00:00
shouldCalculateMaxDepth = false ;
replot ( ) ;
}
void ProfileWidget2 : : divePlannerHandlerReleased ( )
{
2015-03-11 01:23:45 +00:00
if ( zoomLevel )
return ;
2014-06-30 22:08:16 +00:00
shouldCalculateMaxDepth = true ;
replot ( ) ;
}
2014-05-26 20:51:46 +00:00
void ProfileWidget2 : : mouseReleaseEvent ( QMouseEvent * event )
{
2015-03-11 01:23:45 +00:00
if ( zoomLevel )
return ;
2014-05-26 20:51:46 +00:00
QGraphicsView : : mouseReleaseEvent ( event ) ;
2015-01-02 00:28:37 +00:00
if ( currentState = = PLAN ) {
2014-05-26 20:51:46 +00:00
shouldCalculateMaxTime = true ;
replot ( ) ;
}
}
2014-01-15 14:55:33 +00:00
void ProfileWidget2 : : fixBackgroundPos ( )
{
2014-05-28 18:43:32 +00:00
static QPixmap toBeScaled ( backgroundFile ) ;
2014-02-28 04:09:57 +00:00
if ( currentState ! = EMPTY )
2014-02-07 21:42:47 +00:00
return ;
2014-03-10 15:59:01 +00:00
QPixmap p = toBeScaled . scaledToHeight ( viewport ( ) - > height ( ) - 40 , Qt : : SmoothTransformation ) ;
2014-01-16 04:50:56 +00:00
int x = viewport ( ) - > width ( ) / 2 - p . width ( ) / 2 ;
2014-03-10 15:59:01 +00:00
int y = viewport ( ) - > height ( ) / 2 - p . height ( ) / 2 ;
2014-02-07 17:32:39 +00:00
background - > setPixmap ( p ) ;
background - > setX ( mapToScene ( x , 0 ) . x ( ) ) ;
2014-03-10 15:59:01 +00:00
background - > setY ( mapToScene ( y , 20 ) . y ( ) ) ;
2014-01-14 16:30:13 +00:00
}
2014-02-04 23:47:50 +00:00
2014-02-28 04:09:57 +00:00
void ProfileWidget2 : : wheelEvent ( QWheelEvent * event )
2014-02-04 23:47:50 +00:00
{
2014-03-10 15:59:01 +00:00
if ( currentState = = EMPTY )
return ;
2014-02-05 16:34:45 +00:00
QPoint toolTipPos = mapFromScene ( toolTipItem - > pos ( ) ) ;
2015-01-02 00:28:37 +00:00
if ( event - > buttons ( ) = = Qt : : LeftButton )
2014-08-06 11:51:54 +00:00
return ;
2014-02-04 23:47:50 +00:00
if ( event - > delta ( ) > 0 & & zoomLevel < 20 ) {
2014-03-10 15:59:02 +00:00
scale ( zoomFactor , zoomFactor ) ;
2014-02-04 23:47:50 +00:00
zoomLevel + + ;
} else if ( event - > delta ( ) < 0 & & zoomLevel > 0 ) {
// Zooming out
2014-03-10 15:59:02 +00:00
scale ( 1.0 / zoomFactor , 1.0 / zoomFactor ) ;
2014-02-04 23:47:50 +00:00
zoomLevel - - ;
}
scrollViewTo ( event - > pos ( ) ) ;
2014-02-05 16:34:45 +00:00
toolTipItem - > setPos ( mapToScene ( toolTipPos ) ) ;
2014-02-04 23:47:50 +00:00
}
2014-05-21 18:52:24 +00:00
void ProfileWidget2 : : mouseDoubleClickEvent ( QMouseEvent * event )
{
if ( currentState = = PLAN | | currentState = = ADD ) {
DivePlannerPointsModel * plannerModel = DivePlannerPointsModel : : instance ( ) ;
QPointF mappedPos = mapToScene ( event - > pos ( ) ) ;
if ( isPointOutOfBoundaries ( mappedPos ) )
return ;
int minutes = rint ( timeAxis - > valueAt ( mappedPos ) / 60 ) ;
int milimeters = rint ( profileYAxis - > valueAt ( mappedPos ) / M_OR_FT ( 1 , 1 ) ) * M_OR_FT ( 1 , 1 ) ;
2014-06-02 19:36:05 +00:00
plannerModel - > addStop ( milimeters , minutes * 60 , 0 , 0 , true ) ;
2014-05-21 18:52:24 +00:00
}
}
bool ProfileWidget2 : : isPointOutOfBoundaries ( const QPointF & point ) const
{
double xpos = timeAxis - > valueAt ( point ) ;
double ypos = profileYAxis - > valueAt ( point ) ;
return ( xpos > timeAxis - > maximum ( ) | |
xpos < timeAxis - > minimum ( ) | |
ypos > profileYAxis - > maximum ( ) | |
ypos < profileYAxis - > minimum ( ) ) ;
}
2014-02-28 04:09:57 +00:00
void ProfileWidget2 : : scrollViewTo ( const QPoint & pos )
2014-02-04 23:47:50 +00:00
{
2014-02-28 04:09:57 +00:00
/* since we cannot use translate() directly on the scene we hack on
2014-02-04 23:47:50 +00:00
* the scroll bars ( hidden ) functionality */
2014-03-10 15:59:01 +00:00
if ( ! zoomLevel | | currentState = = EMPTY )
2014-02-04 23:47:50 +00:00
return ;
QScrollBar * vs = verticalScrollBar ( ) ;
QScrollBar * hs = horizontalScrollBar ( ) ;
2014-02-05 16:57:02 +00:00
const qreal yRat = ( qreal ) pos . y ( ) / viewport ( ) - > height ( ) ;
const qreal xRat = ( qreal ) pos . x ( ) / viewport ( ) - > width ( ) ;
vs - > setValue ( yRat * vs - > maximum ( ) ) ;
hs - > setValue ( xRat * hs - > maximum ( ) ) ;
2014-02-04 23:47:50 +00:00
}
2014-02-28 04:09:57 +00:00
void ProfileWidget2 : : mouseMoveEvent ( QMouseEvent * event )
2014-02-04 23:47:50 +00:00
{
2015-01-14 16:41:56 +00:00
QPointF pos = mapToScene ( event - > pos ( ) ) ;
toolTipItem - > refresh ( pos ) ;
2014-02-04 23:47:50 +00:00
if ( zoomLevel = = 0 ) {
QGraphicsView : : mouseMoveEvent ( event ) ;
2014-02-05 16:34:45 +00:00
} else {
2015-01-14 16:41:56 +00:00
QPoint toolTipPos = mapFromScene ( toolTipItem - > pos ( ) ) ;
2014-02-04 23:47:50 +00:00
scrollViewTo ( event - > pos ( ) ) ;
2014-02-07 23:38:06 +00:00
toolTipItem - > setPos ( mapToScene ( toolTipPos ) ) ;
2014-02-04 23:47:50 +00:00
}
2014-08-05 21:27:00 +00:00
qreal vValue = profileYAxis - > valueAt ( pos ) ;
qreal hValue = timeAxis - > valueAt ( pos ) ;
2015-01-02 00:28:37 +00:00
if ( profileYAxis - > maximum ( ) > = vValue & & profileYAxis - > minimum ( ) < = vValue ) {
2014-08-05 21:27:00 +00:00
mouseFollowerHorizontal - > setPos ( timeAxis - > pos ( ) . x ( ) , pos . y ( ) ) ;
}
2015-01-02 00:28:37 +00:00
if ( timeAxis - > maximum ( ) > = hValue & & timeAxis - > minimum ( ) < = hValue ) {
2014-08-05 21:27:00 +00:00
mouseFollowerVertical - > setPos ( pos . x ( ) , profileYAxis - > line ( ) . y1 ( ) ) ;
}
2014-02-04 23:47:50 +00:00
}
2014-02-05 18:15:59 +00:00
bool ProfileWidget2 : : eventFilter ( QObject * object , QEvent * event )
{
2014-02-28 04:09:57 +00:00
QGraphicsScene * s = qobject_cast < QGraphicsScene * > ( object ) ;
if ( s & & event - > type ( ) = = QEvent : : GraphicsSceneHelp ) {
2014-02-05 18:15:59 +00:00
event - > ignore ( ) ;
return true ;
}
return QGraphicsView : : eventFilter ( object , event ) ;
}
2014-02-07 18:34:42 +00:00
void ProfileWidget2 : : setEmptyState ( )
{
// Then starting Empty State, move the background up.
if ( currentState = = EMPTY )
return ;
2014-05-22 00:23:19 +00:00
disconnectTemporaryConnections ( ) ;
2014-05-21 23:34:06 +00:00
setBackgroundBrush ( getColor ( : : BACKGROUND , isGrayscale ) ) ;
2014-02-10 16:41:59 +00:00
dataModel - > clear ( ) ;
2014-02-07 18:34:42 +00:00
currentState = EMPTY ;
2014-08-23 01:26:07 +00:00
MainWindow : : instance ( ) - > setEnabledToolbar ( false ) ;
2014-03-10 15:59:01 +00:00
2014-02-07 18:34:42 +00:00
fixBackgroundPos ( ) ;
2014-02-10 17:01:04 +00:00
background - > setVisible ( true ) ;
2014-03-10 15:59:01 +00:00
profileYAxis - > setVisible ( false ) ;
gasYAxis - > setVisible ( false ) ;
timeAxis - > setVisible ( false ) ;
temperatureAxis - > setVisible ( false ) ;
cylinderPressureAxis - > setVisible ( false ) ;
2014-02-07 18:34:42 +00:00
toolTipItem - > setVisible ( false ) ;
diveComputerText - > setVisible ( false ) ;
diveCeiling - > setVisible ( false ) ;
reportedCeiling - > setVisible ( false ) ;
2014-02-27 18:20:03 +00:00
rulerItem - > setVisible ( false ) ;
2014-08-15 00:22:27 +00:00
tankItem - > setVisible ( false ) ;
2014-03-18 18:08:23 +00:00
pn2GasItem - > setVisible ( false ) ;
po2GasItem - > setVisible ( false ) ;
2015-01-05 07:20:26 +00:00
o2SetpointGasItem - > setVisible ( false ) ;
2015-01-20 18:13:53 +00:00
ccrsensor1GasItem - > setVisible ( false ) ;
ccrsensor2GasItem - > setVisible ( false ) ;
ccrsensor3GasItem - > setVisible ( false ) ;
2014-03-18 18:08:23 +00:00
pheGasItem - > setVisible ( false ) ;
2014-09-15 12:09:00 +00:00
ambPressureItem - > setVisible ( false ) ;
gflineItem - > setVisible ( false ) ;
2014-08-05 21:27:00 +00:00
mouseFollowerHorizontal - > setVisible ( false ) ;
mouseFollowerVertical - > setVisible ( false ) ;
2014-05-28 18:43:32 +00:00
2015-01-02 00:28:37 +00:00
# define HIDE_ALL(TYPE, CONTAINER) \
2014-05-28 18:43:32 +00:00
Q_FOREACH ( TYPE * item , CONTAINER ) item - > setVisible ( false ) ;
HIDE_ALL ( DiveCalculatedTissue , allTissues ) ;
2014-09-15 12:09:00 +00:00
HIDE_ALL ( DivePercentageItem , allPercentages ) ;
2014-05-28 18:43:32 +00:00
HIDE_ALL ( DiveEventItem , eventItems ) ;
HIDE_ALL ( DiveHandler , handles ) ;
HIDE_ALL ( QGraphicsSimpleTextItem , gases ) ;
2015-01-02 00:28:37 +00:00
# undef HIDE_ALL
2014-02-07 18:34:42 +00:00
}
void ProfileWidget2 : : setProfileState ( )
{
2014-02-07 18:54:12 +00:00
// Then starting Empty State, move the background up.
if ( currentState = = PROFILE )
return ;
2014-02-07 18:34:42 +00:00
2014-05-22 00:23:19 +00:00
disconnectTemporaryConnections ( ) ;
2014-06-03 22:09:12 +00:00
connect ( DivePictureModel : : instance ( ) , SIGNAL ( dataChanged ( QModelIndex , QModelIndex ) ) , this , SLOT ( plotPictures ( ) ) ) ;
2015-01-02 00:28:37 +00:00
connect ( DivePictureModel : : instance ( ) , SIGNAL ( rowsInserted ( const QModelIndex & , int , int ) ) , this , SLOT ( plotPictures ( ) ) ) ;
connect ( DivePictureModel : : instance ( ) , SIGNAL ( rowsRemoved ( const QModelIndex & , int , int ) ) , this , SLOT ( plotPictures ( ) ) ) ;
2014-06-03 22:09:12 +00:00
/* show the same stuff that the profile shows. */
2014-05-24 15:39:40 +00:00
//TODO: Move the DC handling to another method.
2015-02-03 15:30:08 +00:00
MainWindow : : instance ( ) - > enableShortcuts ( ) ;
2014-05-24 15:39:40 +00:00
2014-02-07 18:54:12 +00:00
currentState = PROFILE ;
2014-08-23 01:26:07 +00:00
MainWindow : : instance ( ) - > setEnabledToolbar ( true ) ;
2014-03-09 14:08:01 +00:00
toolTipItem - > readPos ( ) ;
2014-03-25 21:34:10 +00:00
setBackgroundBrush ( getColor ( : : BACKGROUND , isGrayscale ) ) ;
2014-02-07 19:38:00 +00:00
2014-02-07 21:42:47 +00:00
background - > setVisible ( false ) ;
2014-02-07 18:54:12 +00:00
toolTipItem - > setVisible ( true ) ;
2014-03-10 15:59:01 +00:00
profileYAxis - > setVisible ( true ) ;
gasYAxis - > setVisible ( true ) ;
timeAxis - > setVisible ( true ) ;
temperatureAxis - > setVisible ( true ) ;
cylinderPressureAxis - > setVisible ( true ) ;
2014-02-07 19:38:00 +00:00
2014-02-07 21:42:47 +00:00
profileYAxis - > setPos ( itemPos . depth . pos . on ) ;
2015-01-17 18:54:10 +00:00
if ( ( prefs . percentagegraph | | prefs . hrgraph ) & & PP_GRAPHS_ENABLED ) {
2014-09-28 08:11:38 +00:00
profileYAxis - > animateChangeLine ( itemPos . depth . shrinked ) ;
2014-11-02 18:41:41 +00:00
temperatureAxis - > setPos ( itemPos . temperatureAll . pos . on ) ;
2014-09-28 08:11:38 +00:00
temperatureAxis - > animateChangeLine ( itemPos . temperature . shrinked ) ;
cylinderPressureAxis - > animateChangeLine ( itemPos . cylinder . shrinked ) ;
if ( prefs . tankbar ) {
percentageAxis - > setPos ( itemPos . percentageWithTankBar . pos . on ) ;
percentageAxis - > animateChangeLine ( itemPos . percentageWithTankBar . expanded ) ;
2015-01-17 18:54:10 +00:00
heartBeatAxis - > setPos ( itemPos . heartBeatWithTankBar . pos . on ) ;
heartBeatAxis - > animateChangeLine ( itemPos . heartBeatWithTankBar . expanded ) ;
} else {
2014-09-28 08:11:38 +00:00
percentageAxis - > setPos ( itemPos . percentage . pos . on ) ;
2015-01-17 18:54:10 +00:00
percentageAxis - > animateChangeLine ( itemPos . percentage . expanded ) ;
heartBeatAxis - > setPos ( itemPos . heartBeat . pos . on ) ;
heartBeatAxis - > animateChangeLine ( itemPos . heartBeat . expanded ) ;
2014-09-28 08:11:38 +00:00
}
gasYAxis - > setPos ( itemPos . partialPressureTissue . pos . on ) ;
gasYAxis - > animateChangeLine ( itemPos . partialPressureTissue . expanded ) ;
2015-01-17 18:54:10 +00:00
2014-12-10 22:49:12 +00:00
} else if ( PP_GRAPHS_ENABLED | | prefs . hrgraph | | prefs . percentagegraph ) {
2014-09-28 08:11:38 +00:00
profileYAxis - > animateChangeLine ( itemPos . depth . intermediate ) ;
2014-11-02 18:41:41 +00:00
temperatureAxis - > setPos ( itemPos . temperature . pos . on ) ;
2014-09-28 08:11:38 +00:00
temperatureAxis - > animateChangeLine ( itemPos . temperature . intermediate ) ;
cylinderPressureAxis - > animateChangeLine ( itemPos . cylinder . intermediate ) ;
if ( prefs . tankbar ) {
percentageAxis - > setPos ( itemPos . percentageWithTankBar . pos . on ) ;
percentageAxis - > animateChangeLine ( itemPos . percentageWithTankBar . expanded ) ;
gasYAxis - > setPos ( itemPos . partialPressureWithTankBar . pos . on ) ;
gasYAxis - > setLine ( itemPos . partialPressureWithTankBar . expanded ) ;
2015-01-17 18:54:10 +00:00
heartBeatAxis - > setPos ( itemPos . heartBeatWithTankBar . pos . on ) ;
heartBeatAxis - > animateChangeLine ( itemPos . heartBeatWithTankBar . expanded ) ;
2014-12-10 22:49:12 +00:00
} else {
2014-09-28 08:11:38 +00:00
gasYAxis - > setPos ( itemPos . partialPressure . pos . on ) ;
gasYAxis - > animateChangeLine ( itemPos . partialPressure . expanded ) ;
percentageAxis - > setPos ( itemPos . percentage . pos . on ) ;
percentageAxis - > setLine ( itemPos . percentage . expanded ) ;
2015-01-17 18:54:10 +00:00
heartBeatAxis - > setPos ( itemPos . heartBeat . pos . on ) ;
heartBeatAxis - > animateChangeLine ( itemPos . heartBeat . expanded ) ;
2014-09-28 08:11:38 +00:00
}
2014-02-28 04:09:57 +00:00
} else {
2014-09-28 08:11:38 +00:00
profileYAxis - > animateChangeLine ( itemPos . depth . expanded ) ;
2014-12-12 19:44:14 +00:00
if ( prefs . tankbar ) {
temperatureAxis - > setPos ( itemPos . temperatureAll . pos . on ) ;
} else {
temperatureAxis - > setPos ( itemPos . temperature . pos . on ) ;
}
2014-09-28 08:11:38 +00:00
temperatureAxis - > animateChangeLine ( itemPos . temperature . expanded ) ;
cylinderPressureAxis - > animateChangeLine ( itemPos . cylinder . expanded ) ;
2014-02-07 21:42:47 +00:00
}
2014-04-16 20:03:44 +00:00
pn2GasItem - > setVisible ( prefs . pp_graphs . pn2 ) ;
po2GasItem - > setVisible ( prefs . pp_graphs . po2 ) ;
pheGasItem - > setVisible ( prefs . pp_graphs . phe ) ;
2015-01-23 07:47:33 +00:00
2015-01-24 22:42:25 +00:00
bool setpointflag = current_dive & & ( current_dc - > divemode = = CCR ) & & prefs . pp_graphs . po2 ;
2015-01-23 07:47:33 +00:00
bool sensorflag = setpointflag & & prefs . show_ccr_sensors ;
o2SetpointGasItem - > setVisible ( setpointflag & & prefs . show_ccr_setpoint ) ;
ccrsensor1GasItem - > setVisible ( sensorflag ) ;
ccrsensor2GasItem - > setVisible ( sensorflag & & ( current_dc - > no_o2sensors > 1 ) ) ;
ccrsensor3GasItem - > setVisible ( sensorflag & & ( current_dc - > no_o2sensors > 2 ) ) ;
2014-02-07 21:42:47 +00:00
timeAxis - > setPos ( itemPos . time . pos . on ) ;
2014-02-07 19:38:00 +00:00
timeAxis - > setLine ( itemPos . time . expanded ) ;
2014-02-07 21:42:47 +00:00
cylinderPressureAxis - > setPos ( itemPos . cylinder . pos . on ) ;
2014-04-16 20:03:44 +00:00
heartBeatItem - > setVisible ( prefs . hrgraph ) ;
2015-01-02 00:28:37 +00:00
meanDepthItem - > setVisible ( prefs . show_average_depth ) ;
2014-02-07 23:28:59 +00:00
2014-02-07 23:17:14 +00:00
diveComputerText - > setVisible ( true ) ;
2014-02-07 23:28:59 +00:00
diveComputerText - > setPos ( itemPos . dcLabel . on ) ;
2014-04-16 20:03:44 +00:00
diveCeiling - > setVisible ( prefs . calcceiling ) ;
reportedCeiling - > setVisible ( prefs . dcceiling ) ;
2014-02-07 23:28:59 +00:00
2014-04-16 20:03:44 +00:00
if ( prefs . calcalltissues ) {
2014-05-22 18:40:22 +00:00
Q_FOREACH ( DiveCalculatedTissue * tissue , allTissues ) {
2014-02-07 23:28:59 +00:00
tissue - > setVisible ( true ) ;
}
}
2014-09-28 08:11:38 +00:00
2014-09-15 12:09:00 +00:00
if ( prefs . percentagegraph ) {
Q_FOREACH ( DivePercentageItem * percentage , allPercentages ) {
percentage - > setVisible ( true ) ;
}
ambPressureItem - > setVisible ( true ) ;
2014-09-28 08:11:38 +00:00
gflineItem - > setVisible ( true ) ;
}
2014-09-15 12:09:00 +00:00
2014-05-21 15:57:48 +00:00
rulerItem - > setVisible ( prefs . rulergraph ) ;
2014-08-15 14:11:14 +00:00
tankItem - > setVisible ( prefs . tankbar ) ;
2014-08-15 13:30:31 +00:00
tankItem - > setPos ( itemPos . tankBar . on ) ;
2015-01-02 00:28:37 +00:00
# define HIDE_ALL(TYPE, CONTAINER) \
2014-05-30 02:42:55 +00:00
Q_FOREACH ( TYPE * item , CONTAINER ) item - > setVisible ( false ) ;
HIDE_ALL ( DiveHandler , handles ) ;
HIDE_ALL ( QGraphicsSimpleTextItem , gases ) ;
2015-01-02 00:28:37 +00:00
# undef HIDE_ALL
2014-08-06 19:33:36 +00:00
mouseFollowerHorizontal - > setVisible ( false ) ;
mouseFollowerVertical - > setVisible ( false ) ;
2014-02-07 18:34:42 +00:00
}
2014-02-17 22:15:40 +00:00
2014-08-20 01:59:34 +00:00
void ProfileWidget2 : : clearHandlers ( )
{
if ( handles . count ( ) ) {
foreach ( DiveHandler * handle , handles ) {
scene ( ) - > removeItem ( handle ) ;
2015-03-13 00:32:49 +00:00
delete handle ;
2014-08-20 01:59:34 +00:00
}
handles . clear ( ) ;
}
}
2015-01-31 18:32:02 +00:00
void ProfileWidget2 : : setToolTipVisibile ( bool visible )
{
toolTipItem - > setVisible ( visible ) ;
}
2014-05-21 18:52:24 +00:00
void ProfileWidget2 : : setAddState ( )
{
if ( currentState = = ADD )
return ;
2015-03-13 00:32:50 +00:00
clearHandlers ( ) ;
2014-05-22 02:31:26 +00:00
setProfileState ( ) ;
2014-08-06 19:33:36 +00:00
mouseFollowerHorizontal - > setVisible ( true ) ;
mouseFollowerVertical - > setVisible ( true ) ;
mouseFollowerHorizontal - > setLine ( timeAxis - > line ( ) ) ;
mouseFollowerVertical - > setLine ( QLineF ( 0 , profileYAxis - > pos ( ) . y ( ) , 0 , timeAxis - > pos ( ) . y ( ) ) ) ;
2014-05-22 00:23:19 +00:00
disconnectTemporaryConnections ( ) ;
2014-05-24 15:39:40 +00:00
//TODO: Move this method to another place, shouldn't be on mainwindow.
2015-02-03 15:30:08 +00:00
MainWindow : : instance ( ) - > disableShortcuts ( false ) ;
2014-05-24 15:39:40 +00:00
actionsForKeys [ Qt : : Key_Left ] - > setShortcut ( Qt : : Key_Left ) ;
actionsForKeys [ Qt : : Key_Right ] - > setShortcut ( Qt : : Key_Right ) ;
actionsForKeys [ Qt : : Key_Up ] - > setShortcut ( Qt : : Key_Up ) ;
actionsForKeys [ Qt : : Key_Down ] - > setShortcut ( Qt : : Key_Down ) ;
actionsForKeys [ Qt : : Key_Escape ] - > setShortcut ( Qt : : Key_Escape ) ;
actionsForKeys [ Qt : : Key_Delete ] - > setShortcut ( Qt : : Key_Delete ) ;
2014-05-22 02:31:26 +00:00
DivePlannerPointsModel * plannerModel = DivePlannerPointsModel : : instance ( ) ;
connect ( plannerModel , SIGNAL ( dataChanged ( QModelIndex , QModelIndex ) ) , this , SLOT ( replot ( ) ) ) ;
connect ( plannerModel , SIGNAL ( cylinderModelEdited ( ) ) , this , SLOT ( replot ( ) ) ) ;
connect ( plannerModel , SIGNAL ( rowsInserted ( const QModelIndex & , int , int ) ) ,
this , SLOT ( pointInserted ( const QModelIndex & , int , int ) ) ) ;
connect ( plannerModel , SIGNAL ( rowsRemoved ( const QModelIndex & , int , int ) ) ,
this , SLOT ( pointsRemoved ( const QModelIndex & , int , int ) ) ) ;
2014-05-21 18:52:24 +00:00
/* show the same stuff that the profile shows. */
currentState = ADD ; /* enable the add state. */
2014-05-27 19:55:29 +00:00
diveCeiling - > setVisible ( true ) ;
2014-06-30 21:46:51 +00:00
setBackgroundBrush ( QColor ( " #A7DCFF " ) ) ;
2014-05-21 18:52:24 +00:00
}
void ProfileWidget2 : : setPlanState ( )
{
if ( currentState = = PLAN )
return ;
2014-05-25 18:12:00 +00:00
2014-05-22 02:31:26 +00:00
setProfileState ( ) ;
2014-08-06 19:33:36 +00:00
mouseFollowerHorizontal - > setVisible ( true ) ;
mouseFollowerVertical - > setVisible ( true ) ;
mouseFollowerHorizontal - > setLine ( timeAxis - > line ( ) ) ;
mouseFollowerVertical - > setLine ( QLineF ( 0 , profileYAxis - > pos ( ) . y ( ) , 0 , timeAxis - > pos ( ) . y ( ) ) ) ;
2014-05-22 00:23:19 +00:00
disconnectTemporaryConnections ( ) ;
2014-05-25 18:12:00 +00:00
//TODO: Move this method to another place, shouldn't be on mainwindow.
2015-02-03 15:30:08 +00:00
MainWindow : : instance ( ) - > disableShortcuts ( ) ;
2014-05-25 18:12:00 +00:00
actionsForKeys [ Qt : : Key_Left ] - > setShortcut ( Qt : : Key_Left ) ;
actionsForKeys [ Qt : : Key_Right ] - > setShortcut ( Qt : : Key_Right ) ;
actionsForKeys [ Qt : : Key_Up ] - > setShortcut ( Qt : : Key_Up ) ;
actionsForKeys [ Qt : : Key_Down ] - > setShortcut ( Qt : : Key_Down ) ;
actionsForKeys [ Qt : : Key_Escape ] - > setShortcut ( Qt : : Key_Escape ) ;
actionsForKeys [ Qt : : Key_Delete ] - > setShortcut ( Qt : : Key_Delete ) ;
2014-05-25 17:16:43 +00:00
DivePlannerPointsModel * plannerModel = DivePlannerPointsModel : : instance ( ) ;
connect ( plannerModel , SIGNAL ( dataChanged ( QModelIndex , QModelIndex ) ) , this , SLOT ( replot ( ) ) ) ;
connect ( plannerModel , SIGNAL ( cylinderModelEdited ( ) ) , this , SLOT ( replot ( ) ) ) ;
connect ( plannerModel , SIGNAL ( rowsInserted ( const QModelIndex & , int , int ) ) ,
this , SLOT ( pointInserted ( const QModelIndex & , int , int ) ) ) ;
connect ( plannerModel , SIGNAL ( rowsRemoved ( const QModelIndex & , int , int ) ) ,
this , SLOT ( pointsRemoved ( const QModelIndex & , int , int ) ) ) ;
2014-05-25 18:12:00 +00:00
/* show the same stuff that the profile shows. */
2014-05-21 18:52:24 +00:00
currentState = PLAN ; /* enable the add state. */
2014-05-27 19:55:29 +00:00
diveCeiling - > setVisible ( true ) ;
2014-06-30 21:46:51 +00:00
setBackgroundBrush ( QColor ( " #D7E3EF " ) ) ;
2014-05-21 18:52:24 +00:00
}
2014-02-17 22:15:40 +00:00
extern struct ev_select * ev_namelist ;
extern int evn_allocated ;
extern int evn_used ;
2014-05-26 22:17:34 +00:00
bool ProfileWidget2 : : isPlanner ( )
{
return currentState = = PLAN ;
}
2014-05-31 21:54:36 +00:00
bool ProfileWidget2 : : isAddOrPlanner ( )
{
return currentState = = PLAN | | currentState = = ADD ;
}
2014-11-19 22:31:28 +00:00
struct plot_data * ProfileWidget2 : : getEntryFromPos ( QPointF pos )
{
// find the time stamp corresponding to the mouse position
int seconds = timeAxis - > valueAt ( pos ) ;
struct plot_data * entry ;
for ( int i = 0 ; i < plotInfo . nr ; i + + ) {
entry = plotInfo . entry + i ;
if ( entry - > sec > = seconds )
break ;
}
return entry ;
}
2014-12-13 21:06:52 +00:00
void ProfileWidget2 : : setReplot ( bool state )
{
replotEnabled = state ;
}
2014-02-28 04:09:57 +00:00
void ProfileWidget2 : : contextMenuEvent ( QContextMenuEvent * event )
2014-02-17 22:15:40 +00:00
{
2014-05-25 03:33:39 +00:00
if ( currentState = = ADD | | currentState = = PLAN ) {
QGraphicsView : : contextMenuEvent ( event ) ;
return ;
}
2014-05-19 05:39:34 +00:00
QMenu m ;
bool isDCName = false ;
2014-02-17 22:15:40 +00:00
if ( selected_dive = = - 1 )
return ;
2014-05-19 05:39:34 +00:00
// figure out if we are ontop of the dive computer name in the profile
QGraphicsItem * sceneItem = itemAt ( mapFromGlobal ( event - > globalPos ( ) ) ) ;
if ( sceneItem ) {
QGraphicsItem * parentItem = sceneItem ;
while ( parentItem ) {
if ( parentItem - > data ( SUBSURFACE_OBJ_DATA ) = = SUBSURFACE_OBJ_DC_TEXT ) {
isDCName = true ;
break ;
}
parentItem = parentItem - > parentItem ( ) ;
}
if ( isDCName ) {
2014-06-11 20:56:33 +00:00
if ( dc_number = = 0 & & count_divecomputers ( ) = = 1 )
// nothing to do, can't delete or reorder
2014-05-19 05:39:34 +00:00
return ;
// create menu to show when right clicking on dive computer name
2014-06-11 20:56:33 +00:00
if ( dc_number > 0 )
m . addAction ( tr ( " Make first divecomputer " ) , this , SLOT ( makeFirstDC ( ) ) ) ;
if ( count_divecomputers ( ) > 1 )
m . addAction ( tr ( " Delete this divecomputer " ) , this , SLOT ( deleteCurrentDC ( ) ) ) ;
2014-05-19 05:39:34 +00:00
m . exec ( event - > globalPos ( ) ) ;
// don't show the regular profile context menu
return ;
}
}
// create the profile context menu
2014-11-19 22:44:33 +00:00
QPointF scenePos = mapToScene ( event - > pos ( ) ) ;
struct plot_data * entry = getEntryFromPos ( scenePos ) ;
2014-02-17 22:15:40 +00:00
GasSelectionModel * model = GasSelectionModel : : instance ( ) ;
model - > repopulate ( ) ;
int rowCount = model - > rowCount ( ) ;
2014-11-19 21:03:58 +00:00
if ( rowCount > 1 ) {
// if we have more than one gas, offer to switch to another one
QMenu * gasChange = m . addMenu ( tr ( " Add gas change " ) ) ;
for ( int i = 0 ; i < rowCount ; i + + ) {
QAction * action = new QAction ( & m ) ;
action - > setText ( model - > data ( model - > index ( i , 0 ) , Qt : : DisplayRole ) . toString ( ) + QString ( tr ( " (Tank %1) " ) ) . arg ( i + 1 ) ) ;
connect ( action , SIGNAL ( triggered ( bool ) ) , this , SLOT ( changeGas ( ) ) ) ;
action - > setData ( event - > globalPos ( ) ) ;
2014-11-19 22:44:33 +00:00
if ( i = = entry - > cylinderindex )
action - > setDisabled ( true ) ;
2014-11-19 21:03:58 +00:00
gasChange - > addAction ( action ) ;
}
2014-02-17 22:15:40 +00:00
}
2014-11-26 13:22:41 +00:00
QAction * setpointAction = m . addAction ( tr ( " Add set-point change " ) , this , SLOT ( addSetpointChange ( ) ) ) ;
setpointAction - > setData ( event - > globalPos ( ) ) ;
2014-07-11 17:39:05 +00:00
QAction * action = m . addAction ( tr ( " Add bookmark " ) , this , SLOT ( addBookmark ( ) ) ) ;
2014-02-17 22:15:40 +00:00
action - > setData ( event - > globalPos ( ) ) ;
2015-04-23 20:56:24 +00:00
if ( same_string ( current_dc - > model , " manually added dive " ) )
QAction * editProfileAction = m . addAction ( tr ( " Edit the profile " ) , MainWindow : : instance ( ) , SLOT ( editCurrentDive ( ) ) ) ;
2014-03-16 04:12:34 +00:00
if ( DiveEventItem * item = dynamic_cast < DiveEventItem * > ( sceneItem ) ) {
2014-02-17 22:15:40 +00:00
action = new QAction ( & m ) ;
2014-07-11 17:39:05 +00:00
action - > setText ( tr ( " Remove event " ) ) ;
2014-02-28 04:09:57 +00:00
action - > setData ( QVariant : : fromValue < void * > ( item ) ) ; // so we know what to remove.
2014-02-17 22:15:40 +00:00
connect ( action , SIGNAL ( triggered ( bool ) ) , this , SLOT ( removeEvent ( ) ) ) ;
m . addAction ( action ) ;
action = new QAction ( & m ) ;
action - > setText ( tr ( " Hide similar events " ) ) ;
2014-02-28 04:09:57 +00:00
action - > setData ( QVariant : : fromValue < void * > ( item ) ) ;
2014-02-17 22:15:40 +00:00
connect ( action , SIGNAL ( triggered ( bool ) ) , this , SLOT ( hideEvents ( ) ) ) ;
m . addAction ( action ) ;
2014-11-20 00:15:10 +00:00
struct event * dcEvent = item - > getEvent ( ) ;
if ( dcEvent - > type = = SAMPLE_EVENT_BOOKMARK ) {
2014-04-03 19:16:15 +00:00
action = new QAction ( & m ) ;
action - > setText ( tr ( " Edit name " ) ) ;
action - > setData ( QVariant : : fromValue < void * > ( item ) ) ;
connect ( action , SIGNAL ( triggered ( bool ) ) , this , SLOT ( editName ( ) ) ) ;
m . addAction ( action ) ;
}
2014-11-20 00:15:10 +00:00
#if 0 // FIXME::: FINISH OR DISABLE
// this shows how to figure out if we should ask the user if they want adjust interpolated pressures
// at either side of a gas change
if ( dcEvent - > type = = SAMPLE_EVENT_GASCHANGE | | dcEvent - > type = = SAMPLE_EVENT_GASCHANGE2 ) {
qDebug ( ) < < " figure out if there are interpolated pressures " ;
struct plot_data * gasChangeEntry = entry ;
struct plot_data * newGasEntry ;
while ( gasChangeEntry > plotInfo . entry ) {
- - gasChangeEntry ;
if ( gasChangeEntry - > sec < = dcEvent - > time . seconds )
break ;
}
qDebug ( ) < < " at gas change at " < < gasChangeEntry - > sec < < " : sensor pressure " < < gasChangeEntry - > pressure [ 0 ] < < " interpolated " < < gasChangeEntry - > pressure [ 1 ] ;
// now gasChangeEntry points at the gas change, that entry has the final pressure of
// the old tank, the next entry has the starting pressure of the next tank
if ( gasChangeEntry + 1 < = plotInfo . entry + plotInfo . nr ) {
newGasEntry = gasChangeEntry + 1 ;
qDebug ( ) < < " after gas change at " < < newGasEntry - > sec < < " : sensor pressure " < < newGasEntry - > pressure [ 0 ] < < " interpolated " < < newGasEntry - > pressure [ 1 ] ;
if ( SENSOR_PRESSURE ( gasChangeEntry ) = = 0 | | displayed_dive . cylinder [ gasChangeEntry - > cylinderindex ] . sample_start . mbar = = 0 ) {
// if we have no sensorpressure or if we have no pressure from samples we can assume that
// we only have interpolated pressure (the pressure in the entry may be stored in the sensor
// pressure field if this is the first or last entry for this tank... see details in gaspressures.c
pressure_t pressure ;
pressure . mbar = INTERPOLATED_PRESSURE ( gasChangeEntry ) ? : SENSOR_PRESSURE ( gasChangeEntry ) ;
QAction * adjustOldPressure = m . addAction ( tr ( " Adjust pressure of tank %1 (currently interpolated as %2) " )
. arg ( gasChangeEntry - > cylinderindex + 1 ) . arg ( get_pressure_string ( pressure ) ) ) ;
}
if ( SENSOR_PRESSURE ( newGasEntry ) = = 0 | | displayed_dive . cylinder [ newGasEntry - > cylinderindex ] . sample_start . mbar = = 0 ) {
// we only have interpolated press -- see commend above
pressure_t pressure ;
pressure . mbar = INTERPOLATED_PRESSURE ( newGasEntry ) ? : SENSOR_PRESSURE ( newGasEntry ) ;
QAction * adjustOldPressure = m . addAction ( tr ( " Adjust pressure of tank %1 (currently interpolated as %2) " )
. arg ( newGasEntry - > cylinderindex + 1 ) . arg ( get_pressure_string ( pressure ) ) ) ;
}
}
}
# endif
2014-02-17 22:15:40 +00:00
}
bool some_hidden = false ;
for ( int i = 0 ; i < evn_used ; i + + ) {
if ( ev_namelist [ i ] . plot_ev = = false ) {
some_hidden = true ;
break ;
}
}
if ( some_hidden ) {
action = m . addAction ( tr ( " Unhide all events " ) , this , SLOT ( unhideEvents ( ) ) ) ;
action - > setData ( event - > globalPos ( ) ) ;
}
m . exec ( event - > globalPos ( ) ) ;
}
2014-06-11 20:56:33 +00:00
void ProfileWidget2 : : deleteCurrentDC ( )
{
delete_current_divecomputer ( ) ;
mark_divelist_changed ( true ) ;
// we need to force it since it's likely the same dive and same dc_number - but that's a different dive computer now
2014-07-09 18:19:08 +00:00
MainWindow : : instance ( ) - > graphics ( ) - > plotDive ( 0 , true ) ;
2014-06-11 20:56:33 +00:00
MainWindow : : instance ( ) - > refreshDisplay ( ) ;
}
2014-05-19 05:39:34 +00:00
void ProfileWidget2 : : makeFirstDC ( )
{
make_first_dc ( ) ;
mark_divelist_changed ( true ) ;
// this is now the first DC, so we need to redraw the profile and refresh the dive list
// (and no, it's not just enough to rewrite the text - the first DC is special so values in the
// dive list may change).
// As a side benefit, this returns focus to the dive list.
dc_number = 0 ;
MainWindow : : instance ( ) - > refreshDisplay ( ) ;
}
2014-03-16 04:12:34 +00:00
void ProfileWidget2 : : hideEvents ( )
{
QAction * action = qobject_cast < QAction * > ( sender ( ) ) ;
DiveEventItem * item = static_cast < DiveEventItem * > ( action - > data ( ) . value < void * > ( ) ) ;
struct event * event = item - > getEvent ( ) ;
if ( QMessageBox : : question ( MainWindow : : instance ( ) ,
TITLE_OR_TEXT ( tr ( " Hide events " ) , tr ( " Hide all %1 events? " ) . arg ( event - > name ) ) ,
QMessageBox : : Ok | QMessageBox : : Cancel ) = = QMessageBox : : Ok ) {
if ( event - > name ) {
for ( int i = 0 ; i < evn_used ; i + + ) {
2014-05-15 00:45:39 +00:00
if ( same_string ( event - > name , ev_namelist [ i ] . ev_name ) ) {
2014-03-16 04:12:34 +00:00
ev_namelist [ i ] . plot_ev = false ;
break ;
}
}
2014-05-15 00:45:39 +00:00
Q_FOREACH ( DiveEventItem * evItem , eventItems ) {
2014-05-22 18:40:22 +00:00
if ( same_string ( evItem - > getEvent ( ) - > name , event - > name ) )
2014-05-15 00:45:39 +00:00
evItem - > hide ( ) ;
}
} else {
item - > hide ( ) ;
2014-03-16 04:12:34 +00:00
}
}
}
void ProfileWidget2 : : unhideEvents ( )
{
for ( int i = 0 ; i < evn_used ; i + + ) {
ev_namelist [ i ] . plot_ev = true ;
}
2014-05-15 00:51:45 +00:00
Q_FOREACH ( DiveEventItem * item , eventItems )
item - > show ( ) ;
2014-03-16 04:12:34 +00:00
}
void ProfileWidget2 : : removeEvent ( )
{
QAction * action = qobject_cast < QAction * > ( sender ( ) ) ;
DiveEventItem * item = static_cast < DiveEventItem * > ( action - > data ( ) . value < void * > ( ) ) ;
struct event * event = item - > getEvent ( ) ;
if ( QMessageBox : : question ( MainWindow : : instance ( ) , TITLE_OR_TEXT (
2014-05-22 18:40:22 +00:00
tr ( " Remove the selected event? " ) ,
tr ( " %1 @ %2:%3 " ) . arg ( event - > name ) . arg ( event - > time . seconds / 60 ) . arg ( event - > time . seconds % 60 , 2 , 10 , QChar ( ' 0 ' ) ) ) ,
2014-03-16 04:12:34 +00:00
QMessageBox : : Ok | QMessageBox : : Cancel ) = = QMessageBox : : Ok ) {
2014-05-21 15:06:02 +00:00
remove_event ( event ) ;
2014-03-16 04:12:34 +00:00
mark_divelist_changed ( true ) ;
replot ( ) ;
}
}
void ProfileWidget2 : : addBookmark ( )
{
QAction * action = qobject_cast < QAction * > ( sender ( ) ) ;
QPointF scenePos = mapToScene ( mapFromGlobal ( action - > data ( ) . toPoint ( ) ) ) ;
add_event ( current_dc , timeAxis - > valueAt ( scenePos ) , SAMPLE_EVENT_BOOKMARK , 0 , 0 , " bookmark " ) ;
2014-07-12 05:37:05 +00:00
mark_divelist_changed ( true ) ;
2014-03-16 04:12:34 +00:00
replot ( ) ;
}
2014-11-26 13:22:41 +00:00
void ProfileWidget2 : : addSetpointChange ( )
{
QAction * action = qobject_cast < QAction * > ( sender ( ) ) ;
QPointF scenePos = mapToScene ( mapFromGlobal ( action - > data ( ) . toPoint ( ) ) ) ;
SetpointDialog : : instance ( ) - > setpointData ( current_dc , timeAxis - > valueAt ( scenePos ) ) ;
SetpointDialog : : instance ( ) - > show ( ) ;
}
2014-02-17 22:15:40 +00:00
void ProfileWidget2 : : changeGas ( )
{
2014-02-28 04:09:57 +00:00
QAction * action = qobject_cast < QAction * > ( sender ( ) ) ;
2014-02-17 22:15:40 +00:00
QPointF scenePos = mapToScene ( mapFromGlobal ( action - > data ( ) . toPoint ( ) ) ) ;
QString gas = action - > text ( ) ;
2014-10-29 23:25:00 +00:00
gas . remove ( QRegExp ( " \\ (.* \\ ) " ) ) ;
2014-02-17 22:15:40 +00:00
// backup the things on the dataModel, since we will clear that out.
2014-06-01 21:17:06 +00:00
struct gasmix gasmix ;
2015-03-13 00:32:51 +00:00
qreal sec_val = timeAxis - > valueAt ( scenePos ) ;
2014-02-17 22:15:40 +00:00
2015-03-11 18:23:50 +00:00
// no gas changes before the dive starts
2015-03-13 00:32:51 +00:00
unsigned int seconds = ( sec_val < 0.0 ) ? 0 : ( unsigned int ) sec_val ;
2015-03-11 18:23:50 +00:00
2015-03-11 18:24:30 +00:00
// if there is a gas change at this time stamp, remove it before adding the new one
struct event * gasChangeEvent = current_dc - > events ;
while ( ( gasChangeEvent = get_next_event ( gasChangeEvent , " gaschange " ) ) ! = NULL ) {
if ( gasChangeEvent - > time . seconds = = seconds ) {
remove_event ( gasChangeEvent ) ;
gasChangeEvent = current_dc - > events ;
} else {
gasChangeEvent = gasChangeEvent - > next ;
2015-03-11 00:00:18 +00:00
}
}
2014-06-01 21:17:06 +00:00
validate_gas ( gas . toUtf8 ( ) . constData ( ) , & gasmix ) ;
2014-10-29 23:25:00 +00:00
QRegExp rx ( " \\ ( \\ D*( \\ d+) " ) ;
int tank ;
if ( rx . indexIn ( action - > text ( ) ) > - 1 ) {
tank = rx . cap ( 1 ) . toInt ( ) - 1 ; // we display the tank 1 based
} else {
qDebug ( ) < < " failed to parse tank number " ;
tank = get_gasidx ( & displayed_dive , & gasmix ) ;
}
2014-10-30 21:08:10 +00:00
// add this both to the displayed dive and the current dive
add_gas_switch_event ( current_dive , current_dc , seconds , tank ) ;
add_gas_switch_event ( & displayed_dive , get_dive_dc ( & displayed_dive , dc_number ) , seconds , tank ) ;
2014-02-17 22:15:40 +00:00
// this means we potentially have a new tank that is being used and needs to be shown
2014-07-03 21:34:24 +00:00
fixup_dive ( & displayed_dive ) ;
// FIXME - this no longer gets written to the dive list - so we need to enableEdition() here
2014-07-02 19:58:41 +00:00
MainWindow : : instance ( ) - > information ( ) - > updateDiveInfo ( ) ;
2014-02-17 22:15:40 +00:00
mark_divelist_changed ( true ) ;
2014-03-09 13:59:31 +00:00
replot ( ) ;
2014-02-20 01:18:26 +00:00
}
2014-03-25 21:34:09 +00:00
2014-07-09 20:09:52 +00:00
bool ProfileWidget2 : : getPrintMode ( )
{
return printMode ;
}
2014-03-25 21:34:09 +00:00
void ProfileWidget2 : : setPrintMode ( bool mode , bool grayscale )
{
printMode = mode ;
isGrayscale = mode ? grayscale : false ;
2015-01-02 00:28:37 +00:00
mouseFollowerHorizontal - > setVisible ( ! mode ) ;
mouseFollowerVertical - > setVisible ( ! mode ) ;
2014-03-25 21:34:09 +00:00
}
2014-04-03 19:16:15 +00:00
2014-07-09 20:09:52 +00:00
void ProfileWidget2 : : setFontPrintScale ( double scale )
{
fontPrintScale = scale ;
}
double ProfileWidget2 : : getFontPrintScale ( )
{
if ( printMode )
return fontPrintScale ;
else
return 1.0 ;
}
2014-04-03 19:16:15 +00:00
void ProfileWidget2 : : editName ( )
{
QAction * action = qobject_cast < QAction * > ( sender ( ) ) ;
DiveEventItem * item = static_cast < DiveEventItem * > ( action - > data ( ) . value < void * > ( ) ) ;
struct event * event = item - > getEvent ( ) ;
bool ok ;
QString newName = QInputDialog : : getText ( MainWindow : : instance ( ) , tr ( " Edit name of bookmark " ) ,
tr ( " Custom name: " ) , QLineEdit : : Normal ,
event - > name , & ok ) ;
2014-04-03 19:52:05 +00:00
if ( ok & & ! newName . isEmpty ( ) ) {
if ( newName . length ( ) > 22 ) { //longer names will display as garbage.
2014-04-03 19:16:15 +00:00
QMessageBox lengthWarning ;
2014-07-28 14:12:51 +00:00
lengthWarning . setText ( tr ( " Name is too long! " ) ) ;
2014-04-03 19:16:15 +00:00
lengthWarning . exec ( ) ;
return ;
}
2014-07-12 19:48:27 +00:00
// order is important! first update the current dive (by matching the unchanged event),
// then update the displayed dive (as event is part of the events on displayed dive
// and will be freed as part of changing the name!
update_event_name ( current_dive , event , newName . toUtf8 ( ) . data ( ) ) ;
update_event_name ( & displayed_dive , event , newName . toUtf8 ( ) . data ( ) ) ;
mark_divelist_changed ( true ) ;
replot ( ) ;
2014-04-03 19:16:15 +00:00
}
}
2014-05-22 00:18:10 +00:00
2014-05-22 00:23:19 +00:00
void ProfileWidget2 : : disconnectTemporaryConnections ( )
{
DivePlannerPointsModel * plannerModel = DivePlannerPointsModel : : instance ( ) ;
disconnect ( plannerModel , SIGNAL ( dataChanged ( QModelIndex , QModelIndex ) ) , this , SLOT ( replot ( ) ) ) ;
disconnect ( plannerModel , SIGNAL ( cylinderModelEdited ( ) ) , this , SLOT ( replot ( ) ) ) ;
disconnect ( plannerModel , SIGNAL ( rowsInserted ( const QModelIndex & , int , int ) ) ,
2014-05-22 18:40:22 +00:00
this , SLOT ( pointInserted ( const QModelIndex & , int , int ) ) ) ;
2014-05-22 00:23:19 +00:00
disconnect ( plannerModel , SIGNAL ( rowsRemoved ( const QModelIndex & , int , int ) ) ,
2014-05-22 18:40:22 +00:00
this , SLOT ( pointsRemoved ( const QModelIndex & , int , int ) ) ) ;
2014-05-24 15:39:40 +00:00
2014-06-03 22:28:06 +00:00
Q_FOREACH ( QAction * action , actionsForKeys . values ( ) ) {
2014-05-24 15:39:40 +00:00
action - > setShortcut ( QKeySequence ( ) ) ;
2014-06-03 22:28:06 +00:00
action - > setShortcutContext ( Qt : : WidgetShortcut ) ;
}
2014-05-22 00:23:19 +00:00
}
2014-05-22 00:18:10 +00:00
void ProfileWidget2 : : pointInserted ( const QModelIndex & parent , int start , int end )
{
DiveHandler * item = new DiveHandler ( ) ;
scene ( ) - > addItem ( item ) ;
handles < < item ;
2014-05-23 23:51:30 +00:00
connect ( item , SIGNAL ( moved ( ) ) , this , SLOT ( recreatePlannedDive ( ) ) ) ;
2014-06-30 22:08:16 +00:00
connect ( item , SIGNAL ( clicked ( ) ) , this , SLOT ( divePlannerHandlerClicked ( ) ) ) ;
connect ( item , SIGNAL ( released ( ) ) , this , SLOT ( divePlannerHandlerReleased ( ) ) ) ;
2014-05-22 00:18:10 +00:00
QGraphicsSimpleTextItem * gasChooseBtn = new QGraphicsSimpleTextItem ( ) ;
scene ( ) - > addItem ( gasChooseBtn ) ;
gasChooseBtn - > setZValue ( 10 ) ;
gasChooseBtn - > setFlag ( QGraphicsItem : : ItemIgnoresTransformations ) ;
gases < < gasChooseBtn ;
DivePlannerPointsModel * plannerModel = DivePlannerPointsModel : : instance ( ) ;
if ( plannerModel - > recalcQ ( ) )
replot ( ) ;
}
void ProfileWidget2 : : pointsRemoved ( const QModelIndex & , int start , int end )
{ // start and end are inclusive.
int num = ( end - start ) + 1 ;
for ( int i = num ; i ! = 0 ; i - - ) {
delete handles . back ( ) ;
handles . pop_back ( ) ;
delete gases . back ( ) ;
gases . pop_back ( ) ;
}
scene ( ) - > clearSelection ( ) ;
replot ( ) ;
}
2014-05-22 02:31:26 +00:00
void ProfileWidget2 : : repositionDiveHandlers ( )
{
DivePlannerPointsModel * plannerModel = DivePlannerPointsModel : : instance ( ) ;
// Re-position the user generated dive handlers
for ( int i = 0 ; i < plannerModel - > rowCount ( ) ; i + + ) {
struct divedatapoint datapoint = plannerModel - > at ( i ) ;
if ( datapoint . time = = 0 ) // those are the magic entries for tanks
continue ;
DiveHandler * h = handles . at ( i ) ;
2014-05-30 02:47:03 +00:00
h - > setVisible ( datapoint . entered ) ;
2014-05-22 02:31:26 +00:00
h - > setPos ( timeAxis - > posAtValue ( datapoint . time ) , profileYAxis - > posAtValue ( datapoint . depth ) ) ;
2014-10-21 21:27:50 +00:00
QPointF p1 ;
if ( i = = 0 ) {
if ( prefs . drop_stone_mode )
// place the text on the straight line from the drop to stone position
p1 = QPointF ( timeAxis - > posAtValue ( datapoint . depth / prefs . descrate ) ,
profileYAxis - > posAtValue ( datapoint . depth ) ) ;
else
// place the text on the straight line from the origin to the first position
p1 = QPointF ( timeAxis - > posAtValue ( 0 ) , profileYAxis - > posAtValue ( 0 ) ) ;
} else {
// place the text on the line from the last position
p1 = handles [ i - 1 ] - > pos ( ) ;
}
2014-05-22 02:31:26 +00:00
QPointF p2 = handles [ i ] - > pos ( ) ;
QLineF line ( p1 , p2 ) ;
QPointF pos = line . pointAt ( 0.5 ) ;
gases [ i ] - > setPos ( pos ) ;
2014-05-30 02:47:03 +00:00
gases [ i ] - > setVisible ( datapoint . entered ) ;
2014-05-22 02:31:26 +00:00
gases [ i ] - > setText ( dpGasToStr ( plannerModel - > at ( i ) ) ) ;
}
}
2014-05-23 23:51:30 +00:00
2014-05-24 01:22:02 +00:00
int ProfileWidget2 : : fixHandlerIndex ( DiveHandler * activeHandler )
{
int index = handles . indexOf ( activeHandler ) ;
if ( index > 0 & & index < handles . count ( ) - 1 ) {
DiveHandler * before = handles [ index - 1 ] ;
if ( before - > pos ( ) . x ( ) > activeHandler - > pos ( ) . x ( ) ) {
2014-05-24 15:39:40 +00:00
handles . swap ( index , index - 1 ) ;
2014-05-24 01:22:02 +00:00
return index - 1 ;
}
DiveHandler * after = handles [ index + 1 ] ;
if ( after - > pos ( ) . x ( ) < activeHandler - > pos ( ) . x ( ) ) {
2014-05-24 15:39:40 +00:00
handles . swap ( index , index + 1 ) ;
2014-05-24 01:22:02 +00:00
return index + 1 ;
}
}
return index ;
}
2014-05-23 23:51:30 +00:00
void ProfileWidget2 : : recreatePlannedDive ( )
{
2014-05-24 15:39:40 +00:00
DiveHandler * activeHandler = qobject_cast < DiveHandler * > ( sender ( ) ) ;
2014-05-23 23:51:30 +00:00
DivePlannerPointsModel * plannerModel = DivePlannerPointsModel : : instance ( ) ;
2014-05-24 01:22:02 +00:00
int index = fixHandlerIndex ( activeHandler ) ;
2014-05-23 23:51:30 +00:00
int mintime = 0 , maxtime = ( timeAxis - > maximum ( ) + 10 ) * 60 ;
if ( index > 0 )
mintime = plannerModel - > at ( index - 1 ) . time ;
if ( index < plannerModel - > size ( ) - 1 )
maxtime = plannerModel - > at ( index + 1 ) . time ;
int minutes = rint ( timeAxis - > valueAt ( activeHandler - > pos ( ) ) / 60 ) ;
if ( minutes * 60 < = mintime | | minutes * 60 > = maxtime )
return ;
divedatapoint data = plannerModel - > at ( index ) ;
2014-05-24 15:39:40 +00:00
data . depth = rint ( profileYAxis - > valueAt ( activeHandler - > pos ( ) ) / M_OR_FT ( 1 , 1 ) ) * M_OR_FT ( 1 , 1 ) ;
2014-05-23 23:51:30 +00:00
data . time = rint ( timeAxis - > valueAt ( activeHandler - > pos ( ) ) ) ;
plannerModel - > editStop ( index , data ) ;
}
2014-05-24 15:39:40 +00:00
void ProfileWidget2 : : keyDownAction ( )
{
if ( currentState ! = ADD & & currentState ! = PLAN )
return ;
DivePlannerPointsModel * plannerModel = DivePlannerPointsModel : : instance ( ) ;
Q_FOREACH ( QGraphicsItem * i , scene ( ) - > selectedItems ( ) ) {
if ( DiveHandler * handler = qgraphicsitem_cast < DiveHandler * > ( i ) ) {
int row = handles . indexOf ( handler ) ;
divedatapoint dp = plannerModel - > at ( row ) ;
if ( dp . depth > = profileYAxis - > maximum ( ) )
continue ;
dp . depth + = M_OR_FT ( 1 , 5 ) ;
plannerModel - > editStop ( row , dp ) ;
}
}
}
void ProfileWidget2 : : keyUpAction ( )
{
if ( currentState ! = ADD & & currentState ! = PLAN )
return ;
DivePlannerPointsModel * plannerModel = DivePlannerPointsModel : : instance ( ) ;
Q_FOREACH ( QGraphicsItem * i , scene ( ) - > selectedItems ( ) ) {
if ( DiveHandler * handler = qgraphicsitem_cast < DiveHandler * > ( i ) ) {
int row = handles . indexOf ( handler ) ;
divedatapoint dp = plannerModel - > at ( row ) ;
if ( dp . depth < = 0 )
continue ;
dp . depth - = M_OR_FT ( 1 , 5 ) ;
plannerModel - > editStop ( row , dp ) ;
}
}
}
void ProfileWidget2 : : keyLeftAction ( )
{
if ( currentState ! = ADD & & currentState ! = PLAN )
return ;
DivePlannerPointsModel * plannerModel = DivePlannerPointsModel : : instance ( ) ;
Q_FOREACH ( QGraphicsItem * i , scene ( ) - > selectedItems ( ) ) {
if ( DiveHandler * handler = qgraphicsitem_cast < DiveHandler * > ( i ) ) {
int row = handles . indexOf ( handler ) ;
divedatapoint dp = plannerModel - > at ( row ) ;
if ( dp . time / 60 < = 0 )
continue ;
// don't overlap positions.
// maybe this is a good place for a 'goto'?
double xpos = timeAxis - > posAtValue ( ( dp . time - 60 ) / 60 ) ;
bool nextStep = false ;
Q_FOREACH ( DiveHandler * h , handles ) {
if ( IS_FP_SAME ( h - > pos ( ) . x ( ) , xpos ) ) {
nextStep = true ;
break ;
}
}
if ( nextStep )
continue ;
dp . time - = 60 ;
plannerModel - > editStop ( row , dp ) ;
}
}
}
void ProfileWidget2 : : keyRightAction ( )
{
if ( currentState ! = ADD & & currentState ! = PLAN )
return ;
DivePlannerPointsModel * plannerModel = DivePlannerPointsModel : : instance ( ) ;
Q_FOREACH ( QGraphicsItem * i , scene ( ) - > selectedItems ( ) ) {
if ( DiveHandler * handler = qgraphicsitem_cast < DiveHandler * > ( i ) ) {
int row = handles . indexOf ( handler ) ;
divedatapoint dp = plannerModel - > at ( row ) ;
if ( dp . time / 60 > = timeAxis - > maximum ( ) )
continue ;
// don't overlap positions.
// maybe this is a good place for a 'goto'?
double xpos = timeAxis - > posAtValue ( ( dp . time + 60 ) / 60 ) ;
bool nextStep = false ;
Q_FOREACH ( DiveHandler * h , handles ) {
if ( IS_FP_SAME ( h - > pos ( ) . x ( ) , xpos ) ) {
nextStep = true ;
break ;
}
}
if ( nextStep )
continue ;
dp . time + = 60 ;
plannerModel - > editStop ( row , dp ) ;
}
}
}
void ProfileWidget2 : : keyDeleteAction ( )
{
if ( currentState ! = ADD & & currentState ! = PLAN )
return ;
DivePlannerPointsModel * plannerModel = DivePlannerPointsModel : : instance ( ) ;
int selCount = scene ( ) - > selectedItems ( ) . count ( ) ;
if ( selCount ) {
QVector < int > selectedIndexes ;
Q_FOREACH ( QGraphicsItem * i , scene ( ) - > selectedItems ( ) ) {
if ( DiveHandler * handler = qgraphicsitem_cast < DiveHandler * > ( i ) ) {
selectedIndexes . push_back ( handles . indexOf ( handler ) ) ;
2014-07-30 16:31:22 +00:00
handler - > hide ( ) ;
2014-05-24 15:39:40 +00:00
}
}
plannerModel - > removeSelectedPoints ( selectedIndexes ) ;
}
}
void ProfileWidget2 : : keyEscAction ( )
{
if ( currentState ! = ADD & & currentState ! = PLAN )
return ;
if ( scene ( ) - > selectedItems ( ) . count ( ) ) {
scene ( ) - > clearSelection ( ) ;
return ;
}
DivePlannerPointsModel * plannerModel = DivePlannerPointsModel : : instance ( ) ;
if ( plannerModel - > isPlanner ( ) )
plannerModel - > cancelPlan ( ) ;
}
2014-06-03 22:24:01 +00:00
void ProfileWidget2 : : plotPictures ( )
{
2015-01-02 00:28:37 +00:00
Q_FOREACH ( DivePictureItem * item , pictures ) {
2014-08-05 18:42:19 +00:00
item - > hide ( ) ;
2014-07-30 02:03:32 +00:00
item - > deleteLater ( ) ;
}
2014-07-21 21:54:28 +00:00
pictures . clear ( ) ;
2014-07-02 20:58:06 +00:00
if ( printMode )
return ;
2014-06-08 19:36:27 +00:00
double x , y , lastX = - 1.0 , lastY = - 1.0 ;
2014-06-03 22:24:01 +00:00
DivePictureModel * m = DivePictureModel : : instance ( ) ;
2014-06-03 22:42:47 +00:00
for ( int i = 0 ; i < m - > rowCount ( ) ; i + + ) {
2015-01-02 00:28:37 +00:00
int offsetSeconds = m - > index ( i , 1 ) . data ( Qt : : UserRole ) . value < int > ( ) ;
2014-06-03 22:42:47 +00:00
// it's a correct picture, but doesn't have a timestamp: only show on the widget near the
// information area.
2014-08-05 19:37:14 +00:00
if ( ! offsetSeconds )
2014-06-03 22:42:47 +00:00
continue ;
2014-07-30 01:13:14 +00:00
DivePictureItem * item = new DivePictureItem ( ) ;
2015-01-02 00:28:37 +00:00
item - > setPixmap ( m - > index ( i , 0 ) . data ( Qt : : DecorationRole ) . value < QPixmap > ( ) ) ;
item - > setFileUrl ( m - > index ( i , 1 ) . data ( ) . toString ( ) ) ;
2014-06-08 18:56:35 +00:00
// let's put the picture at the correct time, but at a fixed "depth" on the profile
// not sure this is ideal, but it seems to look right.
2014-08-05 19:37:14 +00:00
x = timeAxis - > posAtValue ( offsetSeconds ) ;
2014-06-08 19:36:27 +00:00
if ( i = = 0 )
y = 10 ;
2014-06-27 21:00:42 +00:00
else if ( fabs ( x - lastX ) < 4 )
y = lastY + 3 ;
2014-06-08 19:36:27 +00:00
lastX = x ;
lastY = y ;
2014-06-08 18:56:35 +00:00
item - > setPos ( x , y ) ;
2014-06-03 22:24:01 +00:00
scene ( ) - > addItem ( item ) ;
pictures . push_back ( item ) ;
}
}