diff --git a/Graphs/gGraphView.cpp b/Graphs/gGraphView.cpp
index 0d4d016d..d0bfc3fc 100644
--- a/Graphs/gGraphView.cpp
+++ b/Graphs/gGraphView.cpp
@@ -90,14 +90,13 @@ void InitGraphs()
         mediumfont->setStyleHint(QFont::AnyStyle,QFont::OpenGLCompatible);
         bigfont->setStyleHint(QFont::AnyStyle,QFont::OpenGLCompatible);
 
-        images["mask"]=new QImage(":/icons/mask.png");
+        //images["mask"]=new QImage(":/icons/mask.png");
         images["oximeter"]=new QImage(":/icons/cubeoximeter.png");
         images["smiley"]=new QImage(":/icons/smileyface.png");
-        images["sad"]=new QImage(":/icons/sadface.png");
+        //images["sad"]=new QImage(":/icons/sadface.png");
+
         images["brick"]=new QImage(":/icons/brick.png");
-        //images["warning"]=new QImage(":/icons/warning.png");
-        //images["bug"]=new QImage(":/icons/bug.png");
-        images["sheep"]=new QImage(":/icons/sheep.png");
+        images["nographs"]=new QImage(":/icons/nographs.png");
         images["nodata"]=new QImage(":/icons/nodata.png");
 
         _graph_init=true;
@@ -2160,9 +2159,9 @@ void gGraphView::selectionTime()
     }
 
 }
-void gGraphView::GetRXBounds(qint64 st, qint64 et)
+void gGraphView::GetRXBounds(qint64 & st, qint64 & et)
 {
-    qint64 m1=0,m2=0;
+    //qint64 m1=0,m2=0;
     gGraph *g=NULL;
     for (int i=0;i<m_graphs.size();i++) {
         g=m_graphs[i];
@@ -2356,7 +2355,7 @@ void gGraphView::renderSomethingFun()
     // When I'm feeling more energetic, I'll change it to a textured sheep or something.
     static float rotqube=0;
 
-    static float xpos=0,ypos=7,spos=0;
+    static float xpos=0,ypos=7;
 
     glLoadIdentity();
 
@@ -2370,12 +2369,17 @@ void gGraphView::renderSomethingFun()
     glEnable(GL_BLEND);
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
-    double xx=sin(M_PI/180.0 * xpos)*2; // ((4.0/width()) * m_mouse.rx())-2.0;
-    double yy=cos(M_PI/180.0 * ypos)*2; //2-((4.0/height()) * m_mouse.ry());
-    xpos+=1;
-    ypos+=1.32;
-    if (xpos > 360) xpos-=360.0;
-    if (ypos > 360) ypos-=360.0;
+    double xx=0.0,yy=0.0;
+
+    // set this to 0 to make the cube stay in the center of the screen
+    if (1) {
+        xx=sin(M_PI/180.0 * xpos)*2; // ((4.0/width()) * m_mouse.rx())-2.0;
+        yy=cos(M_PI/180.0 * ypos)*2; //2-((4.0/height()) * m_mouse.ry());
+        xpos+=1;
+        ypos+=1.32;
+        if (xpos > 360) xpos-=360.0;
+        if (ypos > 360) ypos-=360.0;
+    }
 
 
     //m_mouse.x();
@@ -2808,6 +2812,7 @@ void gGraphView::setCubeImage(QImage *img)
 {
     cubeimg.clear();
     cubeimg.push_back(img);
+
     cubetex=bindTexture(*img);
     glBindTexture(GL_TEXTURE_2D,0);
 }
@@ -2920,22 +2925,8 @@ void gGraphView::mouseMoveEvent(QMouseEvent * event)
                 this->setCursor(Qt::SplitVCursor);
             } else if (!m_button_down && (y >= py) && (y < py+m_graphs[i]->top)) {
                 // Mouse cursor is in top graph margin.
-//                if (m_graphs[i]->isSelected()) {
-//                    m_graphs[i]->deselect();
-//                    if (m_tooltip->visible())
-//                    m_tooltip->cancel();
-//                    redraw();
-//                }
-                //qDebug() << "upper bounds";
             } else if (!m_button_down && (y >= py+h-m_graphs[i]->bottom) && (y <= py+h)) {
                 // Mouse cursor is in bottom grpah margin.
-//                if (m_graphs[i]->isSelected()) {
-//                    if (m_tooltip->visible())
-//                    m_tooltip->cancel();
-//                    m_graphs[i]->deselect();
-//                    redraw();
-//                }
-                //qDebug() << "lower bounds";
             } else if (m_button_down || ((y >= py+m_graphs[i]->top) && (y < py + h-m_graphs[i]->bottom))) {
                 if (m_button_down || (x >= titleWidth+10)) { //(gYAxis::Margin-5)
                     this->setCursor(Qt::ArrowCursor);
@@ -2988,7 +2979,7 @@ void gGraphView::mouseMoveEvent(QMouseEvent * event)
 
         }
         py+=h;
-        py+=graphSpacer; // do we want the extra spacer down the bottom?
+        py+=graphSpacer;
     }
 
 }
@@ -3007,7 +2998,7 @@ void gGraphView::mousePressEvent(QMouseEvent * event)
 
         h=m_graphs[i]->height()*m_scaleY;
         if (py>height())
-            break; // we are done.. can't draw anymore
+            break;
 
         if ((py + h + graphSpacer) >= 0) {
             if ((y >= py) && (y < py + h)) {
@@ -3041,7 +3032,7 @@ void gGraphView::mousePressEvent(QMouseEvent * event)
 
         }
         py+=h;
-        py+=graphSpacer; // do we want the extra spacer down the bottom?
+        py+=graphSpacer;
 
     }
 }
diff --git a/Graphs/gGraphView.h b/Graphs/gGraphView.h
index 99980f54..d40f83dd 100644
--- a/Graphs/gGraphView.h
+++ b/Graphs/gGraphView.h
@@ -836,7 +836,7 @@ public:
     void GetXBounds(qint64 & st,qint64 & et);
 
     //! \brief Returns the maximum time range bounds
-    void GetRXBounds(qint64 st, qint64 et);
+    void GetRXBounds(qint64 & st, qint64 & et);
 
     //! \brief Resets the time range to default for this day. Refreshing the display if refresh==true.
     void ResetBounds(bool refresh=true); //short group=0);
diff --git a/Graphs/gLineChart.cpp b/Graphs/gLineChart.cpp
index 5c1a537c..778a5ce5 100644
--- a/Graphs/gLineChart.cpp
+++ b/Graphs/gLineChart.cpp
@@ -604,7 +604,7 @@ void gLineChart::paint(gGraph & w,int left, int top, int width, int height)
             legendx-=bw/2;
 
             int tp=top-5-bw/2;
-            w.quads()->add(legendx-bw,tp+bw/2,legendx,tp+bw/2,legendx,tp-bw/2,legendx-bw,tp-bw/2,m_line_color.rgba());
+            w.quads()->add(legendx-bw,tp+bw/2,legendx,tp+bw/2,legendx,tp-bw/2,legendx-bw,tp-bw/2,m_colors[gi].rgba());
             legendx-=hi+bw/2;
         }
     }
diff --git a/Resources.qrc b/Resources.qrc
index 18f45453..8c9928df 100644
--- a/Resources.qrc
+++ b/Resources.qrc
@@ -29,7 +29,6 @@
         <file>icons/sadface.png</file>
         <file>icons/mask.png</file>
         <file>icons/brick.png</file>
-        <file>icons/sheep.png</file>
         <file>icons/nodata.png</file>
         <file>icons/cubeoximeter.png</file>
         <file>icons/trophy.png</file>
@@ -41,5 +40,6 @@
         <file>icons/session-on.png</file>
         <file>icons/bob-v3.0.png</file>
         <file>docs/script.js</file>
+        <file>icons/nographs.png</file>
     </qresource>
 </RCC>
diff --git a/SleepLib/calcs.cpp b/SleepLib/calcs.cpp
index e6f4161f..d05788be 100644
--- a/SleepLib/calcs.cpp
+++ b/SleepLib/calcs.cpp
@@ -5,6 +5,7 @@
 */
 
 #include <cmath>
+#include <algorithm>
 
 #include "calcs.h"
 #include "profiles.h"
