2018-06-14 07:25:54 +00:00
/* Daily Panel
2014-04-09 21:01:57 +00:00
*
2024-01-13 20:27:48 +00:00
* Copyright ( c ) 2019 - 2024 The OSCAR Team
2024-03-20 16:59:40 +00:00
* Copyright ( c ) 2011 - 2018 Mark Watkins
2014-04-09 21:01:57 +00:00
*
* This file is subject to the terms and conditions of the GNU General Public
2018-06-04 20:48:38 +00:00
* License . See the file COPYING in the main directory of the source code
* for more details . */
2011-06-26 08:30:44 +00:00
2022-07-01 19:06:53 +00:00
# define TEST_MACROS_ENABLEDoff
# include <test_macros.h>
2024-03-20 16:59:40 +00:00
# define CONFIGURE_MODE
# define COMBINE_MODE_3
2011-06-26 08:30:44 +00:00
# include <QTextCharFormat>
2011-08-20 07:38:50 +00:00
# include <QPalette>
2011-06-26 08:30:44 +00:00
# include <QTextBlock>
# include <QColorDialog>
2011-07-28 11:09:53 +00:00
# include <QSpacerItem>
2023-02-12 01:50:02 +00:00
# include <QElapsedTimer>
2011-06-26 08:30:44 +00:00
# include <QBuffer>
# include <QPixmap>
2011-07-27 09:21:53 +00:00
# include <QMessageBox>
2011-07-28 11:09:53 +00:00
# include <QResizeEvent>
2011-08-20 08:20:22 +00:00
# include <QScrollBar>
2011-12-01 06:06:13 +00:00
# include <QSpacerItem>
2013-10-13 08:07:43 +00:00
# include <QFontMetrics>
2013-10-10 17:36:53 +00:00
# include <QLabel>
2018-05-08 08:12:32 +00:00
# include <QMutexLocker>
2013-10-10 17:36:53 +00:00
2011-12-02 13:48:05 +00:00
# include <cmath>
2011-06-26 08:30:44 +00:00
2011-11-27 22:36:38 +00:00
# include "daily.h"
# include "ui_daily.h"
2023-02-06 16:06:03 +00:00
# include "dailySearchTab.h"
2011-11-27 22:36:38 +00:00
2011-11-15 21:22:08 +00:00
# include "common_gui.h"
2011-10-05 07:41:56 +00:00
# include "SleepLib/profiles.h"
2011-06-26 08:30:44 +00:00
# include "SleepLib/session.h"
# include "Graphs/gLineOverlay.h"
# include "Graphs/gFlagsLine.h"
# include "Graphs/gFooBar.h"
# include "Graphs/gXAxis.h"
# include "Graphs/gYAxis.h"
2011-07-28 17:15:15 +00:00
# include "Graphs/gSegmentChart.h"
2011-08-30 08:46:24 +00:00
# include "Graphs/gStatsLine.h"
2014-08-09 17:12:37 +00:00
# include "Graphs/gdailysummary.h"
2014-08-11 18:29:44 +00:00
# include "Graphs/MinutesAtPressure.h"
2011-06-26 08:30:44 +00:00
2011-12-18 10:53:51 +00:00
extern MainWindow * mainwin ;
2011-12-01 15:40:32 +00:00
2019-07-19 05:39:08 +00:00
QString htmlLeftHeader ;
QString htmlLeftAHI ;
QString htmlLeftMachineInfo ;
QString htmlLeftSleepTime ;
QString htmlLeftIndices ;
QString htmlLeftPieChart = " " ;
QString htmlLeftNoHours = " " ;
QString htmlLeftStatistics ;
QString htmlLeftOximeter ;
QString htmlLeftMachineSettings ;
QString htmlLeftSessionInfo ;
QString htmlLeftFooter ;
2020-04-22 20:52:21 +00:00
extern ChannelID PRS1_PeakFlow ;
2023-05-06 09:58:29 +00:00
extern ChannelID Prisma_ObstructLevel , Prisma_rMVFluctuation , Prisma_rRMV , Prisma_PressureMeasured , Prisma_FlowFull ;
2019-07-19 05:39:08 +00:00
2024-08-23 23:58:36 +00:00
# define WEIGHT_SPIN_BOX_DECIMALS 1
2014-05-13 08:14:20 +00:00
// This was Sean Stangl's idea.. but I couldn't apply that patch.
inline QString channelInfo ( ChannelID code ) {
return schema : : channel [ code ] . fullname ( ) + " \n " + schema : : channel [ code ] . description ( ) + " \n ( " + schema : : channel [ code ] . units ( ) + " ) " ;
2019-07-05 17:29:57 +00:00
// return schema::channel[code].fullname()+"\n"+schema::channel[code].description()
// + (schema::channel[code].units() != "0" ? "\n("+schema::channel[code].units()+")" : "");
2014-05-13 08:14:20 +00:00
}
2019-09-07 05:16:35 +00:00
// Charts displayed on the Daily page are defined in the Daily::Daily constructor. They consist of some hard-coded charts and a table
// of channel codes for which charts are generated. If the list of channel codes is changed, the graph order lists below will need to
// be changed correspondingly.
//
// Note that "graph codes" are strings used to identify graphs and are not the same as "channel codes." The mapping between channel codes
// and graph codes is found in schema.cpp. (What we here call 'graph cdoes' are called 'lookup codes' in schema.cpp.)
//
2019-09-03 19:56:10 +00:00
//
// List here the graph codes in the order they are to be displayed.
// Do NOT list a code twice, or Oscar will crash when the profile is closed!
//
2019-09-02 05:14:36 +00:00
// Standard graph order
const QList < QString > standardGraphOrder = { STR_GRAPH_SleepFlags , STR_GRAPH_FlowRate , STR_GRAPH_Pressure , STR_GRAPH_LeakRate , STR_GRAPH_FlowLimitation ,
STR_GRAPH_Snore , STR_GRAPH_TidalVolume , STR_GRAPH_MaskPressure , STR_GRAPH_RespRate , STR_GRAPH_MinuteVent ,
2022-11-19 09:02:02 +00:00
STR_GRAPH_PTB , STR_GRAPH_RespEvent , STR_GRAPH_Ti , STR_GRAPH_Te , STR_GRAPH_IE ,
2020-01-23 17:51:58 +00:00
STR_GRAPH_SleepStage , STR_GRAPH_Inclination , STR_GRAPH_Orientation , STR_GRAPH_Motion , STR_GRAPH_TestChan1 ,
2019-09-02 05:14:36 +00:00
STR_GRAPH_Oxi_Pulse , STR_GRAPH_Oxi_SPO2 , STR_GRAPH_Oxi_Perf , STR_GRAPH_Oxi_Plethy ,
2021-12-07 20:01:01 +00:00
STR_GRAPH_AHI , STR_GRAPH_TAP , STR_GRAPH_ObstructLevel , STR_GRAPH_PressureMeasured , STR_GRAPH_rRMV , STR_GRAPH_rMVFluctuation ,
2023-05-06 09:58:29 +00:00
STR_GRAPH_FlowFull
2019-09-02 05:14:36 +00:00
} ;
// Advanced graph order
const QList < QString > advancedGraphOrder = { STR_GRAPH_SleepFlags , STR_GRAPH_FlowRate , STR_GRAPH_MaskPressure , STR_GRAPH_TidalVolume , STR_GRAPH_MinuteVent ,
2022-11-19 09:02:02 +00:00
STR_GRAPH_Ti , STR_GRAPH_Te , STR_GRAPH_IE , STR_GRAPH_FlowLimitation , STR_GRAPH_Pressure , STR_GRAPH_LeakRate , STR_GRAPH_Snore ,
2019-09-02 05:14:36 +00:00
STR_GRAPH_RespRate , STR_GRAPH_PTB , STR_GRAPH_RespEvent ,
2020-01-23 17:51:58 +00:00
STR_GRAPH_SleepStage , STR_GRAPH_Inclination , STR_GRAPH_Orientation , STR_GRAPH_Motion , STR_GRAPH_TestChan1 ,
2019-09-02 05:14:36 +00:00
STR_GRAPH_Oxi_Pulse , STR_GRAPH_Oxi_SPO2 , STR_GRAPH_Oxi_Perf , STR_GRAPH_Oxi_Plethy ,
2021-12-07 20:01:01 +00:00
STR_GRAPH_AHI , STR_GRAPH_TAP , STR_GRAPH_ObstructLevel , STR_GRAPH_PressureMeasured , STR_GRAPH_rRMV , STR_GRAPH_rMVFluctuation ,
2023-05-06 09:58:29 +00:00
STR_GRAPH_FlowFull
2019-09-02 05:14:36 +00:00
} ;
// CPAP modes that should have Advanced graphs
const QList < int > useAdvancedGraphs = { MODE_ASV , MODE_ASV_VARIABLE_EPAP , MODE_AVAPS } ;
2019-09-01 00:56:53 +00:00
2014-08-04 21:28:27 +00:00
void Daily : : setCalendarVisible ( bool visible )
{
on_calButton_toggled ( visible ) ;
}
void Daily : : setSidebarVisible ( bool visible )
{
QList < int > a ;
2018-04-22 12:06:48 +00:00
int panel_width = visible ? AppSetting - > dailyPanelWidth ( ) : 0 ;
2019-01-30 21:59:08 +00:00
qDebug ( ) < < " Daily Left Panel Width is " < < panel_width ;
2014-08-04 21:28:27 +00:00
a . push_back ( panel_width ) ;
a . push_back ( this - > width ( ) - panel_width ) ;
ui - > splitter_2 - > setStretchFactor ( 1 , 1 ) ;
ui - > splitter_2 - > setSizes ( a ) ;
ui - > splitter_2 - > setStretchFactor ( 1 , 1 ) ;
}
2011-12-18 10:53:51 +00:00
Daily : : Daily ( QWidget * parent , gGraphView * shared )
: QWidget ( parent ) , ui ( new Ui : : Daily )
2011-06-26 08:30:44 +00:00
{
2019-03-10 16:03:19 +00:00
qDebug ( ) < < " Creating new Daily object " ;
2011-06-26 08:30:44 +00:00
ui - > setupUi ( this ) ;
2020-01-23 01:10:43 +00:00
ui - > JournalNotesBold - > setShortcut ( QKeySequence : : Bold ) ;
ui - > JournalNotesItalic - > setShortcut ( QKeySequence : : Italic ) ;
ui - > JournalNotesUnderline - > setShortcut ( QKeySequence : : Underline ) ;
2011-10-05 12:43:34 +00:00
// Remove Incomplete Extras Tab
2011-12-02 11:40:47 +00:00
//ui->tabWidget->removeTab(3);
2011-10-05 12:43:34 +00:00
2011-12-03 09:26:59 +00:00
BookmarksChanged = false ;
2014-04-23 13:19:56 +00:00
lastcpapday = nullptr ;
2013-10-22 11:42:57 +00:00
2014-08-05 11:17:03 +00:00
setSidebarVisible ( true ) ;
2011-06-26 08:30:44 +00:00
2014-06-16 00:16:49 +00:00
layout = new QHBoxLayout ( ) ;
2011-08-25 06:11:44 +00:00
layout - > setSpacing ( 0 ) ;
layout - > setMargin ( 0 ) ;
layout - > setContentsMargins ( 0 , 0 , 0 , 0 ) ;
2013-10-10 17:36:53 +00:00
2014-08-17 12:56:05 +00:00
dateDisplay = new MyLabel ( this ) ;
2013-10-12 08:07:57 +00:00
dateDisplay - > setAlignment ( Qt : : AlignCenter ) ;
2014-08-17 12:56:05 +00:00
QFont font = dateDisplay - > font ( ) ;
font . setPointSizeF ( font . pointSizeF ( ) * 1.3F ) ;
dateDisplay - > setFont ( font ) ;
QPalette palette = dateDisplay - > palette ( ) ;
palette . setColor ( QPalette : : Base , Qt : : blue ) ;
dateDisplay - > setPalette ( palette ) ;
//dateDisplay->setTextFormat(Qt::RichText);
2013-10-12 08:07:57 +00:00
ui - > sessionBarLayout - > addWidget ( dateDisplay , 1 ) ;
2013-10-12 07:40:45 +00:00
// const bool sessbar_under_graphs=false;
// if (sessbar_under_graphs) {
// ui->sessionBarLayout->addWidget(sessbar,1);
// } else {
// ui->splitter->insertWidget(2,sessbar);
// sessbar->setMaximumHeight(sessbar->height());
// sessbar->setMinimumHeight(sessbar->height());
// }
2013-10-10 17:36:53 +00:00
2014-05-17 11:33:33 +00:00
ui - > calNavWidget - > setMaximumHeight ( ui - > calNavWidget - > height ( ) ) ;
ui - > calNavWidget - > setMinimumHeight ( ui - > calNavWidget - > height ( ) ) ;
2018-05-07 22:09:59 +00:00
QWidget * widget = new QWidget ( ui - > tabWidget ) ;
sessionbar = new SessionBar ( widget ) ;
sessionbar - > setMinimumHeight ( 25 ) ;
sessionbar - > setMouseTracking ( true ) ;
connect ( sessionbar , SIGNAL ( sessionClicked ( Session * ) ) , this , SLOT ( doToggleSession ( Session * ) ) ) ;
QVBoxLayout * layout2 = new QVBoxLayout ( ) ;
layout2 - > setMargin ( 0 ) ;
widget - > setLayout ( layout2 ) ;
2018-05-08 08:12:32 +00:00
webView = new MyTextBrowser ( widget ) ;
2018-05-07 22:09:59 +00:00
webView - > setOpenLinks ( false ) ;
layout2 - > insertWidget ( 0 , webView , 1 ) ;
layout2 - > insertWidget ( 1 , sessionbar , 0 ) ;
// add the sessionbar after it.
2018-06-14 07:25:54 +00:00
ui - > tabWidget - > insertTab ( 0 , widget , QIcon ( ) , tr ( " Details " ) ) ;
2013-10-12 07:40:45 +00:00
2014-05-17 11:33:33 +00:00
ui - > graphFrame - > setLayout ( layout ) ;
2011-08-25 06:11:44 +00:00
//ui->graphMainArea->setLayout(layout);
ui - > graphMainArea - > setAutoFillBackground ( false ) ;
2014-05-17 11:33:33 +00:00
GraphView = new gGraphView ( ui - > graphFrame , shared ) ;
2019-03-10 16:03:19 +00:00
// qDebug() << "New GraphView object created in Daily";
// sleep(3);
2011-08-25 06:11:44 +00:00
GraphView - > setSizePolicy ( QSizePolicy : : Expanding , QSizePolicy : : Expanding ) ;
2019-04-16 17:12:26 +00:00
GraphView - > setEmptyImage ( QPixmap ( " :/icons/logo-md.png " ) ) ;
2019-03-10 16:03:19 +00:00
2014-08-20 17:17:13 +00:00
snapGV = new gGraphView ( GraphView ) ;
2011-09-21 14:10:10 +00:00
snapGV - > setMinimumSize ( 172 , 172 ) ;
snapGV - > hideSplitter ( ) ;
snapGV - > hide ( ) ;
2011-12-08 14:47:10 +00:00
2014-05-17 11:33:33 +00:00
scrollbar = new MyScrollBar ( ui - > graphFrame ) ;
2011-08-25 06:11:44 +00:00
scrollbar - > setOrientation ( Qt : : Vertical ) ;
scrollbar - > setSizePolicy ( QSizePolicy : : Maximum , QSizePolicy : : Expanding ) ;
scrollbar - > setMaximumWidth ( 20 ) ;
2011-12-02 11:40:47 +00:00
ui - > bookmarkTable - > setColumnCount ( 2 ) ;
ui - > bookmarkTable - > setColumnWidth ( 0 , 70 ) ;
//ui->bookmarkTable->setEditTriggers(QAbstractItemView::SelectedClicked);
//ui->bookmarkTable->setColumnHidden(2,true);
//ui->bookmarkTable->setColumnHidden(3,true);
2011-08-25 06:11:44 +00:00
GraphView - > setScrollBar ( scrollbar ) ;
layout - > addWidget ( GraphView , 1 ) ;
layout - > addWidget ( scrollbar , 0 ) ;
2011-07-29 14:58:44 +00:00
2018-04-22 12:06:48 +00:00
int default_height = AppSetting - > graphHeight ( ) ;
2014-04-05 02:27:47 +00:00
2014-05-13 08:14:20 +00:00
gGraph * GAHI = nullptr ,
// *TAP = nullptr,
* SF = nullptr ,
* AHI = nullptr ;
2019-09-01 00:56:53 +00:00
// const QString STR_GRAPH_DailySummary = "DailySummary";
2014-08-09 17:12:37 +00:00
2014-08-19 10:26:44 +00:00
// gGraph * SG;
2018-06-14 07:25:54 +00:00
// graphlist[STR_GRAPH_DailySummary] = SG = new gGraph(STR_GRAPH_DailySummary, GraphView, tr("Summary"), tr("Summary of this daily information"), default_height);
2014-08-19 10:26:44 +00:00
// SG->AddLayer(new gLabelArea(nullptr),LayerLeft,gYAxis::Margin);
2014-09-01 04:49:05 +00:00
// SG->AddLayer(new gDailySummary());
2014-08-09 17:12:37 +00:00
2014-07-16 17:12:52 +00:00
graphlist [ STR_GRAPH_SleepFlags ] = SF = new gGraph ( STR_GRAPH_SleepFlags , GraphView , STR_TR_EventFlags , STR_TR_EventFlags , default_height ) ;
2023-03-14 20:11:46 +00:00
sleepFlags = SF ;
2014-04-05 01:28:07 +00:00
SF - > setPinned ( true ) ;
2011-12-24 05:55:44 +00:00
2023-03-14 20:11:46 +00:00
2019-09-03 19:56:10 +00:00
//============================================
// Create graphs from 'interesting' CPAP codes
//
// If this list of codes is changed, you must
// also adjust the standard and advanced graph
// order at the beginning of daily.cpp.
//============================================
2019-09-03 05:10:36 +00:00
const ChannelID cpapcodes [ ] = {
2019-07-13 02:29:33 +00:00
CPAP_FlowRate , CPAP_Pressure , CPAP_Leak , CPAP_FLG , CPAP_Snore , CPAP_TidalVolume ,
2020-04-22 20:52:21 +00:00
CPAP_MaskPressure , CPAP_RespRate , CPAP_MinuteVent , CPAP_PTB , PRS1_PeakFlow , CPAP_RespEvent , CPAP_Ti , CPAP_Te ,
2022-11-19 09:02:02 +00:00
CPAP_IE , ZEO_SleepStage , POS_Inclination , POS_Orientation , POS_Movement , CPAP_Test1 ,
2023-06-11 22:05:18 +00:00
Prisma_ObstructLevel , Prisma_rRMV , Prisma_rMVFluctuation , Prisma_PressureMeasured , Prisma_FlowFull
2014-05-13 08:14:20 +00:00
} ;
2019-09-01 00:56:53 +00:00
// Create graphs from the cpap code list
2014-05-13 08:14:20 +00:00
int cpapsize = sizeof ( cpapcodes ) / sizeof ( ChannelID ) ;
for ( int i = 0 ; i < cpapsize ; + + i ) {
ChannelID code = cpapcodes [ i ] ;
2014-08-03 13:00:13 +00:00
graphlist [ schema : : channel [ code ] . code ( ) ] = new gGraph ( schema : : channel [ code ] . code ( ) , GraphView , schema : : channel [ code ] . label ( ) , channelInfo ( code ) , default_height ) ;
2019-09-03 05:10:36 +00:00
// qDebug() << "Creating graph for code" << code << schema::channel[code].code();
2014-05-13 08:14:20 +00:00
}
2019-09-03 19:56:10 +00:00
const ChannelID oximetercodes [ ] = {
OXI_Pulse , OXI_SPO2 , OXI_Perf , OXI_Plethy
} ;
2019-09-01 00:56:53 +00:00
// Add graphs from the Oximeter code list
2019-07-31 02:59:01 +00:00
int oxisize = sizeof ( oximetercodes ) / sizeof ( ChannelID ) ;
2014-09-29 14:41:31 +00:00
//int oxigrp=p_profile->ExistsAndTrue("SyncOximetry") ? 0 : 1; // Contemplating killing this setting...
2014-05-13 08:14:20 +00:00
for ( int i = 0 ; i < oxisize ; + + i ) {
2019-07-31 02:59:01 +00:00
ChannelID code = oximetercodes [ i ] ;
2014-09-29 14:41:31 +00:00
graphlist [ schema : : channel [ code ] . code ( ) ] = new gGraph ( schema : : channel [ code ] . code ( ) , GraphView , schema : : channel [ code ] . label ( ) , channelInfo ( code ) , default_height ) ;
2014-05-13 08:14:20 +00:00
}
2011-12-24 05:55:44 +00:00
2019-09-01 00:56:53 +00:00
// Check for some impossible conditions
2019-03-10 16:03:19 +00:00
if ( p_profile = = nullptr ) {
qDebug ( ) < < " In daily, p_profile is NULL " ;
return ;
}
else if ( p_profile - > general = = nullptr ) {
qDebug ( ) < < " In daily, p_profile->general is NULL " ;
return ;
}
2019-09-01 00:56:53 +00:00
// Decide whether we are using AHI or RDI and create graph for the one we are using
2014-07-11 12:09:38 +00:00
if ( p_profile - > general - > calculateRDI ( ) ) {
2019-09-01 00:56:53 +00:00
AHI = new gGraph ( STR_GRAPH_AHI , GraphView , STR_TR_RDI , channelInfo ( CPAP_RDI ) , default_height ) ;
2014-05-13 08:14:20 +00:00
} else {
2019-09-01 00:56:53 +00:00
AHI = new gGraph ( STR_GRAPH_AHI , GraphView , STR_TR_AHI , channelInfo ( CPAP_AHI ) , default_height ) ;
2014-05-13 08:14:20 +00:00
}
2019-09-01 00:56:53 +00:00
graphlist [ STR_GRAPH_AHI ] = AHI ;
2014-05-13 08:14:20 +00:00
2019-09-01 00:56:53 +00:00
// Event breakdown graph
2014-07-16 17:12:52 +00:00
graphlist [ STR_GRAPH_EventBreakdown ] = GAHI = new gGraph ( STR_GRAPH_EventBreakdown , snapGV , tr ( " Breakdown " ) , tr ( " events " ) , 172 ) ;
2011-09-21 14:10:10 +00:00
gSegmentChart * evseg = new gSegmentChart ( GST_Pie ) ;
2013-09-10 15:09:09 +00:00
evseg - > AddSlice ( CPAP_Hypopnea , QColor ( 0x40 , 0x40 , 0xff , 0xff ) , STR_TR_H ) ;
evseg - > AddSlice ( CPAP_Apnea , QColor ( 0x20 , 0x80 , 0x20 , 0xff ) , STR_TR_UA ) ;
evseg - > AddSlice ( CPAP_Obstructive , QColor ( 0x40 , 0xaf , 0xbf , 0xff ) , STR_TR_OA ) ;
evseg - > AddSlice ( CPAP_ClearAirway , QColor ( 0xb2 , 0x54 , 0xcd , 0xff ) , STR_TR_CA ) ;
2021-07-25 04:12:15 +00:00
evseg - > AddSlice ( CPAP_AllApnea , QColor ( 0x40 , 0xaf , 0xbf , 0xff ) , STR_TR_A ) ;
2013-09-10 15:09:09 +00:00
evseg - > AddSlice ( CPAP_RERA , QColor ( 0xff , 0xff , 0x80 , 0xff ) , STR_TR_RE ) ;
evseg - > AddSlice ( CPAP_NRI , QColor ( 0x00 , 0x80 , 0x40 , 0xff ) , STR_TR_NR ) ;
evseg - > AddSlice ( CPAP_FlowLimit , QColor ( 0x40 , 0x40 , 0x40 , 0xff ) , STR_TR_FL ) ;
2014-05-15 03:51:32 +00:00
evseg - > AddSlice ( CPAP_SensAwake , QColor ( 0x40 , 0xC0 , 0x40 , 0xff ) , STR_TR_SA ) ;
2018-04-22 12:06:48 +00:00
if ( AppSetting - > userEventPieChart ( ) ) {
2014-07-20 09:22:31 +00:00
evseg - > AddSlice ( CPAP_UserFlag1 , QColor ( 0xe0 , 0xe0 , 0xe0 , 0xff ) , tr ( " UF1 " ) ) ;
evseg - > AddSlice ( CPAP_UserFlag2 , QColor ( 0xc0 , 0xc0 , 0xe0 , 0xff ) , tr ( " UF2 " ) ) ;
}
2011-09-21 14:10:10 +00:00
2014-08-28 08:01:25 +00:00
GAHI - > AddLayer ( evseg ) ;
2011-09-21 14:10:10 +00:00
GAHI - > setMargins ( 0 , 0 , 0 , 0 ) ;
2019-09-01 00:56:53 +00:00
// Add event flags to the event flags graph
2011-08-25 06:11:44 +00:00
gFlagsGroup * fg = new gFlagsGroup ( ) ;
2023-03-17 15:22:55 +00:00
sleepFlagsGroup = fg ;
2014-08-28 08:01:25 +00:00
SF - > AddLayer ( fg ) ;
2014-08-23 06:21:50 +00:00
2011-08-25 08:02:04 +00:00
SF - > setBlockZoom ( true ) ;
2011-08-25 09:00:19 +00:00
SF - > AddLayer ( new gShadowArea ( ) ) ;
2014-08-12 10:44:05 +00:00
SF - > AddLayer ( new gLabelArea ( fg ) , LayerLeft , gYAxis : : Margin ) ;
2014-08-29 04:02:16 +00:00
SF - > AddLayer ( new gXAxis ( COLOR_Text , false ) , LayerBottom , 0 , gXAxis : : Margin ) ;
2011-08-25 06:11:44 +00:00
2019-09-01 00:56:53 +00:00
// Now take care of xgrid/yaxis labels for all graphs
2014-05-13 08:14:20 +00:00
// The following list contains graphs that don't have standard xgrid/yaxis labels
QStringList skipgraph ;
2014-08-09 17:12:37 +00:00
skipgraph . push_back ( STR_GRAPH_EventBreakdown ) ;
skipgraph . push_back ( STR_GRAPH_SleepFlags ) ;
2014-08-11 18:29:44 +00:00
skipgraph . push_back ( STR_GRAPH_TAP ) ;
2014-05-13 08:14:20 +00:00
QHash < QString , gGraph * > : : iterator it ;
for ( it = graphlist . begin ( ) ; it ! = graphlist . end ( ) ; + + it ) {
if ( skipgraph . contains ( it . key ( ) ) ) continue ;
it . value ( ) - > AddLayer ( new gXGrid ( ) ) ;
}
2011-08-25 06:11:44 +00:00
gLineChart * l ;
2014-08-17 15:36:53 +00:00
l = new gLineChart ( CPAP_FlowRate , false , false ) ;
2014-05-13 08:14:20 +00:00
2014-08-03 13:00:13 +00:00
gGraph * FRW = graphlist [ schema : : channel [ CPAP_FlowRate ] . code ( ) ] ;
2011-08-25 06:11:44 +00:00
FRW - > AddLayer ( l ) ;
2023-03-17 15:43:26 +00:00
l - > setMinimumHeight ( 80 ) ; // set the layer height to 80. or about 130 graph height.
2023-09-25 18:34:18 +00:00
2014-08-23 06:21:50 +00:00
// FRW->AddLayer(AddOXI(new gLineOverlayBar(OXI_SPO2Drop, COLOR_SPO2Drop, STR_TR_O2)));
2011-08-25 06:11:44 +00:00
2018-04-22 12:06:48 +00:00
bool square = AppSetting - > squareWavePlots ( ) ;
2014-08-17 15:36:53 +00:00
gLineChart * pc = new gLineChart ( CPAP_Pressure , square ) ;
2014-08-28 08:01:25 +00:00
graphlist [ schema : : channel [ CPAP_Pressure ] . code ( ) ] - > AddLayer ( pc ) ;
2014-08-03 13:00:13 +00:00
2014-08-23 06:21:50 +00:00
// graphlist[schema::channel[CPAP_Pressure].code()]->AddLayer(AddCPAP(new gLineOverlayBar(CPAP_Ramp, COLOR_Ramp, schema::channel[CPAP_Ramp].label(), FT_Span)));
2014-08-03 13:00:13 +00:00
2014-08-17 15:36:53 +00:00
pc - > addPlot ( CPAP_EPAP , square ) ;
pc - > addPlot ( CPAP_IPAPLo , square ) ;
pc - > addPlot ( CPAP_IPAP , square ) ;
pc - > addPlot ( CPAP_IPAPHi , square ) ;
2022-09-21 01:11:51 +00:00
pc - > addPlot ( CPAP_EEPAP , square ) ;
2019-10-29 15:14:57 +00:00
pc - > addPlot ( CPAP_PressureSet , false ) ;
pc - > addPlot ( CPAP_EPAPSet , false ) ;
pc - > addPlot ( CPAP_IPAPSet , false ) ;
2011-11-07 04:10:48 +00:00
2019-09-01 00:56:53 +00:00
// Create Timea at Pressure graph
2014-08-11 18:29:44 +00:00
gGraph * TAP2 ;
2018-06-14 07:25:54 +00:00
graphlist [ STR_GRAPH_TAP ] = TAP2 = new gGraph ( STR_GRAPH_TAP , GraphView , tr ( " Time at Pressure " ) , tr ( " Time at Pressure " ) , default_height ) ;
2014-08-12 10:44:05 +00:00
MinutesAtPressure * map ;
2014-08-28 08:01:25 +00:00
TAP2 - > AddLayer ( map = new MinutesAtPressure ( ) ) ;
2016-03-07 15:45:28 +00:00
TAP2 - > AddLayer ( new gLabelArea ( map ) , LayerLeft , gYAxis : : Margin ) ;
2016-03-07 09:10:58 +00:00
TAP2 - > AddLayer ( new gXAxisPressure ( ) , LayerBottom , gXAxisPressure : : Margin ) ;
2014-08-12 06:43:10 +00:00
TAP2 - > setBlockSelect ( true ) ;
2014-08-11 18:29:44 +00:00
2019-09-01 00:56:53 +00:00
// Fill in the AHI graph
2014-07-11 12:09:38 +00:00
if ( p_profile - > general - > calculateRDI ( ) ) {
2014-08-28 08:01:25 +00:00
AHI - > AddLayer ( new gLineChart ( CPAP_RDI , square ) ) ;
2012-01-10 10:00:08 +00:00
// AHI->AddLayer(AddCPAP(new AHIChart(QColor("#37a24b"))));
2011-12-24 05:55:44 +00:00
} else {
2014-08-28 08:01:25 +00:00
AHI - > AddLayer ( new gLineChart ( CPAP_AHI , square ) ) ;
2011-12-24 05:55:44 +00:00
}
2011-11-30 06:56:20 +00:00
2014-05-15 19:45:46 +00:00
// this is class wide because the leak redline can be reset in preferences..
// Better way would be having a search for linechart layers in graphlist[...]
2014-08-17 15:36:53 +00:00
gLineChart * leakchart = new gLineChart ( CPAP_Leak , square ) ;
2014-08-23 06:21:50 +00:00
// graphlist[schema::channel[CPAP_Leak].code()]->AddLayer(AddCPAP(new gLineOverlayBar(CPAP_LargeLeak, COLOR_LargeLeak, STR_TR_LL, FT_Span)));
2014-07-15 07:01:47 +00:00
2014-08-17 15:36:53 +00:00
leakchart - > addPlot ( CPAP_LeakTotal , square ) ;
leakchart - > addPlot ( CPAP_MaxLeak , square ) ;
2014-08-19 14:04:29 +00:00
// schema::channel[CPAP_Leak].setUpperThresholdColor(Qt::red);
// schema::channel[CPAP_Leak].setLowerThresholdColor(Qt::green);
2014-05-15 19:45:46 +00:00
2014-08-28 08:01:25 +00:00
graphlist [ schema : : channel [ CPAP_Leak ] . code ( ) ] - > AddLayer ( leakchart ) ;
2013-09-10 15:09:09 +00:00
//LEAK->AddLayer(AddCPAP(new gLineChart(CPAP_Leak, COLOR_Leak,square)));
//LEAK->AddLayer(AddCPAP(new gLineChart(CPAP_MaxLeak, COLOR_MaxLeak,square)));
2014-08-28 08:01:25 +00:00
graphlist [ schema : : channel [ CPAP_Snore ] . code ( ) ] - > AddLayer ( new gLineChart ( CPAP_Snore , true ) ) ;
2012-01-09 03:43:42 +00:00
2014-08-28 08:01:25 +00:00
graphlist [ schema : : channel [ CPAP_PTB ] . code ( ) ] - > AddLayer ( new gLineChart ( CPAP_PTB , square ) ) ;
2020-04-22 20:52:21 +00:00
graphlist [ schema : : channel [ PRS1_PeakFlow ] . code ( ) ] - > AddLayer ( new gLineChart ( PRS1_PeakFlow , square ) ) ;
2021-12-07 20:01:01 +00:00
graphlist [ schema : : channel [ Prisma_ObstructLevel ] . code ( ) ] - > AddLayer ( new gLineChart ( Prisma_ObstructLevel , square ) ) ;
graphlist [ schema : : channel [ Prisma_PressureMeasured ] . code ( ) ] - > AddLayer ( new gLineChart ( Prisma_PressureMeasured , square ) ) ;
graphlist [ schema : : channel [ Prisma_rRMV ] . code ( ) ] - > AddLayer ( new gLineChart ( Prisma_rRMV , square ) ) ;
graphlist [ schema : : channel [ Prisma_rMVFluctuation ] . code ( ) ] - > AddLayer ( new gLineChart ( Prisma_rMVFluctuation , square ) ) ;
graphlist [ schema : : channel [ Prisma_FlowFull ] . code ( ) ] - > AddLayer ( new gLineChart ( Prisma_FlowFull , square ) ) ;
2018-05-05 07:14:44 +00:00
graphlist [ schema : : channel [ CPAP_Test1 ] . code ( ) ] - > AddLayer ( new gLineChart ( CPAP_Test1 , square ) ) ;
//graphlist[schema::channel[CPAP_Test2].code()]->AddLayer(new gLineChart(CPAP_Test2, square));
2014-05-15 17:56:53 +00:00
2014-05-15 19:45:46 +00:00
gLineChart * lc = nullptr ;
2014-08-28 08:01:25 +00:00
graphlist [ schema : : channel [ CPAP_MaskPressure ] . code ( ) ] - > AddLayer ( new gLineChart ( CPAP_MaskPressure , false ) ) ;
2018-05-05 07:14:44 +00:00
graphlist [ schema : : channel [ CPAP_RespRate ] . code ( ) ] - > AddLayer ( lc = new gLineChart ( CPAP_RespRate , square ) ) ;
2014-04-15 13:59:24 +00:00
2014-08-28 08:01:25 +00:00
graphlist [ schema : : channel [ POS_Inclination ] . code ( ) ] - > AddLayer ( new gLineChart ( POS_Inclination ) ) ;
graphlist [ schema : : channel [ POS_Orientation ] . code ( ) ] - > AddLayer ( new gLineChart ( POS_Orientation ) ) ;
2020-01-27 00:50:18 +00:00
graphlist [ schema : : channel [ POS_Movement ] . code ( ) ] - > AddLayer ( new gLineChart ( POS_Movement ) ) ;
2012-01-09 03:43:42 +00:00
2018-05-05 07:14:44 +00:00
graphlist [ schema : : channel [ CPAP_MinuteVent ] . code ( ) ] - > AddLayer ( lc = new gLineChart ( CPAP_MinuteVent , square ) ) ;
2014-08-17 15:36:53 +00:00
lc - > addPlot ( CPAP_TgMV , square ) ;
2012-01-09 15:38:41 +00:00
2018-05-05 07:14:44 +00:00
graphlist [ schema : : channel [ CPAP_TidalVolume ] . code ( ) ] - > AddLayer ( lc = new gLineChart ( CPAP_TidalVolume , square ) ) ;
2013-09-10 15:09:09 +00:00
//lc->addPlot(CPAP_Test2,COLOR_DarkYellow,square);
2012-01-09 03:43:42 +00:00
2014-08-17 15:36:53 +00:00
//graphlist[schema::channel[CPAP_TidalVolume].code()]->AddLayer(AddCPAP(new gLineChart("TidalVolume2", square)));
2014-08-28 08:01:25 +00:00
graphlist [ schema : : channel [ CPAP_FLG ] . code ( ) ] - > AddLayer ( new gLineChart ( CPAP_FLG , true ) ) ;
2014-08-17 15:36:53 +00:00
//graphlist[schema::channel[CPAP_RespiratoryEvent].code()]->AddLayer(AddCPAP(new gLineChart(CPAP_RespiratoryEvent, true)));
2022-11-19 09:02:02 +00:00
graphlist [ schema : : channel [ CPAP_IE ] . code ( ) ] - > AddLayer ( lc = new gLineChart ( CPAP_IE , false ) ) ; // this should be inverse of supplied value
2014-08-28 08:01:25 +00:00
graphlist [ schema : : channel [ CPAP_Te ] . code ( ) ] - > AddLayer ( lc = new gLineChart ( CPAP_Te , false ) ) ;
graphlist [ schema : : channel [ CPAP_Ti ] . code ( ) ] - > AddLayer ( lc = new gLineChart ( CPAP_Ti , false ) ) ;
2013-09-10 15:09:09 +00:00
//lc->addPlot(CPAP_Test2,COLOR:DarkYellow,square);
2011-11-28 22:49:43 +00:00
2014-08-28 08:01:25 +00:00
graphlist [ schema : : channel [ ZEO_SleepStage ] . code ( ) ] - > AddLayer ( new gLineChart ( ZEO_SleepStage , true ) ) ;
2012-01-11 13:55:46 +00:00
2014-08-20 09:31:14 +00:00
// gLineOverlaySummary *los1=new gLineOverlaySummary(STR_UNIT_EventsPerHour,5,-4);
// gLineOverlaySummary *los2=new gLineOverlaySummary(STR_UNIT_EventsPerHour,5,-4);
// graphlist[schema::channel[OXI_Pulse].code()]->AddLayer(AddOXI(los1->add(new gLineOverlayBar(OXI_PulseChange, COLOR_PulseChange, STR_TR_PC,FT_Span))));
// graphlist[schema::channel[OXI_Pulse].code()]->AddLayer(AddOXI(los1));
// graphlist[schema::channel[OXI_SPO2].code()]->AddLayer(AddOXI(los2->add(new gLineOverlayBar(OXI_SPO2Drop, COLOR_SPO2Drop, STR_TR_O2,FT_Span))));
// graphlist[schema::channel[OXI_SPO2].code()]->AddLayer(AddOXI(los2));
2011-11-28 22:49:43 +00:00
2014-08-28 08:01:25 +00:00
graphlist [ schema : : channel [ OXI_Pulse ] . code ( ) ] - > AddLayer ( new gLineChart ( OXI_Pulse , square ) ) ;
graphlist [ schema : : channel [ OXI_SPO2 ] . code ( ) ] - > AddLayer ( new gLineChart ( OXI_SPO2 , true ) ) ;
graphlist [ schema : : channel [ OXI_Perf ] . code ( ) ] - > AddLayer ( new gLineChart ( OXI_Perf , false ) ) ;
graphlist [ schema : : channel [ OXI_Plethy ] . code ( ) ] - > AddLayer ( new gLineChart ( OXI_Plethy , false ) ) ;
2011-08-26 03:26:53 +00:00
2014-05-13 08:14:20 +00:00
// Fix me
2014-08-20 09:31:14 +00:00
// gLineOverlaySummary *los3=new gLineOverlaySummary(STR_UNIT_EventsPerHour,5,-4);
// graphlist["INTPULSE"]->AddLayer(AddCPAP(los3->add(new gLineOverlayBar(OXI_PulseChange, COLOR_PulseChange, STR_TR_PC,FT_Span))));
// graphlist["INTPULSE"]->AddLayer(AddCPAP(los3));
2014-08-21 14:16:23 +00:00
// graphlist["INTPULSE"]->AddLayer(AddCPAP(new gLineChart(OXI_Pulse, square)));
2014-08-20 09:31:14 +00:00
// gLineOverlaySummary *los4=new gLineOverlaySummary(STR_UNIT_EventsPerHour,5,-4);
// graphlist["INTSPO2"]->AddLayer(AddCPAP(los4->add(new gLineOverlayBar(OXI_SPO2Drop, COLOR_SPO2Drop, STR_TR_O2,FT_Span))));
// graphlist["INTSPO2"]->AddLayer(AddCPAP(los4));
2014-08-21 14:16:23 +00:00
// graphlist["INTSPO2"]->AddLayer(AddCPAP(new gLineChart(OXI_SPO2, true)));
2013-10-13 17:33:43 +00:00
2014-08-03 13:00:13 +00:00
graphlist [ schema : : channel [ CPAP_PTB ] . code ( ) ] - > setForceMaxY ( 100 ) ;
graphlist [ schema : : channel [ OXI_SPO2 ] . code ( ) ] - > setForceMaxY ( 100 ) ;
2013-10-13 17:33:43 +00:00
2014-05-13 08:14:20 +00:00
for ( it = graphlist . begin ( ) ; it ! = graphlist . end ( ) ; + + it ) {
if ( skipgraph . contains ( it . key ( ) ) ) continue ;
2011-11-27 06:25:27 +00:00
2014-05-13 08:14:20 +00:00
it . value ( ) - > AddLayer ( new gYAxis ( ) , LayerLeft , gYAxis : : Margin ) ;
2014-08-29 04:02:16 +00:00
it . value ( ) - > AddLayer ( new gXAxis ( ) , LayerBottom , 0 , gXAxis : : Margin ) ;
2011-08-29 11:42:40 +00:00
}
2011-08-25 06:11:44 +00:00
2014-07-11 12:09:38 +00:00
if ( p_profile - > cpap - > showLeakRedline ( ) ) {
schema : : channel [ CPAP_Leak ] . setUpperThreshold ( p_profile - > cpap - > leakRedline ( ) ) ;
2014-05-15 22:48:51 +00:00
} else {
schema : : channel [ CPAP_Leak ] . setUpperThreshold ( 0 ) ; // switch it off
}
2011-08-25 06:11:44 +00:00
layout - > layout ( ) ;
2011-08-26 03:26:53 +00:00
QTextCharFormat format = ui - > calendar - > weekdayTextFormat ( Qt : : Saturday ) ;
2013-09-10 15:09:09 +00:00
format . setForeground ( QBrush ( COLOR_Black , Qt : : SolidPattern ) ) ;
2011-08-26 03:26:53 +00:00
ui - > calendar - > setWeekdayTextFormat ( Qt : : Saturday , format ) ;
ui - > calendar - > setWeekdayTextFormat ( Qt : : Sunday , format ) ;
2011-11-15 21:22:08 +00:00
Qt : : DayOfWeek dow = firstDayOfWeekFromLocale ( ) ;
ui - > calendar - > setFirstDayOfWeek ( dow ) ;
2011-08-26 03:26:53 +00:00
2018-05-07 22:09:59 +00:00
ui - > tabWidget - > setCurrentWidget ( widget ) ;
2011-10-05 10:44:41 +00:00
2018-05-07 22:09:59 +00:00
connect ( webView , SIGNAL ( anchorClicked ( QUrl ) ) , this , SLOT ( Link_clicked ( QUrl ) ) ) ;
2011-11-27 07:41:00 +00:00
2014-07-11 12:09:38 +00:00
int ews = p_profile - > general - > eventWindowSize ( ) ;
2011-11-27 07:41:00 +00:00
ui - > evViewSlider - > setValue ( ews ) ;
ui - > evViewLCD - > display ( ews ) ;
2014-04-05 01:28:07 +00:00
2012-01-03 16:29:35 +00:00
icon_on = new QIcon ( " :/icons/session-on.png " ) ;
icon_off = new QIcon ( " :/icons/session-off.png " ) ;
2021-11-30 04:08:05 +00:00
icon_up_down = new QIcon ( " :/icons/up-down.png " ) ;
icon_warning = new QIcon ( " :/icons/warning.png " ) ;
2012-01-03 16:29:35 +00:00
2011-12-23 14:12:04 +00:00
ui - > splitter - > setVisible ( false ) ;
2011-12-01 06:06:13 +00:00
2022-11-17 01:46:30 +00:00
# ifndef REMOVE_FITNESS
# else // REMOVE_FITNESS
// hide the parent widget to make the gridlayout invisible
QWidget * myparent ;
2023-09-25 18:34:18 +00:00
myparent = ui - > bioMetrics - > parentWidget ( ) ;
2022-11-17 01:46:30 +00:00
if ( myparent ) myparent - > hide ( ) ;
# endif
2019-03-10 16:03:19 +00:00
2019-04-16 17:12:26 +00:00
GraphView - > setEmptyImage ( QPixmap ( " :/icons/logo-md.png " ) ) ;
2014-08-21 08:04:25 +00:00
GraphView - > setEmptyText ( STR_Empty_NoData ) ;
2012-01-25 22:34:21 +00:00
previous_date = QDate ( ) ;
2014-08-06 20:10:40 +00:00
2019-05-08 21:18:00 +00:00
ui - > calButton - > setChecked ( AppSetting - > calendarVisible ( ) ? true : false ) ;
2018-04-22 12:06:48 +00:00
on_calButton_toggled ( AppSetting - > calendarVisible ( ) ) ;
2014-08-06 20:10:40 +00:00
2014-08-11 04:52:14 +00:00
GraphView - > resetLayout ( ) ;
2019-07-31 02:59:01 +00:00
GraphView - > SaveDefaultSettings ( ) ;
2014-08-11 04:52:14 +00:00
GraphView - > LoadSettings ( " Daily " ) ;
2014-08-17 12:56:05 +00:00
connect ( GraphView , SIGNAL ( updateCurrentTime ( double ) ) , this , SLOT ( on_LineCursorUpdate ( double ) ) ) ;
connect ( GraphView , SIGNAL ( updateRange ( double , double ) ) , this , SLOT ( on_RangeUpdate ( double , double ) ) ) ;
2014-08-29 11:34:21 +00:00
connect ( GraphView , SIGNAL ( GraphsChanged ( ) ) , this , SLOT ( updateGraphCombo ( ) ) ) ;
2021-03-28 03:22:31 +00:00
// Watch for focusOut events on the JournalNotes widget
ui - > JournalNotes - > installEventFilter ( this ) ;
2019-03-10 16:03:19 +00:00
// qDebug() << "Finished making new Daily object";
// sleep(3);
2022-12-28 18:24:01 +00:00
saveGraphLayoutSettings = nullptr ;
2023-02-06 16:06:03 +00:00
dailySearchTab = new DailySearchTab ( this , ui - > searchTab , ui - > tabWidget ) ;
2024-03-20 16:59:40 +00:00
htmlLsbSectionHeaderInit ( false ) ;
2011-10-30 03:09:43 +00:00
}
2011-06-26 08:30:44 +00:00
Daily : : ~ Daily ( )
{
2018-06-07 21:53:09 +00:00
disconnect ( GraphView , SIGNAL ( updateCurrentTime ( double ) ) , this , SLOT ( on_LineCursorUpdate ( double ) ) ) ;
disconnect ( GraphView , SIGNAL ( updateRange ( double , double ) ) , this , SLOT ( on_RangeUpdate ( double , double ) ) ) ;
disconnect ( GraphView , SIGNAL ( GraphsChanged ( ) ) , this , SLOT ( updateGraphCombo ( ) ) ) ;
2018-05-07 22:09:59 +00:00
disconnect ( sessionbar , SIGNAL ( sessionClicked ( Session * ) ) , this , SLOT ( doToggleSession ( Session * ) ) ) ;
2019-01-30 21:59:08 +00:00
disconnect ( webView , SIGNAL ( anchorClicked ( QUrl ) ) , this , SLOT ( Link_clicked ( QUrl ) ) ) ;
2021-03-28 03:22:31 +00:00
ui - > JournalNotes - > removeEventFilter ( this ) ;
2011-11-27 16:07:28 +00:00
2021-03-28 03:22:31 +00:00
if ( previous_date . isValid ( ) ) {
2018-06-07 21:53:09 +00:00
Unload ( previous_date ) ;
2021-03-28 03:22:31 +00:00
}
2018-06-07 21:53:09 +00:00
// Save graph orders and pin status, etc...
GraphView - > SaveSettings ( " Daily " ) ;
2011-06-26 08:30:44 +00:00
delete ui ;
2012-01-03 16:29:35 +00:00
delete icon_on ;
delete icon_off ;
2022-12-28 18:24:01 +00:00
if ( saveGraphLayoutSettings ! = nullptr ) delete saveGraphLayoutSettings ;
2023-02-06 16:06:03 +00:00
delete dailySearchTab ;
2011-06-26 08:30:44 +00:00
}
2013-10-10 17:36:53 +00:00
2014-05-15 21:48:53 +00:00
void Daily : : showEvent ( QShowEvent * )
{
2019-03-10 16:03:19 +00:00
// qDebug() << "Start showEvent in Daily object";
// sleep(3);
2014-05-15 21:48:53 +00:00
RedrawGraphs ( ) ;
2019-03-10 16:03:19 +00:00
// qDebug() << "Finished showEvent Daily object";
// sleep(3);
2014-05-15 21:48:53 +00:00
}
2023-02-25 01:18:54 +00:00
bool Daily : : rejectToggleSessionEnable ( Session * sess ) {
if ( ! sess ) return true ;
2023-06-09 16:47:10 +00:00
if ( p_profile - > cpap - > clinicalMode ( ) ) {
2023-07-09 20:09:32 +00:00
QMessageBox mbox ( QMessageBox : : Warning , tr ( " Clinical Mode " ) , tr ( " Disabling Sessions requires Permissive Mode be set in OSCAR Preferences in the Clinical tab. " ) , QMessageBox : : Ok , this ) ;
2023-06-08 16:32:51 +00:00
mbox . exec ( ) ;
return true ;
}
2014-05-25 07:07:08 +00:00
sess - > setEnabled ( ! sess - > enabled ( ) ) ;
2023-02-25 01:18:54 +00:00
return false ;
}
2014-05-25 07:07:08 +00:00
2013-10-10 17:36:53 +00:00
void Daily : : doToggleSession ( Session * sess )
{
2023-02-25 01:18:54 +00:00
if ( rejectToggleSessionEnable ( sess ) ) return ;
2014-08-20 17:17:13 +00:00
LoadDate ( previous_date ) ;
2014-09-14 15:29:07 +00:00
mainwin - > getOverview ( ) - > graphView ( ) - > dataChanged ( ) ;
2023-06-02 17:27:06 +00:00
mainwin - > GenerateStatistics ( ) ;
2013-10-10 17:36:53 +00:00
}
2011-12-03 08:52:24 +00:00
void Daily : : Link_clicked ( const QUrl & url )
2011-11-24 23:03:33 +00:00
{
QString code = url . toString ( ) . section ( " = " , 0 , 0 ) . toLower ( ) ;
QString data = url . toString ( ) . section ( " = " , 1 ) ;
2024-02-12 13:52:00 +00:00
SessionID sid = data . toUInt ( ) ;
2014-04-23 13:19:56 +00:00
Day * day = nullptr ;
2014-08-20 17:17:13 +00:00
2011-12-28 12:03:48 +00:00
if ( code = = " togglecpapsession " ) { // Enable/Disable CPAP session
2014-07-11 12:09:38 +00:00
day = p_profile - > GetDay ( previous_date , MT_CPAP ) ;
2014-08-20 17:17:13 +00:00
if ( ! day ) return ;
2020-11-05 04:12:05 +00:00
Session * sess = day - > find ( sid , MT_CPAP ) ;
2018-05-07 22:09:59 +00:00
// int i=webView->page()->mainFrame()->scrollBarMaximum(Qt::Vertical)-webView->page()->mainFrame()->scrollBarValue(Qt::Vertical);
2023-02-25 01:18:54 +00:00
if ( rejectToggleSessionEnable ( sess ) ) return ;
2011-12-28 12:03:48 +00:00
// Reload day
2014-08-20 17:17:13 +00:00
LoadDate ( previous_date ) ;
2023-01-16 13:26:01 +00:00
mainwin - > getOverview ( ) - > graphView ( ) - > dataChanged ( ) ;
2018-05-07 22:09:59 +00:00
// webView->page()->mainFrame()->setScrollBarValue(Qt::Vertical, webView->page()->mainFrame()->scrollBarMaximum(Qt::Vertical)-i);
2011-12-28 12:03:48 +00:00
} else if ( code = = " toggleoxisession " ) { // Enable/Disable Oximetry session
2014-07-11 12:09:38 +00:00
day = p_profile - > GetDay ( previous_date , MT_OXIMETER ) ;
2021-04-01 00:32:58 +00:00
if ( ! day ) return ;
2020-11-05 04:12:05 +00:00
Session * sess = day - > find ( sid , MT_OXIMETER ) ;
2018-05-07 22:09:59 +00:00
// int i=webView->page()->mainFrame()->scrollBarMaximum(Qt::Vertical)-webView->page()->mainFrame()->scrollBarValue(Qt::Vertical);
2023-02-25 01:18:54 +00:00
if ( rejectToggleSessionEnable ( sess ) ) return ;
2014-08-20 17:17:13 +00:00
2011-12-28 12:03:48 +00:00
// Reload day
2014-08-20 17:17:13 +00:00
LoadDate ( previous_date ) ;
2023-01-16 13:26:01 +00:00
mainwin - > getOverview ( ) - > graphView ( ) - > dataChanged ( ) ;
2018-05-07 22:09:59 +00:00
// webView->page()->mainFrame()->setScrollBarValue(Qt::Vertical, webView->page()->mainFrame()->scrollBarMaximum(Qt::Vertical)-i);
2021-04-01 00:32:58 +00:00
} else if ( code = = " togglestagesession " ) { // Enable/Disable Sleep Stage session
day = p_profile - > GetDay ( previous_date , MT_SLEEPSTAGE ) ;
if ( ! day ) return ;
Session * sess = day - > find ( sid , MT_SLEEPSTAGE ) ;
2023-02-25 01:18:54 +00:00
if ( rejectToggleSessionEnable ( sess ) ) return ;
2021-04-01 00:32:58 +00:00
LoadDate ( previous_date ) ;
2023-01-16 13:26:01 +00:00
mainwin - > getOverview ( ) - > graphView ( ) - > dataChanged ( ) ;
2021-04-01 00:32:58 +00:00
} else if ( code = = " togglepositionsession " ) { // Enable/Disable Position session
day = p_profile - > GetDay ( previous_date , MT_POSITION ) ;
if ( ! day ) return ;
Session * sess = day - > find ( sid , MT_POSITION ) ;
2023-02-25 01:18:54 +00:00
if ( rejectToggleSessionEnable ( sess ) ) return ;
2021-04-01 00:32:58 +00:00
LoadDate ( previous_date ) ;
2023-01-16 13:26:01 +00:00
mainwin - > getOverview ( ) - > graphView ( ) - > dataChanged ( ) ;
2011-12-27 13:21:10 +00:00
} else if ( code = = " cpap " ) {
2014-07-11 12:09:38 +00:00
day = p_profile - > GetDay ( previous_date , MT_CPAP ) ;
2014-08-20 17:17:13 +00:00
if ( day ) {
Session * sess = day - > machine ( MT_CPAP ) - > sessionlist [ sid ] ;
if ( sess & & sess - > enabled ( ) ) {
GraphView - > SetXBounds ( sess - > first ( ) , sess - > last ( ) ) ;
}
}
2011-11-24 23:03:33 +00:00
} else if ( code = = " oxi " ) {
2014-08-20 17:17:13 +00:00
day = p_profile - > GetDay ( previous_date , MT_OXIMETER ) ;
if ( day ) {
Session * sess = day - > machine ( MT_OXIMETER ) - > sessionlist [ sid ] ;
if ( sess & & sess - > enabled ( ) ) {
GraphView - > SetXBounds ( sess - > first ( ) , sess - > last ( ) ) ;
}
}
2011-11-24 23:03:33 +00:00
} else if ( code = = " event " ) {
2013-10-26 05:06:56 +00:00
QList < QTreeWidgetItem * > list = ui - > treeWidget - > findItems ( schema : : channel [ sid ] . fullname ( ) , Qt : : MatchContains ) ;
2011-11-24 23:03:33 +00:00
if ( list . size ( ) > 0 ) {
2011-11-24 23:14:17 +00:00
ui - > treeWidget - > collapseAll ( ) ;
ui - > treeWidget - > expandItem ( list . at ( 0 ) ) ;
QTreeWidgetItem * wi = list . at ( 0 ) - > child ( 0 ) ;
ui - > treeWidget - > setCurrentItem ( wi ) ;
2011-11-24 23:03:33 +00:00
ui - > tabWidget - > setCurrentIndex ( 1 ) ;
2011-12-03 08:52:24 +00:00
} else {
2013-10-26 05:06:56 +00:00
mainwin - > Notify ( tr ( " No %1 events are recorded this day " ) . arg ( schema : : channel [ sid ] . fullname ( ) ) , " " , 1500 ) ;
2011-11-24 23:03:33 +00:00
}
2011-12-03 03:43:23 +00:00
} else if ( code = = " graph " ) {
qDebug ( ) < < " Select graph " < < data ;
2024-03-20 16:59:40 +00:00
} else if ( code = = " leftsidebarenable " ) {
leftSideBarEnable . toggleBit ( data . toInt ( ) ) ;
LoadDate ( previous_date ) ;
2011-11-24 23:03:33 +00:00
} else {
qDebug ( ) < < " Clicked on " < < code < < data ;
}
}
2011-07-04 11:37:26 +00:00
2011-06-26 08:30:44 +00:00
void Daily : : ReloadGraphs ( )
{
2019-03-10 16:03:19 +00:00
// qDebug() << "Start ReloadGraphs Daily object";
// sleep(3);
2014-05-19 07:30:10 +00:00
GraphView - > setDay ( nullptr ) ;
2011-12-23 14:12:04 +00:00
ui - > splitter - > setVisible ( true ) ;
2011-12-06 14:39:14 +00:00
QDate d ;
2012-01-05 04:37:22 +00:00
2011-12-06 14:39:14 +00:00
if ( previous_date . isValid ( ) ) {
d = previous_date ;
2014-09-17 06:12:38 +00:00
//Unload(d);
2012-01-05 04:37:22 +00:00
}
2014-09-29 15:43:00 +00:00
QDate lastcpap = p_profile - > LastDay ( MT_CPAP ) ;
QDate lastoxi = p_profile - > LastDay ( MT_OXIMETER ) ;
d = qMax ( lastcpap , lastoxi ) ;
2011-06-26 08:30:44 +00:00
if ( ! d . isValid ( ) ) {
d = ui - > calendar - > selectedDate ( ) ;
}
on_calendar_currentPageChanged ( d . year ( ) , d . month ( ) ) ;
2012-01-05 04:37:22 +00:00
// this fires a signal which unloads the old and loads the new
2014-05-19 07:30:10 +00:00
ui - > calendar - > blockSignals ( true ) ;
2011-06-26 08:30:44 +00:00
ui - > calendar - > setSelectedDate ( d ) ;
2014-05-19 07:30:10 +00:00
ui - > calendar - > blockSignals ( false ) ;
Load ( d ) ;
2019-08-08 23:24:30 +00:00
ui - > calButton - > setText ( ui - > calendar - > selectedDate ( ) . toString ( MedDateFormat ) ) ;
2014-05-28 17:45:42 +00:00
graphView ( ) - > redraw ( ) ;
2019-03-10 16:03:19 +00:00
// qDebug() << "Finished ReloadGraphs in Daily object";
// sleep(3);
2011-06-26 08:30:44 +00:00
}
2014-05-19 07:30:10 +00:00
2019-07-24 08:48:18 +00:00
void Daily : : updateLeftSidebar ( ) {
if ( webView & & ! htmlLeftHeader . isEmpty ( ) )
webView - > setHtml ( getLeftSidebar ( true ) ) ;
}
2014-08-09 19:45:46 +00:00
void Daily : : hideSpaceHogs ( )
{
2018-04-22 12:06:48 +00:00
if ( AppSetting - > calendarVisible ( ) ) {
2014-08-09 19:45:46 +00:00
ui - > calendarFrame - > setVisible ( false ) ;
}
2019-07-19 05:39:08 +00:00
if ( AppSetting - > showPieChart ( ) ) {
webView - > setHtml ( getLeftSidebar ( false ) ) ;
}
2014-08-09 19:45:46 +00:00
}
void Daily : : showSpaceHogs ( )
{
2018-04-22 12:06:48 +00:00
if ( AppSetting - > calendarVisible ( ) ) {
2014-08-09 19:45:46 +00:00
ui - > calendarFrame - > setVisible ( true ) ;
}
2019-07-19 05:39:08 +00:00
if ( AppSetting - > showPieChart ( ) ) {
webView - > setHtml ( getLeftSidebar ( true ) ) ;
}
2014-08-09 19:45:46 +00:00
}
2011-06-26 08:30:44 +00:00
void Daily : : on_calendar_currentPageChanged ( int year , int month )
{
QDate d ( year , month , 1 ) ;
int dom = d . daysInMonth ( ) ;
for ( int i = 1 ; i < = dom ; i + + ) {
d = QDate ( year , month , i ) ;
this - > UpdateCalendarDay ( d ) ;
}
}
2014-05-19 07:30:10 +00:00
2011-06-26 08:30:44 +00:00
void Daily : : UpdateEventsTree ( QTreeWidget * tree , Day * day )
{
tree - > clear ( ) ;
2011-06-27 10:55:55 +00:00
if ( ! day ) return ;
2011-06-26 08:30:44 +00:00
tree - > setColumnCount ( 1 ) ; // 1 visible common.. (1 hidden)
2014-04-23 13:19:56 +00:00
QTreeWidgetItem * root = nullptr ;
2011-07-31 20:24:43 +00:00
QHash < ChannelID , QTreeWidgetItem * > mcroot ;
QHash < ChannelID , int > mccnt ;
2012-01-19 15:18:34 +00:00
2014-07-11 12:09:38 +00:00
qint64 drift = 0 , clockdrift = p_profile - > cpap - > clockDrift ( ) * 1000L ;
2014-08-20 18:36:44 +00:00
quint32 chantype = schema : : FLAG | schema : : SPAN | schema : : MINOR_FLAG ;
if ( p_profile - > general - > showUnknownFlags ( ) ) chantype | = schema : : UNKNOWN ;
QList < ChannelID > chans = day - > getSortedMachineChannels ( chantype ) ;
2019-08-30 01:47:25 +00:00
// Go through all the enabled sessions of the day
2013-10-22 11:42:57 +00:00
for ( QList < Session * > : : iterator s = day - > begin ( ) ; s ! = day - > end ( ) ; + + s ) {
2014-08-20 18:36:44 +00:00
Session * sess = * s ;
if ( ! sess - > enabled ( ) ) continue ;
2011-06-26 08:30:44 +00:00
2019-08-30 01:47:25 +00:00
// For each session, go through all the channels
2011-07-31 20:24:43 +00:00
QHash < ChannelID , QVector < EventList * > > : : iterator m ;
2014-08-20 18:36:44 +00:00
for ( int c = 0 ; c < chans . size ( ) ; + + c ) {
ChannelID code = chans . at ( c ) ;
m = sess - > eventlist . find ( code ) ;
if ( m = = sess - > eventlist . end ( ) ) continue ;
2011-06-26 08:30:44 +00:00
2014-09-17 06:12:38 +00:00
drift = ( sess - > type ( ) = = MT_CPAP ) ? clockdrift : 0 ;
2012-01-06 16:07:54 +00:00
2019-08-30 01:47:25 +00:00
// Prepare title for this code, if there are any events
2011-06-26 08:30:44 +00:00
QTreeWidgetItem * mcr ;
if ( mcroot . find ( code ) = = mcroot . end ( ) ) {
2011-07-05 05:33:06 +00:00
int cnt = day - > count ( code ) ;
2012-01-14 07:41:50 +00:00
if ( ! cnt ) continue ; // If no events than don't bother showing..
2013-10-26 05:06:56 +00:00
QString st = schema : : channel [ code ] . fullname ( ) ;
2011-06-26 08:30:44 +00:00
if ( st . isEmpty ( ) ) {
2013-10-09 15:56:46 +00:00
st = QString ( " Fixme %1 " ) . arg ( code ) ;
2011-06-26 08:30:44 +00:00
}
2011-12-21 11:09:50 +00:00
st + = " " ;
if ( cnt = = 1 ) st + = tr ( " %1 event " ) . arg ( cnt ) ;
else st + = tr ( " %1 events " ) . arg ( cnt ) ;
2011-06-26 08:30:44 +00:00
QStringList l ( st ) ;
l . append ( " " ) ;
mcroot [ code ] = mcr = new QTreeWidgetItem ( root , l ) ;
mccnt [ code ] = 0 ;
} else {
mcr = mcroot [ code ] ;
}
2012-01-11 04:58:46 +00:00
2019-08-30 01:47:25 +00:00
// number of digits required for count depends on total for day
int numDigits = ceil ( log10 ( day - > count ( code ) + 1 ) ) ;
// Now we go through the event list for the *session* (not for the day)
2011-07-31 20:24:43 +00:00
for ( int z = 0 ; z < m . value ( ) . size ( ) ; z + + ) {
2012-01-11 04:58:46 +00:00
EventList & ev = * ( m . value ( ) [ z ] ) ;
for ( quint32 o = 0 ; o < ev . count ( ) ; o + + ) {
2012-01-19 15:18:34 +00:00
qint64 t = ev . time ( o ) + drift ;
2011-07-30 03:52:29 +00:00
2016-02-27 03:37:56 +00:00
if ( ( code = = CPAP_CSR ) | | ( code = = CPAP_PB ) ) { // center it in the middle of span
t - = float ( ev . raw ( o ) / 2.0 ) * 1000.0 ;
2011-07-27 09:21:53 +00:00
}
QStringList a ;
2016-03-08 12:10:42 +00:00
QDateTime d = QDateTime : : fromMSecsSinceEpoch ( t ) ; // Localtime
2019-08-29 14:21:19 +00:00
QString s = QString ( " #%1: %2 " ) . arg ( ( int ) ( + + mccnt [ code ] ) , ( int ) numDigits , ( int ) 10 , QChar ( ' 0 ' ) ) . arg ( d . toString ( " HH:mm:ss " ) ) ;
2019-07-05 17:29:57 +00:00
if ( m . value ( ) [ z ] - > raw ( o ) > 0 )
s + = QString ( " (%3) " ) . arg ( m . value ( ) [ z ] - > raw ( o ) ) ;
2011-07-27 09:21:53 +00:00
a . append ( s ) ;
2011-12-25 05:05:12 +00:00
QTreeWidgetItem * item = new QTreeWidgetItem ( a ) ;
item - > setData ( 0 , Qt : : UserRole , t ) ;
mcr - > addChild ( item ) ;
2011-06-26 08:30:44 +00:00
}
2011-07-30 03:52:29 +00:00
}
}
2011-06-26 08:30:44 +00:00
}
int cnt = 0 ;
2011-07-31 20:24:43 +00:00
for ( QHash < ChannelID , QTreeWidgetItem * > : : iterator m = mcroot . begin ( ) ; m ! = mcroot . end ( ) ; m + + ) {
tree - > insertTopLevelItem ( cnt + + , m . value ( ) ) ;
2011-06-26 08:30:44 +00:00
}
2014-05-31 21:25:07 +00:00
2014-09-30 05:25:11 +00:00
if ( day - > hasMachine ( MT_CPAP ) | | day - > hasMachine ( MT_OXIMETER ) | | day - > hasMachine ( MT_POSITION ) ) {
2023-03-18 12:50:48 +00:00
QTreeWidgetItem * start = new QTreeWidgetItem ( QStringList ( tr ( " Session Start Times " ) ) , eventTypeStart ) ;
QTreeWidgetItem * end = new QTreeWidgetItem ( QStringList ( tr ( " Session End Times " ) ) , eventTypeEnd ) ;
2014-09-30 05:25:11 +00:00
tree - > insertTopLevelItem ( cnt + + , start ) ;
tree - > insertTopLevelItem ( cnt + + , end ) ;
for ( QList < Session * > : : iterator s = day - > begin ( ) ; s ! = day - > end ( ) ; + + s ) {
2023-03-18 23:37:13 +00:00
Session * sess = * s ;
if ( ( sess - > type ( ) ! = MT_CPAP ) & & ( sess - > type ( ) ! = MT_OXIMETER ) & & ( sess - > type ( ) ! = MT_POSITION ) ) continue ;
QDateTime st = QDateTime : : fromMSecsSinceEpoch ( sess - > first ( ) ) ; // Localtime
QDateTime et = QDateTime : : fromMSecsSinceEpoch ( sess - > last ( ) ) ; // Localtime
2014-09-30 05:25:11 +00:00
QTreeWidgetItem * item = new QTreeWidgetItem ( QStringList ( st . toString ( " HH:mm:ss " ) ) ) ;
2023-03-18 23:37:13 +00:00
item - > setData ( 0 , Qt : : UserRole , sess - > first ( ) ) ;
2014-09-30 05:25:11 +00:00
start - > addChild ( item ) ;
item = new QTreeWidgetItem ( QStringList ( et . toString ( " HH:mm:ss " ) ) ) ;
2023-03-18 23:37:13 +00:00
item - > setData ( 0 , Qt : : UserRole , sess - > last ( ) ) ;
2014-09-30 05:25:11 +00:00
end - > addChild ( item ) ;
}
}
2011-06-26 08:30:44 +00:00
tree - > sortByColumn ( 0 , Qt : : AscendingOrder ) ;
}
2011-12-01 06:06:13 +00:00
2011-06-26 08:30:44 +00:00
void Daily : : UpdateCalendarDay ( QDate date )
{
2011-12-11 09:45:28 +00:00
QTextCharFormat nodata ;
QTextCharFormat cpaponly ;
QTextCharFormat cpapjour ;
2011-07-03 12:08:30 +00:00
QTextCharFormat oxiday ;
2011-12-11 09:45:28 +00:00
QTextCharFormat oxicpap ;
2011-12-02 14:18:47 +00:00
QTextCharFormat jourday ;
2012-01-11 14:49:22 +00:00
QTextCharFormat stageday ;
2011-12-11 09:45:28 +00:00
2013-09-10 15:09:09 +00:00
cpaponly . setForeground ( QBrush ( COLOR_Blue , Qt : : SolidPattern ) ) ;
2011-12-11 09:45:28 +00:00
cpaponly . setFontWeight ( QFont : : Normal ) ;
2013-09-10 15:09:09 +00:00
cpapjour . setForeground ( QBrush ( COLOR_Blue , Qt : : SolidPattern ) ) ;
2011-12-11 09:45:28 +00:00
cpapjour . setFontWeight ( QFont : : Bold ) ;
2019-09-03 05:10:36 +00:00
// cpapjour.setFontUnderline(true);
2013-09-10 15:09:09 +00:00
oxiday . setForeground ( QBrush ( COLOR_Red , Qt : : SolidPattern ) ) ;
2011-12-11 09:45:28 +00:00
oxiday . setFontWeight ( QFont : : Normal ) ;
2013-09-10 15:09:09 +00:00
oxicpap . setForeground ( QBrush ( COLOR_Red , Qt : : SolidPattern ) ) ;
2011-12-11 09:45:28 +00:00
oxicpap . setFontWeight ( QFont : : Bold ) ;
2013-09-10 15:09:09 +00:00
stageday . setForeground ( QBrush ( COLOR_Magenta , Qt : : SolidPattern ) ) ;
2012-01-11 14:49:22 +00:00
stageday . setFontWeight ( QFont : : Bold ) ;
2014-09-29 15:43:00 +00:00
jourday . setForeground ( QBrush ( COLOR_DarkYellow , Qt : : SolidPattern ) ) ;
2011-12-02 14:18:47 +00:00
jourday . setFontWeight ( QFont : : Bold ) ;
2013-09-10 15:09:09 +00:00
nodata . setForeground ( QBrush ( COLOR_Black , Qt : : SolidPattern ) ) ;
2011-12-11 09:45:28 +00:00
nodata . setFontWeight ( QFont : : Normal ) ;
2011-12-02 14:18:47 +00:00
2014-09-29 15:43:00 +00:00
bool hascpap = p_profile - > FindDay ( date , MT_CPAP ) ! = nullptr ;
bool hasoxi = p_profile - > FindDay ( date , MT_OXIMETER ) ! = nullptr ;
bool hasjournal = p_profile - > FindDay ( date , MT_JOURNAL ) ! = nullptr ;
bool hasstage = p_profile - > FindDay ( date , MT_SLEEPSTAGE ) ! = nullptr ;
bool haspos = p_profile - > FindDay ( date , MT_POSITION ) ! = nullptr ;
2011-07-03 12:08:30 +00:00
if ( hascpap ) {
if ( hasoxi ) {
2014-09-29 15:43:00 +00:00
ui - > calendar - > setDateTextFormat ( date , oxicpap ) ;
2011-12-02 14:18:47 +00:00
} else if ( hasjournal ) {
2014-09-29 15:43:00 +00:00
ui - > calendar - > setDateTextFormat ( date , cpapjour ) ;
2014-04-15 13:59:24 +00:00
} else if ( hasstage | | haspos ) {
2014-09-29 15:43:00 +00:00
ui - > calendar - > setDateTextFormat ( date , stageday ) ;
2011-07-03 12:08:30 +00:00
} else {
2014-09-29 15:43:00 +00:00
ui - > calendar - > setDateTextFormat ( date , cpaponly ) ;
2011-07-03 12:08:30 +00:00
}
2011-12-11 09:45:28 +00:00
} else if ( hasoxi ) {
2014-09-29 15:43:00 +00:00
ui - > calendar - > setDateTextFormat ( date , oxiday ) ;
2011-12-11 09:45:28 +00:00
} else if ( hasjournal ) {
2014-09-29 15:43:00 +00:00
ui - > calendar - > setDateTextFormat ( date , jourday ) ;
2014-04-15 13:59:24 +00:00
} else if ( hasstage ) {
2014-09-29 15:43:00 +00:00
ui - > calendar - > setDateTextFormat ( date , oxiday ) ;
2014-04-15 13:59:24 +00:00
} else if ( haspos ) {
2014-09-29 15:43:00 +00:00
ui - > calendar - > setDateTextFormat ( date , oxiday ) ;
2011-06-26 08:30:44 +00:00
} else {
2014-09-29 15:43:00 +00:00
ui - > calendar - > setDateTextFormat ( date , nodata ) ;
2011-06-26 08:30:44 +00:00
}
2019-09-03 05:10:36 +00:00
// if (hasjournal) {
// ui->calendar->setDateTextFormat(date, cpapjour);
// }
2011-06-26 08:30:44 +00:00
ui - > calendar - > setHorizontalHeaderFormat ( QCalendarWidget : : ShortDayNames ) ;
}
2011-10-28 03:45:31 +00:00
void Daily : : LoadDate ( QDate date )
{
2014-07-25 07:53:48 +00:00
if ( ! date . isValid ( ) ) {
qDebug ( ) < < " LoadDate called with invalid date " ;
return ;
}
2011-12-26 04:58:02 +00:00
ui - > calendar - > blockSignals ( true ) ;
2011-12-26 18:26:06 +00:00
if ( date . month ( ) ! = previous_date . month ( ) ) {
on_calendar_currentPageChanged ( date . year ( ) , date . month ( ) ) ;
}
2011-10-28 03:45:31 +00:00
ui - > calendar - > setSelectedDate ( date ) ;
2011-12-26 04:58:02 +00:00
ui - > calendar - > blockSignals ( false ) ;
on_calendar_selectionChanged ( ) ;
2011-10-28 03:45:31 +00:00
}
2011-06-26 08:30:44 +00:00
void Daily : : on_calendar_selectionChanged ( )
2014-08-07 22:47:34 +00:00
{
QTimer : : singleShot ( 0 , this , SLOT ( on_ReloadDay ( ) ) ) ;
}
void Daily : : on_ReloadDay ( )
2011-06-26 08:30:44 +00:00
{
2018-05-08 08:12:32 +00:00
static volatile bool inReload = false ;
if ( inReload ) {
qDebug ( ) < < " attempt to renter on_ReloadDay() " ;
}
inReload = true ;
2014-07-20 10:30:33 +00:00
graphView ( ) - > releaseKeyboard ( ) ;
2023-02-12 01:50:02 +00:00
QElapsedTimer time ;
2012-01-05 04:37:22 +00:00
time_t unload_time , load_time , other_time ;
time . start ( ) ;
2011-06-26 08:30:44 +00:00
2012-01-05 04:37:22 +00:00
this - > setCursor ( Qt : : BusyCursor ) ;
2011-12-20 11:12:52 +00:00
if ( previous_date . isValid ( ) ) {
2011-12-25 16:38:37 +00:00
// GraphView->fadeOut();
2011-12-20 11:12:52 +00:00
Unload ( previous_date ) ;
}
2022-11-17 01:46:30 +00:00
2012-01-05 04:37:22 +00:00
unload_time = time . restart ( ) ;
2012-01-02 15:34:17 +00:00
//bool fadedir=previous_date < ui->calendar->selectedDate();
2022-11-17 01:46:30 +00:00
# ifndef REMOVE_FITNESS
# endif
2011-06-26 08:30:44 +00:00
Load ( ui - > calendar - > selectedDate ( ) ) ;
2012-01-05 04:37:22 +00:00
load_time = time . restart ( ) ;
2011-12-25 16:38:37 +00:00
//GraphView->fadeIn(fadedir);
2011-12-25 16:58:22 +00:00
GraphView - > redraw ( ) ;
2019-08-08 23:24:30 +00:00
ui - > calButton - > setText ( ui - > calendar - > selectedDate ( ) . toString ( MedDateFormat ) ) ;
2011-10-30 04:35:55 +00:00
ui - > calendar - > setFocus ( Qt : : ActiveWindowFocusReason ) ;
2011-12-02 13:48:05 +00:00
2022-11-17 01:46:30 +00:00
# ifndef REMOVE_FITNESS
2024-08-23 23:58:36 +00:00
ui - > weightSpinBox - > setDecimals ( WEIGHT_SPIN_BOX_DECIMALS ) ;
2022-11-17 01:46:30 +00:00
# endif
2011-12-25 16:38:37 +00:00
this - > setCursor ( Qt : : ArrowCursor ) ;
2012-01-05 04:37:22 +00:00
other_time = time . restart ( ) ;
qDebug ( ) < < " Page change time (in ms): Unload = " < < unload_time < < " Load = " < < load_time < < " Other = " < < other_time ;
2018-05-08 08:12:32 +00:00
inReload = false ;
2011-06-26 08:30:44 +00:00
}
2011-07-28 14:20:59 +00:00
void Daily : : ResetGraphLayout ( )
{
2011-09-12 17:47:37 +00:00
GraphView - > resetLayout ( ) ;
2011-07-28 14:20:59 +00:00
}
2019-09-29 03:15:16 +00:00
void Daily : : ResetGraphOrder ( int type )
2019-07-31 02:59:01 +00:00
{
2019-09-29 03:15:16 +00:00
if ( type = = 0 ) { // Auto order
Day * day = p_profile - > GetDay ( previous_date , MT_CPAP ) ;
2019-09-02 05:14:36 +00:00
2019-09-29 03:15:16 +00:00
int cpapMode = day - > getCPAPMode ( ) ;
// qDebug() << "Daily::ResetGraphOrder cpapMode" << cpapMode;
2019-09-02 05:14:36 +00:00
2019-09-29 03:15:16 +00:00
if ( useAdvancedGraphs . contains ( cpapMode ) )
GraphView - > resetGraphOrder ( true , advancedGraphOrder ) ;
else
GraphView - > resetGraphOrder ( true , standardGraphOrder ) ;
} else if ( type = = 2 ) { // Advanced order
2019-09-02 05:14:36 +00:00
GraphView - > resetGraphOrder ( true , advancedGraphOrder ) ;
2019-09-29 03:15:16 +00:00
} else { // type == 1, standard order
2019-09-02 05:14:36 +00:00
GraphView - > resetGraphOrder ( true , standardGraphOrder ) ;
2019-09-29 03:15:16 +00:00
}
2019-08-09 22:32:37 +00:00
// Enable all graphs (make them not hidden)
2023-03-03 00:28:09 +00:00
showAllGraphs ( true ) ;
2023-03-04 15:14:21 +00:00
showAllEvents ( true ) ;
2019-08-09 22:32:37 +00:00
// Reset graph heights (and repaint)
2019-07-31 02:59:01 +00:00
ResetGraphLayout ( ) ;
}
2011-12-03 08:52:24 +00:00
void Daily : : graphtogglebutton_toggled ( bool b )
2011-12-01 06:06:13 +00:00
{
2011-12-03 08:52:24 +00:00
Q_UNUSED ( b )
2011-12-01 06:06:13 +00:00
for ( int i = 0 ; i < GraphView - > size ( ) ; i + + ) {
QString title = ( * GraphView ) [ i ] - > title ( ) ;
( * GraphView ) [ i ] - > setVisible ( GraphToggles [ title ] - > isChecked ( ) ) ;
}
GraphView - > updateScale ( ) ;
2011-12-20 11:12:52 +00:00
GraphView - > redraw ( ) ;
2011-12-01 06:06:13 +00:00
}
2013-10-12 07:40:45 +00:00
2014-08-20 17:17:13 +00:00
QString Daily : : getSessionInformation ( Day * day )
2013-10-13 16:35:53 +00:00
{
QString html ;
2014-08-20 17:17:13 +00:00
if ( ! day ) return html ;
2013-10-13 16:35:53 +00:00
2024-03-20 16:59:40 +00:00
htmlLsbSectionHeader ( html , tr ( " Session Information " ) , LSB_SESSION_INFORMATION ) ;
if ( ! leftSideBarEnable [ LSB_SESSION_INFORMATION ] ) {
html + = " <hr/> " ; // Have sep at the end of sections.
return html ;
}
html + = " <table cellpadding=0 cellspacing=0 border=0 width=100%> " ;
2013-10-13 16:35:53 +00:00
html + = " <tr><td colspan=5 align=center> </td></tr> " ;
QFontMetrics FM ( * defaultfont ) ;
2014-08-20 17:17:13 +00:00
2013-10-13 16:35:53 +00:00
QDateTime fd , ld ;
2020-03-24 17:50:30 +00:00
//bool corrupted_waveform=false;
2013-10-13 16:35:53 +00:00
QString type ;
2014-08-20 17:17:13 +00:00
QHash < MachineType , Machine * > : : iterator mach_end = day - > machines . end ( ) ;
QHash < MachineType , Machine * > : : iterator mi ;
for ( mi = day - > machines . begin ( ) ; mi ! = mach_end ; + + mi ) {
if ( mi . key ( ) = = MT_JOURNAL ) continue ;
html + = " <tr><td colspan=5 align=center><i> " ;
switch ( mi . key ( ) ) {
case MT_CPAP : type = " cpap " ;
html + = tr ( " CPAP Sessions " ) ;
break ;
case MT_OXIMETER : type = " oxi " ;
2018-06-04 20:48:38 +00:00
html + = tr ( " Oximetry Sessions " ) ;
2014-08-20 17:17:13 +00:00
break ;
case MT_SLEEPSTAGE : type = " stage " ;
html + = tr ( " Sleep Stage Sessions " ) ;
break ;
2021-04-01 00:32:58 +00:00
case MT_POSITION : type = " position " ;
2014-08-20 17:17:13 +00:00
html + = tr ( " Position Sensor Sessions " ) ;
break ;
default :
type = " unknown " ;
html + = tr ( " Unknown Session " ) ;
break ;
2013-10-13 16:35:53 +00:00
}
html + = " </i></td></tr> \n " ;
2014-08-17 12:56:05 +00:00
html + = QString ( " <tr> "
2014-08-21 05:46:14 +00:00
" <td> " + STR_TR_On + " </td> "
" <td> " + STR_TR_Date + " </td> "
" <td> " + STR_TR_Start + " </td> "
" <td> " + STR_TR_End + " </td> "
" <td> " + tr ( " Duration " ) + " </td></tr> " ) ;
2013-10-13 16:35:53 +00:00
2014-08-21 05:46:14 +00:00
QList < Session * > sesslist = day - > getSessions ( mi . key ( ) , true ) ;
2014-08-20 17:17:13 +00:00
for ( QList < Session * > : : iterator s = sesslist . begin ( ) ; s ! = sesslist . end ( ) ; + + s ) {
2020-03-24 17:50:30 +00:00
/*
2014-09-17 06:12:38 +00:00
if ( ( ( * s ) - > type ( ) = = MT_CPAP ) & &
2014-08-20 17:17:13 +00:00
( ( * s ) - > settings . find ( CPAP_BrokenWaveform ) ! = ( * s ) - > settings . end ( ) ) )
2013-10-13 16:35:53 +00:00
corrupted_waveform = true ;
2020-03-24 17:50:30 +00:00
*/
2013-10-13 16:35:53 +00:00
fd = QDateTime : : fromTime_t ( ( * s ) - > first ( ) / 1000L ) ;
ld = QDateTime : : fromTime_t ( ( * s ) - > last ( ) / 1000L ) ;
int len = ( * s ) - > length ( ) / 1000L ;
int h = len / 3600 ;
int m = ( len / 60 ) % 60 ;
int s1 = len % 60 ;
Session * sess = * s ;
2014-09-01 04:49:05 +00:00
2018-06-14 07:25:54 +00:00
QString tooltip = tr ( " Click to %1 this session. " ) . arg ( sess - > enabled ( ) ? tr ( " disable " ) : tr ( " enable " ) ) ;
2018-05-07 22:09:59 +00:00
html + = QString ( " <tr><td colspan=5 align=center>%2</td></tr> "
" <tr> "
2018-05-08 08:12:32 +00:00
" <td width=26> "
# ifdef DITCH_ICONS
" [<a href='toggle " + type + " session=%1'><b title=' " + tooltip + " '>%4</b></a>] "
# else
" <a href='toggle " + type + " session=%1'><img src='qrc:/icons/session-%4.png' title= \" " + tooltip + " \" ></a> "
# endif
" </td> "
2014-08-21 05:46:14 +00:00
" <td align=left>%5</td> "
" <td align=left>%6</td> "
" <td align=left>%7</td> "
2014-08-17 12:56:05 +00:00
" <td align=left>%3</td></tr> "
)
2013-10-13 16:35:53 +00:00
. arg ( ( * s ) - > session ( ) )
2018-06-14 07:25:54 +00:00
. arg ( tr ( " %1 Session #%2 " ) . arg ( ( * s ) - > machine ( ) - > loaderName ( ) ) . arg ( ( * s ) - > session ( ) , 8 , 10 , QChar ( ' 0 ' ) ) )
. arg ( tr ( " %1h %2m %3s " ) . arg ( h , 2 , 10 , QChar ( ' 0 ' ) ) . arg ( m , 2 , 10 , QChar ( ' 0 ' ) ) . arg ( s1 , 2 , 10 , QChar ( ' 0 ' ) ) )
2014-10-11 00:44:30 +00:00
. arg ( ( sess - > enabled ( ) ? " on " : " off " ) )
2013-10-13 16:35:53 +00:00
. arg ( fd . date ( ) . toString ( Qt : : SystemLocaleShortDate ) )
2014-08-27 09:00:55 +00:00
. arg ( fd . toString ( " HH:mm:ss " ) )
. arg ( ld . toString ( " HH:mm:ss " ) ) ;
2023-02-25 01:18:54 +00:00
2014-09-01 04:49:05 +00:00
# ifdef SESSION_DEBUG
for ( int i = 0 ; i < sess - > session_files . size ( ) ; + + i ) {
html + = QString ( " <tr><td colspan=5 align=center>%1</td></tr> " ) . arg ( sess - > session_files [ i ] . section ( " / " , - 1 ) ) ;
}
# endif
2013-10-13 16:35:53 +00:00
}
}
2020-03-24 17:50:30 +00:00
/*
2013-10-13 16:35:53 +00:00
if ( corrupted_waveform ) {
2018-06-14 08:58:06 +00:00
html + = QString ( " <tr><td colspan=5 align=center><i>%1</i></td></tr> " ) . arg ( tr ( " One or more waveform record(s) for this session had faulty source data. Some waveform overlay points may not match up correctly. " ) ) ;
2013-10-13 16:35:53 +00:00
}
2020-03-24 17:50:30 +00:00
*/
2013-10-13 16:35:53 +00:00
html + = " </table> " ;
2024-03-20 16:59:40 +00:00
html + = " <hr/> " ; // Have sep at the end of sections.
2013-10-13 16:35:53 +00:00
return html ;
}
2014-08-20 17:17:13 +00:00
QString Daily : : getMachineSettings ( Day * day ) {
2013-10-13 16:35:53 +00:00
QString html ;
2024-07-10 00:11:24 +00:00
2014-08-20 17:17:13 +00:00
Machine * cpap = day - > machine ( MT_CPAP ) ;
if ( cpap & & day - > hasEnabledSessions ( MT_CPAP ) ) {
2024-07-06 16:01:53 +00:00
CPAPLoader * loader = qobject_cast < CPAPLoader * > ( cpap - > loader ( ) ) ;
if ( ! loader ) {
htmlLsbSectionHeader ( html , tr ( " DEVICE SETTINGS ERROR " ) , LSB_DEVICE_SETTINGS ) ;
return html ;
}
2024-03-20 16:59:40 +00:00
htmlLsbSectionHeader ( html , tr ( " Device Settings " ) , LSB_DEVICE_SETTINGS ) ;
if ( ! leftSideBarEnable [ LSB_DEVICE_SETTINGS ] ) {
return html ;
}
html + = " <table cellpadding=0 cellspacing=0 border=0 width=100%> " ;
2020-07-06 17:46:08 +00:00
if ( day - > noSettings ( cpap ) ) {
2020-07-05 18:19:19 +00:00
html + = " <tr><td colspan=5 align=center><i><font color='red'> " + tr ( " <b>Please Note:</b> All settings shown below are based on assumptions that nothing has changed since previous days. " ) + " </font></i></td></tr> \n " ;
2020-07-06 17:46:08 +00:00
} else {
html + = " <tr><td colspan=5> </td></tr> " ;
}
2014-07-02 14:32:01 +00:00
2014-08-04 19:57:48 +00:00
QMap < QString , QString > other ;
2014-08-20 17:17:13 +00:00
Session * sess = day - > firstSession ( MT_CPAP ) ;
QHash < ChannelID , QVariant > : : iterator it ;
QHash < ChannelID , QVariant > : : iterator it_end ;
if ( sess ) {
it_end = sess - > settings . end ( ) ;
it = sess - > settings . begin ( ) ;
}
2014-08-04 19:57:48 +00:00
QMap < int , QString > first ;
2014-08-20 17:17:13 +00:00
2014-09-01 04:49:05 +00:00
ChannelID cpapmode = loader - > CPAPModeChannel ( ) ;
schema : : Channel & chan = schema : : channel [ cpapmode ] ;
2019-05-21 22:12:42 +00:00
first [ cpapmode ] = QString ( " <tr><td><p title='%2'>%1</p></td><td colspan=4>%3</td></tr> " )
2014-09-14 15:29:07 +00:00
. arg ( chan . label ( ) )
. arg ( chan . description ( ) )
2019-09-02 05:14:36 +00:00
. arg ( day - > getCPAPModeStr ( ) ) ;
2014-09-01 04:49:05 +00:00
2020-01-13 01:17:07 +00:00
// The order in which to present pressure settings, which will appear first.
QVector < ChannelID > first_channels = { cpapmode , CPAP_Pressure , CPAP_PressureMin , CPAP_PressureMax , CPAP_EPAP , CPAP_EPAPLo , CPAP_EPAPHi , CPAP_IPAP , CPAP_IPAPLo , CPAP_IPAPHi , CPAP_PS , CPAP_PSMin , CPAP_PSMax } ;
2014-08-20 17:17:13 +00:00
if ( sess ) for ( ; it ! = it_end ; + + it ) {
2014-08-04 19:57:48 +00:00
ChannelID code = it . key ( ) ;
2021-07-17 23:19:30 +00:00
if ( ( code < = 1 ) | | ( code = = RMS9_MaskOnTime ) | | ( code = = CPAP_Mode ) | | ( code = = cpapmode ) | | ( code = = CPAP_SummaryOnly ) )
continue ;
2014-08-04 19:57:48 +00:00
schema : : Channel & chan = schema : : channel [ code ] ;
QString data ;
if ( chan . datatype ( ) = = schema : : LOOKUP ) {
2020-03-25 23:17:39 +00:00
int value = it . value ( ) . toInt ( ) ;
data = chan . option ( value ) ;
if ( data . isEmpty ( ) ) {
data = QString ( ) . number ( value ) + " " + chan . units ( ) ; ;
}
2014-08-04 19:57:48 +00:00
} else if ( chan . datatype ( ) = = schema : : BOOL ) {
data = ( it . value ( ) . toBool ( ) ? STR_TR_Yes : STR_TR_No ) ;
} else if ( chan . datatype ( ) = = schema : : DOUBLE ) {
2016-03-02 21:32:22 +00:00
data = QString ( ) . number ( it . value ( ) . toDouble ( ) , ' f ' , 2 ) + " " + chan . units ( ) ;
} else if ( chan . datatype ( ) = = schema : : DEFAULT ) {
2020-12-30 01:23:37 +00:00
// Check for any options that override the default numeric display.
int value = it . value ( ) . toInt ( ) ;
data = chan . option ( value ) ;
if ( data . isEmpty ( ) ) {
data = QString ( ) . number ( it . value ( ) . toDouble ( ) , ' f ' , 2 ) + " " + chan . units ( ) ;
}
2014-08-04 19:57:48 +00:00
} else {
2016-03-02 21:32:22 +00:00
2014-08-04 19:57:48 +00:00
data = it . value ( ) . toString ( ) + " " + chan . units ( ) ;
}
2019-05-21 22:12:42 +00:00
if ( code = = 0xe202 ) // Format EPR relief correctly
data = formatRelief ( data ) ;
2018-05-07 22:09:59 +00:00
QString tmp = QString ( " <tr><td><p title='%2'>%1</p></td><td colspan=4>%3</td></tr> " )
2014-08-04 19:57:48 +00:00
. arg ( schema : : channel [ code ] . label ( ) )
. arg ( schema : : channel [ code ] . description ( ) )
. arg ( data ) ;
2020-01-13 01:17:07 +00:00
if ( first_channels . contains ( code ) ) {
2014-08-04 19:57:48 +00:00
first [ code ] = tmp ;
} else {
other [ schema : : channel [ code ] . label ( ) ] = tmp ;
}
}
2020-01-13 01:17:07 +00:00
// Put the pressure settings in order.
for ( auto & code : first_channels ) {
if ( first . contains ( code ) ) html + = first [ code ] ;
2014-08-04 19:57:48 +00:00
}
2020-01-13 01:17:07 +00:00
// TODO: add logical (rather than alphabetical) ordering to this list, preferably driven by loader somehow
2014-08-04 19:57:48 +00:00
for ( QMap < QString , QString > : : iterator it = other . begin ( ) ; it ! = other . end ( ) ; + + it ) {
html + = it . value ( ) ;
}
2013-10-13 16:35:53 +00:00
html + = " </table> " ;
html + = " <hr/> \n " ;
}
return html ;
}
2014-08-20 17:17:13 +00:00
QString Daily : : getOximeterInformation ( Day * day )
2013-10-13 16:35:53 +00:00
{
QString html ;
2014-08-20 17:17:13 +00:00
Machine * oxi = day - > machine ( MT_OXIMETER ) ;
if ( oxi & & day - > hasEnabledSessions ( MT_OXIMETER ) ) {
2024-03-20 16:59:40 +00:00
htmlLsbSectionHeader ( html , tr ( " Oximeter Information " ) , LSB_OXIMETER_INFORMATION ) ;
if ( ! leftSideBarEnable [ LSB_OXIMETER_INFORMATION ] ) {
return html ;
}
html + = " <table cellpadding=0 cellspacing=0 border=0 width=100%> " ;
2013-10-13 16:35:53 +00:00
html + = " <tr><td colspan=5 align=center> </td></tr> " ;
2014-08-21 17:37:38 +00:00
html + = " <tr><td colspan=5 align=center> " + oxi - > brand ( ) + " " + oxi - > model ( ) + " </td></tr> \n " ;
2013-10-13 16:35:53 +00:00
html + = " <tr><td colspan=5 align=center> </td></tr> " ;
2021-02-21 22:29:12 +00:00
// Include SpO2 and PC drops per hour of Oximetry data in case CPAP data is missing
html + = QString ( " <tr><td colspan=5 align=center>%1: %2 (%3%) %4/h</td></tr> " ) . arg ( tr ( " SpO2 Desaturations " ) ) . arg ( day - > count ( OXI_SPO2Drop ) ) . arg ( ( 100.0 / day - > hours ( MT_OXIMETER ) ) * ( day - > sum ( OXI_SPO2Drop ) / 3600.0 ) , 0 , ' f ' , 2 ) . arg ( ( day - > count ( OXI_SPO2Drop ) / day - > hours ( MT_OXIMETER ) ) , 0 , ' f ' , 2 ) ;
html + = QString ( " <tr><td colspan=5 align=center>%1: %2 (%3%) %4/h</td></tr> " ) . arg ( tr ( " Pulse Change events " ) ) . arg ( day - > count ( OXI_PulseChange ) ) . arg ( ( 100.0 / day - > hours ( MT_OXIMETER ) ) * ( day - > sum ( OXI_PulseChange ) / 3600.0 ) , 0 , ' f ' , 2 ) . arg ( ( day - > count ( OXI_PulseChange ) / day - > hours ( MT_OXIMETER ) ) , 0 , ' f ' , 2 ) ;
2014-08-20 17:17:13 +00:00
html + = QString ( " <tr><td colspan=5 align=center>%1: %2%</td></tr> " ) . arg ( tr ( " SpO2 Baseline Used " ) ) . arg ( day - > settings_wavg ( OXI_SPO2Drop ) , 0 , ' f ' , 2 ) ; // CHECKME: Should this value be wavg OXI_SPO2 isntead?
2013-10-13 16:35:53 +00:00
html + = " </table> \n " ;
html + = " <hr/> \n " ;
}
return html ;
}
2014-08-20 17:17:13 +00:00
QString Daily : : getCPAPInformation ( Day * day )
2013-10-13 16:35:53 +00:00
{
QString html ;
2014-08-20 17:17:13 +00:00
if ( ! day )
2013-10-13 16:35:53 +00:00
return html ;
2014-08-20 17:17:13 +00:00
Machine * cpap = day - > machine ( MT_CPAP ) ;
if ( ! cpap ) return html ;
MachineInfo info = cpap - > getInfo ( ) ;
2024-03-20 16:59:40 +00:00
htmlLsbSectionHeader ( html , info . brand , LSB_MACHINE_INFO ) ;
if ( ! leftSideBarEnable [ LSB_MACHINE_INFO ] ) {
return html ;
}
html + = " <table cellspacing=0 cellpadding=0 border=0 width='100%'> \n " ;
2013-10-13 16:35:53 +00:00
2018-05-07 22:09:59 +00:00
QString tooltip = tr ( " Model %1 - %2 " ) . arg ( info . modelnumber ) . arg ( info . serial ) ;
2013-10-13 16:35:53 +00:00
tooltip = tooltip . replace ( " " , " " ) ;
2024-03-20 16:59:40 +00:00
html + = " <tr><td align=center><p title= \" " + tooltip + " \" > " + info . model + " </p></td></tr> \n " ;
2014-07-28 17:10:26 +00:00
html + = " <tr><td align=center> " ;
2013-11-19 04:42:10 +00:00
2019-09-02 05:14:36 +00:00
html + = tr ( " PAP Mode: %1 " ) . arg ( day - > getCPAPModeStr ( ) ) + " <br/> " ;
2014-08-20 17:17:13 +00:00
html + = day - > getPressureSettings ( ) ;
2013-11-19 04:42:10 +00:00
html + = " </td></tr> \n " ;
2020-07-06 17:46:08 +00:00
if ( day - > noSettings ( cpap ) ) {
html + = QString ( " <tr><td align=center><font color='red'><i>%1</i></font></td></tr> " ) . arg ( tr ( " (Mode and Pressure settings missing; yesterday's shown.) " ) ) ;
}
2014-07-02 14:32:01 +00:00
2013-10-13 16:35:53 +00:00
html + = " </table> \n " ;
2013-11-19 04:42:10 +00:00
html + = " <hr/> \n " ;
2013-10-13 16:35:53 +00:00
return html ;
}
2014-08-20 17:17:13 +00:00
QString Daily : : getStatisticsInfo ( Day * day )
2013-10-13 16:35:53 +00:00
{
2018-03-28 06:22:42 +00:00
if ( day = = nullptr ) return QString ( ) ;
2013-10-13 16:35:53 +00:00
2014-10-02 10:02:33 +00:00
Machine * cpap = day - > machine ( MT_CPAP ) ;
// *oxi = day->machine(MT_OXIMETER),
// *pos = day->machine(MT_POSITION);
2013-10-13 16:35:53 +00:00
2014-07-11 12:09:38 +00:00
int mididx = p_profile - > general - > prefCalcMiddle ( ) ;
2018-03-28 06:22:42 +00:00
SummaryType ST_mid = ST_AVG ;
2013-10-13 16:35:53 +00:00
if ( mididx = = 0 ) ST_mid = ST_PERC ;
if ( mididx = = 1 ) ST_mid = ST_WAVG ;
if ( mididx = = 2 ) ST_mid = ST_AVG ;
2014-07-11 12:09:38 +00:00
float percentile = p_profile - > general - > prefCalcPercentile ( ) / 100.0 ;
2013-10-13 16:35:53 +00:00
2014-07-11 12:09:38 +00:00
SummaryType ST_max = p_profile - > general - > prefCalcMax ( ) ? ST_PERC : ST_MAX ;
2016-03-04 00:52:26 +00:00
const EventDataType maxperc = 0.995F ;
2013-10-13 16:35:53 +00:00
QString midname ;
2014-05-17 08:34:16 +00:00
if ( ST_mid = = ST_WAVG ) midname = STR_TR_WAvg ;
else if ( ST_mid = = ST_AVG ) midname = STR_TR_Avg ;
else if ( ST_mid = = ST_PERC ) midname = STR_TR_Med ;
2013-10-13 16:35:53 +00:00
QString html ;
2024-03-20 16:59:40 +00:00
htmlLsbSectionHeader ( html , tr ( " Statistics " ) , LSB_STATISTICS ) ;
if ( ! leftSideBarEnable [ LSB_STATISTICS ] ) {
return html ;
}
2013-10-13 16:35:53 +00:00
html + = " <table cellspacing=0 cellpadding=0 border=0 width='100%'> \n " ;
html + = QString ( " <tr><td><b>%1</b></td><td><b>%2</b></td><td><b>%3</b></td><td><b>%4</b></td><td><b>%5</b></td></tr> " )
. arg ( STR_TR_Channel )
. arg ( STR_TR_Min )
. arg ( midname )
2022-01-10 15:49:23 +00:00
. arg ( QString ( " %1%2 " ) . arg ( percentile * 100 , 0 , ' f ' , 0 ) . arg ( STR_UNIT_Percentage ) )
2022-02-27 14:18:39 +00:00
. arg ( ST_max = = ST_MAX ? STR_TR_Max : QString ( " 99.5% " ) ) ;
2013-10-13 16:35:53 +00:00
ChannelID chans [ ] = {
2020-01-27 19:28:25 +00:00
CPAP_Pressure , CPAP_PressureSet , CPAP_EPAP , CPAP_EPAPSet , CPAP_IPAP , CPAP_IPAPSet , CPAP_PS , CPAP_PTB ,
2020-04-22 20:52:21 +00:00
PRS1_PeakFlow ,
2021-12-07 20:01:01 +00:00
Prisma_ObstructLevel , Prisma_PressureMeasured , Prisma_rRMV , Prisma_rMVFluctuation ,
2013-10-13 16:35:53 +00:00
CPAP_MinuteVent , CPAP_RespRate , CPAP_RespEvent , CPAP_FLG ,
2022-11-19 09:02:02 +00:00
CPAP_Leak , CPAP_LeakTotal , CPAP_Snore , CPAP_IE , CPAP_Ti , CPAP_Te , CPAP_TgMV ,
2020-01-27 00:50:18 +00:00
CPAP_TidalVolume , OXI_Pulse , OXI_SPO2 , POS_Inclination , POS_Orientation , POS_Movement
2013-10-13 16:35:53 +00:00
} ;
int numchans = sizeof ( chans ) / sizeof ( ChannelID ) ;
int ccnt = 0 ;
EventDataType tmp , med , perc , mx , mn ;
2014-08-20 17:17:13 +00:00
for ( int i = 0 ; i < numchans ; i + + ) {
2013-10-13 16:35:53 +00:00
2014-08-20 17:17:13 +00:00
ChannelID code = chans [ i ] ;
2013-10-13 16:35:53 +00:00
2014-08-20 17:17:13 +00:00
if ( ! day - > channelHasData ( code ) )
2013-10-13 16:35:53 +00:00
continue ;
2014-08-20 17:17:13 +00:00
QString tooltip = schema : : channel [ code ] . description ( ) ;
2013-10-13 16:35:53 +00:00
2014-08-20 17:17:13 +00:00
if ( ! schema : : channel [ code ] . units ( ) . isEmpty ( ) ) tooltip + = " ( " + schema : : channel [ code ] . units ( ) + " ) " ;
2019-07-05 17:29:57 +00:00
// if (!schema::channel[code].units().isEmpty() && schema::channel[code].units() != "0")
// tooltip+=" ("+schema::channel[code].units()+")";
2013-10-13 16:35:53 +00:00
2014-08-20 17:17:13 +00:00
if ( ST_max = = ST_MAX ) {
mx = day - > Max ( code ) ;
} else {
mx = day - > percentile ( code , maxperc ) ;
}
2013-10-13 16:35:53 +00:00
2014-08-20 17:17:13 +00:00
mn = day - > Min ( code ) ;
perc = day - > percentile ( code , percentile ) ;
2013-10-13 16:35:53 +00:00
2014-08-20 17:17:13 +00:00
if ( ST_mid = = ST_PERC ) {
med = day - > percentile ( code , 0.5 ) ;
tmp = day - > wavg ( code ) ;
if ( tmp > 0 | | mx = = 0 ) {
tooltip + = QString ( " <br/> " + STR_TR_WAvg + " : %1 " ) . arg ( tmp , 0 , ' f ' , 2 ) ;
2013-10-13 16:35:53 +00:00
}
2014-08-20 17:17:13 +00:00
} else if ( ST_mid = = ST_WAVG ) {
med = day - > wavg ( code ) ;
tmp = day - > percentile ( code , 0.5 ) ;
if ( tmp > 0 | | mx = = 0 ) {
tooltip + = QString ( " <br/> " + STR_TR_Median + " : %1 " ) . arg ( tmp , 0 , ' f ' , 2 ) ;
}
} else if ( ST_mid = = ST_AVG ) {
med = day - > avg ( code ) ;
tmp = day - > percentile ( code , 0.5 ) ;
if ( tmp > 0 | | mx = = 0 ) {
tooltip + = QString ( " <br/> " + STR_TR_Median + " : %1 " ) . arg ( tmp , 0 , ' f ' , 2 ) ;
2013-10-13 16:35:53 +00:00
}
}
2014-08-20 17:17:13 +00:00
2020-09-21 02:05:22 +00:00
// QString oldtip = tooltip;
tooltip . replace ( " ' " , " ' " ) ;
2022-01-09 21:51:08 +00:00
// qDebug() << schema::channel[code].label() << "old tooltip" << oldtip << "; new tooltip" << tooltip ;
2020-09-21 02:05:22 +00:00
2018-05-07 22:09:59 +00:00
html + = QString ( " <tr><td align=left title='%6'>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td></tr> " )
2014-08-20 17:17:13 +00:00
. arg ( schema : : channel [ code ] . label ( ) )
. arg ( mn , 0 , ' f ' , 2 )
. arg ( med , 0 , ' f ' , 2 )
. arg ( perc , 0 , ' f ' , 2 )
. arg ( mx , 0 , ' f ' , 2 )
. arg ( tooltip ) ;
ccnt + + ;
2013-10-13 16:35:53 +00:00
}
2014-07-02 14:32:01 +00:00
2014-08-20 17:17:13 +00:00
if ( GraphView - > isEmpty ( ) & & ( ( ccnt > 0 ) | | ( cpap & & day - > summaryOnly ( ) ) ) ) {
2013-10-13 16:35:53 +00:00
html + = " <tr><td colspan=5> </td></tr> \n " ;
2020-07-06 17:46:08 +00:00
html + = QString ( " <tr><td colspan=5 align=center><i>%1</i></td></tr> " ) . arg ( " <b> " + STR_MessageBox_PleaseNote + " </b> " +
2019-03-27 15:24:51 +00:00
tr ( " This day just contains summary data, only limited information is available. " ) ) ;
2014-08-07 21:54:32 +00:00
} else if ( cpap ) {
2014-05-15 20:48:05 +00:00
html + = " <tr><td colspan=5> </td></tr> " ;
2014-08-20 17:17:13 +00:00
if ( ( cpap - > loaderName ( ) = = STR_MACH_ResMed ) | | ( ( cpap - > loaderName ( ) = = STR_MACH_PRS1 ) & & ( p_profile - > cpap - > resyncFromUserFlagging ( ) ) ) ) {
2021-07-25 04:12:15 +00:00
int ttia = day - > sum ( AllAhiChannels ) ;
2014-08-07 21:54:32 +00:00
int h = ttia / 3600 ;
int m = ttia / 60 % 60 ;
int s = ttia % 60 ;
if ( ttia > 0 ) {
2019-03-27 15:24:51 +00:00
html + = " <tr><td colspan=3 align='left' bgcolor='white'><b> " + tr ( " Total time in apnea " ) +
2023-03-01 12:51:45 +00:00
QString ( " </b></td><td colspan=2 bgcolor='white'>%1</td></tr> " ) . arg ( QString : : asprintf ( " %02i:%02i:%02i " , h , m , s ) ) ;
2014-08-07 21:54:32 +00:00
}
}
2014-08-20 17:17:13 +00:00
float hours = day - > hours ( MT_CPAP ) ;
2014-08-07 21:54:32 +00:00
if ( p_profile - > cpap - > showLeakRedline ( ) ) {
2014-08-20 17:17:13 +00:00
float rlt = day - > timeAboveThreshold ( CPAP_Leak , p_profile - > cpap - > leakRedline ( ) ) / 60.0 ;
float pc = 100.0 / hours * rlt ;
2014-08-07 21:54:32 +00:00
html + = " <tr><td colspan=3 align='left' bgcolor='white'><b> " + tr ( " Time over leak redline " ) +
QString ( " </b></td><td colspan=2 bgcolor='white'>%1%</td></tr> " ) . arg ( pc , 0 , ' f ' , 3 ) ;
}
2014-08-20 17:17:13 +00:00
int l = day - > sum ( CPAP_Ramp ) ;
2014-07-30 17:14:28 +00:00
if ( l > 0 ) {
2014-07-30 20:25:06 +00:00
html + = " <tr><td colspan=3 align='left' bgcolor='white'> " + tr ( " Total ramp time " ) +
QString ( " </td><td colspan=2 bgcolor='white'>%1:%2:%3</td></tr> " ) . arg ( l / 3600 , 2 , 10 , QChar ( ' 0 ' ) ) . arg ( ( l / 60 ) % 60 , 2 , 10 , QChar ( ' 0 ' ) ) . arg ( l % 60 , 2 , 10 , QChar ( ' 0 ' ) ) ;
2014-08-20 17:17:13 +00:00
float v = ( hours - ( float ( l ) / 3600.0 ) ) ;
2014-07-30 17:14:28 +00:00
int q = v * 3600.0 ;
2014-07-30 20:25:06 +00:00
html + = " <tr><td colspan=3 align='left' bgcolor='white'> " + tr ( " Time outside of ramp " ) +
QString ( " </td><td colspan=2 bgcolor='white'>%1:%2:%3</td></tr> " ) . arg ( q / 3600 , 2 , 10 , QChar ( ' 0 ' ) ) . arg ( ( q / 60 ) % 60 , 2 , 10 , QChar ( ' 0 ' ) ) . arg ( q % 60 , 2 , 10 , QChar ( ' 0 ' ) ) ;
2014-07-30 17:14:28 +00:00
2014-09-14 15:29:07 +00:00
// EventDataType hc = day->count(CPAP_Hypopnea) - day->countInsideSpan(CPAP_Ramp, CPAP_Hypopnea);
// EventDataType oc = day->count(CPAP_Obstructive) - day->countInsideSpan(CPAP_Ramp, CPAP_Obstructive);
2014-07-30 17:14:28 +00:00
2014-09-14 15:29:07 +00:00
//EventDataType tc = day->count(CPAP_Hypopnea) + day->count(CPAP_Obstructive);
// EventDataType ahi = (hc+oc) / v;
2014-08-20 17:17:13 +00:00
// Not sure if i was trying to be funny, and left on my replication of Devilbiss's bug here... :P
2014-09-14 15:29:07 +00:00
// html+="<tr><td colspan=3 align='left' bgcolor='white'>"+tr("AHI excluding ramp")+
// QString("</td><td colspan=2 bgcolor='white'>%1</td></tr>").arg(ahi, 0, 'f', 2);
2014-07-28 17:10:26 +00:00
}
2014-07-28 13:56:29 +00:00
}
2013-10-13 16:35:53 +00:00
html + = " </table> \n " ;
html + = " <hr/> \n " ;
return html ;
}
QString Daily : : getEventBreakdown ( Day * cpap )
2011-06-26 08:30:44 +00:00
{
2013-10-26 13:59:37 +00:00
Q_UNUSED ( cpap )
2013-10-13 16:35:53 +00:00
QString html ;
html + = " <table cellspacing=0 cellpadding=0 border=0 width='100%'> \n " ;
html + = " </table> " ;
return html ;
}
2014-08-20 17:17:13 +00:00
QString Daily : : getSleepTime ( Day * day )
2013-10-13 16:35:53 +00:00
{
2014-08-20 17:17:13 +00:00
//cpap, Day * oxi
2013-10-13 16:35:53 +00:00
QString html ;
2014-08-20 17:17:13 +00:00
if ( ! day | | ( day - > hours ( ) < 0.0000001 ) )
2013-10-13 16:35:53 +00:00
return html ;
2014-08-20 17:17:13 +00:00
2024-03-20 16:59:40 +00:00
# ifndef COMBINE_MODE_3
htmlLsbSectionHeader ( html , tr ( " General " ) , LSB_SLEEPTIME_INDICES ) ;
if ( ! leftSideBarEnable [ LSB_SLEEPTIME_INDICES ] ) {
return html ;
}
# else
if ( ! leftSideBarEnable [ LSB_MACHINE_INFO ] ) return html ;
# endif
2013-10-13 16:35:53 +00:00
html + = " <table cellspacing=0 cellpadding=0 border=0 width='100%'> \n " ;
2018-06-14 08:58:06 +00:00
html + = " <tr><td align='center'><b> " + STR_TR_Date + " </b></td><td align='center'><b> " + tr ( " Start " ) + " </b></td><td align='center'><b> " + tr ( " End " ) + " </b></td><td align='center'><b> " + STR_UNIT_Hours + " </b></td></tr> " ;
2020-07-24 18:29:19 +00:00
int tt = qint64 ( day - > total_time ( MT_CPAP ) ) / 1000L ;
2013-10-13 16:35:53 +00:00
QDateTime date = QDateTime : : fromTime_t ( day - > first ( ) / 1000L ) ;
QDateTime date2 = QDateTime : : fromTime_t ( day - > last ( ) / 1000L ) ;
int h = tt / 3600 ;
int m = ( tt / 60 ) % 60 ;
int s = tt % 60 ;
html + = QString ( " <tr><td align='center'>%1</td><td align='center'>%2</td><td align='center'>%3</td><td align='center'>%4</td></tr> \n " )
. arg ( date . date ( ) . toString ( Qt : : SystemLocaleShortDate ) )
2014-08-27 09:00:55 +00:00
. arg ( date . toString ( " HH:mm:ss " ) )
. arg ( date2 . toString ( " HH:mm:ss " ) )
2023-03-01 12:51:45 +00:00
. arg ( QString : : asprintf ( " %02i:%02i:%02i " , h , m , s ) ) ;
2013-10-13 16:35:53 +00:00
html + = " </table> \n " ;
2024-03-20 16:59:40 +00:00
html + = " <hr/> " ;
return html ;
}
QString Daily : : getAHI ( Day * day , bool isBrick ) {
QString html ;
float hours = day - > hours ( MT_CPAP ) ;
EventDataType ahi = day - > count ( AllAhiChannels ) ;
if ( p_profile - > general - > calculateRDI ( ) ) ahi + = day - > count ( CPAP_RERA ) ;
ahi / = hours ;
html = " <table cellspacing=0 cellpadding=0 border=0 width='100%'> \n " ;
// Show application font, for debugging font issues
// QString appFont = QApplication::font().toString();
// html +=QString("<tr><td colspan=5 align=center>%1</td></tr>").arg(appFont);
html + = " <tr> " ;
if ( ! isBrick ) {
ChannelID ahichan = CPAP_AHI ;
QString ahiname = STR_TR_AHI ;
if ( p_profile - > general - > calculateRDI ( ) ) {
ahichan = CPAP_RDI ;
ahiname = STR_TR_RDI ;
}
html + = QString ( " <td colspan=5 bgcolor='%1' align=center><p title='%4'><font size=+3 color='%2'><b>%3</b></font></p> <font size=+3 color='%2'><b>%5</b></font></td> \n " )
. arg ( " #F88017 " ) . arg ( COLOR_Text . name ( ) ) . arg ( ahiname ) . arg ( schema : : channel [ ahichan ] . fullname ( ) ) . arg ( ahi , 0 , ' f ' , 2 ) ;
} else {
html + = QString ( " <td colspan=5 bgcolor='%1' align=center><font size=+3 color='yellow'><b>%2</b></font></td> \n " )
. arg ( " #F88017 " ) . arg ( tr ( " This CPAP device does NOT record detailed data " ) ) ;
}
html + = " </tr> \n " ;
html + = " </table> \n " ;
return html ;
}
QString Daily : : getIndices ( Day * day , QHash < ChannelID , EventDataType > & values ) {
QString html ;
float hours = day - > hours ( MT_CPAP ) ;
html = " <table cellspacing=0 cellpadding=0 border=0 width='100%'> \n " ;
quint32 zchans = schema : : SPAN | schema : : FLAG ;
bool show_minors = false ; // true;
if ( p_profile - > general - > showUnknownFlags ( ) ) zchans | = schema : : UNKNOWN ;
if ( show_minors ) zchans | = schema : : MINOR_FLAG ;
QList < ChannelID > available = day - > getSortedMachineChannels ( zchans ) ;
EventDataType val ;
for ( int i = 0 ; i < available . size ( ) ; + + i ) {
ChannelID code = available . at ( i ) ;
schema : : Channel & chan = schema : : channel [ code ] ;
// if (!chan.enabled()) continue;
QString data ;
if (
( code = = CPAP_UserFlag1 | | code = = CPAP_UserFlag2 ) & &
( ( ! p_profile - > cpap - > userEventFlagging ( ) ) | | ( p_profile - > cpap - > clinicalMode ( ) ) ) ) {
continue ;
}
float channelHours = hours ;
if ( chan . machtype ( ) ! = MT_CPAP ) {
// Use device type hours (if available) rather than CPAP hours, since
// might have Oximetry (for example) longer or shorter than CPAP
channelHours = day - > hours ( chan . machtype ( ) ) ;
if ( channelHours < = 0 ) {
channelHours = hours ;
}
}
if ( chan . type ( ) = = schema : : SPAN ) {
val = ( 100.0 / channelHours ) * ( day - > sum ( code ) / 3600.0 ) ;
data = QString ( " %1% " ) . arg ( val , 0 , ' f ' , 2 ) ;
} else if ( code = = CPAP_VSnore2 ) { // TODO: This should be generalized rather than special-casing a single channel here.
val = day - > sum ( code ) / channelHours ;
data = QString ( " %1 " ) . arg ( val , 0 , ' f ' , 2 ) ;
} else {
val = day - > count ( code ) / channelHours ;
data = QString ( " %1 " ) . arg ( val , 0 , ' f ' , 2 ) ;
}
// TODO: percentage would be another useful option here for things like
// percentage of patient-triggered breaths, which is much more useful
// than the duration of timed breaths per hour.
values [ code ] = val ;
QString tooltip = schema : : channel [ code ] . description ( ) ;
tooltip . replace ( " ' " , " ' " ) ;
QColor altcolor = ( brightness ( chan . defaultColor ( ) ) < 0.3 ) ? Qt : : white : Qt : : black ; // pick a contrasting color
html + = QString ( " <tr><td align='left' bgcolor='%1'><b><font color='%2'><a href='event=%5' style='text-decoration:none;color:%2' title='<p>%6</p>'>%3</a></font></b></td><td width=20% bgcolor='%1'><b><font color='%2'>%4</font></b></td></tr> " )
. arg ( chan . defaultColor ( ) . name ( ) )
. arg ( altcolor . name ( ) )
. arg ( chan . fullname ( ) )
. arg ( data )
. arg ( code )
. arg ( tooltip ) ;
}
html + = " </table><hr/> " ;
# ifndef COMBINE_MODE_3
if ( ! leftSideBarEnable [ LSB_SLEEPTIME_INDICES ] )
# else
if ( ! leftSideBarEnable [ LSB_MACHINE_INFO ] )
# endif
{
return QString ( ) ; // must calculate values first for pie chart.
}
2013-10-13 16:35:53 +00:00
return html ;
}
2024-03-20 16:59:40 +00:00
void Daily : : htmlLsbSectionHeaderInit ( bool section ) {
if ( ! section ) {
leftSideBarEnable . fill ( true ) ; // turn all sections On
//leftSideBarEnable.fill(false); // turn all sections off for testing
}
htmlLsbPrevSectionHeader = true ;
}
void Daily : : htmlLsbSectionHeader ( QString & html , const QString & name , LEFT_SIDEBAR checkBox ) {
QString handle = " leftsidebarenable " ;
bool on = leftSideBarEnable [ checkBox ] ; // this section is enabled
bool prev = htmlLsbPrevSectionHeader ; // prev section will be displayed
// only false when just section name is display
// true when full section should be displayed.
htmlLsbPrevSectionHeader = on ;
if ( ( ! prev ) & & on ) {
html + = " <hr/> " ;
}
html + = QString (
" <table cellspacing=0 cellpadding=0 border=0 width='100%'> "
" <tr> "
" <td align=left> "
# ifdef CONFIGURE_MODE
" <a href='leftsidebarenable=%3'> " " <img src='qrc:/icons/session-%2.png'/a> "
# else
" "
# endif
" </td> "
" <td align=centered;> "
" <a href='leftsidebarenable=%3' style='text-decoration:none;color:black'> "
" <b>%1</b></a> "
" </td> "
" </table> \n "
)
. arg ( name )
. arg ( on ? " on " : " off " )
. arg ( checkBox ) ;
}
2019-07-19 05:39:08 +00:00
QString Daily : : getPieChart ( float values , Day * day ) {
2024-03-20 16:59:40 +00:00
QString pieChartName = tr ( " Event Breakdown " ) ;
QString html ;
htmlLsbSectionHeader ( html , pieChartName , LSB_PIE_CHART ) ;
if ( ! leftSideBarEnable [ LSB_PIE_CHART ] ) {
return html ;
}
html + = " <table cellspacing=0 cellpadding=0 border=0 width='100%'> " ;
2019-07-19 05:39:08 +00:00
if ( values > 0 ) {
2024-03-20 16:59:40 +00:00
html + = QString ( " <tr><td align=center><b>%1</b></td></tr> " ) . arg ( " " ) ;
2019-07-19 05:39:08 +00:00
eventBreakdownPie ( ) - > setShowTitle ( false ) ;
int w = 155 ;
int h = 155 ;
QPixmap pixmap = eventBreakdownPie ( ) - > renderPixmap ( w , h , false ) ;
if ( ! pixmap . isNull ( ) ) {
QByteArray byteArray ;
QBuffer buffer ( & byteArray ) ; // use buffer to store pixmap into byteArray
buffer . open ( QIODevice : : WriteOnly ) ;
pixmap . save ( & buffer , " PNG " ) ;
2024-03-20 16:59:40 +00:00
// Close section where pie chart is pressed
html + = QString ( " <tr><td align=center> "
" <a href='%1' style='text-decoration:none;color:black'> "
" <img src= \" data:image/png;base64, " + byteArray . toBase64 ( ) + " \" ></td></tr> \n " )
. arg ( " leftsidebarenable=%1 " ) . arg ( LSB_PIE_CHART )
;
2019-07-19 05:39:08 +00:00
} else {
html + = " <tr><td align=center> " + tr ( " Unable to display Pie Chart on this system " ) + " </td></tr> \n " ;
}
2021-07-25 04:12:15 +00:00
} else {
bool gotsome = false ;
for ( int i = 0 ; i < ahiChannels . size ( ) ; i + + )
gotsome = gotsome | | day - > channelHasData ( ahiChannels . at ( i ) ) ;
// if ( day->channelHasData(CPAP_Obstructive)
// || day->channelHasData(CPAP_AllApnea)
// || day->channelHasData(CPAP_Hypopnea)
// || day->channelHasData(CPAP_ClearAirway)
// || day->channelHasData(CPAP_Apnea)
if ( gotsome
2019-07-19 05:39:08 +00:00
| | day - > channelHasData ( CPAP_RERA )
| | day - > channelHasData ( CPAP_FlowLimit )
| | day - > channelHasData ( CPAP_SensAwake )
) {
html + = " <tr><td align=center><img src= \" qrc:/docs/0.0.gif \" ></td></tr> \n " ;
2021-07-25 04:12:15 +00:00
}
2019-07-19 05:39:08 +00:00
}
html + = " </table> \n " ;
html + = " <hr/> \n " ;
return html ;
}
// honorPieChart true - show pie chart if it is enabled. False, do not show pie chart
QString Daily : : getLeftSidebar ( bool honorPieChart ) {
QString html = htmlLeftHeader
+ htmlLeftAHI
+ htmlLeftMachineInfo
+ htmlLeftSleepTime
+ htmlLeftIndices ;
// Include pie chart if wanted and enabled.
if ( honorPieChart & & AppSetting - > showPieChart ( ) )
html + = htmlLeftPieChart ;
html + = htmlLeftNoHours
+ htmlLeftStatistics
+ htmlLeftOximeter
+ htmlLeftMachineSettings
+ htmlLeftSessionInfo
+ htmlLeftFooter ;
return html ;
}
2018-05-08 08:12:32 +00:00
QVariant MyTextBrowser : : loadResource ( int type , const QUrl & url )
{
2018-06-08 05:43:03 +00:00
if ( type = = QTextDocument : : ImageResource & & url . scheme ( ) . compare ( QLatin1String ( " data " ) , Qt : : CaseInsensitive ) = = 0 ) {
static QRegularExpression re ( " ^image/[^;]+;base64,.+={0,2}$ " ) ;
QRegularExpressionMatch match = re . match ( url . path ( ) ) ;
if ( match . hasMatch ( ) )
return QVariant ( ) ;
}
return QTextBrowser : : loadResource ( type , url ) ;
2018-05-08 08:12:32 +00:00
}
2013-10-13 10:13:14 +00:00
2014-08-07 20:27:23 +00:00
2013-10-13 16:35:53 +00:00
void Daily : : Load ( QDate date )
{
2021-04-01 00:32:58 +00:00
qDebug ( ) < < " Daily::Load called for " < < date . toString ( ) < < " using " < < QApplication : : font ( ) . toString ( ) ;
2021-01-16 01:20:36 +00:00
2021-04-01 00:32:58 +00:00
qDebug ( ) < < " Setting App font in Daily::Load " ;
setApplicationFont ( ) ;
2021-01-16 01:20:36 +00:00
2013-10-12 08:07:57 +00:00
dateDisplay - > setText ( " <i> " + date . toString ( Qt : : SystemLocaleLongDate ) + " </i> " ) ;
2011-06-26 08:30:44 +00:00
previous_date = date ;
2014-08-20 17:17:13 +00:00
Day * day = p_profile - > GetDay ( date ) ;
Machine * cpap = nullptr ,
* oxi = nullptr ,
2014-10-02 10:02:33 +00:00
//*stage = nullptr,
2014-08-20 17:17:13 +00:00
* posit = nullptr ;
if ( day ) {
cpap = day - > machine ( MT_CPAP ) ;
oxi = day - > machine ( MT_OXIMETER ) ;
2014-10-02 10:02:33 +00:00
// stage = day->machine(MT_SLEEPSTAGE);
2014-08-20 17:17:13 +00:00
posit = day - > machine ( MT_POSITION ) ;
}
2011-06-26 08:30:44 +00:00
2018-04-22 12:06:48 +00:00
if ( ! AppSetting - > cacheSessions ( ) ) {
2013-10-22 11:42:57 +00:00
// Getting trashed on purge last day...
2014-05-18 17:06:58 +00:00
// lastcpapday can get purged and be invalid
2014-08-20 17:17:13 +00:00
if ( lastcpapday & & ( lastcpapday ! = day ) ) {
2014-08-28 08:01:25 +00:00
for ( QMap < QDate , Day * > : : iterator di = p_profile - > daylist . begin ( ) ; di ! = p_profile - > daylist . end ( ) ; + + di ) {
Day * d = di . value ( ) ;
if ( d - > eventsLoaded ( ) ) {
if ( d - > useCounter ( ) = = 0 ) {
2014-09-11 14:23:08 +00:00
d - > CloseEvents ( ) ;
2014-08-28 08:01:25 +00:00
}
}
2011-07-28 07:32:02 +00:00
}
2011-07-27 10:47:50 +00:00
}
}
2011-12-03 08:52:24 +00:00
2014-08-20 17:17:13 +00:00
lastcpapday = day ;
2011-12-10 15:50:40 +00:00
2019-07-19 05:39:08 +00:00
// Clear the components of the left sidebar prior to recreating them
htmlLeftAHI . clear ( ) ;
htmlLeftMachineInfo . clear ( ) ;
htmlLeftSleepTime . clear ( ) ;
htmlLeftIndices . clear ( ) ;
htmlLeftPieChart . clear ( ) ;
htmlLeftNoHours . clear ( ) ;
htmlLeftStatistics . clear ( ) ;
htmlLeftOximeter . clear ( ) ;
htmlLeftMachineSettings . clear ( ) ;
htmlLeftSessionInfo . clear ( ) ;
htmlLeftHeader = " <html><head> "
2011-07-05 05:33:06 +00:00
" </head> "
2013-10-13 16:35:53 +00:00
" <body leftmargin=0 rightmargin=0 topmargin=0 marginwidth=0 marginheight=0> " ;
2012-01-06 16:07:54 +00:00
2014-08-20 17:17:13 +00:00
if ( day ) {
day - > OpenEvents ( ) ;
}
GraphView - > setDay ( day ) ;
UpdateEventsTree ( ui - > treeWidget , day ) ;
2011-12-22 10:29:12 +00:00
2014-04-28 03:27:33 +00:00
// FIXME:
// Generating entire statistics because bookmarks may have changed.. (This updates the side panel too)
mainwin - > GenerateStatistics ( ) ;
2011-12-22 10:29:12 +00:00
2014-08-20 17:17:13 +00:00
snapGV - > setDay ( day ) ;
2012-01-06 05:22:13 +00:00
QString modestr ;
2011-06-26 08:30:44 +00:00
CPAPMode mode = MODE_UNKNOWN ;
QString a ;
2011-12-10 12:14:48 +00:00
bool isBrick = false ;
2011-12-23 10:52:31 +00:00
2012-01-03 16:29:35 +00:00
updateGraphCombo ( ) ;
2013-10-13 16:35:53 +00:00
2023-03-04 15:14:21 +00:00
updateEventsCombo ( day ) ;
2014-08-05 11:17:03 +00:00
2014-09-01 11:39:38 +00:00
if ( ! cpap ) {
2019-04-16 17:12:26 +00:00
GraphView - > setEmptyImage ( QPixmap ( " :/icons/logo-md.png " ) ) ;
2014-09-01 11:39:38 +00:00
}
2014-08-05 11:17:03 +00:00
if ( cpap ) {
2014-08-20 17:17:13 +00:00
float hours = day - > hours ( MT_CPAP ) ;
2012-01-11 04:58:46 +00:00
if ( GraphView - > isEmpty ( ) & & ( hours > 0 ) ) {
2020-03-26 13:54:55 +00:00
// TODO: Eventually we should get isBrick from the loader, since some summary days
// on a non-brick might legitimately have no graph data.
2021-07-25 04:12:15 +00:00
bool gotsome = false ;
2024-03-20 16:59:40 +00:00
for ( int i = 0 ; i < ahiChannels . size ( ) & & ! gotsome ; i + + ) {
gotsome = p_profile - > hasChannel ( ahiChannels . at ( i ) ) ;
}
2021-07-25 04:12:15 +00:00
if ( ! gotsome ) {
2014-09-01 11:39:38 +00:00
GraphView - > setEmptyText ( STR_Empty_Brick ) ;
2011-12-22 10:29:12 +00:00
2014-09-01 11:39:38 +00:00
GraphView - > setEmptyImage ( QPixmap ( " :/icons/sadface.png " ) ) ;
2011-12-30 23:02:45 +00:00
isBrick = true ;
2014-09-01 11:39:38 +00:00
} else {
2019-04-16 17:12:26 +00:00
GraphView - > setEmptyImage ( QPixmap ( " :/icons/logo-md.png " ) ) ;
2011-12-30 23:02:45 +00:00
}
2011-12-10 12:14:48 +00:00
}
2011-12-22 10:29:12 +00:00
2014-08-20 17:17:13 +00:00
mode = ( CPAPMode ) ( int ) day - > settings_max ( CPAP_Mode ) ;
2011-12-14 05:15:13 +00:00
2011-09-17 12:39:00 +00:00
modestr = schema : : channel [ CPAP_Mode ] . m_options [ mode ] ;
2014-09-01 11:39:38 +00:00
if ( hours > 0 ) {
2024-03-20 16:59:40 +00:00
htmlLeftAHI = getAHI ( day , isBrick ) ;
2013-10-20 16:20:31 +00:00
2024-02-28 00:04:48 +00:00
htmlLeftMachineInfo = getCPAPInformation ( day ) ;
2014-08-07 20:27:23 +00:00
2024-03-20 16:59:40 +00:00
htmlLsbSectionHeaderInit ( ) ;
2024-02-28 00:04:48 +00:00
2024-03-20 16:59:40 +00:00
htmlLeftSleepTime = getSleepTime ( day ) ;
2024-02-28 00:04:48 +00:00
2014-08-07 22:10:50 +00:00
QHash < ChannelID , EventDataType > values ;
2024-03-20 16:59:40 +00:00
htmlLeftIndices = getIndices ( day , values ) ;
2011-12-10 12:14:48 +00:00
2021-07-25 04:12:15 +00:00
htmlLeftPieChart = getPieChart ( ( values [ CPAP_Obstructive ] + values [ CPAP_Hypopnea ] + values [ CPAP_AllApnea ] +
2019-07-19 05:39:08 +00:00
values [ CPAP_ClearAirway ] + values [ CPAP_Apnea ] + values [ CPAP_RERA ] +
values [ CPAP_FlowLimit ] + values [ CPAP_SensAwake ] ) , day ) ;
2024-03-20 16:59:40 +00:00
htmlLsbSectionHeaderInit ( ) ;
2011-12-23 10:52:31 +00:00
2019-07-19 05:39:08 +00:00
} else { // No hours
htmlLeftNoHours + = " <table cellspacing=0 cellpadding=0 border=0 width='100%'> \n " ;
2012-01-11 04:58:46 +00:00
if ( ! isBrick ) {
2019-07-19 05:39:08 +00:00
htmlLeftNoHours + = " <tr><td colspan='5'> </td></tr> \n " ;
2014-08-20 17:17:13 +00:00
if ( day - > size ( ) > 0 ) {
2019-07-19 05:39:08 +00:00
htmlLeftNoHours + = " <tr><td colspan=5 align='center'><font size='+3'> " + tr ( " Sessions all off! " ) + " </font></td></tr> " ;
htmlLeftNoHours + = " <tr><td colspan=5 align='center><img src='qrc:/icons/logo-md.png'></td></tr> " ;
htmlLeftNoHours + = " <tr bgcolor='#89abcd'><td colspan=5 align='center'><i><font color=white size=+1> " + tr ( " Sessions exist for this day but are switched off. " ) + " </font></i></td></tr> \n " ;
2014-08-21 08:04:25 +00:00
GraphView - > setEmptyText ( STR_Empty_NoSessions ) ;
2012-01-11 04:58:46 +00:00
} else {
2019-07-19 05:39:08 +00:00
htmlLeftNoHours + = " <tr><td colspan=5 align='center'><b><h2> " + tr ( " Impossibly short session " ) + " </h2></b></td></tr> " ;
htmlLeftNoHours + = " <tr><td colspan=5 align='center'><i> " + tr ( " Zero hours?? " ) + " </i></td></tr> \n " ;
2012-01-11 04:58:46 +00:00
}
2022-02-27 14:18:39 +00:00
} else { // Device is a brick
htmlLeftNoHours + = " <tr><td colspan=5 align='center'><b><h2> " + tr ( " no data :( " ) + " </h2></b></td></tr> " ;
htmlLeftNoHours + = " <tr><td colspan=5 align='center'><i> " + tr ( " Sorry, this device only provides compliance data. " ) + " </i></td></tr> \n " ;
2019-07-19 05:39:08 +00:00
htmlLeftNoHours + = " <tr><td colspan=5 align='center'><i> " + tr ( " Complain to your Equipment Provider! " ) + " </i></td></tr> \n " ;
2012-01-11 04:58:46 +00:00
}
2019-07-19 05:39:08 +00:00
htmlLeftNoHours + = " <tr><td colspan='5'> </td></tr> \n " ;
2024-03-20 16:59:40 +00:00
htmlLeftNoHours + = " </table><hr/> \n " ;
2011-12-23 10:52:31 +00:00
}
2024-07-10 00:11:24 +00:00
} else { // if (!CPAP)
htmlLeftSleepTime = getSleepTime ( day ) ;
}
if ( day ) {
htmlLeftOximeter = getOximeterInformation ( day ) ;
htmlLeftMachineSettings = getMachineSettings ( day ) ;
htmlLeftSessionInfo = getSessionInformation ( day ) ;
}
2012-01-12 23:34:52 +00:00
2014-08-20 17:17:13 +00:00
if ( ( cpap & & ! isBrick & & ( day - > hours ( ) > 0 ) ) | | oxi | | posit ) {
2012-01-12 23:34:52 +00:00
2024-07-10 00:11:24 +00:00
if ( ( ! cpap ) & & ( ! isBrick ) ) {
// add message when there is no cpap data but there exists oximeter data.
QString msg = tr ( " No CPAP data is available for this day " ) ;
QString beg = " <table cellspacing=0 cellpadding=0 border=0 width='100%'> "
" <tr><td colspan=5 bgcolor='#89abcd' align=center><p title=''> <b><font size=+0 color=white> " ;
htmlLeftAHI = QString ( " %1 %2 </b></td></tr></table> " ) . arg ( beg ) . arg ( msg ) ;
}
2019-07-19 05:39:08 +00:00
htmlLeftStatistics = getStatisticsInfo ( day ) ;
2014-05-15 20:48:05 +00:00
2011-06-26 08:30:44 +00:00
} else {
2014-08-20 17:17:13 +00:00
if ( cpap & & day - > hours ( MT_CPAP ) < 0.0000001 ) {
2014-09-01 11:39:38 +00:00
} else if ( ! isBrick ) {
2024-07-10 00:11:24 +00:00
htmlLeftAHI . clear ( ) ; // clear AHI (no cpap data) msg when there is no oximeter data
htmlLeftSessionInfo . clear ( ) ; // clear session info
2019-07-19 05:39:08 +00:00
htmlLeftStatistics = " <table cellspacing=0 cellpadding=0 border=0 height=100% width=100%> " ;
htmlLeftStatistics + = " <tr height=25%><td align=center></td></tr> " ;
htmlLeftStatistics + = " <tr><td align=center><font size='+3'> " + tr ( " \" Nothing's here! \" " ) + " </font></td></tr> " ;
htmlLeftStatistics + = " <tr><td align=center><img src='qrc:/icons/logo-md.png'></td></tr> " ;
htmlLeftStatistics + = " <tr height=5px><td align=center></td></tr> " ;
htmlLeftStatistics + = " <tr bgcolor='#89abcd'><td align=center><i><font size=+1 color=white> " + tr ( " No data is available for this day. " ) + " </font></i></td></tr> " ;
htmlLeftStatistics + = " <tr height=25%><td align=center></td></tr> " ;
htmlLeftStatistics + = " </table> \n " ;
2012-01-11 04:58:46 +00:00
}
2011-06-26 08:30:44 +00:00
}
2011-12-31 11:36:19 +00:00
2019-07-19 05:39:08 +00:00
htmlLeftFooter = " </body></html> " ;
2011-06-26 08:30:44 +00:00
2019-09-16 18:54:42 +00:00
// SessionBar colors. Colors alternate.
2013-10-12 07:40:45 +00:00
QColor cols [ ] = {
2014-09-11 14:23:08 +00:00
COLOR_Gold ,
2019-09-16 18:54:42 +00:00
// QColor("light blue"),
QColor ( " skyblue " ) ,
2013-10-12 07:40:45 +00:00
} ;
const int maxcolors = sizeof ( cols ) / sizeof ( QColor ) ;
2013-10-22 11:42:57 +00:00
QList < Session * > : : iterator i ;
2013-10-12 07:40:45 +00:00
2019-05-20 00:44:10 +00:00
sessionbar - > clear ( ) ; // clear sessionbar as some days don't have sessions
2013-10-12 07:46:06 +00:00
if ( cpap ) {
int c = 0 ;
2014-08-20 17:17:13 +00:00
for ( i = day - > begin ( ) ; i ! = day - > end ( ) ; + + i ) {
2013-10-12 07:46:06 +00:00
Session * s = * i ;
2014-09-17 06:12:38 +00:00
if ( ( * s ) . type ( ) = = MT_CPAP )
2018-05-07 22:09:59 +00:00
sessionbar - > add ( s , cols [ c % maxcolors ] ) ;
2013-10-12 07:46:06 +00:00
c + + ;
}
2018-05-07 22:09:59 +00:00
}
2013-10-12 07:40:45 +00:00
//sessbar->update();
2018-05-08 08:12:32 +00:00
# ifdef DEBUG_DAILY_HTML
2019-03-25 23:43:04 +00:00
QString name = GetAppData ( ) + " /test.html " ;
2018-05-08 08:12:32 +00:00
QFile file ( name ) ;
if ( file . open ( QFile : : WriteOnly ) ) {
const QByteArray & b = html . toLocal8Bit ( ) ;
file . write ( b . data ( ) , b . size ( ) ) ;
file . close ( ) ;
}
# endif
2019-07-19 05:39:08 +00:00
webView - > setHtml ( getLeftSidebar ( true ) ) ;
2011-06-26 08:30:44 +00:00
2011-09-17 15:41:31 +00:00
ui - > JournalNotes - > clear ( ) ;
2011-12-02 11:40:47 +00:00
2011-12-18 16:39:36 +00:00
ui - > bookmarkTable - > clearContents ( ) ;
2011-12-02 11:40:47 +00:00
ui - > bookmarkTable - > setRowCount ( 0 ) ;
QStringList sl ;
ui - > bookmarkTable - > setHorizontalHeaderLabels ( sl ) ;
2022-11-17 01:46:30 +00:00
# ifndef REMOVE_FITNESS
2023-09-25 18:34:18 +00:00
user_height_cm = p_profile - > user - > height ( ) ;
2024-03-25 19:36:42 +00:00
set_ZombieUI ( 0 ) ;
set_WeightUI ( 0 ) ;
2023-09-25 18:34:18 +00:00
2022-11-17 01:46:30 +00:00
# endif
2011-12-02 14:18:47 +00:00
BookmarksChanged = false ;
2011-06-26 08:30:44 +00:00
Session * journal = GetJournalSession ( date ) ;
if ( journal ) {
2024-03-25 19:36:42 +00:00
if ( journal - > settings . contains ( Journal_Notes ) ) {
set_NotesUI ( journal - > settings [ Journal_Notes ] . toString ( ) ) ;
}
2011-12-02 11:40:47 +00:00
2022-11-17 01:46:30 +00:00
# ifndef REMOVE_FITNESS
bool ok ;
2011-12-21 05:47:33 +00:00
if ( journal - > settings . contains ( Journal_Weight ) ) {
double kg = journal - > settings [ Journal_Weight ] . toDouble ( & ok ) ;
2023-09-25 18:34:18 +00:00
set_WeightUI ( kg ) ;
2011-12-02 13:48:05 +00:00
}
2011-12-02 11:40:47 +00:00
2011-12-21 05:47:33 +00:00
if ( journal - > settings . contains ( Journal_ZombieMeter ) ) {
2023-09-25 18:34:18 +00:00
int value = journal - > settings [ Journal_ZombieMeter ] . toInt ( & ok ) ;
2024-03-25 19:36:42 +00:00
set_ZombieUI ( value ) ;
2011-12-10 15:24:45 +00:00
}
2022-11-17 01:46:30 +00:00
# endif
2011-12-02 11:40:47 +00:00
2011-12-21 05:47:33 +00:00
if ( journal - > settings . contains ( Bookmark_Start ) ) {
QVariantList start = journal - > settings [ Bookmark_Start ] . toList ( ) ;
QVariantList end = journal - > settings [ Bookmark_End ] . toList ( ) ;
QStringList notes = journal - > settings [ Bookmark_Notes ] . toStringList ( ) ;
2011-12-02 11:40:47 +00:00
2024-03-25 19:36:42 +00:00
if ( start . size ( ) > 0 ) {
// Careful with drift here - apply to the label but not the
// stored data (which will be saved if journal changes occur).
qint64 clockdrift = p_profile - > cpap - > clockDrift ( ) * 1000L , drift ;
Day * dday = p_profile - > GetDay ( previous_date , MT_CPAP ) ;
drift = ( dday ! = nullptr ) ? clockdrift : 0 ;
set_BookmarksUI ( start , end , notes , drift ) ;
}
2011-12-23 10:52:31 +00:00
} // if (journal->settings.contains(Bookmark_Start))
} // if (journal)
2011-06-26 08:30:44 +00:00
}
2011-12-02 13:48:05 +00:00
void Daily : : UnitsChanged ( )
{
2022-11-17 01:46:30 +00:00
# ifndef REMOVE_FITNESS
2024-03-25 19:36:42 +00:00
// Called from newprofile when height changed or when units changed metric / english
// just as if weight changed. may make bmi visible.
on_weightSpinBox_editingFinished ( ) ;
2022-11-17 01:46:30 +00:00
# endif
2011-12-02 13:48:05 +00:00
}
2024-03-25 19:36:42 +00:00
double Daily : : calculateBMI ( double weight_kg , double height_cm ) {
double height = height_cm / 100.0 ;
double bmi = weight_kg / ( height * height ) ;
return bmi ;
}
QString Daily : : convertHtmlToPlainText ( QString html ) {
QTextDocument doc ;
doc . setHtml ( html ) ;
QString plain = doc . toPlainText ( ) ;
return plain . simplified ( ) ;
}
void Daily : : set_JournalZombie ( QDate & date , int value ) {
Session * journal = GetJournalSession ( date ) ;
if ( ! journal ) {
journal = CreateJournalSession ( date ) ;
}
if ( value = = 0 ) {
// should delete zombie entry here. if null.
auto jit = journal - > settings . find ( Journal_ZombieMeter ) ;
if ( jit ! = journal - > settings . end ( ) ) {
journal - > settings . erase ( jit ) ;
}
} else {
journal - > settings [ Journal_ZombieMeter ] = value ;
}
journal - > SetChanged ( true ) ;
} ;
void Daily : : set_JournalWeightValue ( QDate & date , double kg ) {
Session * journal = GetJournalSession ( date ) ;
if ( ! journal ) {
journal = CreateJournalSession ( date ) ;
}
if ( journal - > settings . contains ( Journal_Weight ) ) {
QVariant old = journal - > settings [ Journal_Weight ] ;
if ( abs ( old . toDouble ( ) - kg ) < zeroD & & kg > zeroD ) {
// No change to weight - skip
return ;
}
} else if ( kg < zeroD ) {
// Still zero - skip
return ;
}
if ( kg > zeroD ) {
journal - > settings [ Journal_Weight ] = kg ;
} else {
// Weight now zero - remove from journal
auto jit = journal - > settings . find ( Journal_Weight ) ;
if ( jit ! = journal - > settings . end ( ) ) {
journal - > settings . erase ( jit ) ;
}
}
journal - > SetChanged ( true ) ;
return ;
}
void Daily : : set_JournalNotesHtml ( QDate & date , QString html ) {
QString newHtmlPlaintText = convertHtmlToPlainText ( html ) ; // have a look as plaintext to see if really empty.
bool newHtmlHasContent = ! newHtmlPlaintText . isEmpty ( ) ; // have a look as plaintext to see if really empty.
Session * journal = GetJournalSession ( date , false ) ;
QString prevHtml ;
if ( journal ) {
auto jit = journal - > settings . find ( Journal_Notes ) ;
if ( jit ! = journal - > settings . end ( ) ) {
prevHtml = journal - > settings [ Journal_Notes ] . toString ( ) ;
}
}
if ( ! newHtmlHasContent ) {
if ( ! journal ) {
return ; //no action required
}
// removing previous notes.
auto jit = journal - > settings . find ( Journal_Notes ) ;
if ( jit ! = journal - > settings . end ( ) ) {
journal - > settings . erase ( jit ) ;
journal - > SetChanged ( true ) ;
}
return ;
} else if ( html = = prevHtml ) {
return ; //no action required
}
if ( ! journal ) {
journal = GetJournalSession ( date , true ) ;
if ( ! journal ) {
journal = CreateJournalSession ( date ) ;
}
}
journal - > settings [ Journal_Notes ] = html ;
journal - > SetChanged ( true ) ;
}
2013-10-22 11:42:57 +00:00
void Daily : : clearLastDay ( )
{
2014-04-23 13:19:56 +00:00
lastcpapday = nullptr ;
2013-10-22 11:42:57 +00:00
}
2011-06-26 08:30:44 +00:00
void Daily : : Unload ( QDate date )
{
2014-07-25 07:53:48 +00:00
if ( ! date . isValid ( ) ) {
date = getDate ( ) ;
if ( ! date . isValid ( ) ) {
graphView ( ) - > setDay ( nullptr ) ;
return ;
}
}
2014-08-07 22:47:34 +00:00
2018-05-08 08:12:32 +00:00
// Update the journal notes
2024-03-25 19:36:42 +00:00
set_JournalNotesHtml ( date , ui - > JournalNotes - > toHtml ( ) ) ;
2018-05-08 08:12:32 +00:00
Session * journal = GetJournalSession ( date ) ;
2011-06-26 08:30:44 +00:00
if ( journal ) {
2011-12-02 13:48:05 +00:00
if ( journal - > IsChanged ( ) ) {
2018-05-08 08:12:32 +00:00
journal - > settings [ LastUpdated ] = QDateTime : : currentDateTime ( ) ;
2018-05-30 08:51:43 +00:00
journal - > machine ( ) - > SaveSummaryCache ( ) ;
2018-05-08 08:12:32 +00:00
journal - > SetChanged ( false ) ; // save summary doesn't automatically do this
2011-12-02 13:48:05 +00:00
}
2011-09-17 15:41:31 +00:00
}
2011-06-26 08:30:44 +00:00
UpdateCalendarDay ( date ) ;
}
void Daily : : on_JournalNotesItalic_clicked ( )
{
QTextCursor cursor = ui - > JournalNotes - > textCursor ( ) ;
if ( ! cursor . hasSelection ( ) )
cursor . select ( QTextCursor : : WordUnderCursor ) ;
QTextCharFormat format = cursor . charFormat ( ) ;
format . setFontItalic ( ! format . fontItalic ( ) ) ;
cursor . mergeCharFormat ( format ) ;
//ui->JournalNotes->mergeCurrentCharFormat(format);
}
void Daily : : on_JournalNotesBold_clicked ( )
{
QTextCursor cursor = ui - > JournalNotes - > textCursor ( ) ;
if ( ! cursor . hasSelection ( ) )
cursor . select ( QTextCursor : : WordUnderCursor ) ;
QTextCharFormat format = cursor . charFormat ( ) ;
int fw = format . fontWeight ( ) ;
if ( fw ! = QFont : : Bold )
format . setFontWeight ( QFont : : Bold ) ;
else
format . setFontWeight ( QFont : : Normal ) ;
cursor . mergeCharFormat ( format ) ;
//ui->JournalNotes->mergeCurrentCharFormat(format);
}
void Daily : : on_JournalNotesFontsize_activated ( int index )
{
QTextCursor cursor = ui - > JournalNotes - > textCursor ( ) ;
if ( ! cursor . hasSelection ( ) )
cursor . select ( QTextCursor : : WordUnderCursor ) ;
QTextCharFormat format = cursor . charFormat ( ) ;
QFont font = format . font ( ) ;
int fontsize = 10 ;
if ( index = = 1 ) fontsize = 15 ;
else if ( index = = 2 ) fontsize = 25 ;
font . setPointSize ( fontsize ) ;
format . setFont ( font ) ;
cursor . mergeCharFormat ( format ) ;
}
void Daily : : on_JournalNotesColour_clicked ( )
{
2013-09-10 15:09:09 +00:00
QColor col = QColorDialog : : getColor ( COLOR_Black , this , tr ( " Pick a Colour " ) ) ; //,QColorDialog::NoButtons);
2011-06-26 08:30:44 +00:00
if ( ! col . isValid ( ) ) return ;
QTextCursor cursor = ui - > JournalNotes - > textCursor ( ) ;
if ( ! cursor . hasSelection ( ) )
cursor . select ( QTextCursor : : WordUnderCursor ) ;
QBrush b ( col ) ;
QPalette newPalette = palette ( ) ;
newPalette . setColor ( QPalette : : ButtonText , col ) ;
ui - > JournalNotesColour - > setPalette ( newPalette ) ;
QTextCharFormat format = cursor . charFormat ( ) ;
format . setForeground ( b ) ;
cursor . setCharFormat ( format ) ;
}
Session * Daily : : CreateJournalSession ( QDate date )
{
2014-08-20 17:17:13 +00:00
Machine * m = p_profile - > GetMachine ( MT_JOURNAL ) ;
2011-06-26 08:30:44 +00:00
if ( ! m ) {
2018-06-05 22:08:12 +00:00
m = new Machine ( p_profile , 0 ) ;
2014-07-28 13:56:29 +00:00
MachineInfo info ;
info . loadername = " Journal " ;
info . serial = m - > hexid ( ) ;
info . brand = " Journal " ;
info . type = MT_JOURNAL ;
m - > setInfo ( info ) ;
2014-08-20 17:17:13 +00:00
m - > setType ( MT_JOURNAL ) ;
2014-07-11 12:09:38 +00:00
p_profile - > AddMachine ( m ) ;
2011-06-26 08:30:44 +00:00
}
2014-08-20 17:17:13 +00:00
2011-06-26 08:30:44 +00:00
Session * sess = new Session ( m , 0 ) ;
2011-12-25 05:05:12 +00:00
qint64 st , et ;
2014-08-20 17:17:13 +00:00
2014-08-20 21:23:33 +00:00
Day * cday = p_profile - > GetDay ( date ) ;
2011-12-25 05:05:12 +00:00
if ( cday ) {
st = cday - > first ( ) ;
et = cday - > last ( ) ;
} else {
QDateTime dt ( date , QTime ( 20 , 0 ) ) ;
st = qint64 ( dt . toTime_t ( ) ) * 1000L ;
2014-08-07 17:20:52 +00:00
et = st + 3600000L ;
2011-12-25 05:05:12 +00:00
}
2014-08-20 21:23:33 +00:00
sess - > SetSessionID ( st / 1000L ) ;
2011-12-25 05:05:12 +00:00
sess - > set_first ( st ) ;
sess - > set_last ( et ) ;
2021-05-21 00:42:38 +00:00
m - > AddSession ( sess , true ) ;
2011-06-26 08:30:44 +00:00
return sess ;
}
2024-03-25 19:36:42 +00:00
Session * Daily : : GetJournalSession ( QDate date , bool create ) // Get the first journal session
2011-06-26 08:30:44 +00:00
{
2014-08-20 21:23:33 +00:00
Day * day = p_profile - > GetDay ( date , MT_JOURNAL ) ;
if ( day ) {
Session * session = day - > firstSession ( MT_JOURNAL ) ;
2024-03-25 19:36:42 +00:00
if ( ! session & & create ) {
2014-08-20 21:23:33 +00:00
session = CreateJournalSession ( date ) ;
}
return session ;
2014-08-20 17:17:13 +00:00
}
2014-08-20 21:23:33 +00:00
return nullptr ;
2011-06-26 08:30:44 +00:00
}
2011-06-27 07:45:59 +00:00
void Daily : : RedrawGraphs ( )
{
2014-05-15 19:45:46 +00:00
// setting this here, because it needs to be done when preferences change
2014-07-11 12:09:38 +00:00
if ( p_profile - > cpap - > showLeakRedline ( ) ) {
schema : : channel [ CPAP_Leak ] . setUpperThreshold ( p_profile - > cpap - > leakRedline ( ) ) ;
2014-05-15 19:45:46 +00:00
} else {
2014-05-15 21:48:53 +00:00
schema : : channel [ CPAP_Leak ] . setUpperThreshold ( 0 ) ; // switch it off
2014-05-15 19:45:46 +00:00
}
2019-07-02 15:01:20 +00:00
QFont appFont = QApplication : : font ( ) ;
dateDisplay - > setFont ( appFont ) ;
2011-12-20 11:12:52 +00:00
GraphView - > redraw ( ) ;
2011-06-27 07:45:59 +00:00
}
2011-06-26 08:30:44 +00:00
2014-08-17 12:56:05 +00:00
void Daily : : on_LineCursorUpdate ( double time )
{
2014-08-21 14:16:23 +00:00
if ( time > 1 ) {
2015-08-11 20:04:30 +00:00
// use local time since this string is displayed to the user
QDateTime dt = QDateTime : : fromMSecsSinceEpoch ( time , Qt : : LocalTime ) ;
2014-08-27 09:55:31 +00:00
QString txt = dt . toString ( " MMM dd HH:mm:ss.zzz " ) ;
2014-08-21 14:16:23 +00:00
dateDisplay - > setText ( txt ) ;
} else dateDisplay - > setText ( QString ( GraphView - > emptyText ( ) ) ) ;
2014-08-17 12:56:05 +00:00
}
2014-10-02 10:02:33 +00:00
void Daily : : on_RangeUpdate ( double minx , double /*maxx*/ )
2014-08-17 12:56:05 +00:00
{
2014-08-21 14:16:23 +00:00
if ( minx > 1 ) {
2014-08-17 12:56:05 +00:00
dateDisplay - > setText ( GraphView - > getRangeString ( ) ) ;
2014-08-21 14:16:23 +00:00
} else {
dateDisplay - > setText ( QString ( GraphView - > emptyText ( ) ) ) ;
}
2014-08-17 12:56:05 +00:00
}
2023-03-18 12:50:48 +00:00
void Daily : : on_treeWidget_itemClicked ( QTreeWidgetItem * item , int )
2011-06-26 08:30:44 +00:00
{
2023-03-18 12:50:48 +00:00
if ( ! item ) return ;
QTreeWidgetItem * parent = item - > parent ( ) ;
if ( ! parent ) return ;
gGraph * g = GraphView - > findGraph ( STR_GRAPH_SleepFlags ) ;
if ( ! g ) return ;
2011-06-26 08:30:44 +00:00
QDateTime d ;
2011-12-25 05:05:12 +00:00
if ( ! item - > data ( 0 , Qt : : UserRole ) . isNull ( ) ) {
2023-03-18 12:50:48 +00:00
int eventType = parent - > type ( ) ;
qint64 time = item - > data ( 0 , Qt : : UserRole ) . toLongLong ( ) ;
2011-12-25 05:05:12 +00:00
2023-03-18 12:50:48 +00:00
// for events display 3 minutes before and 20 seconds after
// for start time skip abit before graph
// for end time skip abut after graph
2011-12-25 05:05:12 +00:00
2023-03-18 12:50:48 +00:00
qint64 period = qint64 ( p_profile - > general - > eventWindowSize ( ) ) * 60000L ; // eventwindowsize units minutes
2023-09-25 18:34:18 +00:00
qint64 small = period / 10 ;
2023-03-18 12:50:48 +00:00
qint64 start , end ;
if ( eventType = = eventTypeStart ) {
start = time - small ;
end = time + period ;
} else {
start = time - period ;
end = time + small ;
2011-11-27 08:31:05 +00:00
}
2023-03-18 12:50:48 +00:00
GraphView - > SetXBounds ( start , end ) ;
2011-06-26 08:30:44 +00:00
}
}
2011-06-28 01:51:21 +00:00
2011-11-27 22:36:38 +00:00
void Daily : : on_treeWidget_itemSelectionChanged ( )
{
if ( ui - > treeWidget - > selectedItems ( ) . size ( ) = = 0 ) return ;
QTreeWidgetItem * item = ui - > treeWidget - > selectedItems ( ) . at ( 0 ) ;
if ( ! item ) return ;
on_treeWidget_itemClicked ( item , 0 ) ;
}
2011-06-28 01:51:21 +00:00
void Daily : : on_JournalNotesUnderline_clicked ( )
{
QTextCursor cursor = ui - > JournalNotes - > textCursor ( ) ;
if ( ! cursor . hasSelection ( ) )
cursor . select ( QTextCursor : : WordUnderCursor ) ;
QTextCharFormat format = cursor . charFormat ( ) ;
format . setFontUnderline ( ! format . fontUnderline ( ) ) ;
cursor . mergeCharFormat ( format ) ;
//ui->JournalNotes->mergeCurrentCharFormat(format);
}
2011-10-30 02:46:17 +00:00
void Daily : : on_prevDayButton_clicked ( )
{
2021-03-28 03:22:31 +00:00
if ( previous_date . isValid ( ) ) {
Unload ( previous_date ) ;
}
2014-07-11 12:09:38 +00:00
if ( ! p_profile - > ExistsAndTrue ( " SkipEmptyDays " ) ) {
2011-10-30 04:51:57 +00:00
LoadDate ( previous_date . addDays ( - 1 ) ) ;
} else {
QDate d = previous_date ;
for ( int i = 0 ; i < 90 ; i + + ) {
d = d . addDays ( - 1 ) ;
2014-07-11 12:09:38 +00:00
if ( p_profile - > GetDay ( d ) ) {
2011-10-30 04:51:57 +00:00
LoadDate ( d ) ;
break ;
}
2011-10-30 04:43:15 +00:00
}
}
2011-10-30 02:46:17 +00:00
}
2021-03-28 03:22:31 +00:00
bool Daily : : eventFilter ( QObject * object , QEvent * event )
{
if ( object = = ui - > JournalNotes & & event - > type ( ) = = QEvent : : FocusOut ) {
// Trigger immediate save of journal when we focus out from it so we never
// lose any journal entry text...
if ( previous_date . isValid ( ) ) {
Unload ( previous_date ) ;
}
}
return false ;
}
2011-10-30 02:46:17 +00:00
void Daily : : on_nextDayButton_clicked ( )
{
2021-03-28 03:22:31 +00:00
if ( previous_date . isValid ( ) ) {
Unload ( previous_date ) ;
}
2014-07-11 12:09:38 +00:00
if ( ! p_profile - > ExistsAndTrue ( " SkipEmptyDays " ) ) {
2011-10-30 04:51:57 +00:00
LoadDate ( previous_date . addDays ( 1 ) ) ;
} else {
QDate d = previous_date ;
for ( int i = 0 ; i < 90 ; i + + ) {
d = d . addDays ( 1 ) ;
2014-07-11 12:09:38 +00:00
if ( p_profile - > GetDay ( d ) ) {
2011-10-30 04:51:57 +00:00
LoadDate ( d ) ;
break ;
}
2011-10-30 04:43:15 +00:00
}
}
2011-10-30 02:46:17 +00:00
}
void Daily : : on_calButton_toggled ( bool checked )
{
2011-10-30 14:23:59 +00:00
bool b = checked ;
2014-05-17 11:33:33 +00:00
ui - > calendarFrame - > setVisible ( b ) ;
2018-04-22 12:06:48 +00:00
AppSetting - > setCalendarVisible ( b ) ;
2014-05-17 11:33:33 +00:00
if ( ! b ) {
ui - > calButton - > setArrowType ( Qt : : DownArrow ) ;
} else {
ui - > calButton - > setArrowType ( Qt : : UpArrow ) ;
}
2011-10-30 02:46:17 +00:00
}
2011-10-30 03:18:20 +00:00
void Daily : : on_todayButton_clicked ( )
{
2021-03-28 03:22:31 +00:00
if ( previous_date . isValid ( ) ) {
Unload ( previous_date ) ;
}
2014-09-29 15:43:00 +00:00
// QDate d=QDate::currentDate();
// if (d > p_profile->LastDay()) {
QDate lastcpap = p_profile - > LastDay ( MT_CPAP ) ;
QDate lastoxi = p_profile - > LastDay ( MT_OXIMETER ) ;
QDate d = qMax ( lastcpap , lastoxi ) ;
// }
2011-10-30 03:18:20 +00:00
LoadDate ( d ) ;
}
2011-11-24 12:47:25 +00:00
2011-11-27 07:41:00 +00:00
void Daily : : on_evViewSlider_valueChanged ( int value )
{
ui - > evViewLCD - > display ( value ) ;
2014-07-11 12:09:38 +00:00
p_profile - > general - > setEventWindowSize ( value ) ;
2011-11-27 08:00:20 +00:00
2011-12-21 12:47:47 +00:00
int winsize = value * 60 ;
2011-11-27 08:31:05 +00:00
2014-07-16 17:12:52 +00:00
gGraph * g = GraphView - > findGraph ( STR_GRAPH_SleepFlags ) ;
2011-12-11 13:57:07 +00:00
if ( ! g ) return ;
qint64 st = g - > min_x ;
qint64 et = g - > max_x ;
qint64 len = et - st ;
qint64 d = st + len / 2.0 ;
st = d - ( winsize / 2 ) * 1000 ;
et = d + ( winsize / 2 ) * 1000 ;
if ( st < g - > rmin_x ) {
st = g - > rmin_x ;
et = st + winsize * 1000 ;
}
if ( et > g - > rmax_x ) {
et = g - > rmax_x ;
st = et - winsize * 1000 ;
2011-11-27 08:00:20 +00:00
}
2011-12-11 13:57:07 +00:00
GraphView - > SetXBounds ( st , et ) ;
2011-11-27 07:41:00 +00:00
}
2011-12-01 15:40:32 +00:00
2024-07-11 18:46:57 +00:00
void Daily : : on_bookmarkTable_currentItemChanged ( QTableWidgetItem * item , QTableWidgetItem * )
2011-12-02 11:40:47 +00:00
{
int row = item - > row ( ) ;
qint64 st , et ;
2021-05-11 04:48:14 +00:00
qint64 clockdrift = p_profile - > cpap - > clockDrift ( ) * 1000L , drift ;
Day * dday = p_profile - > GetDay ( previous_date , MT_CPAP ) ;
drift = ( dday ! = nullptr ) ? clockdrift : 0 ;
2012-01-19 15:18:34 +00:00
2011-12-02 11:40:47 +00:00
QTableWidgetItem * it = ui - > bookmarkTable - > item ( row , 1 ) ;
bool ok ;
2021-05-11 04:48:14 +00:00
// Add drift back in (it was removed in addBookmark)
st = it - > data ( Qt : : UserRole ) . toLongLong ( & ok ) + drift ;
et = it - > data ( Qt : : UserRole + 1 ) . toLongLong ( & ok ) + drift ;
2012-01-05 12:12:42 +00:00
qint64 st2 = 0 , et2 = 0 , st3 , et3 ;
2014-07-11 12:09:38 +00:00
Day * day = p_profile - > GetGoodDay ( previous_date , MT_CPAP ) ;
2011-12-28 14:21:45 +00:00
if ( day ) {
st2 = day - > first ( ) ;
et2 = day - > last ( ) ;
}
2014-07-11 12:09:38 +00:00
Day * oxi = p_profile - > GetGoodDay ( previous_date , MT_OXIMETER ) ;
2011-12-28 14:21:45 +00:00
if ( oxi ) {
st3 = oxi - > first ( ) ;
et3 = oxi - > last ( ) ;
}
if ( oxi & & day ) {
st2 = qMin ( st2 , st3 ) ;
et2 = qMax ( et2 , et3 ) ;
} else if ( oxi ) {
st2 = st3 ;
et2 = et3 ;
} else if ( ! day ) return ;
if ( ( et < st2 ) | | ( st > et2 ) ) {
2019-08-22 09:17:44 +00:00
mainwin - > Notify ( tr ( " This bookmark is in a currently disabled area.. " ) ) ;
2011-12-28 14:21:45 +00:00
return ;
}
if ( st < st2 ) st = st2 ;
if ( et > et2 ) et = et2 ;
2011-12-02 11:40:47 +00:00
GraphView - > SetXBounds ( st , et ) ;
2011-12-20 11:12:52 +00:00
GraphView - > redraw ( ) ;
2011-12-02 11:40:47 +00:00
}
2014-08-07 17:20:52 +00:00
void Daily : : addBookmark ( qint64 st , qint64 et , QString text )
2011-12-02 11:40:47 +00:00
{
2011-12-11 14:05:07 +00:00
ui - > bookmarkTable - > blockSignals ( true ) ;
2015-08-11 20:52:19 +00:00
QDateTime d = QDateTime : : fromTime_t ( st / 1000L , Qt : : LocalTime ) ;
2011-12-02 11:40:47 +00:00
int row = ui - > bookmarkTable - > rowCount ( ) ;
ui - > bookmarkTable - > insertRow ( row ) ;
2014-08-07 17:20:52 +00:00
QTableWidgetItem * tw = new QTableWidgetItem ( text ) ;
2011-12-02 11:40:47 +00:00
QTableWidgetItem * dw = new QTableWidgetItem ( d . time ( ) . toString ( " HH:mm:ss " ) ) ;
dw - > setFlags ( Qt : : ItemIsSelectable | Qt : : ItemIsEnabled ) ;
ui - > bookmarkTable - > setItem ( row , 0 , dw ) ;
ui - > bookmarkTable - > setItem ( row , 1 , tw ) ;
2014-07-11 12:09:38 +00:00
qint64 clockdrift = p_profile - > cpap - > clockDrift ( ) * 1000L , drift ;
Day * day = p_profile - > GetDay ( previous_date , MT_CPAP ) ;
2014-04-23 13:19:56 +00:00
drift = ( day ! = nullptr ) ? clockdrift : 0 ;
2012-01-19 15:18:34 +00:00
// Counter CPAP clock drift for storage, in case user changes it later on
// This won't fix the text string names..
tw - > setData ( Qt : : UserRole , st - drift ) ;
tw - > setData ( Qt : : UserRole + 1 , et - drift ) ;
2011-12-02 11:40:47 +00:00
2011-12-11 14:05:07 +00:00
ui - > bookmarkTable - > blockSignals ( false ) ;
2011-12-11 13:57:07 +00:00
update_Bookmarks ( ) ;
2011-12-26 04:41:28 +00:00
mainwin - > updateFavourites ( ) ;
2011-12-11 13:57:07 +00:00
2014-08-07 17:20:52 +00:00
}
void Daily : : on_addBookmarkButton_clicked ( )
{
qint64 st , et ;
GraphView - > GetXBounds ( st , et ) ;
2015-08-11 20:52:19 +00:00
QDateTime d = QDateTime : : fromTime_t ( st / 1000L , Qt : : LocalTime ) ;
2014-08-07 17:20:52 +00:00
addBookmark ( st , et , tr ( " Bookmark at %1 " ) . arg ( d . time ( ) . toString ( " HH:mm:ss " ) ) ) ;
2011-12-02 11:40:47 +00:00
}
2011-12-11 13:57:07 +00:00
void Daily : : update_Bookmarks ( )
{
QVariantList start ;
QVariantList end ;
QStringList notes ;
QTableWidgetItem * item ;
for ( int row = 0 ; row < ui - > bookmarkTable - > rowCount ( ) ; row + + ) {
item = ui - > bookmarkTable - > item ( row , 1 ) ;
2011-12-11 14:05:07 +00:00
2011-12-11 13:57:07 +00:00
start . push_back ( item - > data ( Qt : : UserRole ) ) ;
end . push_back ( item - > data ( Qt : : UserRole + 1 ) ) ;
notes . push_back ( item - > text ( ) ) ;
}
Session * journal = GetJournalSession ( previous_date ) ;
if ( ! journal ) {
journal = CreateJournalSession ( previous_date ) ;
}
2011-12-21 05:47:33 +00:00
journal - > settings [ Bookmark_Start ] = start ;
journal - > settings [ Bookmark_End ] = end ;
journal - > settings [ Bookmark_Notes ] = notes ;
2014-08-17 12:56:05 +00:00
journal - > settings [ LastUpdated ] = QDateTime : : currentDateTime ( ) ;
2011-12-11 13:57:07 +00:00
journal - > SetChanged ( true ) ;
BookmarksChanged = true ;
2011-12-26 04:41:28 +00:00
mainwin - > updateFavourites ( ) ;
2011-12-11 13:57:07 +00:00
}
2011-12-02 11:40:47 +00:00
void Daily : : on_removeBookmarkButton_clicked ( )
{
int row = ui - > bookmarkTable - > currentRow ( ) ;
if ( row > = 0 ) {
2011-12-11 14:05:07 +00:00
ui - > bookmarkTable - > blockSignals ( true ) ;
2011-12-02 11:40:47 +00:00
ui - > bookmarkTable - > removeRow ( row ) ;
2011-12-11 14:05:07 +00:00
ui - > bookmarkTable - > blockSignals ( false ) ;
2011-12-11 13:57:07 +00:00
update_Bookmarks ( ) ;
2011-12-02 11:40:47 +00:00
}
2011-12-26 04:41:28 +00:00
mainwin - > updateFavourites ( ) ;
2011-12-02 11:40:47 +00:00
}
2024-03-25 19:36:42 +00:00
2022-11-17 01:46:30 +00:00
# ifndef REMOVE_FITNESS
2024-03-25 19:36:42 +00:00
void Daily : : set_NotesUI ( QString htmlNote ) {
ui - > JournalNotes - > setHtml ( htmlNote ) ;
} ;
2023-09-25 18:34:18 +00:00
2024-03-25 19:36:42 +00:00
void Daily : : set_BmiUI ( double user_weight_kg ) {
if ( ( user_height_cm > zeroD ) & & ( user_weight_kg > zeroD ) ) {
double bmi = calculateBMI ( user_weight_kg , user_height_cm ) ;
2023-09-25 18:34:18 +00:00
ui - > BMI - > display ( bmi ) ;
ui - > BMI - > setVisible ( true ) ;
ui - > BMIlabel - > setVisible ( true ) ;
} else {
// BMI now zero - remove it
// And make it invisible
ui - > BMI - > setVisible ( false ) ;
ui - > BMIlabel - > setVisible ( false ) ;
}
mainwin - > updateOverview ( ) ;
} ;
void Daily : : set_WeightUI ( double kg ) {
ui - > weightSpinBox - > blockSignals ( true ) ;
2024-08-23 23:58:36 +00:00
ui - > weightSpinBox - > setDecimals ( WEIGHT_SPIN_BOX_DECIMALS ) ;
2023-09-25 18:34:18 +00:00
if ( p_profile - > general - > unitSystem ( ) = = US_Metric ) {
2024-08-23 23:58:36 +00:00
ui - > weightSpinBox - > setSuffix ( QString ( " %1 " ) . arg ( STR_UNIT_KG ) ) ;
ui - > weightSpinBox - > setValue ( kg ) ;
2023-09-25 18:34:18 +00:00
} else {
2024-08-23 23:58:36 +00:00
double lbs = kg * pounds_per_kg ;
ui - > weightSpinBox - > setSuffix ( QString ( " %1 " ) . arg ( STR_UNIT_POUND ) ) ;
ui - > weightSpinBox - > setValue ( lbs ) ;
2023-09-25 18:34:18 +00:00
}
ui - > weightSpinBox - > blockSignals ( false ) ;
2024-03-25 19:36:42 +00:00
set_BmiUI ( kg ) ;
2023-09-25 18:34:18 +00:00
} ;
2024-03-25 19:36:42 +00:00
void Daily : : set_ZombieUI ( int value )
2023-09-20 02:35:24 +00:00
{
2024-03-25 19:36:42 +00:00
ui - > ZombieMeter - > blockSignals ( true ) ;
if ( value = = 0 ) {
2023-09-20 02:35:24 +00:00
ui - > ZombieValue - > setText ( tr ( " No Value Selected " ) ) ;
} else {
2024-03-25 19:36:42 +00:00
ui - > ZombieValue - > setText ( QString ( " %1:%2 " ) . arg ( tr ( " Value " ) ) . arg ( value ) ) ;
2023-09-20 02:35:24 +00:00
}
2024-03-25 19:36:42 +00:00
ui - > ZombieMeter - > setValue ( value ) ;
ui - > ZombieMeter - > blockSignals ( false ) ;
}
void Daily : : set_BookmarksUI ( QVariantList & start , QVariantList & end , QStringList & notes , qint64 drift ) {
ui - > bookmarkTable - > blockSignals ( true ) ;
ui - > bookmarkTable - > setRowCount ( 0 ) ;
// Careful with drift here - apply to the label but not the
// stored data (which will be saved if journal changes occur).
bool ok ;
int qty = start . size ( ) ;
for ( int i = 0 ; i < qty ; i + + ) {
qint64 st = start . at ( i ) . toLongLong ( & ok ) ;
qint64 et = end . at ( i ) . toLongLong ( & ok ) ;
QDateTime d = QDateTime : : fromTime_t ( ( st + drift ) / 1000L ) ;
ui - > bookmarkTable - > insertRow ( i ) ;
QTableWidgetItem * tw = new QTableWidgetItem ( notes . at ( i ) ) ;
QTableWidgetItem * dw = new QTableWidgetItem ( d . time ( ) . toString ( " HH:mm:ss " ) ) ;
dw - > setFlags ( Qt : : ItemIsSelectable | Qt : : ItemIsEnabled ) ;
ui - > bookmarkTable - > setItem ( i , 0 , dw ) ;
ui - > bookmarkTable - > setItem ( i , 1 , tw ) ;
tw - > setData ( Qt : : UserRole , st ) ;
tw - > setData ( Qt : : UserRole + 1 , et ) ;
} // for (int i
ui - > bookmarkTable - > blockSignals ( false ) ;
2023-09-20 02:35:24 +00:00
}
2023-09-25 18:34:18 +00:00
void Daily : : on_ZombieMeter_valueChanged ( int value )
2011-12-02 11:40:47 +00:00
{
2024-03-25 19:36:42 +00:00
set_ZombieUI ( value ) ;
set_JournalZombie ( previous_date , value ) ;
2021-09-20 15:03:34 +00:00
mainwin - > updateOverview ( ) ;
2011-12-02 11:40:47 +00:00
}
2022-11-17 01:46:30 +00:00
# endif
2011-12-02 11:40:47 +00:00
2011-12-02 14:18:47 +00:00
void Daily : : on_bookmarkTable_itemChanged ( QTableWidgetItem * item )
{
Q_UNUSED ( item ) ;
2011-12-11 13:57:07 +00:00
update_Bookmarks ( ) ;
2011-12-02 14:18:47 +00:00
}
2012-01-05 15:17:50 +00:00
2022-11-17 01:46:30 +00:00
# ifndef REMOVE_FITNESS
2023-09-25 18:34:18 +00:00
void Daily : : on_weightSpinBox_valueChanged ( double )
2011-12-03 01:05:17 +00:00
{
2024-03-25 19:36:42 +00:00
on_weightSpinBox_editingFinished ( ) ;
2012-01-05 15:17:50 +00:00
}
void Daily : : on_weightSpinBox_editingFinished ( )
{
2023-09-25 18:34:18 +00:00
user_height_cm = p_profile - > user - > height ( ) ;
double kg = ui - > weightSpinBox - > value ( ) ;
if ( p_profile - > general - > unitSystem ( ) = = US_English ) {
2024-08-23 23:58:36 +00:00
double lbs = ui - > weightSpinBox - > value ( ) ;
kg = lbs * kgs_per_pound ; // convert pounds to kg.
2023-09-25 18:34:18 +00:00
}
2024-03-25 19:36:42 +00:00
if ( kg < zeroD ) kg = 0.0 ;
set_JournalWeightValue ( previous_date , kg ) ;
set_BmiUI ( kg ) ;
2011-12-10 15:24:45 +00:00
gGraphView * gv = mainwin - > getOverview ( ) - > graphView ( ) ;
gGraph * g ;
if ( gv ) {
2014-07-16 17:12:52 +00:00
g = gv - > findGraph ( STR_GRAPH_Weight ) ;
2014-04-23 13:19:56 +00:00
if ( g ) g - > setDay ( nullptr ) ;
2011-12-10 15:24:45 +00:00
}
2021-03-28 03:22:31 +00:00
if ( gv ) {
g = gv - > findGraph ( STR_GRAPH_BMI ) ;
if ( g ) g - > setDay ( nullptr ) ;
}
2021-09-20 15:03:34 +00:00
mainwin - > updateOverview ( ) ;
2011-12-03 01:05:17 +00:00
}
2022-11-17 01:46:30 +00:00
# endif
2012-01-05 15:17:50 +00:00
2011-12-12 03:39:00 +00:00
QString Daily : : GetDetailsText ( )
{
2018-05-07 22:09:59 +00:00
QTextDocument * doc = webView - > document ( ) ;
QString content = doc - > toHtml ( ) ;
return content ;
2011-12-12 03:39:00 +00:00
}
2012-01-03 16:29:35 +00:00
2021-11-30 04:08:05 +00:00
void Daily : : setGraphText ( ) {
int numOff = 0 ;
int numTotal = 0 ;
gGraph * g ;
for ( int i = 0 ; i < GraphView - > size ( ) ; i + + ) {
g = ( * GraphView ) [ i ] ;
if ( ! g - > isEmpty ( ) ) {
numTotal + + ;
if ( ! g - > visible ( ) ) {
numOff + + ;
}
}
}
ui - > graphCombo - > setItemIcon ( 0 , numOff ? * icon_warning : * icon_up_down ) ;
QString graphText ;
2023-03-03 21:03:18 +00:00
int lastIndex = ui - > graphCombo - > count ( ) - 1 ; // account for hideshow button
if ( numOff = = 0 ) {
// all graphs are shown
graphText = QObject : : tr ( " %1 Graphs " ) . arg ( numTotal ) ;
2023-03-04 15:14:21 +00:00
ui - > graphCombo - > setItemText ( lastIndex , STR_HIDE_ALL_GRAPHS ) ;
2023-03-03 21:03:18 +00:00
} else {
// some graphs are hidden
graphText = QObject : : tr ( " %1 of %2 Graphs " ) . arg ( numTotal - numOff ) . arg ( numTotal ) ;
if ( numOff = = numTotal ) {
// all graphs are hidden
2023-03-04 15:14:21 +00:00
ui - > graphCombo - > setItemText ( lastIndex , STR_SHOW_ALL_GRAPHS ) ;
2023-03-03 21:03:18 +00:00
}
}
2021-11-30 04:08:05 +00:00
ui - > graphCombo - > setItemText ( 0 , graphText ) ;
}
void Daily : : setFlagText ( ) {
int numOff = 0 ;
int numTotal = 0 ;
2023-03-04 15:14:21 +00:00
int lastIndex = ui - > eventsCombo - > count ( ) - 1 ; // account for hideshow button
for ( int i = 1 ; i < lastIndex ; + + i ) {
2021-11-30 04:08:05 +00:00
numTotal + + ;
ChannelID code = ui - > eventsCombo - > itemData ( i , Qt : : UserRole ) . toUInt ( ) ;
schema : : Channel * chan = & schema : : channel [ code ] ;
if ( ! chan - > enabled ( ) )
numOff + + ;
}
2023-03-14 20:11:46 +00:00
int numOn = numTotal ;
2021-11-30 04:08:05 +00:00
ui - > eventsCombo - > setItemIcon ( 0 , numOff ? * icon_warning : * icon_up_down ) ;
QString flagsText ;
2023-03-04 15:14:21 +00:00
if ( numOff = = 0 ) {
flagsText = ( QObject : : tr ( " %1 Event Types " ) + " " ) . arg ( numTotal ) ;
ui - > eventsCombo - > setItemText ( lastIndex , STR_HIDE_ALL_EVENTS ) ;
} else {
2023-03-14 20:11:46 +00:00
numOn - = numOff ;
2023-03-04 15:14:21 +00:00
flagsText = QObject : : tr ( " %1 of %2 Event Types " ) . arg ( numOn ) . arg ( numTotal ) ;
if ( numOn = = 0 ) ui - > eventsCombo - > setItemText ( lastIndex , STR_SHOW_ALL_EVENTS ) ;
}
2023-03-14 20:11:46 +00:00
2021-11-30 04:08:05 +00:00
ui - > eventsCombo - > setItemText ( 0 , flagsText ) ;
2023-03-17 15:22:55 +00:00
sleepFlagsGroup - > refreshConfiguration ( sleepFlags ) ; // need to know display changes before painting.
2021-11-30 04:08:05 +00:00
}
2023-03-03 00:28:09 +00:00
void Daily : : showAllGraphs ( bool show ) {
//Skip over first button - label for comboBox
2023-03-03 21:03:18 +00:00
int lastIndex = ui - > graphCombo - > count ( ) - 1 ;
for ( int i = 1 ; i < lastIndex ; i + + ) {
2023-03-03 00:28:09 +00:00
showGraph ( i , show ) ;
}
setGraphText ( ) ;
2023-03-03 21:03:18 +00:00
updateCube ( ) ;
GraphView - > updateScale ( ) ;
GraphView - > redraw ( ) ;
2023-03-03 00:28:09 +00:00
}
2023-03-03 21:03:18 +00:00
void Daily : : showGraph ( int index , bool show , bool updateGraph ) {
ui - > graphCombo - > setItemData ( index , show , Qt : : UserRole ) ;
ui - > graphCombo - > setItemIcon ( index , show ? * icon_on : * icon_off ) ;
if ( ! updateGraph ) return ;
2023-03-03 00:28:09 +00:00
QString graphName = ui - > graphCombo - > itemText ( index ) ;
gGraph * graph = GraphView - > findGraphTitle ( graphName ) ;
2023-03-03 21:03:18 +00:00
if ( graph ) graph - > setVisible ( show ) ;
2021-11-30 04:08:05 +00:00
}
2012-01-03 16:29:35 +00:00
void Daily : : on_graphCombo_activated ( int index )
{
2023-03-03 00:28:09 +00:00
if ( index < 0 ) return ;
2023-03-03 21:03:18 +00:00
int lastIndex = ui - > graphCombo - > count ( ) - 1 ;
2021-11-30 04:08:05 +00:00
if ( index > 0 ) {
2023-03-03 21:03:18 +00:00
bool nextOn = ! ui - > graphCombo - > itemData ( index , Qt : : UserRole ) . toBool ( ) ;
if ( index = = lastIndex ) {
// user just pressed hide show button - toggle sates of the button and apply the new state
showAllGraphs ( nextOn ) ;
showGraph ( index , nextOn , false ) ;
} else {
showGraph ( index , nextOn , true ) ;
}
2022-07-01 19:06:53 +00:00
ui - > graphCombo - > showPopup ( ) ;
2012-01-03 16:29:35 +00:00
}
2021-11-30 04:08:05 +00:00
ui - > graphCombo - > setCurrentIndex ( 0 ) ;
setGraphText ( ) ;
2012-01-03 16:29:35 +00:00
updateCube ( ) ;
GraphView - > updateScale ( ) ;
GraphView - > redraw ( ) ;
}
2019-08-09 22:32:37 +00:00
2012-01-03 16:29:35 +00:00
void Daily : : updateCube ( )
{
//brick..
if ( ( GraphView - > visibleGraphs ( ) = = 0 ) ) {
2014-07-13 04:39:26 +00:00
if ( ui - > graphCombo - > count ( ) > 0 ) {
2014-08-21 08:04:25 +00:00
GraphView - > setEmptyText ( STR_Empty_NoGraphs ) ;
2012-01-03 16:29:35 +00:00
} else {
2014-07-13 04:39:26 +00:00
if ( ! p_profile - > GetGoodDay ( getDate ( ) , MT_CPAP )
& & ! p_profile - > GetGoodDay ( getDate ( ) , MT_OXIMETER )
& & ! p_profile - > GetGoodDay ( getDate ( ) , MT_SLEEPSTAGE )
& & ! p_profile - > GetGoodDay ( getDate ( ) , MT_POSITION ) ) {
2014-08-21 08:04:25 +00:00
GraphView - > setEmptyText ( STR_Empty_NoData ) ;
2014-09-01 11:39:38 +00:00
2014-07-13 04:39:26 +00:00
} else {
2014-09-01 11:39:38 +00:00
if ( GraphView - > emptyText ( ) ! = STR_Empty_Brick )
GraphView - > setEmptyText ( STR_Empty_SummaryOnly ) ;
2014-07-13 04:39:26 +00:00
}
2012-01-03 16:29:35 +00:00
}
}
}
void Daily : : updateGraphCombo ( )
{
ui - > graphCombo - > clear ( ) ;
gGraph * g ;
2023-03-04 15:14:21 +00:00
ui - > graphCombo - > addItem ( * icon_up_down , " " , true ) ; // text updated in setGRaphText
2021-11-30 04:08:05 +00:00
2012-01-03 16:29:35 +00:00
for ( int i = 0 ; i < GraphView - > size ( ) ; i + + ) {
g = ( * GraphView ) [ i ] ;
if ( g - > isEmpty ( ) ) continue ;
if ( g - > visible ( ) ) {
ui - > graphCombo - > addItem ( * icon_on , g - > title ( ) , true ) ;
} else {
ui - > graphCombo - > addItem ( * icon_off , g - > title ( ) , false ) ;
}
}
2023-03-04 15:14:21 +00:00
ui - > graphCombo - > addItem ( * icon_on , STR_HIDE_ALL_GRAPHS , true ) ;
2021-11-30 04:08:05 +00:00
ui - > graphCombo - > setCurrentIndex ( 0 ) ;
setGraphText ( ) ;
2012-01-03 16:29:35 +00:00
updateCube ( ) ;
}
2023-03-04 15:14:21 +00:00
void Daily : : updateEventsCombo ( Day * day ) {
2014-08-05 11:17:03 +00:00
2023-03-04 15:14:21 +00:00
quint32 chans = schema : : SPAN | schema : : FLAG | schema : : MINOR_FLAG ;
if ( p_profile - > general - > showUnknownFlags ( ) ) chans | = schema : : UNKNOWN ;
2014-08-05 11:17:03 +00:00
2023-03-04 15:14:21 +00:00
QList < ChannelID > available ;
if ( day ) available . append ( day - > getSortedMachineChannels ( chans ) ) ;
ui - > eventsCombo - > clear ( ) ;
ui - > eventsCombo - > addItem ( * icon_up_down , " " , 0 ) ; // text updated in setflagText
for ( int i = 0 ; i < available . size ( ) ; + + i ) {
ChannelID code = available . at ( i ) ;
int comboxBoxIndex = i + 1 ;
schema : : Channel & chan = schema : : channel [ code ] ;
ui - > eventsCombo - > addItem ( chan . enabled ( ) ? * icon_on : * icon_off , chan . label ( ) , code ) ;
ui - > eventsCombo - > setItemData ( comboxBoxIndex , chan . fullname ( ) , Qt : : ToolTipRole ) ;
2023-09-23 23:25:37 +00:00
dailySearchTab - > updateEvents ( code , chan . fullname ( ) ) ;
2021-11-30 04:08:05 +00:00
}
2023-03-04 15:14:21 +00:00
ui - > eventsCombo - > addItem ( * icon_on , " " , Qt : : ToolTipRole ) ;
ui - > eventsCombo - > setCurrentIndex ( 0 ) ;
setFlagText ( ) ;
}
2014-08-05 11:17:03 +00:00
2023-03-04 15:14:21 +00:00
void Daily : : showAllEvents ( bool show ) {
// Mark all events as active
int lastIndex = ui - > eventsCombo - > count ( ) - 1 ; // account for hideshow button
for ( int i = 1 ; i < lastIndex ; i + + ) {
// If disabled, emulate a click to enable the event
ChannelID code = ui - > eventsCombo - > itemData ( i , Qt : : UserRole ) . toUInt ( ) ;
schema : : Channel * chan = & schema : : channel [ code ] ;
if ( chan - > enabled ( ) ! = show ) {
Daily : : on_eventsCombo_activated ( i ) ;
}
}
ui - > eventsCombo - > setItemData ( lastIndex , show , Qt : : UserRole ) ;
2021-11-30 04:08:05 +00:00
ui - > eventsCombo - > setCurrentIndex ( 0 ) ;
setFlagText ( ) ;
2014-08-05 11:17:03 +00:00
}
void Daily : : on_eventsCombo_activated ( int index )
{
if ( index < 0 )
return ;
2023-03-04 15:14:21 +00:00
int lastIndex = ui - > eventsCombo - > count ( ) - 1 ;
2021-11-30 04:08:05 +00:00
if ( index > 0 ) {
2023-03-04 15:14:21 +00:00
if ( index = = lastIndex ) {
bool nextOn = ! ui - > eventsCombo - > itemData ( index , Qt : : UserRole ) . toBool ( ) ;
showAllEvents ( nextOn ) ;
} else {
ChannelID code = ui - > eventsCombo - > itemData ( index , Qt : : UserRole ) . toUInt ( ) ;
schema : : Channel * chan = & schema : : channel [ code ] ;
2014-08-05 11:17:03 +00:00
2023-03-04 15:14:21 +00:00
bool b = ! chan - > enabled ( ) ;
chan - > setEnabled ( b ) ;
ui - > eventsCombo - > setItemIcon ( index , b ? * icon_on : * icon_off ) ;
}
2022-07-01 19:06:53 +00:00
ui - > eventsCombo - > showPopup ( ) ;
2014-08-05 11:17:03 +00:00
}
2021-11-30 04:08:05 +00:00
ui - > eventsCombo - > setCurrentIndex ( 0 ) ;
setFlagText ( ) ;
2014-08-05 11:17:03 +00:00
GraphView - > redraw ( ) ;
}
2014-09-24 01:42:14 +00:00
2014-10-02 11:22:30 +00:00
void Daily : : on_splitter_2_splitterMoved ( int , int )
{
int size = ui - > splitter_2 - > sizes ( ) [ 0 ] ;
if ( size = = 0 ) return ;
2019-03-10 16:03:19 +00:00
// qDebug() << "Left Panel width set to " << size;
2018-04-22 12:06:48 +00:00
AppSetting - > setDailyPanelWidth ( size ) ;
2014-10-02 11:22:30 +00:00
}
2022-12-27 00:26:23 +00:00
2023-10-15 00:13:50 +00:00
void Daily : : on_graphHelp_clicked ( ) {
if ( ! saveGraphLayoutSettings ) {
saveGraphLayoutSettings = new SaveGraphLayoutSettings ( " daily " , this ) ;
}
if ( saveGraphLayoutSettings ) {
saveGraphLayoutSettings - > hintHelp ( ) ;
}
}
2022-12-29 17:54:22 +00:00
void Daily : : on_layout_clicked ( ) {
2022-12-28 18:24:01 +00:00
if ( ! saveGraphLayoutSettings ) {
saveGraphLayoutSettings = new SaveGraphLayoutSettings ( " daily " , this ) ;
2022-12-27 00:26:23 +00:00
}
2022-12-28 18:24:01 +00:00
if ( saveGraphLayoutSettings ) {
2023-10-15 00:13:50 +00:00
saveGraphLayoutSettings - > triggerLayout ( GraphView ) ;
2022-12-27 00:26:23 +00:00
}
}