@@ -117,6 +118,8 @@ int filterFlow(Session *session, EventList *in, EventList *out, EventList *tv, E
 //    int rpos=0;
     EventDataType min=0,max=0;
     qint64 peakmin=0, peakmax=0;
+    double avgmax=0;
+    double avgmin=0;
     for (i=0;i<size;i++) {
         c=stage2[i];
 
@@ -144,6 +147,7 @@ int filterFlow(Session *session, EventList *in, EventList *out, EventList *tv, E
                     // keep previously calculated negative peak
                     breaths_min_peak.push_back(peakmin);
                     breaths_min.push_back(min);
+                    avgmin+=min;
                     max=0;
                 }
             } else {
@@ -176,6 +180,7 @@ int filterFlow(Session *session, EventList *in, EventList *out, EventList *tv, E
                     // keep previously calculated positive peak
                     breaths_max_peak.push_back(peakmax);
                     breaths_max.push_back(max);
+                    avgmax+=max;
                     min=0;
 
                 }
@@ -195,53 +200,90 @@ int filterFlow(Session *session, EventList *in, EventList *out, EventList *tv, E
     if (!breaths.size()) {
         return 0;
     }
-    double avgmax=0;
-    for (int i=0;i<breaths_max.size();i++)  {
-        max=breaths_max[i];
-        avgmax+=max;
-    }
-    avgmax/=EventDataType(breaths_max.size());
 
-    double avgmin=0;
-    for (int i=0;i<breaths_min.size();i++)  {
-        min=breaths_min[i];
-        avgmin+=min;
-    }
+    avgmax/=EventDataType(breaths_max.size());
     avgmin/=EventDataType(breaths_min.size());
 
-    QVector<qint64> goodb;
-    for (int i=0;i<breaths_max.size();i++)  {
-        max=breaths_max[i];
-        time=breaths_max_peak[i];
+    if ((breaths_max.size()>5) && (breaths_min.size()>5) && (p_profile->cpap->userEventFlagging())) {
+        EventDataType maxperc,minperc;
 
-        if (max > avgmax*0.2) {
-            goodb.push_back(time);
-        }
-    }
-    for (int i=0;i<breaths_min.size();i++)  {
-        min=breaths_min[i];
-        time=breaths_min_peak[i];
-        if (min < avgmin*0.2) {
-            goodb.push_back(time);
-        }
-    }
-    EventList *uf=NULL;
+        int n=breaths_max.size()*0.8;
+        if (n > breaths_max.size()-1) n-=1;
+        nth_element(breaths_max.begin(),breaths_max.begin()+n,breaths_max.end());
+        maxperc=breaths_max[n];
 
-    qSort(goodb);
-    for (int  i=1;i<goodb.size();i++) {
-        qint64 len=qAbs(goodb[i]-goodb[i-1]);
-        if (len>=10000) {
-            time=goodb[i-1]+len/2;
-            if (!SearchApnea(session,time)) {
-                if (!uf) {
-                    uf=new EventList(EVL_Event,1,0,0,0,0,true);
-                    session->eventlist[CPAP_UserFlag1].push_back(uf);
+        n=breaths_min.size()*0.2;
+        if (n > breaths_min.size()-1) n-=1;
+        nth_element(breaths_min.begin(),breaths_min.begin()+n,breaths_min.end());
+        minperc=breaths_min[n];
+
+
+        QVector<qint64> goodb;
+
+        EventDataType restriction=p_profile->cpap->userFlowRestriction()/100.0;
+
+        // This is faster than vector access.
+        EventDataType *dptr=breaths_max.data();
+        qint64 * tptr=breaths_max_peak.data();
+
+        EventDataType restrict=maxperc * restriction;
+
+        // Knock out all the upper breath components above the flow restriction
+        for (int i=0;i<breaths_max.size();i++)  {
+            max=*dptr++; //breaths_max[i];
+            time=*tptr++; //breaths_max_peak[i];
+
+            if ((time > 0) && (max > restrict)) {
+                goodb.push_back(time);
+            }
+        }
+        dptr=breaths_min.data();
+        tptr=breaths_min_peak.data();
+
+        restrict=minperc * restriction;
+
+        // Knock out all the lower breath components above the flow restriction
+        for (int i=0;i<breaths_min.size();i++)  {
+            min=*dptr++; //breaths_min[i];
+            time=*tptr++; //breaths_min_peak[i];
+            if ((time > 0) && (min < restrict)) {
+                goodb.push_back(time);
+            }
+        }
+        EventList *uf=NULL;
+
+        if (goodb.size()>2) {
+            qint64 duration=p_profile->cpap->userEventDuration()*1000;
+
+            qSort(goodb);
+
+            tptr=goodb.data();
+
+            qint64 g0=*tptr++,g1;
+
+            EventDataType lf;
+            //
+            for (int i=1;i<goodb.size();i++) {
+                g1=*tptr++;
+                qint64 len=g1-g0;
+                if (len >= duration) {
+                    time=g0 + (len/2);
+                    if (!SearchApnea(session,time)) {
+                        if (!uf) {
+                            uf=new EventList(EVL_Event,1,0,0,0,0,true);
+                            session->eventlist[CPAP_UserFlag1].push_back(uf);
+                        }
+                        lf=double(len)/1000.0;
+                        if (lf>30) {
+                            int i=5;
+                        }
+                        uf->AddEvent(time,lf,1);
+                    }
                 }
-                uf->AddEvent(time,len/1000L,1);
+                g0=g1;
             }
         }
     }
-
     qint64 window=60000;
     qint64 t1=in->first()-window/2;
     qint64 t2=in->first()+window/2;
@@ -385,7 +427,7 @@ int calcRespRate(Session *session)
 EventDataType calcAHI(Session *session,qint64 start, qint64 end)
 {
     double hours,ahi,cnt;
-    if ((start==end) && (start==0)) {
+    if (start<0) {
         // much faster..
         hours=session->hours();
         cnt=session->count(CPAP_Obstructive)
@@ -396,6 +438,7 @@ EventDataType calcAHI(Session *session,qint64 start, qint64 end)
         ahi=cnt/hours;
     } else {
         hours=double(end-start)/3600000L;
+        if (hours==0) return 0;
         cnt=session->rangeCount(CPAP_Obstructive,start,end)
                 +session->rangeCount(CPAP_Hypopnea,start,end)
                 +session->rangeCount(CPAP_ClearAirway,start,end)
@@ -408,8 +451,11 @@ EventDataType calcAHI(Session *session,qint64 start, qint64 end)
 
 int calcAHIGraph(Session *session)
 {
-    const qint64 window_size=3600000L;
     const qint64 window_step=30000; // 30 second windows
+    double window_size=p_profile->cpap->AHIWindow();
+    qint64 window_size_ms=window_size*60000L;
+
+    bool zeroreset=p_profile->cpap->AHIReset();
 
     if (session->machine()->GetType()!=MT_CPAP) return 0;
     if (session->eventlist.contains(CPAP_AHI)) return 0; // abort if already there
@@ -428,22 +474,55 @@ int calcAHIGraph(Session *session)
 
     EventDataType ahi;
 
-    qint64 ti;
+    qint64 ti=first,lastti=first;
+
     double avg=0;
     int cnt=0;
-    for (ti=first;ti<last;ti+=window_step) {
-        f=ti-window_size;
-        ahi=calcAHI(session,f,ti);
-        if  (ti>=last) {
-            AHI->AddEvent(last,ahi);
+
+    double events;
+    double hours=(window_size/60.0);
+    if (zeroreset) {
+        // I personally don't see the point of resetting each hour.
+        do {
+            // For each window, in 30 second increments
+            for (qint64 t=ti;t < ti+window_size_ms; t+=window_step) {
+                if (t > last)
+                    break;
+                events=session->rangeCount(CPAP_Obstructive,ti,t)
+                        +session->rangeCount(CPAP_Hypopnea,ti,t)
+                        +session->rangeCount(CPAP_ClearAirway,ti,t)
+                        +session->rangeCount(CPAP_Apnea,ti,t);
+
+                //ahi=calcAHI(session,ti,t)* hours;
+
+                ahi = events / hours;
+
+                AHI->AddEvent(t,ahi);
+                avg+=ahi;
+                cnt++;
+            }
+            lastti=ti;
+            ti+=window_size_ms;
+        } while (ti<last);
+
+    } else {
+        for (ti=first;ti<last;ti+=window_step) {
+//            if  (ti>last) {
+////                AHI->AddEvent(last,ahi);
+////                avg+=ahi;
+////                cnt++;
+//                break;
+//            }
+            f=ti-window_size_ms;
+            ahi=calcAHI(session,f,ti);
             avg+=ahi;
             cnt++;
-            break;
+            AHI->AddEvent(ti,ahi);
+            lastti=ti;
+            ti+=window_step;
         }
-        AHI->AddEvent(ti,ahi);
-        ti+=window_step;
     }
-    AHI->AddEvent(last,0);
+    AHI->AddEvent(lastti,0);
     if (!cnt) avg=0; else avg/=double(cnt);
     session->setAvg(CPAP_AHI,avg);
 
diff --git a/SleepLib/calcs.h b/SleepLib/calcs.h
index 7cf6e2e9..5eee64eb 100644
--- a/SleepLib/calcs.h
+++ b/SleepLib/calcs.h
@@ -15,7 +15,7 @@ int calcRespRate(Session *session);
 int calcAHIGraph(Session *session);
 
 //! \brief Calculates AHI for a session between start & end (a support function for the sliding window graph)
-EventDataType calcAHI(Session *session,qint64 start=0, qint64 end=0);
+EventDataType calcAHI(Session *session,qint64 start=-1, qint64 end=-1);
 
 //! \brief Leaks calculations for PRS1
 int calcLeaks(Session *session);
diff --git a/SleepLib/loader_plugins/resmed_loader.cpp b/SleepLib/loader_plugins/resmed_loader.cpp
index 71034b35..f108f912 100644
--- a/SleepLib/loader_plugins/resmed_loader.cpp
+++ b/SleepLib/loader_plugins/resmed_loader.cpp
@@ -430,15 +430,18 @@ int ResmedLoader::Open(QString & path,Profile *profile)
         QFile::copy(path+idfile+ext_TGT,backup_path+idfile+ext_TGT);
         QFile::copy(path+idfile+ext_CRC,backup_path+idfile+ext_CRC);
 
-
         //copy STR files to backup folder
         if (strpath.endsWith(ext_gz))  // Already compressed.
             QFile::copy(strpath,backup_path+strfile+ext_EDF+ext_gz);
         else { // Compress STR file to backup folder
+            QString strf=backup_path+strfile+ext_EDF;
+            if (QFile::exists(strf))
+                QFile::remove(strf);
+
             compress_backups ?
-                compressFile(strpath,backup_path+strfile+ext_EDF)
+                compressFile(strpath,strf)
             :
-                QFile::copy(strpath,backup_path+strfile+ext_EDF);
+                QFile::copy(strpath,strf);
         }
 
         QFile::copy(path+"STR.crc",backup_path+"STR.crc");
@@ -983,15 +986,41 @@ int ResmedLoader::Open(QString & path,Profile *profile)
             // Copy the EDF file to the backup folder
             if (create_backups) {
                 backupfile=backup_path+filename;
-                if (!gz) {
-                    compress_backups ?
-                        compressFile(fullpath, backupfile)
-                    :
+                bool dobackup=true;
+                if (!gz && QFile::exists(backupfile+".gz")) {
+                    dobackup=false;
+                } else if (QFile::exists(backupfile)) {
+                    if (gz) {
+                        // don't bother, it's already there and compressed.
+                        dobackup=false;
+                    } else {
+                        // non compressed file is there..
+                        if (compress_backups) {
+                            // remove old edf file, as we are writing a compressed one
+                            QFile::remove(backupfile);
+                        } else { // don't bother copying it.
+                            dobackup=false;
+                        }
+                    }
+                }
+                if (dobackup) {
+                    if (!gz) {
+                        compress_backups ?
+                            compressFile(fullpath, backupfile)
+                        :
+                            QFile::copy(fullpath, backupfile);
+                    } else {
+                        // already compressed, just copy it.
                         QFile::copy(fullpath, backupfile);
-                } else // already compressed, just copy it.
-                    QFile::copy(fullpath, backupfile);
+                    }
+                }
+
+                if (!gz) {
+                    backfile=filename.replace(".edf",".crc",Qt::CaseInsensitive);
+                } else {
+                    backfile=filename.replace(".edf.gz",".crc",Qt::CaseInsensitive);
+                }
 
-                backfile=filename.replace(".edf",".crc",Qt::CaseInsensitive);
                 backupfile=backup_path+backfile;
                 crcfile=newpath+backfile;
                 QFile::copy(crcfile, backupfile);
@@ -1311,13 +1340,16 @@ bool ResmedLoader::LoadBRP(Session *sess,EDFParser &edf)
     for (int s=0;s<edf.GetNumSignals();s++) {
         EDFSignal & es=*edf.edfsignals[s];
         //qDebug() << "BRP:" << es.digital_maximum << es.digital_minimum << es.physical_maximum << es.physical_minimum;
-        long recs=edf.edfsignals[s]->nr*edf.GetNumDataRecords();
+        long recs=es.nr*edf.GetNumDataRecords();
         ChannelID code;
-        if (edf.edfsignals[s]->label=="Flow") {
+        if (es.offset>0) {
+            int i=5;
+        }
+        if (es.label=="Flow") {
             es.gain*=60;
             es.physical_dimension="L/M";
             code=CPAP_FlowRate;
-        } else if (edf.edfsignals[s]->label.startsWith("Mask Pres")) {
+        } else if (es.label.startsWith("Mask Pres")) {
             code=CPAP_MaskPressureHi;
         } else if (es.label.startsWith("Resp Event")) {
             code=CPAP_RespEvent;
@@ -1400,11 +1432,11 @@ bool ResmedLoader::LoadSAD(Session *sess,EDFParser &edf)
     for (int s=0;s<edf.GetNumSignals();s++) {
         EDFSignal & es=*edf.edfsignals[s];
         //qDebug() << "SAD:" << es.label << es.digital_maximum << es.digital_minimum << es.physical_maximum << es.physical_minimum;
-        long recs=edf.edfsignals[s]->nr*edf.GetNumDataRecords();
+        long recs=es.nr*edf.GetNumDataRecords();
         ChannelID code;
-        if (edf.edfsignals[s]->label.startsWith("Puls")) {
+        if (es.label.startsWith("Puls")) {
             code=OXI_Pulse;
-        } else if (edf.edfsignals[s]->label=="SpO2") {
+        } else if (es.label=="SpO2") {
             code=OXI_SPO2;
         } else {
             qDebug() << "Unobserved ResMed SAD Signal " << edf.edfsignals[s]->label;
@@ -1446,6 +1478,9 @@ bool ResmedLoader::LoadPLD(Session *sess,EDFParser &edf)
     ChannelID code;
     for (int s=0;s<edf.GetNumSignals();s++) {
         EDFSignal & es=*edf.edfsignals[s];
+        if (es.offset>0) {
+            int i=5;
+        }
         recs=es.nr*edf.GetNumDataRecords();
         if (recs<=0) continue;
         rate=double(duration)/double(recs);
diff --git a/SleepLib/preferences.cpp b/SleepLib/preferences.cpp
index 21eb5187..750c4389 100644
--- a/SleepLib/preferences.cpp
+++ b/SleepLib/preferences.cpp
@@ -61,33 +61,6 @@ const QString & GetAppRoot()
     return HomeAppRoot;
 }
 
-Preference::Preference(Preferences * pref,QString code, PrefType type, QString label, QString tooltip, QVariant default_value) :
-    m_pref(pref), m_code(code), m_type(type), m_label(label),m_tooltip(tooltip), m_defaultValue(default_value)
-{
-}
-void Preference::setValue(QVariant v)
-{
-    if (!m_pref) {
-        qDebug() << "Bad Preferences object" << m_code;
-        return;
-    }
-    if (m_pref)
-        (*m_pref)[m_code]=v;
-}
-QVariant & Preference::value() {
-    if (!m_pref) {
-        qDebug() << "Bad Preferences object" << m_code;
-        return m_defaultValue;
-    }
-    QHash<QString,QVariant>::iterator i=m_pref->find(m_code);
-    if (i==m_pref->end()) {
-        (*m_pref)[m_code]=m_defaultValue;
-        return (*m_pref)[m_code];
-    }
-
-    return i.value();
-}
-
 
 Preferences::Preferences()
 {
diff --git a/SleepLib/preferences.h b/SleepLib/preferences.h
index 76db1870..774b6b1e 100644
--- a/SleepLib/preferences.h
+++ b/SleepLib/preferences.h
@@ -121,49 +121,6 @@ protected:
     QString p_path;
 };
 
-enum PrefType { PT_Checkbox, PT_Spinbox, PT_Integer, PT_Number, PT_Date, PT_Time, PT_DateTime, PT_LineEdit, PT_TextEdit, PT_Dropdown };
-
-/*! \class Preference
-    \brief Holds a single preference
-    \note This is a work in progress to clean up preferences system
-    */
-class Preference
-{
-public:
-    Preference() {
-        m_pref=NULL;
-    }
-    Preference(const Preference & copy) {
-        m_pref=copy.m_pref;
-        m_code=copy.m_code;
-        m_type=copy.m_type;
-        m_label=copy.m_label;
-        m_tooltip=copy.m_tooltip;
-        m_defaultValue=copy.m_defaultValue;
-    }
-    Preference(Preferences * pref, QString code, PrefType type, QString label, QString tooltip, QVariant default_value);
-    ~Preference() {}
-
-    QString code() { return m_code; }
-
-    void setValue(QVariant v);
-    QVariant & value();
-
-    PrefType type() { return m_type; }
-    QString label() { return m_label; }
-    QString tooltip() { return m_tooltip; }
-    QVariant defaultValue() { return m_defaultValue; }
-protected:
-    Preferences * m_pref;
-    QString m_code;
-    PrefType m_type;
-    QString m_label;
-    QString m_tooltip;
-    QVariant m_defaultValue;
-};
-
-Q_DECLARE_METATYPE(Preference)
-
 //! \brief Main Preferences Object used throughout the application
 extern Preferences PREF;
 
diff --git a/SleepLib/profiles.cpp b/SleepLib/profiles.cpp
index ef157a8b..97618ffa 100644
--- a/SleepLib/profiles.cpp
+++ b/SleepLib/profiles.cpp
@@ -97,10 +97,10 @@ void Profile::DataFormatError(Machine *m)
         if (!m->Purge(3478216)) { // Do not copy this line without thinking.. You will be eaten by a Grue if you do
 
             QMessageBox::critical(NULL,QObject::tr("Purge Failed"),QObject::tr("Sorry, I could not purge this data, which means this version of SleepyHead can't start.. SleepyHead's Data folder needs to be removed manually\n\nThis folder currently resides at the following location:\n")+PREF[STR_GEN_DataFolder].toString(),QMessageBox::Ok);
-            exit(-1);
+            QApplication::exit(-1);
         }
     } else {
-        exit(-1);
+        QApplication::exit(-1);
     }
     return;
 
@@ -909,6 +909,11 @@ const char * STR_CS_PrescribedMaxPressure="CPAPPrescribedMaxPressure";
 const char * STR_CS_UntreatedAHI="UntreatedAHI";
 const char * STR_CS_Notes="CPAPNotes";
 const char * STR_CS_DateDiagnosed="DateDiagnosed";
+const char * STR_CS_UserEventFlagging="UserEventFlagging";
+const char * STR_CS_UserFlowRestriction="UserFlowRestriction";
+const char * STR_CS_UserEventDuration="UserEventDuration";
+const char * STR_CS_AHIWindow="AHIWindow";
+const char * STR_CS_AHIReset="AHIReset";
 
 // ImportSettings Strings
 const char * STR_IS_DaySplitTime="DaySplitTime";
diff --git a/SleepLib/profiles.h b/SleepLib/profiles.h
index a4979d73..1ce50018 100644
--- a/SleepLib/profiles.h
+++ b/SleepLib/profiles.h
@@ -342,6 +342,11 @@ extern const char * STR_CS_PrescribedMaxPressure;
 extern const char * STR_CS_UntreatedAHI;
 extern const char * STR_CS_Notes;
 extern const char * STR_CS_DateDiagnosed;
+extern const char * STR_CS_UserEventFlagging;
+extern const char * STR_CS_UserFlowRestriction;
+extern const char * STR_CS_UserEventDuration;
+extern const char * STR_CS_AHIWindow;
+extern const char * STR_CS_AHIReset;
 
 /*! \class CPAPSettings
     \brief Profile Options relating to the CPAP settings
@@ -365,6 +370,11 @@ public:
         if (!m_profile->contains(STR_CS_UntreatedAHI)) (*m_profile)[STR_CS_UntreatedAHI]=0.0;
         if (!m_profile->contains(STR_CS_Notes)) (*m_profile)[STR_CS_Notes]=QString();
         if (!m_profile->contains(STR_CS_DateDiagnosed)) (*m_profile)[STR_CS_DateDiagnosed]=QDate();
+        if (!m_profile->contains(STR_CS_UserFlowRestriction)) (*m_profile)[STR_CS_UserFlowRestriction]=10.0;
+        if (!m_profile->contains(STR_CS_UserEventDuration)) (*m_profile)[STR_CS_UserEventDuration]=10.0;
+        if (!m_profile->contains(STR_CS_UserEventFlagging)) (*m_profile)[STR_CS_UserEventFlagging]=false;
+        if (!m_profile->contains(STR_CS_AHIWindow)) (*m_profile)[STR_CS_AHIWindow]=60.0;
+        if (!m_profile->contains(STR_CS_AHIReset)) (*m_profile)[STR_CS_AHIReset]=false;
     }
 
     ~CPAPSettings() {}
@@ -384,6 +394,11 @@ public:
     double untreatedAHI() { return (*m_profile)[STR_CS_UntreatedAHI].toDouble(); }
     const QString notes() { return (*m_profile)[STR_CS_Notes].toString(); }
     QDate dateDiagnosed() { return (*m_profile)[STR_CS_DateDiagnosed].toDate(); }
+    double userFlowRestriction() { return (*m_profile)[STR_CS_UserFlowRestriction].toDouble(); }
+    double userEventDuration() { return (*m_profile)[STR_CS_UserEventDuration].toDouble(); }
+    double AHIWindow() { return (*m_profile)[STR_CS_AHIWindow].toDouble(); }
+    bool AHIReset() { return (*m_profile)[STR_CS_AHIReset].toBool(); }
+    bool userEventFlagging() { return (*m_profile)[STR_CS_UserEventFlagging].toBool(); }
 
     //Setters
     void setMode(CPAPMode mode) { (*m_profile)[STR_CS_PrescribedMode]=(int)mode; }
@@ -398,6 +413,11 @@ public:
     void setMaskStartDate(QDate date) { (*m_profile)[STR_CS_MaskStartDate]=date; }
     void setMaskDescription(QString description) { (*m_profile)[STR_CS_MaskDescription]=description; }
     void setMaskType(MaskType masktype) { (*m_profile)[STR_CS_MaskType]=(int)masktype; }
+    void setUserFlowRestriction(double flow) { (*m_profile)[STR_CS_UserFlowRestriction]=flow; }
+    void setUserEventDuration(double duration) { (*m_profile)[STR_CS_UserEventDuration]=duration; }
+    void setAHIWindow(double window) { (*m_profile)[STR_CS_AHIWindow]=window; }
+    void setAHIReset(bool reset) { (*m_profile)[STR_CS_AHIReset]=reset; }
+    void setUserEventFlagging(bool flagging) { (*m_profile)[STR_CS_UserEventFlagging]=flagging; }
 
     Profile *m_profile;
 };
diff --git a/daily.cpp b/daily.cpp
index 0c135573..1953a666 100644
--- a/daily.cpp
+++ b/daily.cpp
@@ -153,8 +153,10 @@ Daily::Daily(QWidget *parent,gGraphView * shared)
     fg->AddLayer((new gFlagsLine(CPAP_FlowLimit,QColor("black"),tr("FL"))));
     fg->AddLayer((new gFlagsLine(CPAP_RERA,QColor("gold"),tr("RE"))));
     fg->AddLayer((new gFlagsLine(CPAP_VSnore,QColor("red"),tr("VS"))));
-    fg->AddLayer((new gFlagsLine(CPAP_UserFlag1,QColor("yellow"),tr("UF1"))));
-    fg->AddLayer((new gFlagsLine(CPAP_UserFlag2,QColor("green"),tr("UF2"))));
+    if (PROFILE.cpap->userEventFlagging()) {
+        fg->AddLayer((new gFlagsLine(CPAP_UserFlag1,QColor("yellow"),tr("UF1"))));
+        fg->AddLayer((new gFlagsLine(CPAP_UserFlag2,QColor("green"),tr("UF2"))));
+    }
     //fg->AddLayer((new gFlagsLine(PRS1_0B,QColor("dark green"),tr("U0B"))));
     fg->AddLayer((new gFlagsLine(CPAP_VSnore2,QColor("red"),tr("VS2"))));
     SF->setBlockZoom(true);
@@ -189,8 +191,10 @@ Daily::Daily(QWidget *parent,gGraphView * shared)
     FRW->AddLayer(AddCPAP(new gLineOverlayBar(CPAP_FlowLimit,QColor("black"),tr("FL"))));
     FRW->AddLayer(AddCPAP(los->add(new gLineOverlayBar(CPAP_Obstructive,QColor("#40c0ff"),tr("OA")))));
     FRW->AddLayer(AddCPAP(los->add(new gLineOverlayBar(CPAP_ClearAirway,QColor("purple"),tr("CA")))));
-    FRW->AddLayer(AddCPAP(new gLineOverlayBar(CPAP_UserFlag1,QColor("yellow"),tr("U1"),FT_Bar)));
-    FRW->AddLayer(AddCPAP(new gLineOverlayBar(CPAP_UserFlag2,QColor("orange"),tr("U2"),FT_Bar)));
+    if (PROFILE.cpap->userEventFlagging()) {
+        FRW->AddLayer(AddCPAP(new gLineOverlayBar(CPAP_UserFlag1,QColor("yellow"),tr("U1"),FT_Bar)));
+        FRW->AddLayer(AddCPAP(new gLineOverlayBar(CPAP_UserFlag2,QColor("orange"),tr("U2"),FT_Bar)));
+    }
     FRW->AddLayer(AddOXI(new gLineOverlayBar(OXI_SPO2Drop,QColor("red"),tr("O2"))));
     FRW->AddLayer(AddOXI(new gLineOverlayBar(OXI_PulseChange,QColor("blue"),tr("PC"),FT_Dot)));
 
@@ -437,6 +441,7 @@ void Daily::UpdateEventsTree(QTreeWidget *tree,Day *day)
     QHash<ChannelID,QTreeWidgetItem *> mcroot;
     QHash<ChannelID,int> mccnt;
     int total_events=0;
+    bool userflags=p_profile->cpap->userEventFlagging();
     for (QVector<Session *>::iterator s=day->begin();s!=day->end();s++) {
         if (!(*s)->enabled()) continue;
 
@@ -460,6 +465,9 @@ void Daily::UpdateEventsTree(QTreeWidget *tree,Day *day)
                 && (code!=CPAP_PressurePulse)
                 && (code!=CPAP_VSnore2)
                 && (code!=CPAP_VSnore)) continue;
+
+            if (!userflags && ((code==CPAP_UserFlag1) || (code==CPAP_UserFlag2))) continue;
+
             QTreeWidgetItem *mcr;
             if (mcroot.find(code)==mcroot.end()) {
                 int cnt=day->count(code);
@@ -657,8 +665,7 @@ void Daily::Load(QDate date)
     "<body leftmargin=0 rightmargin=0 topmargin=0 marginwidth=0 marginheight=0>"
     "<table cellspacing=0 cellpadding=1 border=0 width='100%'>\n";
     QString tmp;
-    //const int gwwidth=240;
-    //const int gwheight=100;
+
     UpdateOXIGraphs(oxi);
     UpdateCPAPGraphs(cpap);
     UpdateEventsTree(ui->treeWidget,cpap);
@@ -667,51 +674,20 @@ void Daily::Load(QDate date)
 
     snapGV->setDay(cpap);
 
-
     GraphView->ResetBounds(false);
 
-    //GraphView->setEmptyText(tr("No Data")); //tr("No data for ")+date.toString(Qt::SystemLocaleLongDate));
     if (!cpap && !oxi) {
-        //splitter->setMinimumHeight(0);
         scrollbar->hide();
- //       GraphView->hide();
     } else {
-        //NoData->hide();
-   //     GraphView->show();
         scrollbar->show();
     }
-    //GraphView->redraw();
-    //snapGV->redraw();
-//    for (int i=0;i<GraphView->size();i++) {
-//        QString title=(*GraphView)[i]->title();
-//        bool empty=(*GraphView)[i]->isEmpty();
-//        if (!empty) graphsAvailable++;
-//        GraphToggles[title]->setVisible(!empty);
-//    }
-//    emptyToggleArea->setVisible(graphsAvailable==0);
-
-    //ui->graphVisibilityToggleArea->setVisible(graphsAvailable>0);
-
-    //RedrawGraphs();
 
     QString modestr;
-    //float iap90,eap90;
     CPAPMode mode=MODE_UNKNOWN;
     QString a;
     bool isBrick=false;
 
-    //ui->graphVisibilityToggleArea->setVisible(true);
-
     updateGraphCombo();
-    //int graphsAvailable=GraphView->visibleGraphs();
-//    if (graphsAvailable>0) {
-//            GraphView->setCubeImage(images["sheep"]);
-//            GraphView->setEmptyText(tr("Graphs Switched Off"));
-//    } else {
-//        GraphView->setCubeImage(images["nodata"]);
-//        GraphView->setEmptyText(tr("No Data"));
-//        emptyToggleArea->setText("No graph data available for this day");
-//    }
 
     if (cpap) {
         if (GraphView->isEmpty()) {
@@ -867,6 +843,12 @@ void Daily::Load(QDate date)
             }
             html+="</tr>";
 
+            if (PROFILE.cpap->userEventFlagging()) {
+                EventDataType uf=cpap->count(CPAP_UserFlag1) / cpap->hours();
+                if (uf>0)
+                    html+=QString("<tr><td colspan=5>User flag index=%1</td></tr>").arg(uf,0,'f',2);
+            }
+
 
             // Note, this may not be a problem since Qt bug 13622 was discovered
             // as it only relates to text drawing, which the Pie chart does not do
@@ -1762,7 +1744,7 @@ void Daily::updateCube()
 
         if (ui->graphCombo->count()>0) {
             GraphView->setEmptyText(tr("No Graphs On!"));
-            GraphView->setCubeImage(images["sheep"]);
+            GraphView->setCubeImage(images["nographs"]);
 
         } else {
             GraphView->setEmptyText("No Data");
diff --git a/daily.ui b/daily.ui
index 5aa9b982..1acf63e8 100644
--- a/daily.ui
+++ b/daily.ui
@@ -248,7 +248,7 @@
         </size>
        </property>
        <property name="currentIndex">
-        <number>2</number>
+        <number>0</number>
        </property>
        <property name="movable">
         <bool>true</bool>
@@ -773,14 +773,10 @@
           <item>
            <widget class="QToolButton" name="resetLayoutButton">
             <property name="toolTip">
-             <string>Reset the graphs to uniform sizes</string>
+             <string>Reset the graph heights to uniform sizes</string>
             </property>
             <property name="text">
-             <string>...</string>
-            </property>
-            <property name="icon">
-             <iconset resource="Resources.qrc">
-              <normaloff>:/icons/refresh.png</normaloff>:/icons/refresh.png</iconset>
+             <string>Reset</string>
             </property>
             <property name="autoRaise">
              <bool>true</bool>
diff --git a/docs/channels.xml b/docs/channels.xml
index 8c711014..85b89a2a 100644
--- a/docs/channels.xml
+++ b/docs/channels.xml
@@ -48,7 +48,7 @@ Important: One id code per item, DO NOT CHANGE ID NUMBERS!!!
   <channel id="0x1110" class="data" name="IPAPLo" details="Inspiratory Pressure Lo" label="IPAP" unit="cmH20" color="grey"/>
   <channel id="0x1111" class="data" name="IPAPHi" details="Inspiratory Pressure Hi" label="IPAP" unit="cmH20" color="grey"/>
   <channel id="0x1112" class="data" name="RespEvent" details="Respiratory Events" label="Resp Events" unit="" color="black"/>
-  <channel id="0x1113" class="data" name="FLG" details="Flow Limit Graph" label="Flow Limit" unit="0&lt;n&lt;1" color="dark grey"/>
+  <channel id="0x1113" class="data" name="FLG" details="Flow Limit Graph" label="Flow Limit" unit="0-1" color="dark grey"/>
   <channel id="0x1114" class="data" name="TgMV" details="Target Minute Ventilation" label="Target Vent." unit="" color="dark cyan"/>
   <channel id="0x1115" class="data" name="MaxLeak" details="Maximum Leak" label="MaxLeaks" unit="L/min" color="dark red"/>
   <channel id="0x1116" class="data" name="AHI" details="Apnea / Hypopnea Index" label="AHI/Hr" unit="events/hr" color="dark red"/>
@@ -69,7 +69,7 @@ Important: One id code per item, DO NOT CHANGE ID NUMBERS!!!
   <channel id="0x1158" class="data" name="PRS1_10" details="Unknown 10" label="U10" unit="?" color="black"/>
   <channel id="0x1159" class="data" name="PRS1_12" details="PRS1 Unknown 12" label="U12" unit="" color="black"/>
   <channel id="0x1160" class="data" name="RMS9_E01" details="RMS9 Empty 1" label="E01" unit="" color="black"/>
-  <channel id="0x1161" class="data" name="RMS9_E02" details="RMS9 Empty 2" label="U02" unit="" color="black"/>
+  <channel id="0x1161" class="data" name="RMS9_E02" details="RMS9 Empty 2" label="E02" unit="" color="black"/>
   <channel id="0x1162" class="data" name="SetPressure" details="Set Pressure" label="Pressure" unit="" color="black"/>
   <channel id="0x1163" class="data" name="BrokenSummary" details="Broken Summary" label="Broken Summary" unit="" color="black"/>
   <channel id="0x1164" class="data" name="BrokenWaveform" details="Broken Waveform" label="Broken Waveform" unit="" color="black"/>
diff --git a/docs/release_notes.html b/docs/release_notes.html
index 2d8b7948..f9d410b2 100644
--- a/docs/release_notes.html
+++ b/docs/release_notes.html
@@ -11,16 +11,19 @@
 <p><b>New Features:</b></br>
 <list>
 <li>Auto-Updater for Windows & Mac Platforms</li>
-<li>SleepLib database improvements, and lots of other underneath stuff and code cleanups you don't see.</li>
+<li>SleepLib database improvements, and lots of other underneath stuff, code cleanups and optimisations you don't see.</li>
 <li>Session Hiding capabilities, by clicking on the toggle button down the bottom of Daily views details panel</li>
 <li>New Statistics page showing some more useful data.</li>
+<li>Prescription Settings list in statistics shows recent machine settings changes, and jumps to overview when clicked on</li>
 <li>Welcome page has become a Help Browser.</li>
 <li>New Navigation Panel on the right side, now accessible from all tabs. It can be hidden to reclaim screen space.</li>
-<li>New Favourites tab in this right panel for bookmarking days and quickly finding them again.</li>
+<li>New Bookmarks tab in this right panel for showing days with bookmarks, allowing you to quickly jump to them.</li>
 <li>New Records tab to show some best/worst entries, which have links going directly to the related day or overview range.</li>
-<li>Daily reports bookmarked areas show oximetry data when available.</li>
+<li>Daily (printed) reports show oximetry data when showing bookmarks.</li>
 <li>Can print from both the Statistics & Help Browser pages.</li>
-<li>New Context cube can be switched on to make empty pages more attractive.</li>
+<li>Option to automatically maintain backup folder for ResMed users. (on by default)</li>
+<li>Compression options to save disk space for SleepyHead data and backups.</li>
+<li>New Context cube to make empty pages more attractive.. Yes you can switch it off. No it doesn't take much resources.</li>
 <li>Plenty of other bug fixes, including more oximetry fixes.</li>
 </list></p>
 <p><b>Important Information:</b><br/>
diff --git a/icons/sheep.png b/icons/nographs.png
similarity index 100%
rename from icons/sheep.png
rename to icons/nographs.png
diff --git a/main.cpp b/main.cpp
index f097722c..ab7ee837 100644
--- a/main.cpp
+++ b/main.cpp
@@ -105,36 +105,47 @@ int main(int argc, char *argv[])
     a.setApplicationName("SleepyHead");
     initialize();
 
+
+    ////////////////////////////////////////////////////////////////////////////////////////////
+    // Register Importer Modules
+    ////////////////////////////////////////////////////////////////////////////////////////////
     PRS1Loader::Register();
     CMS50Loader::Register();
-    ZEOLoader::Register();
+    //ZEOLoader::Register();
     ResmedLoader::Register();
     IntellipapLoader::Register();
+
+    // Scan for user profiles
     Profiles::Scan();
-    qRegisterMetaType<Preference>("Preference");
+    //qRegisterMetaType<Preference>("Preference");
     PREF["AppName"]=QObject::tr("SleepyHead");
+
+
+    // Skip login screen, unless asked not to on the command line
     bool skip_login=(PREF.ExistsAndTrue("SkipLoginScreen"));
     if (force_login_screen) skip_login=false;
 
+    // Todo: Make a wrapper for Preference settings, like Profile settings have..
     QDateTime lastchecked, today=QDateTime::currentDateTime();
     if (!PREF.contains(STR_GEN_UpdatesAutoCheck)) {
         PREF[STR_GEN_UpdatesAutoCheck]=true;
         PREF[STR_GEN_UpdateCheckFrequency]=7;
     }
+
+    ////////////////////////////////////////////////////////////////////////////////////////////
+    // Check when last checked for updates..
+    ////////////////////////////////////////////////////////////////////////////////////////////
     bool check_updates=false;
     if (PREF[STR_GEN_UpdatesAutoCheck].toBool()) {
         int update_frequency=PREF[STR_GEN_UpdateCheckFrequency].toInt();
         int days=1000;
-        // p_pref ->Get
         lastchecked=PREF[STR_GEN_UpdatesLastChecked].toDateTime();
         if (PREF.contains(STR_GEN_UpdatesLastChecked)) {
             days=lastchecked.secsTo(today);
             days/=86400;
         };
         if (days>update_frequency) {
-            //QMessageBox::information(NULL,"Check for updates","Placeholder. Would automatically check for updates here.",QMessageBox::Ok);
             check_updates=true;
-            //PREF[STR_GEN_UpdatesLastChecked]=today;
         }
     }
 
@@ -173,14 +184,13 @@ int main(int argc, char *argv[])
     p_profile=Profiles::Get(PREF[STR_GEN_Profile].toString());
 
     qDebug() << "Selected Profile" << p_profile->user->userName();
-    //if (!PREF.Exists(STR_GEN_Profile)) PREF[STR_GEN_Profile]=getUserName();
 
-    //int id=QFontDatabase::addApplicationFont(":/fonts/FreeSans.ttf");
-   /* QFontDatabase fdb;
-    QStringList ffam=fdb.families();
-    for (QStringList::iterator i=ffam.begin();i!=ffam.end();i++) {
-        qDebug() << "Loaded Font: " << (*i);
-    } */
+//    int id=QFontDatabase::addApplicationFont(":/fonts/FreeSans.ttf");
+//    QFontDatabase fdb;
+//    QStringList ffam=fdb.families();
+//    for (QStringList::iterator i=ffam.begin();i!=ffam.end();i++) {
+//        qDebug() << "Loaded Font: " << (*i);
+//    }
 
     if (!PREF.contains("Fonts_Application_Name")) {
         PREF["Fonts_Application_Name"]="Sans Serif";
diff --git a/mainwindow.cpp b/mainwindow.cpp
index 3ec8a416..33b5842a 100644
--- a/mainwindow.cpp
+++ b/mainwindow.cpp
@@ -151,6 +151,7 @@ MainWindow::MainWindow(QWidget *parent) :
     ui->recordsBox->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
     ui->summaryView->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
     ui->webView->page()->setLinkDelegationPolicy(QWebPage::DelegateExternalLinks);
+    ui->bookmarkView->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
     ui->toolBox->setStyleSheet(
                                "QToolBox::tab {"
                                "background: #6789ab;"
@@ -278,8 +279,11 @@ void MainWindow::on_action_Import_Data_triggered()
         }
         if (res==2) return;
     }
+    if (asknew) {
+        mainwin->Notify("Please remember to point the importer at the root folder or drive letter of your data-card, and not a subfolder.","Import Reminder",8000);
+    }
 
-    QStringList importFrom=importLocations;
+    QStringList importFrom;
 
     if (asknew) {
         QFileDialog w;
@@ -311,7 +315,7 @@ void MainWindow::on_action_Import_Data_triggered()
                 //addnew=true;
             }
         }
-    }
+    } else importFrom=importLocations;
 
     int successful=false;
 
@@ -559,8 +563,9 @@ void MainWindow::on_summaryButton_clicked()
 
 
     if (mach.size()==0) {
-        html+="<table cellpadding=2 cellspacing=0 border=0 width=100% height=70%>";
-        html+="<tr><td align=center><h1>Please Import Some Data</h1><br/><i>SleepyHead is pretty much useless without it.</i><br/>First import can take a few minutes.</td></tr></table>";
+        html+="<table cellpadding=2 cellspacing=0 border=0 width=100% height=60%>";
+        QString datacard;
+        html+="<tr><td align=center><h1>Please Import Some Data</h1><i>SleepyHead is pretty much useless without it.</i><br/><p>It might be a good idea to check preferences first,</br>as there are some options that affect import.</p><p>First import can take a few minutes.</p></td></tr></table>";
         html+=htmlFooter();
         ui->summaryView->setHtml(html);
         return;
@@ -581,6 +586,8 @@ void MainWindow::on_summaryButton_clicked()
     } else {
         ahitxt=tr("AHI");
     }
+
+    int decimals=2;
     html+="<div align=center>";
     html+=QString("<table cellpadding=2 cellspacing=0 border=1 width=90%>");
     if (cpapdays==0)  {
@@ -603,30 +610,30 @@ void MainWindow::on_summaryButton_clicked()
                 .arg(tr("Details")).arg(tr("Most Recent")).arg(tr("Last 7 Days")).arg(tr("Last 30 Days")).arg(tr("Last 6 months")).arg(tr("Last Year"));
             html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
             .arg(ahitxt)
-            .arg(calcAHI(lastcpap,lastcpap),0,'f',3)
-            .arg(calcAHI(cpapweek,lastcpap),0,'f',3)
-            .arg(calcAHI(cpapmonth,lastcpap),0,'f',3)
-            .arg(calcAHI(cpap6month,lastcpap),0,'f',3)
-            .arg(calcAHI(cpapyear,lastcpap),0,'f',3);
+            .arg(calcAHI(lastcpap,lastcpap),0,'f',decimals)
+            .arg(calcAHI(cpapweek,lastcpap),0,'f',decimals)
+            .arg(calcAHI(cpapmonth,lastcpap),0,'f',decimals)
+            .arg(calcAHI(cpap6month,lastcpap),0,'f',decimals)
+            .arg(calcAHI(cpapyear,lastcpap),0,'f',decimals);
 
             if (PROFILE.calcCount(CPAP_RERA,MT_CPAP,cpapyear,lastcpap)) {
                 html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
                 .arg(tr("RERA Index"))
-                .arg(PROFILE.calcCount(CPAP_RERA,MT_CPAP,lastcpap,lastcpap)/PROFILE.calcHours(MT_CPAP,lastcpap,lastcpap),0,'f',3)
-                .arg(PROFILE.calcCount(CPAP_RERA,MT_CPAP,cpapweek,lastcpap)/PROFILE.calcHours(MT_CPAP,cpapweek,lastcpap),0,'f',3)
-                .arg(PROFILE.calcCount(CPAP_RERA,MT_CPAP,cpapmonth,lastcpap)/PROFILE.calcHours(MT_CPAP,cpapmonth,lastcpap),0,'f',3)
-                .arg(PROFILE.calcCount(CPAP_RERA,MT_CPAP,cpap6month,lastcpap)/PROFILE.calcHours(MT_CPAP,cpap6month,lastcpap),0,'f',3)
-                .arg(PROFILE.calcCount(CPAP_RERA,MT_CPAP,cpapyear,lastcpap)/PROFILE.calcHours(MT_CPAP,cpapyear,lastcpap),0,'f',3);
+                .arg(PROFILE.calcCount(CPAP_RERA,MT_CPAP,lastcpap,lastcpap)/PROFILE.calcHours(MT_CPAP,lastcpap,lastcpap),0,'f',decimals)
+                .arg(PROFILE.calcCount(CPAP_RERA,MT_CPAP,cpapweek,lastcpap)/PROFILE.calcHours(MT_CPAP,cpapweek,lastcpap),0,'f',decimals)
+                .arg(PROFILE.calcCount(CPAP_RERA,MT_CPAP,cpapmonth,lastcpap)/PROFILE.calcHours(MT_CPAP,cpapmonth,lastcpap),0,'f',decimals)
+                .arg(PROFILE.calcCount(CPAP_RERA,MT_CPAP,cpap6month,lastcpap)/PROFILE.calcHours(MT_CPAP,cpap6month,lastcpap),0,'f',decimals)
+                .arg(PROFILE.calcCount(CPAP_RERA,MT_CPAP,cpapyear,lastcpap)/PROFILE.calcHours(MT_CPAP,cpapyear,lastcpap),0,'f',decimals);
             }
 
             if (PROFILE.calcCount(CPAP_FlowLimit,MT_CPAP,cpapyear,lastcpap)) {
                 html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
                 .arg(tr("Flow Limit Index"))
-                .arg(PROFILE.calcCount(CPAP_FlowLimit,MT_CPAP,lastcpap,lastcpap)/PROFILE.calcHours(MT_CPAP,lastcpap,lastcpap),0,'f',3)
-                .arg(PROFILE.calcCount(CPAP_FlowLimit,MT_CPAP,cpapweek,lastcpap)/PROFILE.calcHours(MT_CPAP,cpapweek,lastcpap),0,'f',3)
-                .arg(PROFILE.calcCount(CPAP_FlowLimit,MT_CPAP,cpapmonth,lastcpap)/PROFILE.calcHours(MT_CPAP,cpapmonth,lastcpap),0,'f',3)
-                .arg(PROFILE.calcCount(CPAP_FlowLimit,MT_CPAP,cpap6month,lastcpap)/PROFILE.calcHours(MT_CPAP,cpap6month,lastcpap),0,'f',3)
-                .arg(PROFILE.calcCount(CPAP_FlowLimit,MT_CPAP,cpapyear,lastcpap)/PROFILE.calcHours(MT_CPAP,cpapyear,lastcpap),0,'f',3);
+                .arg(PROFILE.calcCount(CPAP_FlowLimit,MT_CPAP,lastcpap,lastcpap)/PROFILE.calcHours(MT_CPAP,lastcpap,lastcpap),0,'f',decimals)
+                .arg(PROFILE.calcCount(CPAP_FlowLimit,MT_CPAP,cpapweek,lastcpap)/PROFILE.calcHours(MT_CPAP,cpapweek,lastcpap),0,'f',decimals)
+                .arg(PROFILE.calcCount(CPAP_FlowLimit,MT_CPAP,cpapmonth,lastcpap)/PROFILE.calcHours(MT_CPAP,cpapmonth,lastcpap),0,'f',decimals)
+                .arg(PROFILE.calcCount(CPAP_FlowLimit,MT_CPAP,cpap6month,lastcpap)/PROFILE.calcHours(MT_CPAP,cpap6month,lastcpap),0,'f',decimals)
+                .arg(PROFILE.calcCount(CPAP_FlowLimit,MT_CPAP,cpapyear,lastcpap)/PROFILE.calcHours(MT_CPAP,cpapyear,lastcpap),0,'f',decimals);
             }
 
 
@@ -642,55 +649,55 @@ void MainWindow::on_summaryButton_clicked()
             if (cpapmode>=MODE_BIPAP) {
                 html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
                 .arg(tr("Min EPAP"))
-                .arg(p_profile->calcMin(CPAP_EPAP,MT_CPAP),0,'f',3)
-                .arg(p_profile->calcMin(CPAP_EPAP,MT_CPAP,cpapweek,lastcpap),0,'f',3)
-                .arg(p_profile->calcMin(CPAP_EPAP,MT_CPAP,cpapmonth,lastcpap),0,'f',3)
-                .arg(p_profile->calcMin(CPAP_EPAP,MT_CPAP,cpap6month,lastcpap),0,'f',3)
-                .arg(p_profile->calcMin(CPAP_EPAP,MT_CPAP,cpapyear,lastcpap),0,'f',3);
+                .arg(p_profile->calcMin(CPAP_EPAP,MT_CPAP),0,'f',decimals)
+                .arg(p_profile->calcMin(CPAP_EPAP,MT_CPAP,cpapweek,lastcpap),0,'f',decimals)
+                .arg(p_profile->calcMin(CPAP_EPAP,MT_CPAP,cpapmonth,lastcpap),0,'f',decimals)
+                .arg(p_profile->calcMin(CPAP_EPAP,MT_CPAP,cpap6month,lastcpap),0,'f',decimals)
+                .arg(p_profile->calcMin(CPAP_EPAP,MT_CPAP,cpapyear,lastcpap),0,'f',decimals);
                 html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
                 .arg(tr("95% EPAP"))
-                .arg(p_profile->calcPercentile(CPAP_EPAP,percentile,MT_CPAP),0,'f',3)
-                .arg(p_profile->calcPercentile(CPAP_EPAP,percentile,MT_CPAP,cpapweek,lastcpap),0,'f',3)
-                .arg(p_profile->calcPercentile(CPAP_EPAP,percentile,MT_CPAP,cpapmonth,lastcpap),0,'f',3)
-                .arg(p_profile->calcPercentile(CPAP_EPAP,percentile,MT_CPAP,cpap6month,lastcpap),0,'f',3)
-                .arg(p_profile->calcPercentile(CPAP_EPAP,percentile,MT_CPAP,cpapyear,lastcpap),0,'f',3);
+                .arg(p_profile->calcPercentile(CPAP_EPAP,percentile,MT_CPAP),0,'f',decimals)
+                .arg(p_profile->calcPercentile(CPAP_EPAP,percentile,MT_CPAP,cpapweek,lastcpap),0,'f',decimals)
+                .arg(p_profile->calcPercentile(CPAP_EPAP,percentile,MT_CPAP,cpapmonth,lastcpap),0,'f',decimals)
+                .arg(p_profile->calcPercentile(CPAP_EPAP,percentile,MT_CPAP,cpap6month,lastcpap),0,'f',decimals)
+                .arg(p_profile->calcPercentile(CPAP_EPAP,percentile,MT_CPAP,cpapyear,lastcpap),0,'f',decimals);
                 html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
                 .arg(tr("Max IPAP"))
-                .arg(p_profile->calcMax(CPAP_IPAP,MT_CPAP),0,'f',3)
-                .arg(p_profile->calcMax(CPAP_IPAP,MT_CPAP,cpapweek,lastcpap),0,'f',3)
-                .arg(p_profile->calcMax(CPAP_IPAP,MT_CPAP,cpapmonth,lastcpap),0,'f',3)
-                .arg(p_profile->calcMax(CPAP_IPAP,MT_CPAP,cpap6month,lastcpap),0,'f',3)
-                .arg(p_profile->calcMax(CPAP_IPAP,MT_CPAP,cpapyear,lastcpap),0,'f',3);
+                .arg(p_profile->calcMax(CPAP_IPAP,MT_CPAP),0,'f',decimals)
+                .arg(p_profile->calcMax(CPAP_IPAP,MT_CPAP,cpapweek,lastcpap),0,'f',decimals)
+                .arg(p_profile->calcMax(CPAP_IPAP,MT_CPAP,cpapmonth,lastcpap),0,'f',decimals)
+                .arg(p_profile->calcMax(CPAP_IPAP,MT_CPAP,cpap6month,lastcpap),0,'f',decimals)
+                .arg(p_profile->calcMax(CPAP_IPAP,MT_CPAP,cpapyear,lastcpap),0,'f',decimals);
                 html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
                 .arg(tr("95% IPAP"))
-                .arg(p_profile->calcPercentile(CPAP_IPAP,percentile,MT_CPAP),0,'f',3)
-                .arg(p_profile->calcPercentile(CPAP_IPAP,percentile,MT_CPAP,cpapweek,lastcpap),0,'f',3)
-                .arg(p_profile->calcPercentile(CPAP_IPAP,percentile,MT_CPAP,cpapmonth,lastcpap),0,'f',3)
-                .arg(p_profile->calcPercentile(CPAP_IPAP,percentile,MT_CPAP,cpap6month,lastcpap),0,'f',3)
-                .arg(p_profile->calcPercentile(CPAP_IPAP,percentile,MT_CPAP,cpapyear,lastcpap),0,'f',3);
+                .arg(p_profile->calcPercentile(CPAP_IPAP,percentile,MT_CPAP),0,'f',decimals)
+                .arg(p_profile->calcPercentile(CPAP_IPAP,percentile,MT_CPAP,cpapweek,lastcpap),0,'f',decimals)
+                .arg(p_profile->calcPercentile(CPAP_IPAP,percentile,MT_CPAP,cpapmonth,lastcpap),0,'f',decimals)
+                .arg(p_profile->calcPercentile(CPAP_IPAP,percentile,MT_CPAP,cpap6month,lastcpap),0,'f',decimals)
+                .arg(p_profile->calcPercentile(CPAP_IPAP,percentile,MT_CPAP,cpapyear,lastcpap),0,'f',decimals);
             } else if (cpapmode>=MODE_APAP) {
                 html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
                 .arg(tr("Average Pressure"))
-                .arg(p_profile->calcWavg(CPAP_Pressure,MT_CPAP),0,'f',3)
-                .arg(p_profile->calcWavg(CPAP_Pressure,MT_CPAP,cpapweek,lastcpap),0,'f',3)
-                .arg(p_profile->calcWavg(CPAP_Pressure,MT_CPAP,cpapmonth,lastcpap),0,'f',3)
-                .arg(p_profile->calcWavg(CPAP_Pressure,MT_CPAP,cpap6month,lastcpap),0,'f',3)
-                .arg(p_profile->calcWavg(CPAP_Pressure,MT_CPAP,cpapyear,lastcpap),0,'f',3);
+                .arg(p_profile->calcWavg(CPAP_Pressure,MT_CPAP),0,'f',decimals)
+                .arg(p_profile->calcWavg(CPAP_Pressure,MT_CPAP,cpapweek,lastcpap),0,'f',decimals)
+                .arg(p_profile->calcWavg(CPAP_Pressure,MT_CPAP,cpapmonth,lastcpap),0,'f',decimals)
+                .arg(p_profile->calcWavg(CPAP_Pressure,MT_CPAP,cpap6month,lastcpap),0,'f',decimals)
+                .arg(p_profile->calcWavg(CPAP_Pressure,MT_CPAP,cpapyear,lastcpap),0,'f',decimals);
                 html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
                 .arg(tr("95% Pressure"))
-                .arg(p_profile->calcPercentile(CPAP_Pressure,percentile,MT_CPAP),0,'f',3)
-                .arg(p_profile->calcPercentile(CPAP_Pressure,percentile,MT_CPAP,cpapweek,lastcpap),0,'f',3)
-                .arg(p_profile->calcPercentile(CPAP_Pressure,percentile,MT_CPAP,cpapmonth,lastcpap),0,'f',3)
-                .arg(p_profile->calcPercentile(CPAP_Pressure,percentile,MT_CPAP,cpap6month,lastcpap),0,'f',3)
-                .arg(p_profile->calcPercentile(CPAP_Pressure,percentile,MT_CPAP,cpapyear,lastcpap),0,'f',3);
+                .arg(p_profile->calcPercentile(CPAP_Pressure,percentile,MT_CPAP),0,'f',decimals)
+                .arg(p_profile->calcPercentile(CPAP_Pressure,percentile,MT_CPAP,cpapweek,lastcpap),0,'f',decimals)
+                .arg(p_profile->calcPercentile(CPAP_Pressure,percentile,MT_CPAP,cpapmonth,lastcpap),0,'f',decimals)
+                .arg(p_profile->calcPercentile(CPAP_Pressure,percentile,MT_CPAP,cpap6month,lastcpap),0,'f',decimals)
+                .arg(p_profile->calcPercentile(CPAP_Pressure,percentile,MT_CPAP,cpapyear,lastcpap),0,'f',decimals);
             } else {
                 html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
                 .arg(tr("Pressure"))
-                .arg(p_profile->calcSettingsMin(CPAP_Pressure,MT_CPAP),0,'f',3)
-                .arg(p_profile->calcSettingsMin(CPAP_Pressure,MT_CPAP,cpapweek,lastcpap),0,'f',3)
-                .arg(p_profile->calcSettingsMin(CPAP_Pressure,MT_CPAP,cpapmonth,lastcpap),0,'f',3)
-                .arg(p_profile->calcSettingsMin(CPAP_Pressure,MT_CPAP,cpap6month,lastcpap),0,'f',3)
-                .arg(p_profile->calcSettingsMin(CPAP_Pressure,MT_CPAP,cpapyear,lastcpap),0,'f',3);
+                .arg(p_profile->calcSettingsMin(CPAP_Pressure,MT_CPAP),0,'f',decimals)
+                .arg(p_profile->calcSettingsMin(CPAP_Pressure,MT_CPAP,cpapweek,lastcpap),0,'f',decimals)
+                .arg(p_profile->calcSettingsMin(CPAP_Pressure,MT_CPAP,cpapmonth,lastcpap),0,'f',decimals)
+                .arg(p_profile->calcSettingsMin(CPAP_Pressure,MT_CPAP,cpap6month,lastcpap),0,'f',decimals)
+                .arg(p_profile->calcSettingsMin(CPAP_Pressure,MT_CPAP,cpapyear,lastcpap),0,'f',decimals);
             }
             //html+="<tr><td colspan=6>TODO: 90% pressure.. Any point showing if this is all CPAP?</td></tr>";
 
@@ -702,18 +709,18 @@ void MainWindow::on_summaryButton_clicked()
 
             html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
             .arg(tr("Average %1").arg(schema::channel[leak].label()))
-            .arg(p_profile->calcWavg(leak,MT_CPAP),0,'f',3)
-            .arg(p_profile->calcWavg(leak,MT_CPAP,cpapweek,lastcpap),0,'f',3)
-            .arg(p_profile->calcWavg(leak,MT_CPAP,cpapmonth,lastcpap),0,'f',3)
-            .arg(p_profile->calcWavg(leak,MT_CPAP,cpap6month,lastcpap),0,'f',3)
-            .arg(p_profile->calcWavg(leak,MT_CPAP,cpapyear,lastcpap),0,'f',3);
+            .arg(p_profile->calcWavg(leak,MT_CPAP),0,'f',decimals)
+            .arg(p_profile->calcWavg(leak,MT_CPAP,cpapweek,lastcpap),0,'f',decimals)
+            .arg(p_profile->calcWavg(leak,MT_CPAP,cpapmonth,lastcpap),0,'f',decimals)
+            .arg(p_profile->calcWavg(leak,MT_CPAP,cpap6month,lastcpap),0,'f',decimals)
+            .arg(p_profile->calcWavg(leak,MT_CPAP,cpapyear,lastcpap),0,'f',decimals);
             html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
             .arg(tr("%1% %2").arg(percentile*100.0f,0,'f',0).arg(schema::channel[leak].label()))
-            .arg(p_profile->calcPercentile(leak,percentile,MT_CPAP),0,'f',3)
-            .arg(p_profile->calcPercentile(leak,percentile,MT_CPAP,cpapweek,lastcpap),0,'f',3)
-            .arg(p_profile->calcPercentile(leak,percentile,MT_CPAP,cpapmonth,lastcpap),0,'f',3)
-            .arg(p_profile->calcPercentile(leak,percentile,MT_CPAP,cpap6month,lastcpap),0,'f',3)
-            .arg(p_profile->calcPercentile(leak,percentile,MT_CPAP,cpapyear,lastcpap),0,'f',3);
+            .arg(p_profile->calcPercentile(leak,percentile,MT_CPAP),0,'f',decimals)
+            .arg(p_profile->calcPercentile(leak,percentile,MT_CPAP,cpapweek,lastcpap),0,'f',decimals)
+            .arg(p_profile->calcPercentile(leak,percentile,MT_CPAP,cpapmonth,lastcpap),0,'f',decimals)
+            .arg(p_profile->calcPercentile(leak,percentile,MT_CPAP,cpap6month,lastcpap),0,'f',decimals)
+            .arg(p_profile->calcPercentile(leak,percentile,MT_CPAP,cpapyear,lastcpap),0,'f',decimals);
         }
     }
     int oxisize=oximeters.size();
@@ -741,60 +748,60 @@ void MainWindow::on_summaryButton_clicked()
             if (oxiyear<firstoxi) oxiyear=firstoxi;
             html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
                 .arg(tr("Average SpO2"))
-                .arg(p_profile->calcWavg(OXI_SPO2,MT_OXIMETER),0,'f',3)
-                .arg(p_profile->calcWavg(OXI_SPO2,MT_OXIMETER,oxiweek,lastoxi),0,'f',3)
-                .arg(p_profile->calcWavg(OXI_SPO2,MT_OXIMETER,oximonth,lastoxi),0,'f',3)
-                .arg(p_profile->calcWavg(OXI_SPO2,MT_OXIMETER,oxi6month,lastoxi),0,'f',3)
-                .arg(p_profile->calcWavg(OXI_SPO2,MT_OXIMETER,oxiyear,lastoxi),0,'f',3);
+                .arg(p_profile->calcWavg(OXI_SPO2,MT_OXIMETER),0,'f',decimals)
+                .arg(p_profile->calcWavg(OXI_SPO2,MT_OXIMETER,oxiweek,lastoxi),0,'f',decimals)
+                .arg(p_profile->calcWavg(OXI_SPO2,MT_OXIMETER,oximonth,lastoxi),0,'f',decimals)
+                .arg(p_profile->calcWavg(OXI_SPO2,MT_OXIMETER,oxi6month,lastoxi),0,'f',decimals)
+                .arg(p_profile->calcWavg(OXI_SPO2,MT_OXIMETER,oxiyear,lastoxi),0,'f',decimals);
             html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
                 .arg(tr("Minimum SpO2"))
-                .arg(p_profile->calcMin(OXI_SPO2,MT_OXIMETER),0,'f',3)
-                .arg(p_profile->calcMin(OXI_SPO2,MT_OXIMETER,oxiweek,lastoxi),0,'f',3)
-                .arg(p_profile->calcMin(OXI_SPO2,MT_OXIMETER,oximonth,lastoxi),0,'f',3)
-                .arg(p_profile->calcMin(OXI_SPO2,MT_OXIMETER,oxi6month,lastoxi),0,'f',3)
-                .arg(p_profile->calcMin(OXI_SPO2,MT_OXIMETER,oxiyear,lastoxi),0,'f',3);
+                .arg(p_profile->calcMin(OXI_SPO2,MT_OXIMETER),0,'f',decimals)
+                .arg(p_profile->calcMin(OXI_SPO2,MT_OXIMETER,oxiweek,lastoxi),0,'f',decimals)
+                .arg(p_profile->calcMin(OXI_SPO2,MT_OXIMETER,oximonth,lastoxi),0,'f',decimals)
+                .arg(p_profile->calcMin(OXI_SPO2,MT_OXIMETER,oxi6month,lastoxi),0,'f',decimals)
+                .arg(p_profile->calcMin(OXI_SPO2,MT_OXIMETER,oxiyear,lastoxi),0,'f',decimals);
             html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
                 .arg(tr("SpO2 Events / Hour"))
-                .arg(p_profile->calcCount(OXI_SPO2Drop,MT_OXIMETER)/p_profile->calcHours(MT_OXIMETER),0,'f',3)
-                .arg(p_profile->calcCount(OXI_SPO2Drop,MT_OXIMETER,oxiweek,lastoxi)/p_profile->calcHours(MT_OXIMETER,oxiweek,lastoxi),0,'f',3)
-                .arg(p_profile->calcCount(OXI_SPO2Drop,MT_OXIMETER,oximonth,lastoxi)/p_profile->calcHours(MT_OXIMETER,oximonth,lastoxi),0,'f',3)
-                .arg(p_profile->calcCount(OXI_SPO2Drop,MT_OXIMETER,oxi6month,lastoxi)/p_profile->calcHours(MT_OXIMETER,oxi6month,lastoxi),0,'f',3)
-                .arg(p_profile->calcCount(OXI_SPO2Drop,MT_OXIMETER,oxiyear,lastoxi)/p_profile->calcHours(MT_OXIMETER,oxiyear,lastoxi),0,'f',3);
+                .arg(p_profile->calcCount(OXI_SPO2Drop,MT_OXIMETER)/p_profile->calcHours(MT_OXIMETER),0,'f',decimals)
+                .arg(p_profile->calcCount(OXI_SPO2Drop,MT_OXIMETER,oxiweek,lastoxi)/p_profile->calcHours(MT_OXIMETER,oxiweek,lastoxi),0,'f',decimals)
+                .arg(p_profile->calcCount(OXI_SPO2Drop,MT_OXIMETER,oximonth,lastoxi)/p_profile->calcHours(MT_OXIMETER,oximonth,lastoxi),0,'f',decimals)
+                .arg(p_profile->calcCount(OXI_SPO2Drop,MT_OXIMETER,oxi6month,lastoxi)/p_profile->calcHours(MT_OXIMETER,oxi6month,lastoxi),0,'f',decimals)
+                .arg(p_profile->calcCount(OXI_SPO2Drop,MT_OXIMETER,oxiyear,lastoxi)/p_profile->calcHours(MT_OXIMETER,oxiyear,lastoxi),0,'f',decimals);
             html+=QString("<tr><td>%1</td><td>%2\%</td><td>%3\%</td><td>%4\%</td><td>%5\%</td><td>%6\%</td></tr>")
                 .arg(tr("% of time in SpO2 Events"))
-                .arg(100.0/p_profile->calcHours(MT_OXIMETER)*p_profile->calcSum(OXI_SPO2Drop,MT_OXIMETER)/3600.0,0,'f',3)
-                .arg(100.0/p_profile->calcHours(MT_OXIMETER,oxiweek,lastoxi)*p_profile->calcSum(OXI_SPO2Drop,MT_OXIMETER,oxiweek,lastoxi)/3600.0,0,'f',3)
-                .arg(100.0/p_profile->calcHours(MT_OXIMETER,oximonth,lastoxi)*p_profile->calcSum(OXI_SPO2Drop,MT_OXIMETER,oximonth,lastoxi)/3600.0,0,'f',3)
-                .arg(100.0/p_profile->calcHours(MT_OXIMETER,oxi6month,lastoxi)*p_profile->calcSum(OXI_SPO2Drop,MT_OXIMETER,oxi6month,lastoxi)/3600.0,0,'f',3)
-                .arg(100.0/p_profile->calcHours(MT_OXIMETER,oxiyear,lastoxi)*p_profile->calcSum(OXI_SPO2Drop,MT_OXIMETER,oxiyear,lastoxi)/3600.0,0,'f',3);
+                .arg(100.0/p_profile->calcHours(MT_OXIMETER)*p_profile->calcSum(OXI_SPO2Drop,MT_OXIMETER)/3600.0,0,'f',decimals)
+                .arg(100.0/p_profile->calcHours(MT_OXIMETER,oxiweek,lastoxi)*p_profile->calcSum(OXI_SPO2Drop,MT_OXIMETER,oxiweek,lastoxi)/3600.0,0,'f',decimals)
+                .arg(100.0/p_profile->calcHours(MT_OXIMETER,oximonth,lastoxi)*p_profile->calcSum(OXI_SPO2Drop,MT_OXIMETER,oximonth,lastoxi)/3600.0,0,'f',decimals)
+                .arg(100.0/p_profile->calcHours(MT_OXIMETER,oxi6month,lastoxi)*p_profile->calcSum(OXI_SPO2Drop,MT_OXIMETER,oxi6month,lastoxi)/3600.0,0,'f',decimals)
+                .arg(100.0/p_profile->calcHours(MT_OXIMETER,oxiyear,lastoxi)*p_profile->calcSum(OXI_SPO2Drop,MT_OXIMETER,oxiyear,lastoxi)/3600.0,0,'f',decimals);
             html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
                 .arg(tr("Average Pulse Rate"))
-                .arg(p_profile->calcWavg(OXI_Pulse,MT_OXIMETER),0,'f',3)
-                .arg(p_profile->calcWavg(OXI_Pulse,MT_OXIMETER,oxiweek,lastoxi),0,'f',3)
-                .arg(p_profile->calcWavg(OXI_Pulse,MT_OXIMETER,oximonth,lastoxi),0,'f',3)
-                .arg(p_profile->calcWavg(OXI_Pulse,MT_OXIMETER,oxi6month,lastoxi),0,'f',3)
-                .arg(p_profile->calcWavg(OXI_Pulse,MT_OXIMETER,oxiyear,lastoxi),0,'f',3);
+                .arg(p_profile->calcWavg(OXI_Pulse,MT_OXIMETER),0,'f',decimals)
+                .arg(p_profile->calcWavg(OXI_Pulse,MT_OXIMETER,oxiweek,lastoxi),0,'f',decimals)
+                .arg(p_profile->calcWavg(OXI_Pulse,MT_OXIMETER,oximonth,lastoxi),0,'f',decimals)
+                .arg(p_profile->calcWavg(OXI_Pulse,MT_OXIMETER,oxi6month,lastoxi),0,'f',decimals)
+                .arg(p_profile->calcWavg(OXI_Pulse,MT_OXIMETER,oxiyear,lastoxi),0,'f',decimals);
             html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
                 .arg(tr("Minimum Pulse Rate"))
-                .arg(p_profile->calcMin(OXI_Pulse,MT_OXIMETER),0,'f',3)
-                .arg(p_profile->calcMin(OXI_Pulse,MT_OXIMETER,oxiweek,lastoxi),0,'f',3)
-                .arg(p_profile->calcMin(OXI_Pulse,MT_OXIMETER,oximonth,lastoxi),0,'f',3)
-                .arg(p_profile->calcMin(OXI_Pulse,MT_OXIMETER,oxi6month,lastoxi),0,'f',3)
-                .arg(p_profile->calcMin(OXI_Pulse,MT_OXIMETER,oxiyear,lastoxi),0,'f',3);
+                .arg(p_profile->calcMin(OXI_Pulse,MT_OXIMETER),0,'f',decimals)
+                .arg(p_profile->calcMin(OXI_Pulse,MT_OXIMETER,oxiweek,lastoxi),0,'f',decimals)
+                .arg(p_profile->calcMin(OXI_Pulse,MT_OXIMETER,oximonth,lastoxi),0,'f',decimals)
+                .arg(p_profile->calcMin(OXI_Pulse,MT_OXIMETER,oxi6month,lastoxi),0,'f',decimals)
+                .arg(p_profile->calcMin(OXI_Pulse,MT_OXIMETER,oxiyear,lastoxi),0,'f',decimals);
             html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
                 .arg(tr("Maximum Pulse Rate"))
-                .arg(p_profile->calcMax(OXI_Pulse,MT_OXIMETER),0,'f',3)
-                .arg(p_profile->calcMax(OXI_Pulse,MT_OXIMETER,oxiweek,lastoxi),0,'f',3)
-                .arg(p_profile->calcMax(OXI_Pulse,MT_OXIMETER,oximonth,lastoxi),0,'f',3)
-                .arg(p_profile->calcMax(OXI_Pulse,MT_OXIMETER,oxi6month,lastoxi),0,'f',3)
-                .arg(p_profile->calcMax(OXI_Pulse,MT_OXIMETER,oxiyear,lastoxi),0,'f',3);
+                .arg(p_profile->calcMax(OXI_Pulse,MT_OXIMETER),0,'f',decimals)
+                .arg(p_profile->calcMax(OXI_Pulse,MT_OXIMETER,oxiweek,lastoxi),0,'f',decimals)
+                .arg(p_profile->calcMax(OXI_Pulse,MT_OXIMETER,oximonth,lastoxi),0,'f',decimals)
+                .arg(p_profile->calcMax(OXI_Pulse,MT_OXIMETER,oxi6month,lastoxi),0,'f',decimals)
+                .arg(p_profile->calcMax(OXI_Pulse,MT_OXIMETER,oxiyear,lastoxi),0,'f',decimals);
             html+=QString("<tr><td>%1</td><td>%2</td><td>%3</td><td>%4</td><td>%5</td><td>%6</td></tr>")
                 .arg(tr("Pulse Change Events / Hour"))
-                .arg(p_profile->calcCount(OXI_PulseChange,MT_OXIMETER)/p_profile->calcHours(MT_OXIMETER),0,'f',3)
-                .arg(p_profile->calcCount(OXI_PulseChange,MT_OXIMETER,oxiweek,lastoxi)/p_profile->calcHours(MT_OXIMETER,oxiweek,lastoxi),0,'f',3)
-                .arg(p_profile->calcCount(OXI_PulseChange,MT_OXIMETER,oximonth,lastoxi)/p_profile->calcHours(MT_OXIMETER,oximonth,lastoxi),0,'f',3)
-                .arg(p_profile->calcCount(OXI_PulseChange,MT_OXIMETER,oxi6month,lastoxi)/p_profile->calcHours(MT_OXIMETER,oxi6month,lastoxi),0,'f',3)
-                .arg(p_profile->calcCount(OXI_PulseChange,MT_OXIMETER,oxiyear,lastoxi)/p_profile->calcHours(MT_OXIMETER,oxiyear,lastoxi),0,'f',3);
+                .arg(p_profile->calcCount(OXI_PulseChange,MT_OXIMETER)/p_profile->calcHours(MT_OXIMETER),0,'f',decimals)
+                .arg(p_profile->calcCount(OXI_PulseChange,MT_OXIMETER,oxiweek,lastoxi)/p_profile->calcHours(MT_OXIMETER,oxiweek,lastoxi),0,'f',decimals)
+                .arg(p_profile->calcCount(OXI_PulseChange,MT_OXIMETER,oximonth,lastoxi)/p_profile->calcHours(MT_OXIMETER,oximonth,lastoxi),0,'f',decimals)
+                .arg(p_profile->calcCount(OXI_PulseChange,MT_OXIMETER,oxi6month,lastoxi)/p_profile->calcHours(MT_OXIMETER,oxi6month,lastoxi),0,'f',decimals)
+                .arg(p_profile->calcCount(OXI_PulseChange,MT_OXIMETER,oxiyear,lastoxi)/p_profile->calcHours(MT_OXIMETER,oxiyear,lastoxi),0,'f',decimals);
         }
     }
 
@@ -944,10 +951,10 @@ void MainWindow::on_summaryButton_clicked()
             "a:hover { background-color: inherit; color: white; text-decoration:none; font-weight: bold; }"
             "</style></head><body>";
         recbox+="<table width=100% cellpadding=2 cellspacing=0>";
-        recbox+=QString("<tr><td><b><a href='daily=%1'>%2</b></td><td><b>%3</b></td></tr>").arg(bestAHIdate.toString(Qt::ISODate)).arg(tr("Best&nbsp;%1").arg(ahitxt)).arg(bestAHI,0,'f',2);
+        recbox+=QString("<tr><td><b><a href='daily=%1'>%2</b></td><td><b>%3</b></td></tr>").arg(bestAHIdate.toString(Qt::ISODate)).arg(tr("Best&nbsp;%1").arg(ahitxt)).arg(bestAHI,0,'f',decimals);
         recbox+=QString("<tr><td colspan=2>%1</td></tr>").arg(bestAHIdate.toString(Qt::SystemLocaleShortDate));
         recbox+=QString("<tr><td colspan=2>&nbsp;</td></tr>");
-        recbox+=QString("<tr><td><b><a href='daily=%1'>%2</a></b></td><td><b>%3</b></td></tr>").arg(worstAHIdate.toString(Qt::ISODate)).arg(tr("Worst&nbsp;%1").arg(ahitxt)).arg(worstAHI,0,'f',2);
+        recbox+=QString("<tr><td><b><a href='daily=%1'>%2</a></b></td><td><b>%3</b></td></tr>").arg(worstAHIdate.toString(Qt::ISODate)).arg(tr("Worst&nbsp;%1").arg(ahitxt)).arg(worstAHI,0,'f',decimals);
         recbox+=QString("<tr><td colspan=2>%1</td></tr>").arg(worstAHIdate.toString(Qt::SystemLocaleShortDate));
         recbox+=QString("<tr><td colspan=2>&nbsp;</td></tr>");
 
@@ -985,7 +992,7 @@ void MainWindow::on_summaryButton_clicked()
                     .arg(tmpRX[ls]->first.toString(Qt::ISODate))
                     .arg(tmpRX[ls]->last.toString(Qt::ISODate))
                     .arg(tr("Best RX Setting"));
-            recbox+=QString("<tr><td colspan=2>%1: %2</td></tr>").arg(ahitxt).arg(tmpRX[ls]->ahi,0,'f',2);
+            recbox+=QString("<tr><td colspan=2>%1: %2</td></tr>").arg(ahitxt).arg(tmpRX[ls]->ahi,0,'f',decimals);
             recbox+=QString("<tr><td colspan=2>%1: %2</td></tr>").arg(tr("Mode")).arg(modestr);
             recbox+=QString("<tr><td colspan=2>%1: %2").arg(minstr).arg(tmpRX[ls]->min,0,'f',1);
             if (!maxstr.isEmpty()) recbox+=QString(" %1: %2").arg(maxstr).arg(tmpRX[ls]->max,0,'f',1);
@@ -1020,7 +1027,7 @@ void MainWindow::on_summaryButton_clicked()
                     .arg(tmpRX[0]->first.toString(Qt::ISODate))
                     .arg(tmpRX[0]->last.toString(Qt::ISODate))
                     .arg(tr("Worst RX Setting"));
-            recbox+=QString("<tr><td colspan=2>%1: %2</td></tr>").arg(ahitxt).arg(tmpRX[0]->ahi,0,'f',2);
+            recbox+=QString("<tr><td colspan=2>%1: %2</td></tr>").arg(ahitxt).arg(tmpRX[0]->ahi,0,'f',decimals);
             recbox+=QString("<tr><td colspan=2>%1: %2</td></tr>").arg(tr("Mode")).arg(modestr);
             recbox+=QString("<tr><td colspan=2>%1: %2").arg(minstr).arg(tmpRX[0]->min,0,'f',1);
             if (!maxstr.isEmpty()) recbox+=QString(" %1: %2").arg(maxstr).arg(tmpRX[0]->max,0,'f',1);
@@ -1088,30 +1095,30 @@ void MainWindow::on_summaryButton_clicked()
             mode=rx.mode;
             if(mode>=MODE_ASV) {
                 extratxt=QString("<td>%1</td><td>%2</td><td>%3</td><td>%4</td>")
-                        .arg(rx.max,0,'f',2).arg(rx.maxhi,0,'f',2).arg(rx.max-rx.min,0,'f',2).arg(rx.maxhi-rx.min,0,'f',2);
+                        .arg(rx.max,0,'f',decimals).arg(rx.maxhi,0,'f',decimals).arg(rx.max-rx.min,0,'f',decimals).arg(rx.maxhi-rx.min,0,'f',decimals);
 
                 tooltip=tr("%5 %1% EPAP=%2<br/>%3% IPAP=%4")
                         .arg(percentile*100.0)
-                        .arg(rx.per1,0,'f',2)
+                        .arg(rx.per1,0,'f',decimals)
                         .arg(percentile*100.0)
-                        .arg(rx.per2,0,'f',2)
+                        .arg(rx.per2,0,'f',decimals)
                         .arg(machstr)
                         ;
             } else if (mode>=MODE_BIPAP) {
                 extratxt=QString("<td>%1</td><td>%2</td>")
-                       .arg(rx.max,0,'f',2).arg(rx.max-rx.min,0,'f',2);
+                       .arg(rx.max,0,'f',decimals).arg(rx.max-rx.min,0,'f',decimals);
                 tooltip=tr("%5 %1% EPAP=%2<br/>%3% IPAP=%4")
                         .arg(percentile*100.0)
-                        .arg(rx.per1,0,'f',2)
+                        .arg(rx.per1,0,'f',decimals)
                         .arg(percentile*100.0)
-                        .arg(rx.per2,0,'f',2)
+                        .arg(rx.per2,0,'f',decimals)
                         .arg(machstr)
                         ;
             } else if (mode>MODE_CPAP) {
-                extratxt=QString("<td>%1</td>").arg(rx.max,0,'f',2);
+                extratxt=QString("<td>%1</td>").arg(rx.max,0,'f',decimals);
                 tooltip=tr("%3 %1% Pressure=%2")
                         .arg(percentile*100.0)
-                        .arg(rx.per1,0,'f',2)
+                        .arg(rx.per1,0,'f',decimals)
                         .arg(machstr)
                         ;
             } else {
@@ -1139,11 +1146,11 @@ void MainWindow::on_summaryButton_clicked()
                     .arg(rx.first.toString(Qt::SystemLocaleShortDate))
                     .arg(rx.last.toString(Qt::SystemLocaleShortDate))
                     .arg(rx.days)
-                    .arg(rx.ahi,0,'f',2)
+                    .arg(rx.ahi,0,'f',decimals)
                     .arg(rx.machine->GetClass())
                     .arg(schema::channel[CPAP_Mode].option(int(rx.mode)-1))
                     .arg(presrel)
-                    .arg(rx.min,0,'f',2)
+                    .arg(rx.min,0,'f',decimals)
                     .arg(extratxt)
                     .arg(tooltipshow)
                     .arg(tooltiphide);
@@ -1201,8 +1208,16 @@ void MainWindow::updateFavourites()
     if (!date.isValid())
         return;
 
-    ui->favouritesList->blockSignals(true);
-    ui->favouritesList->clear();
+    QString html="<html><head><style type='text/css'>"
+        "p,a,td,body { font-family: '"+QApplication::font().family()+"'; }"
+        "p,a,td,body { font-size: "+QString::number(QApplication::font().pointSize() + 2)+"px; }"
+        "a:link,a:visited { color: inherit; text-decoration: none; }" //font-weight: normal;
+        "a:hover { background-color: inherit; color: white; text-decoration:none; font-weight: bold; }"
+        "</style></head><body>";
+    html+="<table width=100% cellpadding=2 cellspacing=0>";
+
+    //ui->favouritesList->blockSignals(true);
+    //ui->favouritesList->clear();
 
     do {
         Day * journal=PROFILE.GetDay(date,MT_JOURNAL);
@@ -1210,20 +1225,19 @@ void MainWindow::updateFavourites()
             if (journal->size()>0) {
                 Session *sess=(*journal)[0];
                 if (sess->settings.contains(Bookmark_Start)) {
-                    QVariantList start=sess->settings[Bookmark_Start].toList();
-                    QVariantList end=sess->settings[Bookmark_End].toList();
+                    //QVariantList start=sess->settings[Bookmark_Start].toList();
+                    //QVariantList end=sess->settings[Bookmark_End].toList();
                     QStringList notes=sess->settings[Bookmark_Notes].toStringList();
                     if (notes.size()>0) {
-                        QListWidgetItem *item=new QListWidgetItem(date.toString());
-                        /*QString tooltip;
+                        html+=QString("<tr><td><b><a href='daily=%1'>%2</a></b><br/>")
+                                .arg(date.toString(Qt::ISODate))
+                                .arg(date.toString());
+
                         for (int i=0;i<notes.size();i++) {
-                            QDate d=start[i].toDate();
-                            tooltip+=d.toString(Qt::SystemLocaleShortDate)+":"+notes[i];
-                            if (i<notes.size()-1) tooltip+="\n";
+                            //QDate d=start[i].toDate();
+                            html+="&nbsp;"+notes[i]+"<br/>";
                         }
-                        item->setToolTip(tooltip);*/
-                        item->setData(Qt::UserRole,date);
-                        ui->favouritesList->addItem(item);
+                        html+="</td>";
                     }
                 }
             }
@@ -1231,7 +1245,9 @@ void MainWindow::updateFavourites()
 
         date=date.addDays(-1);
     } while (date>=PROFILE.FirstDay(MT_JOURNAL));
-    ui->favouritesList->blockSignals(false);
+    html+="</table></body></html>";
+    ui->bookmarkView->setHtml(html);
+    //ui->favouritesList->blockSignals(false);
 }
 
 void MainWindow::on_backButton_clicked()
@@ -1841,13 +1857,17 @@ void MainWindow::PrintReport(gGraphView *gv,QString name, QDate date)
                         graphs.push_back(g);
                         labels.push_back(tr("Entire Day's Flow Waveform"));
                     }
+                    start.push_back(savest);
+                    end.push_back(saveet);
+                    graphs.push_back(g);
+                    labels.push_back("Current Selection");
+                } else {
+                    start.push_back(savest);
+                    end.push_back(saveet);
+                    graphs.push_back(g);
+                    labels.push_back("");
                 }
 
-                start.push_back(savest);
-                end.push_back(saveet);
-                graphs.push_back(g);
-                labels.push_back("");
-
             }
         } else {
             if (journal) {
@@ -2243,6 +2263,8 @@ void MainWindow::on_actionAll_Data_for_current_CPAP_machine_triggered()
         }
         if (QMessageBox::question(this,tr("Are you sure?"),tr("Are you sure you want to purge all CPAP data for the following machine:\n")+m->properties[STR_PROP_Brand]+" "+m->properties[STR_PROP_Model]+" "+m->properties[STR_PROP_ModelNumber]+" ("+m->properties[STR_PROP_Serial]+")",QMessageBox::Yes,QMessageBox::No)==QMessageBox::Yes) {
             m->Purge(3478216);
+            PROFILE.machlist.erase(PROFILE.machlist.find(m->id()));
+            delete m;
             RestartApplication();
         }
     }
@@ -2308,16 +2330,16 @@ void MainWindow::on_webView_linkClicked(const QUrl &url)
     }
 }
 
-void MainWindow::on_favouritesList_itemSelectionChanged()
-{
-    QListWidgetItem *item=ui->favouritesList->currentItem();
-    if (!item) return;
-    QDate date=item->data(Qt::UserRole).toDate();
-    if (date.isValid()) {
-        daily->LoadDate(date);
-        ui->tabWidget->setCurrentWidget(daily);
-    }
-}
+//void MainWindow::on_favouritesList_itemSelectionChanged()
+//{
+//    QListWidgetItem *item=ui->favouritesList->currentItem();
+//    if (!item) return;
+//    QDate date=item->data(Qt::UserRole).toDate();
+//    if (date.isValid()) {
+//        daily->LoadDate(date);
+//        ui->tabWidget->setCurrentWidget(daily);
+//    }
+//}
 
 /*void MainWindow::on_favouritesList_itemClicked(QListWidgetItem *item)
 {
@@ -2364,6 +2386,11 @@ void MainWindow::on_tabWidget_currentChanged(int index)
 
 void MainWindow::on_summaryView_linkClicked(const QUrl &arg1)
 {
-    qDebug() << arg1;
+    //qDebug() << arg1;
+    on_recordsBox_linkClicked(arg1);
+}
+
+void MainWindow::on_bookmarkView_linkClicked(const QUrl &arg1)
+{
     on_recordsBox_linkClicked(arg1);
 }
diff --git a/mainwindow.h b/mainwindow.h
index afb22b7e..01f9320d 100644
--- a/mainwindow.h
+++ b/mainwindow.h
@@ -265,7 +265,7 @@ private slots:
 
     void on_webView_linkClicked(const QUrl &arg1);
 
-    void on_favouritesList_itemSelectionChanged();
+    //void on_favouritesList_itemSelectionChanged();
 
     //void on_favouritesList_itemClicked(QListWidgetItem *item);
 
@@ -277,6 +277,8 @@ private slots:
 
     void on_summaryView_linkClicked(const QUrl &arg1);
 
+    void on_bookmarkView_linkClicked(const QUrl &arg1);
+
 private:
 
     Ui::MainWindow *ui;
diff --git a/mainwindow.ui b/mainwindow.ui
index 6654f6ae..50496ddc 100644
--- a/mainwindow.ui
+++ b/mainwindow.ui
@@ -286,13 +286,13 @@
       <widget class="QToolBox" name="toolBox">
        <property name="minimumSize">
         <size>
-         <width>160</width>
+         <width>180</width>
          <height>0</height>
         </size>
        </property>
        <property name="maximumSize">
         <size>
-         <width>160</width>
+         <width>180</width>
          <height>16777215</height>
         </size>
        </property>
@@ -405,7 +405,7 @@
         <number>1</number>
        </property>
        <property name="currentIndex">
-        <number>0</number>
+        <number>1</number>
        </property>
        <property name="tabSpacing">
         <number>0</number>
@@ -743,7 +743,7 @@
          <rect>
           <x>0</x>
           <y>0</y>
-          <width>158</width>
+          <width>178</width>
           <height>313</height>
          </rect>
         </property>
@@ -765,7 +765,7 @@
           <number>0</number>
          </property>
          <item>
-          <widget class="QListWidget" name="favouritesList">
+          <widget class="QWebView" name="bookmarkView">
            <property name="palette">
             <palette>
              <active>
@@ -778,15 +778,6 @@
                 </color>
                </brush>
               </colorrole>
-              <colorrole role="AlternateBase">
-               <brush brushstyle="SolidPattern">
-                <color alpha="255">
-                 <red>85</red>
-                 <green>170</green>
-                 <blue>255</blue>
-                </color>
-               </brush>
-              </colorrole>
              </active>
              <inactive>
               <colorrole role="Base">
@@ -798,15 +789,6 @@
                 </color>
                </brush>
               </colorrole>
-              <colorrole role="AlternateBase">
-               <brush brushstyle="SolidPattern">
-                <color alpha="255">
-                 <red>85</red>
-                 <green>170</green>
-                 <blue>255</blue>
-                </color>
-               </brush>
-              </colorrole>
              </inactive>
              <disabled>
               <colorrole role="Base">
@@ -818,40 +800,13 @@
                 </color>
                </brush>
               </colorrole>
-              <colorrole role="AlternateBase">
-               <brush brushstyle="SolidPattern">
-                <color alpha="255">
-                 <red>85</red>
-                 <green>170</green>
-                 <blue>255</blue>
-                </color>
-               </brush>
-              </colorrole>
              </disabled>
             </palette>
            </property>
-           <property name="font">
-            <font>
-             <pointsize>10</pointsize>
-            </font>
-           </property>
-           <property name="mouseTracking">
-            <bool>true</bool>
-           </property>
-           <property name="editTriggers">
-            <set>QAbstractItemView::NoEditTriggers</set>
-           </property>
-           <property name="alternatingRowColors">
-            <bool>true</bool>
-           </property>
-           <property name="selectionMode">
-            <enum>QAbstractItemView::ExtendedSelection</enum>
-           </property>
-           <property name="selectionBehavior">
-            <enum>QAbstractItemView::SelectRows</enum>
-           </property>
-           <property name="selectionRectVisible">
-            <bool>false</bool>
+           <property name="url">
+            <url>
+             <string>about:blank</string>
+            </url>
            </property>
           </widget>
          </item>
@@ -862,8 +817,8 @@
          <rect>
           <x>0</x>
           <y>0</y>
-          <width>98</width>
-          <height>28</height>
+          <width>158</width>
+          <height>313</height>
          </rect>
         </property>
         <property name="mouseTracking">
diff --git a/overview.cpp b/overview.cpp
index 84721fda..f05e4e9c 100644
--- a/overview.cpp
+++ b/overview.cpp
@@ -564,7 +564,7 @@ void Overview::updateCube()
 
         if (ui->graphCombo->count()>0) {
             GraphView->setEmptyText(tr("No Graphs On!"));
-            GraphView->setCubeImage(images["sheep"]);
+            GraphView->setCubeImage(images["nographs"]);
 
         } else {
             GraphView->setEmptyText("No Data");
diff --git a/preferencesdialog.cpp b/preferencesdialog.cpp
index 0158437d..ff13db5c 100644
--- a/preferencesdialog.cpp
+++ b/preferencesdialog.cpp
@@ -43,8 +43,8 @@ PreferencesDialog::PreferencesDialog(QWidget *parent,Profile * _profile) :
     ui->leakProfile->setColumnWidth(0,100);
     ui->maskTypeCombo->clear();
 
-    ui->ahiGraphGroupbox->setEnabled(false);
-    ui->customEventGroupbox->setEnabled(false);
+    //ui->ahiGraphGroupbox->setEnabled(false);
+    //ui->customEventGroupbox->setEnabled(false);
 
     QString masktype=tr("Nasal Pillows");
     //masktype=PROFILEMaskType
@@ -194,6 +194,13 @@ PreferencesDialog::PreferencesDialog(QWidget *parent,Profile * _profile) :
     if (ot<0) ot=0;
     ui->oximetryType->setCurrentIndex(ot);
 
+    ui->ahiGraphWindowSize->setValue(profile->cpap->AHIWindow());
+    ui->ahiGraphZeroReset->setChecked(profile->cpap->AHIReset());
+
+    ui->customEventGroupbox->setChecked(profile->cpap->userEventFlagging());
+    ui->apneaDuration->setValue(profile->cpap->userEventDuration());
+    ui->apneaFlowRestriction->setValue(profile->cpap->userFlowRestriction());
+
     ui->eventTable->setColumnWidth(0,40);
     ui->eventTable->setColumnWidth(1,55);
     ui->eventTable->setColumnHidden(3,true);
@@ -338,6 +345,17 @@ void PreferencesDialog::Save()
     profile->oxi->setPulseChangeDuration(ui->pulseChangeTime->value());
     profile->oxi->setOxiDiscardThreshold(ui->oxiDiscardThreshold->value());
 
+    profile->cpap->setAHIWindow(ui->ahiGraphWindowSize->value());
+    profile->cpap->setAHIReset(ui->ahiGraphZeroReset->isChecked());
+
+    // Restart if turning user event flagging on/off
+    if (profile->cpap->userEventFlagging()!=ui->customEventGroupbox->isChecked())
+        needs_restart=true;
+
+    profile->cpap->setUserEventFlagging(ui->customEventGroupbox->isChecked());
+    profile->cpap->setUserEventDuration(ui->apneaDuration->value());
+    profile->cpap->setUserFlowRestriction(ui->apneaFlowRestriction->value());
+
     PREF[STR_GEN_SkipLogin]=ui->skipLoginScreen->isChecked();
 
     PREF[STR_GEN_UpdatesAutoCheck]=ui->automaticallyCheckUpdates->isChecked();
diff --git a/preferencesdialog.ui b/preferencesdialog.ui
index da9c3124..9799331b 100644
--- a/preferencesdialog.ui
+++ b/preferencesdialog.ui
@@ -42,7 +42,7 @@
    <item>
     <widget class="QTabWidget" name="tabWidget">
      <property name="currentIndex">
-      <number>0</number>
+      <number>5</number>
      </property>
      <widget class="QWidget" name="importTab">
       <attribute name="title">
@@ -310,7 +310,7 @@ p, li { white-space: pre-wrap; }
           <item row="1" column="0">
            <widget class="QCheckBox" name="createSDBackups">
             <property name="text">
-             <string>Create SD Card Backups during Import (especially important for ResMed users)</string>
+             <string>Create SD Card Backups during Import (only works with ResMed for now)</string>
             </property>
            </widget>
           </item>
@@ -507,24 +507,7 @@ p, li { white-space: pre-wrap; }
             </property>
            </widget>
           </item>
-          <item row="5" column="0" colspan="3">
-           <widget class="QLabel" name="label_31">
-            <property name="font">
-             <font>
-              <italic>true</italic>
-             </font>
-            </property>
-            <property name="text">
-             <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
-&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
-p, li { white-space: pre-wrap; }
-&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans'; font-size:10pt; font-weight:400; font-style:italic;&quot;&gt;
-&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600; font-style:normal;&quot;&gt;Note: &lt;/span&gt;Before the following date, all leaks &lt;/p&gt;
-&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;will show as reported by the machine.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
-            </property>
-           </widget>
-          </item>
-          <item row="10" column="0">
+          <item row="11" column="0">
            <widget class="QLabel" name="label_28">
             <property name="font">
              <font>
@@ -537,7 +520,7 @@ p, li { white-space: pre-wrap; }
             </property>
            </widget>
           </item>
-          <item row="11" column="0" colspan="3">
+          <item row="12" column="0" colspan="3">
            <widget class="QTableWidget" name="leakProfile">
             <property name="alternatingRowColors">
              <bool>true</bool>
@@ -557,6 +540,22 @@ p, li { white-space: pre-wrap; }
             </column>
            </widget>
           </item>
+          <item row="10" column="0" colspan="3">
+           <widget class="QLabel" name="label_31">
+            <property name="font">
+             <font>
+              <italic>true</italic>
+             </font>
+            </property>
+            <property name="text">
+             <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans'; font-size:10pt; font-weight:400; font-style:italic;&quot;&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600; font-style:normal;&quot;&gt;Note: &lt;/span&gt;Leak profiles currently does not work yet..&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+            </property>
+           </widget>
+          </item>
          </layout>
         </widget>
        </item>
@@ -651,20 +650,19 @@ p, li { white-space: pre-wrap; }
          <item>
           <widget class="QGroupBox" name="customEventGroupbox">
            <property name="title">
-            <string>Custom Event Flagging</string>
+            <string>Custom PRS1 Event Flagging</string>
            </property>
            <property name="checkable">
             <bool>true</bool>
            </property>
            <layout class="QGridLayout" name="gridLayout_6">
-            <item row="0" column="1">
-             <widget class="QLabel" name="label_38">
-              <property name="text">
-               <string>Duration</string>
-              </property>
-             </widget>
-            </item>
-            <item row="0" column="2">
+            <property name="margin">
+             <number>4</number>
+            </property>
+            <property name="spacing">
+             <number>4</number>
+            </property>
+            <item row="1" column="1">
              <widget class="QLabel" name="label_35">
               <property name="sizePolicy">
                <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
@@ -677,34 +675,14 @@ p, li { white-space: pre-wrap; }
               </property>
              </widget>
             </item>
-            <item row="1" column="0">
-             <widget class="QLabel" name="label_34">
+            <item row="2" column="1">
+             <widget class="QDoubleSpinBox" name="apneaFlowRestriction">
               <property name="sizePolicy">
-               <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+               <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
                 <horstretch>0</horstretch>
                 <verstretch>0</verstretch>
                </sizepolicy>
               </property>
-              <property name="text">
-               <string>Apnea</string>
-              </property>
-             </widget>
-            </item>
-            <item row="1" column="1">
-             <widget class="QDoubleSpinBox" name="apneaDuration">
-              <property name="suffix">
-               <string>s</string>
-              </property>
-              <property name="minimum">
-               <double>1.000000000000000</double>
-              </property>
-              <property name="value">
-               <double>10.000000000000000</double>
-              </property>
-             </widget>
-            </item>
-            <item row="1" column="2">
-             <widget class="QDoubleSpinBox" name="apneaFlowRestriction">
               <property name="suffix">
                <string>%</string>
               </property>
@@ -713,7 +691,7 @@ p, li { white-space: pre-wrap; }
               </property>
              </widget>
             </item>
-            <item row="1" column="3">
+            <item row="2" column="4">
              <spacer name="horizontalSpacer_4">
               <property name="orientation">
                <enum>Qt::Horizontal</enum>
@@ -726,30 +704,44 @@ p, li { white-space: pre-wrap; }
               </property>
              </spacer>
             </item>
-            <item row="2" column="0">
-             <widget class="QLabel" name="label_37">
+            <item row="0" column="0" colspan="5">
+             <widget class="QLabel" name="label_34">
+              <property name="font">
+               <font>
+                <italic>true</italic>
+               </font>
+              </property>
               <property name="text">
-               <string>Hypopnea</string>
+               <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans'; font-size:10pt; font-weight:400; font-style:italic;&quot;&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Custom flagging is an experimental method of detecting events missed by the machine.&lt;/p&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;** This only affects &lt;span style=&quot; text-decoration: underline;&quot;&gt;future&lt;/span&gt; imports **&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+              </property>
+              <property name="wordWrap">
+               <bool>true</bool>
               </property>
              </widget>
             </item>
-            <item row="2" column="1">
-             <widget class="QDoubleSpinBox" name="hypopneaDuration">
+            <item row="2" column="3">
+             <widget class="QDoubleSpinBox" name="apneaDuration">
               <property name="suffix">
                <string>s</string>
               </property>
+              <property name="minimum">
+               <double>1.000000000000000</double>
+              </property>
               <property name="value">
                <double>10.000000000000000</double>
               </property>
              </widget>
             </item>
-            <item row="2" column="2">
-             <widget class="QDoubleSpinBox" name="hypopneaFlowRestriction">
-              <property name="suffix">
-               <string>%</string>
-              </property>
-              <property name="value">
-               <double>40.000000000000000</double>
+            <item row="1" column="3">
+             <widget class="QLabel" name="label_38">
+              <property name="text">
+               <string>Event Duration</string>
               </property>
              </widget>
             </item>
@@ -765,6 +757,12 @@ p, li { white-space: pre-wrap; }
             <bool>true</bool>
            </property>
            <layout class="QGridLayout" name="gridLayout_8">
+            <property name="horizontalSpacing">
+             <number>4</number>
+            </property>
+            <property name="margin">
+             <number>4</number>
+            </property>
             <item row="0" column="0">
              <widget class="QLabel" name="label_36">
               <property name="sizePolicy">