[med-svn] [Git][med-team/edfbrowser][upstream] New upstream version 2.12+dfsg

Étienne Mollier (@emollier) gitlab at salsa.debian.org
Wed Oct 9 19:38:37 BST 2024



Étienne Mollier pushed to branch upstream at Debian Med / edfbrowser


Commits:
06f42aed by Étienne Mollier at 2024-10-09T20:30:29+02:00
New upstream version 2.12+dfsg
- - - - -


30 changed files:

- amplitude_dialog.cpp
- cnvs/edfplusd_cnv.cpp
- cnvs/ishne2edf.cpp
- doc/manual.html
- doc/montage_file_format.txt
- edf_annot_list.c
- edfbrowser.pro
- edit_annotation_dock.cpp
- global.h
- load_montage_dialog.cpp
- load_session.cpp
- mainwindow.cpp
- mainwindow_constr.cpp
- options_dialog.cpp
- rc_host.cpp
- save_montage_dialog.cpp
- save_session.cpp
- show_actual_montage_dialog.cpp
- show_edf_hdr.cpp
- signal_chooser.cpp
- signals_dialog.cpp
- utils.h
- vc_painter.cpp
- vc_signal_props.cpp
- version.txt
- view_montage_dialog.cpp
- view_session_dialog.cpp
- viewcurve.cpp
- viewcurve.h
- z_score_dialog.cpp


Changes:

=====================================
amplitude_dialog.cpp
=====================================
@@ -123,7 +123,9 @@ void UI_Userdefined_amplitude_Dialog::okbutton_pressed()
 
     mainwindow->signalcomp[i]->voltpercm = value2;
 
-    mainwindow->signalcomp[i]->screen_offset *= (original_value / value2);
+    mainwindow->signalcomp[i]->screen_offset_pix *= (original_value / value2);
+
+    mainwindow->signalcomp[i]->screen_offset_unit *= (original_value / value2);
   }
 
   mainwindow->maincurve->drawCurve_stage_1();


=====================================
cnvs/edfplusd_cnv.cpp
=====================================
@@ -253,11 +253,11 @@ void UI_EDFDwindow::SelectFileButton()
   remove_extension_from_filename(output_path);
   if(edfhdr->edfplus)
   {
-    snprintf(output_path + strlen(output_path), MAX_PATH_LENGTH, "_%04i.edf", file_number);
+    snprintf(output_path + strlen(output_path), MAX_PATH_LENGTH - strlen(output_path), "_%04i.edf", file_number);
   }
   else
   {
-    snprintf(output_path + strlen(output_path), MAX_PATH_LENGTH, "_%04i.bdf", file_number);
+    snprintf(output_path + strlen(output_path), MAX_PATH_LENGTH - strlen(output_path), "_%04i.bdf", file_number);
   }
 
   strlcpy(str1_2048, "Creating file ", 2048);


=====================================
cnvs/ishne2edf.cpp
=====================================
@@ -29,8 +29,43 @@
 #include "ishne2edf.h"
 
 
+/*
+ *                      |--------- CRC Domain (header) ----------|
+ * +--------------+-----+------------------+---------------------+----------+
+ * | Magic Number | CRC | fixed-size block | variable-size block | ECG-data |
+ * +--------------+-----+------------------+---------------------+----------+
+ * |      8       |  2  |       512        |         var         |    var   |
+ * +--------------+-----+------------------+---------------------+----------+
+ */
+
 #define ISHNE_MAX_CHNS   (12)
 
+#define MAGICNUMBER_HDROFF        (0)  /* string "ISHNE1.0"  8 bytes */
+#define CRC_HDROFF                (8)  /* CRC-CCITT checksum 2 bytes */
+#define VARLENBLCKSZ_HDROFF      (10)  /* Size (in bytes) of variable length block, integer, 4 bytes */
+#define ECGSMPLSZ_HDROFF         (14)  /* Size (in samples) of ECG, integer, 4 bytes */
+#define VARLENBLCKSTART_HDROFF   (18)  /* Offset of variable length block (in bytes from beginning of file, i.e. 8 + 2 + 512 = 522), integer, 4 bytes */
+#define ECGSMPLBLCKSTART_HDROFF  (22)  /* Offset of ECG block (in bytes from beginning of file), integer, 4 bytes */
+#define FILEVER_HDROFF           (26)  /* Version of the file, short int, 2 bytes */
+#define SUBJ1STNAME_HDROFF       (28)  /* Subject First Name, char[40], 40 bytes */
+#define SUBJLASTNAME_HDROFF      (68)  /* Subject Last Name, char[40], 40 bytes */
+#define SUBJID_HDROFF           (108)  /* Subject ID, char[20], 20 bytes */
+#define SUBJSEX_HDROFF          (128)  /* Subject Sex (0: unknown, 1: male, 2: female), short int, 2 bytes */
+#define SUBJRACE_HDROFF         (130)  /* Subject Race (0: unknown, 1: Caucasian, 2 Black, 3 Oriental, 4-9 Reserved), short int, 2 bytes */
+#define SUBJBIRTHDATE_HDROFF    (132)  /* Date of Birth (European: day, month, year), 3 short int, 6 bytes */
+#define STARTDATE_HDROFF        (138)  /* Date of recording (European), 3 short int, 6 bytes */
+#define CREATEDATE_HDROFF       (144)  /* Date of creation of output file (European), 3 short int, 6 bytes */
+#define STARTTIME_HDROFF        (150)  /* Start time (European: hour [0-23], min, sec), 3 short int, 6 bytes */
+#define NUMLEADS_HDROFF         (156)  /* Number of stored leads, short int, 2 bytes */
+#define LEADSPEC_HDROFF         (158)  /* Lead specification (see included Table), 12 short int, 24 bytes */
+#define LEADQUAL_HDROFF         (182)  /* Lead quality (see included Table), 12 short int, 24 bytes */
+#define AMPRES_HDROFF           (206)  /* Amplitude resolution in integer no. of nV, 12 short int, 24 bytes */
+#define PACEMAKCODE_HDROFF      (230)  /* Pacemaker code (see text for description), short int, 2 bytes */
+#define RECORDERTYPE_HDROFF     (232)  /* Type of recorder (either analog or digital), char[40], 40 bytes */
+#define SMPLRATE_HDROFF         (272)  /* Sampling rate (in hertz), short int, 2 bytes */
+#define PROPECG_HDROFF          (274)  /* Proprietary of ECG (if any), char[80], 80 bytes */
+#define COPYRIGHT_HDROFF        (354)  /* Copyright and restriction of diffusion (if any), char[80], 80 bytes */
+#define RESERV_HDROFF           (434)  /* Reserved, char[88], 88 bytes */
 
 
 UI_IshneEDFwindow::UI_IshneEDFwindow(QWidget *w_parent, char *recent_dir, char *save_dir)
@@ -92,6 +127,7 @@ int i, j,
     lead_spec[ISHNE_MAX_CHNS],
     amp_resolution[ISHNE_MAX_CHNS],
     sex,
+    pacemaker,
     edf_hdl=-99,
     birthdate_valid=0,
     total_blocks=0,
@@ -105,7 +141,7 @@ int i, j,
         *outbuf=NULL;
 
   char path[MAX_PATH_LENGTH]={""},
-       hdr[4096]={""},
+       hdr_4096[4096]={""},
        scratchpad_4096[4096]={""},
        str1_128[128]={""},
        rbuf[4]={0,0,0,0},
@@ -114,7 +150,11 @@ int i, j,
   const char *lead_label[20]={"Unknown","Generic bipolar","X bipolar","Y bipolar","Z bipolar","I","II","III","aVR","aVL",
                               "aVF","V1","V2","V3","V4","V5","V6","ES","AS","AI"};
 
-  FILE *inputfile=NULL;
+  const char *pacemaker_list[]={"No pacemaker","Pacemaker type not known","Single chamber unipolar",
+                                "Dual chamber unipolar","Single chamber bipolar","Dual chamber bipolar",""};
+
+  FILE *inputfile=NULL,
+       *annotfile=NULL;
 
   QProgressDialog progress("Converting ECG data ...", "Abort", 0, 0, myobjectDialog);
                   progress.reset();
@@ -159,6 +199,11 @@ struct
   snprintf(scratchpad_4096, 4096, "Processing ecg file:\n%s", path);
   textEdit1->append(QString::fromLocal8Bit(scratchpad_4096));
 
+  remove_extension_from_filename(path);
+  strlcat(path, ".ann", MAX_PATH_LENGTH);
+
+  annotfile = fopen(path, "rb");
+
   fseek(inputfile, 0, SEEK_END);
 
   file_sz = ftell(inputfile);
@@ -171,42 +216,42 @@ struct
 
   rewind(inputfile);
 
-  if(fread(hdr, 522, 1, inputfile) != 1)
+  if(fread(hdr_4096, 522, 1, inputfile) != 1)
   {
     textEdit1->append("A read error occurred when trying to read the header.");
     goto OUT_EXIT;
   }
 
-  if(strncmp(hdr, "ISHNE1.0", 8))
+////////////////////////////////// GET THE HEADER DATA ////////////////////////
+
+  if(strncmp(hdr_4096 + MAGICNUMBER_HDROFF, "ISHNE1.0", 8))
   {
     textEdit1->append("Error, wrong magic string in header.");
     goto OUT_EXIT;
   }
 
-////////////////////////////////// GET THE HEADER DATA ////////////////////////
-
-  var_block_sz = *((int *)(hdr + 10));
+  var_block_sz = *((int *)(hdr_4096 + VARLENBLCKSZ_HDROFF));
   if(var_block_sz < 0)
   {
     textEdit1->append("Error, parameter size of variable length block in header is lower than zero.");
     goto OUT_EXIT;
   }
 
-  ecg_smpl_sz = *((int *)(hdr + 14));
+  ecg_smpl_sz = *((int *)(hdr_4096 + ECGSMPLSZ_HDROFF));
   if(ecg_smpl_sz < 0)
   {
     textEdit1->append("Error, parameter ECG sample size in header is lower than zero.");
     goto OUT_EXIT;
   }
 
-  var_block_offset = *((int *)(hdr + 18));
+  var_block_offset = *((int *)(hdr_4096 + VARLENBLCKSTART_HDROFF));
   if(var_block_offset != 522)
   {
     textEdit1->append("Error, parameter offset of variable length block in header differs from 522");
     goto OUT_EXIT;
   }
 
-  ecg_block_offset = *((int *)(hdr + 22));
+  ecg_block_offset = *((int *)(hdr_4096 + ECGSMPLBLCKSTART_HDROFF));
   if(ecg_block_offset != (var_block_sz + 522))
   {
     textEdit1->append("Error, parameter offset of ECG block in header differs from 522 + variable length block");
@@ -219,7 +264,7 @@ struct
     goto OUT_EXIT;
   }
 
-  chns = *((short *)(hdr + 156));
+  chns = *((short *)(hdr_4096 + NUMLEADS_HDROFF));
   if(chns < 1)
   {
     textEdit1->append("Error, number of leads is less than 1.");
@@ -232,18 +277,23 @@ struct
     goto OUT_EXIT;
   }
 
-  sf = *((short *)(hdr + 272));
+  sf = *((short *)(hdr_4096 + SMPLRATE_HDROFF));
   if(sf < 1)
   {
     textEdit1->append("Error, sampling rate is less than 1Hz.");
     goto OUT_EXIT;
   }
 
-  sex = *((short *)(hdr + 128));
-  if((sex < 0) || (sex > 2))
+  sex = *((short *)(hdr_4096 + SUBJSEX_HDROFF));
+  if((sex != 1) && (sex != 2))
   {
-    textEdit1->append("Error, subject sex is out of range.");
-    goto OUT_EXIT;
+    sex = 0;
+  }
+
+  pacemaker = *((short *)(hdr_4096 + PACEMAKCODE_HDROFF));
+  if((pacemaker < 0) && (pacemaker > 5))
+  {
+    pacemaker = 0;
   }
 
   total_blocks = ecg_smpl_sz / sf;
@@ -269,7 +319,7 @@ struct
 
   for(i=0; i<chns; i++)
   {
-    lead_spec[i] = *((short *)(hdr + 158 + (i * 2)));
+    lead_spec[i] = *((short *)(hdr_4096 + 158 + (i * 2)));
     if((lead_spec[i] < 0) || (lead_spec[i] > 19))
     {
       snprintf(scratchpad_4096, 4096, "Error, lead specification of lead %i is out of range.", i + 1);
@@ -277,7 +327,7 @@ struct
       goto OUT_EXIT;
     }
 
-    amp_resolution[i] = *((short *)(hdr + 206 + (i * 2)));
+    amp_resolution[i] = *((short *)(hdr_4096 + 206 + (i * 2)));
     if(amp_resolution[i] < 1)
     {
       snprintf(scratchpad_4096, 4096, "Error, amplitude resolution of lead %i is less than 1nV.", i + 1);
@@ -288,42 +338,42 @@ struct
 
 /////////////////////////////////////// GET THE START DATE AND TIME /////////////////////
 
-  start_dt.day = *((short *)(hdr + 138));
+  start_dt.day = *((short *)(hdr_4096 + STARTDATE_HDROFF));
   if((start_dt.day < 1) || (start_dt.day > 31))
   {
     textEdit1->append("Error, illegal start date.");
     goto OUT_EXIT;
   }
 
-  start_dt.month = *((short *)(hdr + 140));
+  start_dt.month = *((short *)(hdr_4096 + STARTDATE_HDROFF + 2));
   if((start_dt.month < 1) || (start_dt.month > 12))
   {
     textEdit1->append("Error, illegal start date.");
     goto OUT_EXIT;
   }
 
-  start_dt.year = *((short *)(hdr + 142));
+  start_dt.year = *((short *)(hdr_4096 + STARTDATE_HDROFF + 4));
   if((start_dt.year < 1000) || (start_dt.year > 3000))
   {
     textEdit1->append("Error, illegal start date.");
     goto OUT_EXIT;
   }
 
-  start_dt.hour = *((short *)(hdr + 150));
+  start_dt.hour = *((short *)(hdr_4096 + STARTTIME_HDROFF));
   if((start_dt.hour < 0) || (start_dt.hour > 23))
   {
     textEdit1->append("Error, illegal start time.");
     goto OUT_EXIT;
   }
 
-  start_dt.minute = *((short *)(hdr + 152));
+  start_dt.minute = *((short *)(hdr_4096 + STARTTIME_HDROFF + 2));
   if((start_dt.minute < 0) || (start_dt.minute > 59))
   {
     textEdit1->append("Error, illegal start time.");
     goto OUT_EXIT;
   }
 
-  start_dt.second = *((short *)(hdr + 154));
+  start_dt.second = *((short *)(hdr_4096 + STARTTIME_HDROFF + 4));
   if((start_dt.second < 0) || (start_dt.second > 59))
   {
     textEdit1->append("Error, illegal start time.");
@@ -332,19 +382,19 @@ struct
 
   birthdate_valid = 1;
 
-  birth_d.year = *((short *)(hdr + 136));
+  birth_d.year = *((short *)(hdr_4096 + SUBJBIRTHDATE_HDROFF + 4));
   if((birth_d.year < 1000) || (birth_d.year > 3000))
   {
     birthdate_valid = 0;
   }
 
-  birth_d.month = *((short *)(hdr + 134));
+  birth_d.month = *((short *)(hdr_4096 + SUBJBIRTHDATE_HDROFF + 2));
   if((birth_d.month < 1) || (birth_d.month > 12))
   {
     birthdate_valid = 0;
   }
 
-  birth_d.day = *((short *)(hdr + 132));
+  birth_d.day = *((short *)(hdr_4096 + SUBJBIRTHDATE_HDROFF));
   if((birth_d.day < 1) || (birth_d.day > 31))
   {
     birthdate_valid = 0;
@@ -438,13 +488,13 @@ struct
     goto OUT_EXIT;
   }
 
-  strncpy(str1_128, hdr + 28, 40);
+  strncpy(str1_128, hdr_4096 + 28, 40);
   str1_128[40] = 0;
 
   trim_spaces(str1_128);
   strlcat(str1_128, " ", 128);
 
-  strncpy(scratchpad_4096, hdr + 68, 40);
+  strncpy(scratchpad_4096, hdr_4096 + 68, 40);
   scratchpad_4096[40] = 0;
 
   trim_spaces(scratchpad_4096);
@@ -461,7 +511,7 @@ struct
     }
   }
 
-  strncpy(str1_128, hdr + 108, 20);
+  strncpy(str1_128, hdr_4096 + 108, 20);
   str1_128[20] = 0;
 
   trim_spaces(str1_128);
@@ -501,7 +551,7 @@ struct
     }
   }
 
-  strncpy(str1_128, hdr + 232, 40);
+  strncpy(str1_128, hdr_4096 + 232, 40);
   str1_128[40] = 0;
 
   trim_spaces(str1_128);
@@ -515,12 +565,23 @@ struct
     }
   }
 
-  if(edf_set_number_of_annotation_signals(edf_hdl, 2))
+  if(edf_set_recording_additional(edf_hdl, pacemaker_list[pacemaker]))
   {
-    textEdit1->append("Error, edf_set_number_of_annotation_signals()\n");
+    fprintf(stderr, "Error, edf_set_recording_additional()\n");
     goto OUT_EXIT;
   }
 
+  if(annotfile)
+  {
+    if(edf_set_number_of_annotation_signals(edf_hdl, 2))
+    {
+      textEdit1->append("Error, edf_set_number_of_annotation_signals()\n");
+      goto OUT_EXIT;
+    }
+  }
+
+  edf_set_annot_chan_idx_pos(edf_hdl, EDF_ANNOT_IDX_POS_START);
+
 /////////////////// Start conversion //////////////////////////////////////////
 
 //   printf("sf: %i   chns: %i   var_block_offset: %i   var_block_sz: %i   ecg_block_offset: %i   ecg_smpl_sz: %i   total_blocks: %i\n",
@@ -584,13 +645,7 @@ struct
 
 /////// CHECK ANNOTATIONS FILE ///////////////////////////
 
-  remove_extension_from_filename(path);
-  strlcat(path, ".ann", MAX_PATH_LENGTH);
-
-  fclose(inputfile);
-
-  inputfile = fopen(path, "rb");
-  if(inputfile == NULL)
+  if(annotfile == NULL)
   {
     textEdit1->append("Done\n");
     goto OUT_EXIT;
@@ -599,9 +654,9 @@ struct
   snprintf(scratchpad_4096, 4096, "Processing annotations file:\n%s", path);
   textEdit1->append(QString::fromLocal8Bit(scratchpad_4096));
 
-  fseek(inputfile, 0, SEEK_END);
+  fseek(annotfile, 0, SEEK_END);
 
-  file_sz = ftell(inputfile);
+  file_sz = ftell(annotfile);
 
   if(file_sz < 522)
   {
@@ -609,15 +664,15 @@ struct
     goto OUT_EXIT;
   }
 
-  rewind(inputfile);
+  rewind(annotfile);
 
-  if(fread(hdr, 522, 1, inputfile) != 1)
+  if(fread(hdr_4096, 522, 1, annotfile) != 1)
   {
     textEdit1->append("A read error occurred when trying to read the header.");
     goto OUT_EXIT;
   }
 
-  if(strncmp(hdr, "ANN  1.0", 8))
+  if(strncmp(hdr_4096, "ANN  1.0", 8))
   {
     textEdit1->append("Error, wrong magic string in header.");
     goto OUT_EXIT;
@@ -625,14 +680,14 @@ struct
 
 ////////////////////////////////// GET THE HEADER DATA ////////////////////////
 
-  var_block_sz = *((int *)(hdr + 10));
+  var_block_sz = *((int *)(hdr_4096 + 10));
   if(var_block_sz < 0)
   {
     textEdit1->append("Error, parameter size of variable length block in header is lower than zero.");
     goto OUT_EXIT;
   }
 
-  ecg_smpl_sz = *((int *)(hdr + 14));
+  ecg_smpl_sz = *((int *)(hdr_4096 + 14));
   if(ecg_smpl_sz < 0)
   {
     textEdit1->append("Error, parameter ECG sample size in header is lower than zero.");
@@ -645,7 +700,7 @@ struct
   }
   else
   {
-    var_block_offset = *((int *)(hdr + 18));
+    var_block_offset = *((int *)(hdr_4096 + 18));
   }
 
   if(var_block_offset != 522)
@@ -654,7 +709,7 @@ struct
     goto OUT_EXIT;
   }
 
-  ecg_block_offset = *((int *)(hdr + 22));
+  ecg_block_offset = *((int *)(hdr_4096 + 22));
   if(ecg_block_offset != (var_block_sz + 522))
   {
     textEdit1->append("Error, parameter offset of ECG block in header differs from 522 + variable length block");
@@ -667,7 +722,7 @@ struct
     goto OUT_EXIT;
   }
 
-  chns = *((short *)(hdr + 156));
+  chns = *((short *)(hdr_4096 + 156));
   if(chns < 1)
   {
     textEdit1->append("Error, number of leads is less than 1.");
@@ -680,21 +735,21 @@ struct
     goto OUT_EXIT;
   }
 
-  sf = *((short *)(hdr + 272));
+  sf = *((short *)(hdr_4096 + 272));
   if(sf < 1)
   {
     textEdit1->append("Error, sampling rate is less than 1Hz.");
     goto OUT_EXIT;
   }
 
-  sex = *((short *)(hdr + 128));
+  sex = *((short *)(hdr_4096 + 128));
   if((sex < 0) || (sex > 2))
   {
     textEdit1->append("Error, subject sex is out of range.");
     goto OUT_EXIT;
   }
 
-  if(check_crc(inputfile, var_block_offset + var_block_sz))
+  if(check_crc(annotfile, var_block_offset + var_block_sz))
   {
     textEdit1->append("CRC error, file header is corrupt.");
     goto OUT_EXIT;
@@ -704,7 +759,7 @@ struct
 
   for(i=0; i<chns; i++)
   {
-    lead_spec[i] = *((short *)(hdr + 158 + (i * 2)));
+    lead_spec[i] = *((short *)(hdr_4096 + 158 + (i * 2)));
     if((lead_spec[i] < 0) || (lead_spec[i] > 19))
     {
       snprintf(scratchpad_4096, 4096, "Error, lead specification of lead %i is out of range.", i + 1);
@@ -712,7 +767,7 @@ struct
       goto OUT_EXIT;
     }
 
-    amp_resolution[i] = *((short *)(hdr + 206 + (i * 2)));
+    amp_resolution[i] = *((short *)(hdr_4096 + 206 + (i * 2)));
     if(amp_resolution[i] < 1)
     {
       snprintf(scratchpad_4096, 4096, "Error, amplitude resolution of lead %i is less than 1nV.", i + 1);
@@ -723,42 +778,42 @@ struct
 
 /////////////////////////////////////// GET THE START DATE AND TIME /////////////////////
 
-  start_dt.day = *((short *)(hdr + 138));
+  start_dt.day = *((short *)(hdr_4096 + 138));
   if((start_dt.day < 1) || (start_dt.day > 31))
   {
     textEdit1->append("Error, illegal start date.");
     goto OUT_EXIT;
   }
 
-  start_dt.month = *((short *)(hdr + 140));
+  start_dt.month = *((short *)(hdr_4096 + 140));
   if((start_dt.month < 1) || (start_dt.month > 12))
   {
     textEdit1->append("Error, illegal start date.");
     goto OUT_EXIT;
   }
 
-  start_dt.year = *((short *)(hdr + 142));
+  start_dt.year = *((short *)(hdr_4096 + 142));
   if((start_dt.year < 1000) || (start_dt.year > 3000))
   {
     textEdit1->append("Error, illegal start date.");
     goto OUT_EXIT;
   }
 
-  start_dt.hour = *((short *)(hdr + 150));
+  start_dt.hour = *((short *)(hdr_4096 + 150));
   if((start_dt.hour < 0) || (start_dt.hour > 23))
   {
     textEdit1->append("Error, illegal start time.");
     goto OUT_EXIT;
   }
 
-  start_dt.minute = *((short *)(hdr + 152));
+  start_dt.minute = *((short *)(hdr_4096 + 152));
   if((start_dt.minute < 0) || (start_dt.minute > 59))
   {
     textEdit1->append("Error, illegal start time.");
     goto OUT_EXIT;
   }
 
-  start_dt.second = *((short *)(hdr + 154));
+  start_dt.second = *((short *)(hdr_4096 + 154));
   if((start_dt.second < 0) || (start_dt.second > 59))
   {
     textEdit1->append("Error, illegal start time.");
@@ -767,19 +822,19 @@ struct
 
   birthdate_valid = 1;
 
-  birth_d.year = *((short *)(hdr + 136));
+  birth_d.year = *((short *)(hdr_4096 + 136));
   if((birth_d.year < 1000) || (birth_d.year > 3000))
   {
     birthdate_valid = 0;
   }
 
-  birth_d.month = *((short *)(hdr + 134));
+  birth_d.month = *((short *)(hdr_4096 + 134));
   if((birth_d.month < 1) || (birth_d.month > 12))
   {
     birthdate_valid = 0;
   }
 
-  birth_d.day = *((short *)(hdr + 132));
+  birth_d.day = *((short *)(hdr_4096 + 132));
   if((birth_d.day < 1) || (birth_d.day > 31))
   {
     birthdate_valid = 0;
@@ -787,11 +842,11 @@ struct
 
 /////////////////// Start conversion //////////////////////////////////////////
 
-  fseek(inputfile, ecg_block_offset, SEEK_SET);
+  fseek(annotfile, ecg_block_offset, SEEK_SET);
 
   while(1)
   {
-    if(fread(rbuf, 4, 1, inputfile) != 1)
+    if(fread(rbuf, 4, 1, annotfile) != 1)
     {
       break;
     }
@@ -852,6 +907,8 @@ OUT_EXIT:
 
   if(inputfile != NULL)  fclose(inputfile);
 
+  if(annotfile != NULL)  fclose(annotfile);
+
   free(inbuf);
   free(outbuf);
 }


=====================================
doc/manual.html
=====================================
@@ -21,7 +21,7 @@
     </style>
 </head><body>
 
-<h1>EDFbrowser 2.11 manual</h1>
+<h1>EDFbrowser 2.12 manual</h1>
 
 <p><br></p>
 


=====================================
doc/montage_file_format.txt
=====================================
@@ -54,7 +54,7 @@ Inside every element "signalcomposition", there must be one element with the nam
 
 The value of this element must be an integer or floating point number. (The example has a value of 0.)
 
-The value represents the vertical offset compared to the baseline.
+The value represents the vertical offset compared to the baseline expressed in screen pixels.
 
 
 


=====================================
edf_annot_list.c
=====================================
@@ -92,6 +92,8 @@ void edfplus_annotation_remove_item(annotlist_t *list, int n)
   {
     list->idx[i] = list->idx[i+1];
   }
+
+  if(!list->sz)  edfplus_annotation_empty_list(list);
 }
 
 
@@ -129,11 +131,7 @@ void edfplus_annotation_empty_list(annotlist_t *list)
 
   free(list->items);
   free(list->idx);
-  list->items = NULL;
-  list->idx = NULL;
-  list->sz = 0;
-  list->mem_sz = 0;
-  list->used_sz = 0;
+  memset(list, 0, sizeof(annotlist_t));
 }
 
 
@@ -300,33 +298,32 @@ annotlist_t * edfplus_annotation_create_list_copy(annotlist_t *list)
     return NULL;
   }
 
-  if(list->sz > 0)
+  if(!list->sz)  return cpy;
+
+  cpy->items = (annotblck_t *)malloc(sizeof(annotblck_t) * list->mem_sz);
+  if(cpy->items == NULL)
   {
-    cpy->items = (annotblck_t *)calloc(1, sizeof(annotblck_t) * list->mem_sz);
-    if(cpy->items == NULL)
-    {
-      free(cpy);
-      return NULL;
-    }
+    free(cpy);
+    return NULL;
+  }
 
-    cpy->idx = (int *)calloc(1, sizeof(int) * list->mem_sz);
-    if(cpy->idx == NULL)
-    {
-      free(cpy->items);
-      free(cpy);
-      return NULL;
-    }
+  cpy->idx = (int *)malloc(sizeof(int) * list->mem_sz);
+  if(cpy->idx == NULL)
+  {
+    free(cpy->items);
+    free(cpy);
+    return NULL;
+  }
 
-    cpy->mem_sz = list->mem_sz;
+  cpy->mem_sz = list->mem_sz;
 
-    cpy->sz = list->sz;
+  cpy->sz = list->sz;
 
-    cpy->used_sz = list->used_sz;
+  cpy->used_sz = list->used_sz;
 
-    memcpy(cpy->items, list->items, cpy->mem_sz * sizeof(annotblck_t));
+  memcpy(cpy->items, list->items, cpy->used_sz * sizeof(annotblck_t));
 
-    memcpy(cpy->idx, list->idx, cpy->mem_sz * sizeof(int));
-  }
+  memcpy(cpy->idx, list->idx, cpy->used_sz * sizeof(int));
 
   return cpy;
 }
@@ -336,30 +333,15 @@ void edfplus_annotation_copy_list(annotlist_t *destlist, annotlist_t *srclist)
 {
   if((destlist == NULL) || (srclist == NULL)) return;
 
-  if(destlist->sz > 0)
-  {
-    free(destlist->items);
-
-    destlist->items = NULL;
-
-    free(destlist->idx);
-
-    destlist->idx = NULL;
-
-    destlist->sz = 0;
-
-    destlist->mem_sz = 0;
-
-    destlist->used_sz = 0;
-  }
+  edfplus_annotation_empty_list(destlist);
 
-  destlist->items = (annotblck_t *)calloc(1, srclist->mem_sz * sizeof(annotblck_t));
+  destlist->items = (annotblck_t *)malloc(srclist->mem_sz * sizeof(annotblck_t));
   if(destlist->items == NULL)
   {
     return;
   }
 
-  destlist->idx = (int *)calloc(1, srclist->mem_sz * sizeof(int));
+  destlist->idx = (int *)malloc(srclist->mem_sz * sizeof(int));
   if(destlist->idx == NULL)
   {
     free(destlist->items);
@@ -373,9 +355,9 @@ void edfplus_annotation_copy_list(annotlist_t *destlist, annotlist_t *srclist)
 
   destlist->mem_sz = srclist->mem_sz;
 
-  memcpy(destlist->items, srclist->items, destlist->mem_sz * sizeof(annotblck_t));
+  memcpy(destlist->items, srclist->items, destlist->used_sz * sizeof(annotblck_t));
 
-  memcpy(destlist->idx, srclist->idx, destlist->mem_sz * sizeof(int));
+  memcpy(destlist->idx, srclist->idx, destlist->used_sz * sizeof(int));
 }
 
 
@@ -471,7 +453,7 @@ void edfplus_annotation_cancel_all_selected_in_dock(annotlist_t *list)
 
   if(list == NULL)  return;
 
-  for(i=0; i<(list->sz); i++)
+  for(i=0; i<(list->used_sz); i++)
   {
     list->items[i].selected_in_dock = 0;
   }


=====================================
edfbrowser.pro
=====================================
@@ -61,9 +61,9 @@ win32 {
 }
 
 
-QMAKE_CFLAGS += -Wall -Wextra -Wshadow -Wformat-nonliteral -Wformat-security -Wtype-limits -Wfatal-errors -Wdeprecated-declarations -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -U_FORTIFY_SOURCE
+QMAKE_CFLAGS += -Wall -Wextra -Wshadow -Wformat-nonliteral -Wformat-security -Wtype-limits -Wfatal-errors -Wstringop-overflow=2 -Wdeprecated-declarations -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -U_FORTIFY_SOURCE
 
-QMAKE_CXXFLAGS += -Wextra -Wshadow -Wformat -Wformat-nonliteral -Wformat-security -Wtype-limits -Wfatal-errors -Wdeprecated-declarations -U_FORTIFY_SOURCE
+QMAKE_CXXFLAGS += -Wextra -Wshadow -Wformat -Wformat-nonliteral -Wformat-security -Wtype-limits -Wfatal-errors -Wstringop-overflow=2 -Wdeprecated-declarations -U_FORTIFY_SOURCE
 
 
 OBJECTS_DIR = ./objects


=====================================
edit_annotation_dock.cpp
=====================================
@@ -343,6 +343,8 @@ void UI_AnnotationEditwindow::deleteButtonClicked()
     return;
   }
 
+  file_num = mainwindow->get_filenum((edfhdrblck_t *)(annot->edfhdr));
+
   edfplus_annotation_remove_item(annot_list, annot_num);
 
   modifybutton->setEnabled(false);
@@ -353,7 +355,6 @@ void UI_AnnotationEditwindow::deleteButtonClicked()
 
   mainwindow->save_act->setEnabled(true);
 
-  file_num = mainwindow->get_filenum((edfhdrblck_t *)(annot->edfhdr));
   if(file_num >= 0)
   {
     mainwindow->annotations_dock[file_num]->updateList(0);


=====================================
global.h
=====================================
@@ -67,7 +67,7 @@
 #endif
 
 #define PROGRAM_NAME                "EDFbrowser"
-#define PROGRAM_VERSION                   "2.11"
+#define PROGRAM_VERSION                   "2.12"
 #define PROGRAM_BETA_SUFFIX                   ""
 #define MINIMUM_QT4_VERSION           (0x040807)
 #define MINIMUM_QT5_VERSION           (0x050C06)
@@ -314,7 +314,8 @@ typedef struct
   int hasoffsettracking;
   int hasgaintracking;
   int hasruler;
-  double screen_offset;
+  double screen_offset_pix;
+  double screen_offset_unit;
   double voltpercm;
   char physdimension[9];
   char physdimension_bu[9];
@@ -388,7 +389,7 @@ typedef struct
   long long pagetime[MAXZOOMHISTORY];
   double voltpercm[MAXZOOMHISTORY][MAXSIGNALS];
   double sensitivity[MAXZOOMHISTORY][MAXSIGNALS];
-  double screen_offset[MAXZOOMHISTORY][MAXSIGNALS];
+  double screen_offset_unit[MAXZOOMHISTORY][MAXSIGNALS];
 } zoomhistblck_t;
 
 typedef struct


=====================================
load_montage_dialog.cpp
=====================================
@@ -500,7 +500,8 @@ int UI_LoadMontagewindow::LoadButtonClicked()
     newsignalcomp->hascursor2 = 0;
     newsignalcomp->hasoffsettracking = 0;
     newsignalcomp->hasgaintracking = 0;
-    newsignalcomp->screen_offset = 0;
+    newsignalcomp->screen_offset_pix = 0;
+    newsignalcomp->screen_offset_unit = 0;
     newsignalcomp->math_func_cnt_before = 0;
     newsignalcomp->math_func_cnt_after = 0;
     newsignalcomp->filter_cnt = 0;
@@ -543,16 +544,27 @@ int UI_LoadMontagewindow::LoadButtonClicked()
     newsignalcomp->voltpercm = atof(result);
     if(newsignalcomp->voltpercm==0.0)  newsignalcomp->voltpercm = 0.000000001;
     xml_go_up(xml_hdl);
-    if(xml_goto_nth_element_inside(xml_hdl, "screen_offset", 0))
-    {
-      return format_error(__FILE__, __LINE__, newsignalcomp, xml_hdl);
-    }
-    if(xml_get_content_of_element(xml_hdl, result, XML_STRBUFLEN))
+
+    if(!xml_goto_nth_element_inside(xml_hdl, "screen_offset_unit", 0))
     {
-      return format_error(__FILE__, __LINE__, newsignalcomp, xml_hdl);
+      if(xml_get_content_of_element(xml_hdl, result, XML_STRBUFLEN))
+      {
+        return format_error(__FILE__, __LINE__, newsignalcomp, xml_hdl);
+      }
+      newsignalcomp->screen_offset_unit = atof(result);
+      newsignalcomp->screen_offset_pix = -newsignalcomp->screen_offset_unit / (mainwindow->y_pixelsizefactor * newsignalcomp->voltpercm);
+      xml_go_up(xml_hdl);
     }
-    newsignalcomp->screen_offset = atof(result);
-    xml_go_up(xml_hdl);
+    else if(!xml_goto_nth_element_inside(xml_hdl, "screen_offset", 0))
+      {
+        if(xml_get_content_of_element(xml_hdl, result, XML_STRBUFLEN))
+        {
+          return format_error(__FILE__, __LINE__, newsignalcomp, xml_hdl);
+        }
+        newsignalcomp->screen_offset_pix = atof(result);
+        newsignalcomp->screen_offset_unit = -newsignalcomp->screen_offset_pix * mainwindow->y_pixelsizefactor * newsignalcomp->voltpercm;
+        xml_go_up(xml_hdl);
+      }
 
     if(!(xml_goto_nth_element_inside(xml_hdl, "polarity", 0)))
     {


=====================================
load_session.cpp
=====================================
@@ -362,7 +362,8 @@ int UI_Mainwindow::read_session_file(const char *path_session)
     newsignalcomp->hascursor2 = 0;
     newsignalcomp->hasoffsettracking = 0;
     newsignalcomp->hasgaintracking = 0;
-    newsignalcomp->screen_offset = 0;
+    newsignalcomp->screen_offset_pix = 0;
+    newsignalcomp->screen_offset_unit = 0;
     newsignalcomp->filter_cnt = 0;
     newsignalcomp->ravg_filter_cnt = 0;
     newsignalcomp->fir_filter_cnt = 0;
@@ -403,16 +404,26 @@ int UI_Mainwindow::read_session_file(const char *path_session)
     if(newsignalcomp->voltpercm==0.0)  newsignalcomp->voltpercm = 0.000000001;
     xml_go_up(xml_hdl);
 
-    if(xml_goto_nth_element_inside(xml_hdl, "screen_offset", 0))
+    if(!xml_goto_nth_element_inside(xml_hdl, "screen_offset_unit", 0))
     {
-      return session_format_error(__FILE__, __LINE__, newsignalcomp, xml_hdl);
-    }
-    if(xml_get_content_of_element(xml_hdl, result, XML_STRBUFLEN))
-    {
-      return session_format_error(__FILE__, __LINE__, newsignalcomp, xml_hdl);
+      if(xml_get_content_of_element(xml_hdl, result, XML_STRBUFLEN))
+      {
+        return session_format_error(__FILE__, __LINE__, newsignalcomp, xml_hdl);
+      }
+      newsignalcomp->screen_offset_unit = atof(result);
+      newsignalcomp->screen_offset_pix = -newsignalcomp->screen_offset_unit / (y_pixelsizefactor * newsignalcomp->voltpercm);
+      xml_go_up(xml_hdl);
     }
-    newsignalcomp->screen_offset = atof(result);
-    xml_go_up(xml_hdl);
+    else if(!xml_goto_nth_element_inside(xml_hdl, "screen_offset", 0))
+      {
+        if(xml_get_content_of_element(xml_hdl, result, XML_STRBUFLEN))
+        {
+          return session_format_error(__FILE__, __LINE__, newsignalcomp, xml_hdl);
+        }
+        newsignalcomp->screen_offset_pix = atof(result);
+        newsignalcomp->screen_offset_unit = -newsignalcomp->screen_offset_pix * y_pixelsizefactor * newsignalcomp->voltpercm;
+        xml_go_up(xml_hdl);
+      }
 
     if(!(xml_goto_nth_element_inside(xml_hdl, "polarity", 0)))
     {


=====================================
mainwindow.cpp
=====================================
@@ -1107,8 +1107,8 @@ void UI_Mainwindow::zoomback()
   for(i=0; i<signalcomps; i++)
   {
     zoomhistory->voltpercm[zoomhistory->idx][i] = signalcomp[i]->voltpercm;
-    zoomhistory->screen_offset[zoomhistory->idx][i] = signalcomp[i]->screen_offset;
     zoomhistory->sensitivity[zoomhistory->idx][i] = signalcomp[i]->sensitivity;
+    zoomhistory->screen_offset_unit[zoomhistory->idx][i] = signalcomp[i]->screen_offset_unit;
   }
 
   zoomhistory->idx--;
@@ -1124,8 +1124,9 @@ void UI_Mainwindow::zoomback()
   for(i=0; i<signalcomps; i++)
   {
     signalcomp[i]->voltpercm = zoomhistory->voltpercm[zoomhistory->idx][i];
-    signalcomp[i]->screen_offset = zoomhistory->screen_offset[zoomhistory->idx][i];
     signalcomp[i]->sensitivity = zoomhistory->sensitivity[zoomhistory->idx][i];
+    signalcomp[i]->screen_offset_unit = zoomhistory->screen_offset_unit[zoomhistory->idx][i];
+    signalcomp[i]->screen_offset_pix = -signalcomp[i]->screen_offset_unit / (y_pixelsizefactor * signalcomp[i]->voltpercm);
   }
 
   setup_viewbuf();
@@ -1157,8 +1158,9 @@ void UI_Mainwindow::forward()
   for(i=0; i<signalcomps; i++)
   {
     signalcomp[i]->voltpercm = zoomhistory->voltpercm[zoomhistory->idx][i];
-    signalcomp[i]->screen_offset = zoomhistory->screen_offset[zoomhistory->idx][i];
     signalcomp[i]->sensitivity = zoomhistory->sensitivity[zoomhistory->idx][i];
+    signalcomp[i]->screen_offset_unit = zoomhistory->screen_offset_unit[zoomhistory->idx][i];
+    signalcomp[i]->screen_offset_pix = -signalcomp[i]->screen_offset_unit / (y_pixelsizefactor * signalcomp[i]->voltpercm);
   }
 
   setup_viewbuf();
@@ -1447,8 +1449,9 @@ void UI_Mainwindow::shift_page_up()
 
   for(i=0; i<signalcomps; i++)
   {
-    signalcomp[i]->screen_offset += (height() / 20.0);
+    signalcomp[i]->screen_offset_pix += (height() / 20.0);
 
+    signalcomp[i]->screen_offset_unit = -signalcomp[i]->screen_offset_pix * y_pixelsizefactor * signalcomp[i]->voltpercm;
   }
 
   maincurve->drawCurve_stage_1();
@@ -1463,8 +1466,9 @@ void UI_Mainwindow::shift_page_down()
 
   for(i=0; i<signalcomps; i++)
   {
-    signalcomp[i]->screen_offset -= (height() / 20.0);
+    signalcomp[i]->screen_offset_pix -= (height() / 20.0);
 
+    signalcomp[i]->screen_offset_unit = -signalcomp[i]->screen_offset_pix * y_pixelsizefactor * signalcomp[i]->voltpercm;
   }
 
   maincurve->drawCurve_stage_1();
@@ -3151,7 +3155,7 @@ void UI_Mainwindow::close_all_files()
     for(j=0; j<MAXSIGNALS; j++)
     {
       zoomhistory->voltpercm[i][j] = 70;
-      zoomhistory->screen_offset[i][j] = 0.0;
+      zoomhistory->screen_offset_unit[i][j] = 0;
       zoomhistory->sensitivity[i][j] = 0.0475;
     }
   }
@@ -3781,11 +3785,11 @@ void UI_Mainwindow::fit_signals_to_pane(int n)
       signalcomp[i]->sensitivity = pane_size;
     }
 
-    signalcomp[i]->voltpercm =
-     signalcomp[i]->edfparam_0->bitvalue
-     / (signalcomp[i]->sensitivity * y_pixelsizefactor);
+    signalcomp[i]->voltpercm = signalcomp[i]->edfparam_0->bitvalue / (signalcomp[i]->sensitivity * y_pixelsizefactor);
 
-    signalcomp[i]->screen_offset = ((signalcomp[i]->max_dig_value + signalcomp[i]->min_dig_value) / 2.0) * signalcomp[i]->sensitivity * signalcomp[i]->polarity;
+    signalcomp[i]->screen_offset_pix = ((signalcomp[i]->max_dig_value + signalcomp[i]->min_dig_value) / 2.0) * signalcomp[i]->sensitivity * signalcomp[i]->polarity;
+
+    signalcomp[i]->screen_offset_unit = -signalcomp[i]->screen_offset_pix * y_pixelsizefactor * signalcomp[i]->voltpercm;
   }
 
   maincurve->drawCurve_stage_1();
@@ -3805,7 +3809,9 @@ void UI_Mainwindow::fit_signals_dc_offset(int n)
       continue;
     }
 
-    signalcomp[i]->screen_offset = ((signalcomp[i]->max_dig_value + signalcomp[i]->min_dig_value) / 2.0) * signalcomp[i]->sensitivity * signalcomp[i]->polarity;
+    signalcomp[i]->screen_offset_pix = ((signalcomp[i]->max_dig_value + signalcomp[i]->min_dig_value) / 2.0) * signalcomp[i]->sensitivity * signalcomp[i]->polarity;
+
+    signalcomp[i]->screen_offset_unit = -signalcomp[i]->screen_offset_pix * y_pixelsizefactor * signalcomp[i]->voltpercm;
   }
 
   maincurve->drawCurve_stage_1();
@@ -3963,7 +3969,9 @@ void UI_Mainwindow::set_amplitude(QAction *action)
 
     signalcomp[i]->sensitivity = (signalcomp[i]->edfparam_0->bitvalue / value) / y_pixelsizefactor;
 
-    signalcomp[i]->screen_offset *= (signalcomp[i]->voltpercm / value);
+    signalcomp[i]->screen_offset_pix *= (signalcomp[i]->voltpercm / value);
+
+    signalcomp[i]->screen_offset_unit = -signalcomp[i]->screen_offset_pix * y_pixelsizefactor * signalcomp[i]->voltpercm;
 
     signalcomp[i]->voltpercm = value;
   }
@@ -4000,16 +4008,18 @@ void UI_Mainwindow::set_amplitude_mult2()
     {
       signalcomp[i]->voltpercm *= 2;
 
-      signalcomp[i]->screen_offset /= 2;
+      signalcomp[i]->screen_offset_pix /= 2;
     }
     else
     {
       signalcomp[i]->voltpercm *= 2.5;
 
-      signalcomp[i]->screen_offset /= 2.5;
+      signalcomp[i]->screen_offset_pix /= 2.5;
     }
 
     signalcomp[i]->sensitivity = (signalcomp[i]->edfparam_0->bitvalue / signalcomp[i]->voltpercm) / y_pixelsizefactor;
+
+    signalcomp[i]->screen_offset_unit = -signalcomp[i]->screen_offset_pix * y_pixelsizefactor * signalcomp[i]->voltpercm;
   }
 
   if(amplitude_doubler == 10)
@@ -4060,16 +4070,18 @@ void UI_Mainwindow::set_amplitude_div2()
     {
       signalcomp[i]->voltpercm /= 2;
 
-      signalcomp[i]->screen_offset *= 2;
+      signalcomp[i]->screen_offset_pix *= 2;
     }
     else
     {
       signalcomp[i]->voltpercm /= 2.5;
 
-      signalcomp[i]->screen_offset *= 2.5;
+      signalcomp[i]->screen_offset_pix *= 2.5;
     }
 
     signalcomp[i]->sensitivity = (signalcomp[i]->edfparam_0->bitvalue / signalcomp[i]->voltpercm) / y_pixelsizefactor;
+
+    signalcomp[i]->screen_offset_unit = -signalcomp[i]->screen_offset_pix * y_pixelsizefactor * signalcomp[i]->voltpercm;
   }
 
   if(amplitude_doubler == 10)
@@ -4555,7 +4567,9 @@ void UI_Mainwindow::set_dc_offset_to_zero(int n)
       continue;
     }
 
-    signalcomp[i]->screen_offset = 0.0;
+    signalcomp[i]->screen_offset_pix = 0.0;
+
+    signalcomp[i]->screen_offset_unit = 0.0;
   }
 
   maincurve->drawCurve_stage_1();
@@ -5364,19 +5378,25 @@ void UI_Mainwindow::signalcomp_invert(int inv, int n)
     {
       signalcomp[i]->polarity *= -1;
 
-      signalcomp[i]->screen_offset *= -1;
+      signalcomp[i]->screen_offset_pix *= -1;
+
+      signalcomp[i]->screen_offset_unit *= -1;
     }
     else if((inv == 1) && (signalcomp[i]->polarity == 1))  /* inverted */
       {
         signalcomp[i]->polarity *= -1;
 
-        signalcomp[i]->screen_offset *= -1;
+        signalcomp[i]->screen_offset_pix *= -1;
+
+        signalcomp[i]->screen_offset_unit *= -1;
       }
       else if(inv == 2)  /* toggle */
       {
         signalcomp[i]->polarity *= -1;
 
-        signalcomp[i]->screen_offset *= -1;
+        signalcomp[i]->screen_offset_pix *= -1;
+
+        signalcomp[i]->screen_offset_unit *= -1;
       }
   }
 
@@ -5388,12 +5408,16 @@ void UI_Mainwindow::desktop_resized()
 {
   set_font_metrics(0);
 
-  maincurve->update();
+  setup_viewbuf();
 }
 
 
 void UI_Mainwindow::set_font_metrics(int starting_up)
 {
+  int i, dpiy_old;
+
+  double dpi_ratio;
+
   QFontMetrics fm(*normfont);
 
   norm_font_pixel_height = fm.height();
@@ -5422,6 +5446,8 @@ void UI_Mainwindow::set_font_metrics(int starting_up)
 
   if(!starting_up)
   {
+    dpiy_old = dpiy;
+
     dpix = maincurve->physicalDpiX();
 
     dpiy = maincurve->physicalDpiY();
@@ -5434,6 +5460,18 @@ void UI_Mainwindow::set_font_metrics(int starting_up)
 
       x_pixelsizefactor = 2.54 / dpix;
     }
+
+    if(dpiy != dpiy_old)
+    {
+      dpi_ratio = (double)dpiy / (double)dpiy_old;
+
+      for(i=0; i<signalcomps; i++)
+      {
+        signalcomp[i]->screen_offset_pix = dpi_ratio * signalcomp[i]->screen_offset_pix;
+
+        signalcomp[i]->screen_offset_unit = -signalcomp[i]->screen_offset_pix * y_pixelsizefactor * signalcomp[i]->voltpercm;
+      }
+    }
   }
 }
 


=====================================
mainwindow_constr.cpp
=====================================
@@ -1410,7 +1410,7 @@ UI_Mainwindow::UI_Mainwindow()
     for(j=0; j<MAXSIGNALS; j++)
     {
       zoomhistory->voltpercm[i][j] = 70;
-      zoomhistory->screen_offset[i][j] = 0;
+      zoomhistory->screen_offset_unit[i][j] = 0;
       zoomhistory->sensitivity[i][j] = 0.0475;
     }
   }


=====================================
options_dialog.cpp
=====================================
@@ -3727,9 +3727,11 @@ void UI_OptionsDialog::update_interface(void)
 
       mainwindow->signalcomp[i]->sensitivity = (mainwindow->signalcomp[i]->edfparam_0->bitvalue / value) / mainwindow->y_pixelsizefactor;
 
-      mainwindow->signalcomp[i]->screen_offset *= (mainwindow->signalcomp[i]->voltpercm / value);
+      mainwindow->signalcomp[i]->screen_offset_pix *= (mainwindow->signalcomp[i]->voltpercm / value);
 
       mainwindow->signalcomp[i]->voltpercm = value;
+
+      mainwindow->signalcomp[i]->screen_offset_unit = -mainwindow->signalcomp[i]->screen_offset_pix * mainwindow->y_pixelsizefactor * mainwindow->signalcomp[i]->voltpercm;
     }
 
     mainwindow->pagetime = mainwindow->maincurve->width() * mainwindow->x_pixelsizefactor * TIME_FIXP_SCALING / 5.0;


=====================================
rc_host.cpp
=====================================
@@ -991,7 +991,9 @@ int UI_Mainwindow::process_rc_cmd_signal(const char *cmd_args, int *cmds_parsed_
 
         signalcomp[i]->voltpercm = value2;
 
-        signalcomp[i]->screen_offset *= (original_value / value2);
+        signalcomp[i]->screen_offset_pix *= (original_value / value2);
+
+        signalcomp[i]->screen_offset_unit *= (original_value / value2);
       }
 
       maincurve->drawCurve_stage_1();
@@ -1027,7 +1029,9 @@ int UI_Mainwindow::process_rc_cmd_signal(const char *cmd_args, int *cmds_parsed_
 
       signalcomp[n]->voltpercm = value2;
 
-      signalcomp[n]->screen_offset *= (original_value / value2);
+      signalcomp[n]->screen_offset_pix *= (original_value / value2);
+
+      signalcomp[n]->screen_offset_unit *= (original_value / value2);
 
       maincurve->drawCurve_stage_1();
 


=====================================
save_montage_dialog.cpp
=====================================
@@ -166,9 +166,11 @@ void UI_SaveMontagewindow::SaveButtonClicked()
 
       fprintf(mtgfile, "    <num_of_signals>%i</num_of_signals>\n", mainwindow->signalcomp[i]->num_of_signals);
 
-      fprintf(mtgfile, "    <voltpercm>%f</voltpercm>\n", mainwindow->signalcomp[i]->voltpercm);
+      fprintf(mtgfile, "    <voltpercm>%e</voltpercm>\n", mainwindow->signalcomp[i]->voltpercm);
 
-      fprintf(mtgfile, "    <screen_offset>%f</screen_offset>\n", mainwindow->signalcomp[i]->screen_offset);
+      fprintf(mtgfile, "    <screen_offset>%e</screen_offset>\n", mainwindow->signalcomp[i]->screen_offset_pix);
+
+      fprintf(mtgfile, "    <screen_offset_unit>%e</screen_offset_unit>\n", mainwindow->signalcomp[i]->screen_offset_unit);
 
       fprintf(mtgfile, "    <polarity>%i</polarity>\n", mainwindow->signalcomp[i]->polarity);
 
@@ -346,7 +348,7 @@ void UI_SaveMontagewindow::SaveButtonClicked()
 
         fprintf(mtgfile, "      <type>1</type>\n");
 
-        fprintf(mtgfile, "      <crossoverfreq>%f</crossoverfreq>\n", mainwindow->signalcomp[i]->zratio_crossoverfreq);
+        fprintf(mtgfile, "      <crossoverfreq>%e</crossoverfreq>\n", mainwindow->signalcomp[i]->zratio_crossoverfreq);
 
         fprintf(mtgfile, "    </zratio_filter>\n");
       }


=====================================
save_session.cpp
=====================================
@@ -157,9 +157,11 @@ void UI_Mainwindow::save_session()
 
     fprintf(pro_file, "    <num_of_signals>%i</num_of_signals>\n", signalcomp[i]->num_of_signals);
 
-    fprintf(pro_file, "    <voltpercm>%f</voltpercm>\n", signalcomp[i]->voltpercm);
+    fprintf(pro_file, "    <voltpercm>%e</voltpercm>\n", signalcomp[i]->voltpercm);
 
-    fprintf(pro_file, "    <screen_offset>%f</screen_offset>\n", signalcomp[i]->screen_offset);
+    fprintf(pro_file, "    <screen_offset>%e</screen_offset>\n", signalcomp[i]->screen_offset_pix);
+
+    fprintf(pro_file, "    <screen_offset_unit>%e</screen_offset_unit>\n", signalcomp[i]->screen_offset_unit);
 
     fprintf(pro_file, "    <polarity>%i</polarity>\n", signalcomp[i]->polarity);
 
@@ -337,7 +339,7 @@ void UI_Mainwindow::save_session()
 
       fprintf(pro_file, "      <type>1</type>\n");
 
-      fprintf(pro_file, "      <crossoverfreq>%f</crossoverfreq>\n", signalcomp[i]->zratio_crossoverfreq);
+      fprintf(pro_file, "      <crossoverfreq>%e</crossoverfreq>\n", signalcomp[i]->zratio_crossoverfreq);
 
       fprintf(pro_file, "    </zratio_filter>\n");
     }


=====================================
show_actual_montage_dialog.cpp
=====================================
@@ -132,7 +132,8 @@ UI_ShowActualMontagewindow::UI_ShowActualMontagewindow(QWidget *w_parent)
     remove_trailing_spaces(txtbuf_2048);
 
     snprintf(txtbuf_2048 + strlen(txtbuf_2048), 2048 - strlen(txtbuf_2048), "/cm offset: %f%s",
-            mainwindow->signalcomp[i]->screen_offset * mainwindow->y_pixelsizefactor * mainwindow->signalcomp[i]->voltpercm,
+//            mainwindow->signalcomp[i]->screen_offset_pix * mainwindow->y_pixelsizefactor * mainwindow->signalcomp[i]->voltpercm,
+            mainwindow->signalcomp[i]->screen_offset_unit,
             mainwindow->signalcomp[i]->physdimension);
 
     remove_trailing_zeros(txtbuf_2048);


=====================================
show_edf_hdr.cpp
=====================================
@@ -337,9 +337,9 @@ void UI_EDFhdrwindow::show_params(int row)
   if(mainwindow->edfheaderlist[row]->starttime_subsec != 0LL)
   {
 #ifdef Q_OS_WIN32
-    __mingw_snprintf(str1_512 + strlen(str1_512), 100, ".%07lli", mainwindow->edfheaderlist[row]->starttime_subsec);
+    __mingw_snprintf(str1_512 + strlen(str1_512), 512 - strlen(str1_512), ".%07lli", mainwindow->edfheaderlist[row]->starttime_subsec);
 #else
-    snprintf(str1_512 + strlen(str1_512), 100, ".%07lli", mainwindow->edfheaderlist[row]->starttime_subsec);
+    snprintf(str1_512 + strlen(str1_512), 512 - strlen(str1_512), ".%07lli", mainwindow->edfheaderlist[row]->starttime_subsec);
 #endif
 
     remove_trailing_zeros(str1_512);
@@ -379,9 +379,9 @@ void UI_EDFhdrwindow::show_params(int row)
           date_time.minute,
           date_time.second);
 #ifdef Q_OS_WIN32
-  __mingw_snprintf(str1_512 + strlen(str1_512), 100, ".%07lli", (mainwindow->edfheaderlist[row]->starttime_subsec + file_duration) % TIME_FIXP_SCALING);
+  __mingw_snprintf(str1_512 + strlen(str1_512), 512 - strlen(str1_512), ".%07lli", (mainwindow->edfheaderlist[row]->starttime_subsec + file_duration) % TIME_FIXP_SCALING);
 #else
-  snprintf(str1_512 + strlen(str1_512), 100, ".%07lli", (mainwindow->edfheaderlist[row]->starttime_subsec + file_duration) % TIME_FIXP_SCALING);
+  snprintf(str1_512 + strlen(str1_512), 512 - strlen(str1_512), ".%07lli", (mainwindow->edfheaderlist[row]->starttime_subsec + file_duration) % TIME_FIXP_SCALING);
 #endif
   remove_trailing_zeros(str1_512);
 
@@ -558,11 +558,19 @@ void UI_EDFhdrwindow::load_signal_params(int row, int page)
       ql->setToolTip(str1_512);
     }
     signallist->setCellWidget(i%512, 6, ql);
-    snprintf(str1_512, 512, "%e", mainwindow->edfheaderlist[row]->edfparam[i].bitvalue);
-    ql = new QLineEdit(str1_512);
+    if(mainwindow->edfheaderlist[row]->edfparam[i].annotation)
+    {
+      ql = new QLineEdit("n.a.");
+    }
+    else
+    {
+      snprintf(str1_512, 512, "%e", mainwindow->edfheaderlist[row]->edfparam[i].bitvalue);
+      remove_trailing_zeros(str1_512);
+      ql = new QLineEdit(str1_512);
+      ql->setToolTip("Computed as: (physical maximum - physical minimum) / (digital maximum - digital minimum)");
+    }
     ql->setReadOnly(true);
     ql->setCursorPosition(0);
-    ql->setToolTip("Computed as: (physical maximum - physical minimum) / (digital maximum - digital minimum)");
     signallist->setCellWidget(i%512, 7, ql);
     ql = new QLineEdit(mainwindow->edfheaderlist[row]->edfparam[i].physdimension);
     ql->setReadOnly(true);


=====================================
signal_chooser.cpp
=====================================
@@ -596,7 +596,9 @@ void UI_SignalChooser::signalInvert()
   {
     mainwindow->signalcomp[selected_signals[i]]->polarity *= -1;
 
-    mainwindow->signalcomp[selected_signals[i]]->screen_offset *= -1;
+    mainwindow->signalcomp[selected_signals[i]]->screen_offset_pix *= -1;
+
+    mainwindow->signalcomp[selected_signals[i]]->screen_offset_unit *= -1;
   }
 
   load_signalcomps();


=====================================
signals_dialog.cpp
=====================================
@@ -416,7 +416,9 @@ void UI_Signalswindow::DisplayCompButtonClicked()
         {
           newsignalcomp->polarity *= -1;
 
-          newsignalcomp->screen_offset *= -1;
+          newsignalcomp->screen_offset_pix *= -1;
+
+          newsignalcomp->screen_offset_unit *= -1;
         }
       }
     }
@@ -555,7 +557,9 @@ void UI_Signalswindow::DisplayButtonClicked()
           {
             newsignalcomp->polarity *= -1;
 
-            newsignalcomp->screen_offset *= -1;
+            newsignalcomp->screen_offset_pix *= -1;
+
+            newsignalcomp->screen_offset_unit *= -1;
           }
         }
       }
@@ -835,9 +839,9 @@ void UI_Signalswindow::show_signals(int row)
   if(mainwindow->edfheaderlist[row]->starttime_subsec != 0LL)
   {
 #ifdef Q_OS_WIN32
-    __mingw_snprintf(str1_256 + strlen(str1_256), 100, ".%07lli", mainwindow->edfheaderlist[row]->starttime_subsec);
+    __mingw_snprintf(str1_256 + strlen(str1_256), 256 - strlen(str1_256), ".%07lli", mainwindow->edfheaderlist[row]->starttime_subsec);
 #else
-    snprintf(str1_256 + strlen(str1_256), 100, ".%07lli", mainwindow->edfheaderlist[row]->starttime_subsec);
+    snprintf(str1_256 + strlen(str1_256), 256 - strlen(str1_256), ".%07lli", mainwindow->edfheaderlist[row]->starttime_subsec);
 #endif
 
     remove_trailing_zeros(str1_256);
@@ -870,9 +874,9 @@ void UI_Signalswindow::show_signals(int row)
           date_time.minute,
           date_time.second);
 #ifdef Q_OS_WIN32
-  __mingw_snprintf(str1_256 + strlen(str1_256), 100, ".%07lli", (mainwindow->edfheaderlist[row]->starttime_subsec + file_duration) % TIME_FIXP_SCALING);
+  __mingw_snprintf(str1_256 + strlen(str1_256), 256 - strlen(str1_256), ".%07lli", (mainwindow->edfheaderlist[row]->starttime_subsec + file_duration) % TIME_FIXP_SCALING);
 #else
-  snprintf(str1_256 + strlen(str1_256), 100, ".%07lli", (mainwindow->edfheaderlist[row]->starttime_subsec + file_duration) % TIME_FIXP_SCALING);
+  snprintf(str1_256 + strlen(str1_256), 256 - strlen(str1_256), ".%07lli", (mainwindow->edfheaderlist[row]->starttime_subsec + file_duration) % TIME_FIXP_SCALING);
 #endif
   remove_trailing_zeros(str1_256);
 


=====================================
utils.h
=====================================
@@ -40,6 +40,9 @@ extern "C" {
 #include <stdio.h>
 #include <ctype.h>
 #include <math.h>
+#ifdef __linux__
+#include <features.h>
+#endif
 
 
 void remove_trailing_spaces(char *);


=====================================
vc_painter.cpp
=====================================
@@ -730,7 +730,7 @@ void ViewCurve::drawCurve_stage_2(QPainter *painter, int w_width, int w_height,
                     {
                       if(!strcmp(chp, signalcomp[k]->signallabel))
                       {
-                        baseline = (vertical_distance * (k + 1)) + signalcomp[k]->screen_offset;
+                        baseline = (vertical_distance * (k + 1)) + signalcomp[k]->screen_offset_pix;
 
                         if(annot->selected_in_dock)
                         {
@@ -963,13 +963,13 @@ void ViewCurve::drawCurve_stage_2(QPainter *painter, int w_width, int w_height,
             if(!(j%10))
             {
               snprintf(str1_600, 128, "%+.*f %s", p_decimals,
-                ((sense * j / 5) + ((signalcomp[i]->screen_offset * signalcomp[i]->voltpercm) / (painter_pixelsizefactor / printsize_y_factor))) * (double)signalcomp[i]->polarity,
+                ((sense * j / 5) + ((signalcomp[i]->screen_offset_pix * signalcomp[i]->voltpercm) / (painter_pixelsizefactor / printsize_y_factor))) * (double)signalcomp[i]->polarity,
                 signalcomp[i]->physdimension);
 
               painter->drawText(5 * printsize_x_factor, baseline - vert_ruler_offset - (4 * printsize_y_factor) - scroll_h_offset, str1_600);
 
               snprintf(str1_600, 128, "%+.*f %s", p_decimals,
-                (((signalcomp[i]->screen_offset * signalcomp[i]->voltpercm) / (painter_pixelsizefactor / printsize_y_factor)) - (sense * j / 5)) * (double)signalcomp[i]->polarity,
+                (((signalcomp[i]->screen_offset_pix * signalcomp[i]->voltpercm) / (painter_pixelsizefactor / printsize_y_factor)) - (sense * j / 5)) * (double)signalcomp[i]->polarity,
                 signalcomp[i]->physdimension);
 
               painter->drawText(5 * printsize_x_factor, baseline + vert_ruler_offset - (4 * printsize_y_factor) - scroll_h_offset, str1_600);
@@ -1004,7 +1004,7 @@ void ViewCurve::drawCurve_stage_2(QPainter *painter, int w_width, int w_height,
           painter->drawLine(0, baseline - vert_ruler_offset - scroll_h_offset, w, baseline - vert_ruler_offset - scroll_h_offset);
 
           snprintf(str1_600, 128, "%+.*f %s", p_decimals,
-            ((signalcomp[i]->voltpercm * j) + ((signalcomp[i]->screen_offset * signalcomp[i]->voltpercm) / (painter_pixelsizefactor / printsize_y_factor))) * (double)signalcomp[i]->polarity,
+            ((signalcomp[i]->voltpercm * j) + ((signalcomp[i]->screen_offset_pix * signalcomp[i]->voltpercm) / (painter_pixelsizefactor / printsize_y_factor))) * (double)signalcomp[i]->polarity,
             signalcomp[i]->physdimension);
 
           painter->drawText(5 * printsize_x_factor, baseline - vert_ruler_offset - (4 * printsize_y_factor) - scroll_h_offset, str1_600);
@@ -1012,7 +1012,7 @@ void ViewCurve::drawCurve_stage_2(QPainter *painter, int w_width, int w_height,
           painter->drawLine(0, baseline + vert_ruler_offset - scroll_h_offset, w, baseline + vert_ruler_offset - scroll_h_offset);
 
           snprintf(str1_600, 128, "%+.*f %s", p_decimals,
-            (((signalcomp[i]->screen_offset * signalcomp[i]->voltpercm) / (painter_pixelsizefactor / printsize_y_factor)) - (signalcomp[i]->voltpercm * j)) * (double)signalcomp[i]->polarity,
+            (((signalcomp[i]->screen_offset_pix * signalcomp[i]->voltpercm) / (painter_pixelsizefactor / printsize_y_factor)) - (signalcomp[i]->voltpercm * j)) * (double)signalcomp[i]->polarity,
             signalcomp[i]->physdimension);
 
           painter->drawText(5 * printsize_x_factor, baseline + vert_ruler_offset - (4 * printsize_y_factor) - scroll_h_offset, str1_600);
@@ -1103,7 +1103,7 @@ void ViewCurve::drawCurve_stage_2(QPainter *painter, int w_width, int w_height,
                   {
                     if(!strcmp(chp, signalcomp[k]->signallabel))
                     {
-                      baseline = (vertical_distance * (k + 1)) + signalcomp[k]->screen_offset;
+                      baseline = (vertical_distance * (k + 1)) + signalcomp[k]->screen_offset_pix;
 
                       painter->drawLine(marker_x, baseline + (vertical_distance / 2) - scroll_h_offset, marker_x, baseline - (vertical_distance / 2) - scroll_h_offset);
 
@@ -1614,7 +1614,7 @@ void ViewCurve::drawCurve_stage_2(QPainter *painter, int w_width, int w_height,
     if(signalcomp[i]->hasoffsettracking)
     {
       n = snprintf(str1_600, 128, "offset: %f %s",
-        -signalcomp[i]->screen_offset * mainwindow->y_pixelsizefactor * signalcomp[i]->voltpercm,
+        -signalcomp[i]->screen_offset_pix * mainwindow->y_pixelsizefactor * signalcomp[i]->voltpercm,
         signalcomp[i]->physdimension);
       painter->fillRect((135 * w_scaling) - (mono_font_pixel_width / 2), baseline - (2 * h_scaling) - scroll_h_offset, (n + 1) * mono_font_pixel_width, -15 * h_scaling, backgroundcolor);
       painter->setPen((Qt::GlobalColor)signalcomp[i]->color);


=====================================
vc_signal_props.cpp
=====================================
@@ -75,7 +75,7 @@ void ViewCurve::exec_sidemenu(int signal_nr_intern)
   ScaleBox2->setDecimals(8);
   ScaleBox2->setMaximum(1000000.0);
   ScaleBox2->setMinimum(-1000000.0);
-  ScaleBox2->setValue(-mainwindow->signalcomp[signal_nr]->screen_offset * mainwindow->y_pixelsizefactor * mainwindow->signalcomp[signal_nr]->voltpercm);
+  ScaleBox2->setValue(-mainwindow->signalcomp[signal_nr]->screen_offset_pix * mainwindow->y_pixelsizefactor * mainwindow->signalcomp[signal_nr]->voltpercm);
   ScaleBox2->setSuffix(mainwindow->signalcomp[signal_nr]->physdimension);
   strlcpy(str_32, mainwindow->signalcomp[signal_nr]->physdimension, 32);
   trim_spaces(str_32);
@@ -303,7 +303,7 @@ void ViewCurve::ECGdetectButton()
   {
     newsignalcomp->sensitivity = newsignalcomp->edfparam_0->bitvalue / -5.0 / mainwindow->y_pixelsizefactor;
 
-    newsignalcomp->voltpercm = -5.0;
+    newsignalcomp->voltpercm = -5;
   }
   else
   {
@@ -312,7 +312,9 @@ void ViewCurve::ECGdetectButton()
     newsignalcomp->voltpercm = 5.0;
   }
 
-  newsignalcomp->screen_offset = 55.0 / (mainwindow->y_pixelsizefactor * newsignalcomp->voltpercm);
+  newsignalcomp->screen_offset_unit = -55.0;
+
+  newsignalcomp->screen_offset_pix = -newsignalcomp->screen_offset_unit / (mainwindow->y_pixelsizefactor * newsignalcomp->voltpercm);
 
   mainwindow->setup_viewbuf();
 }
@@ -646,7 +648,9 @@ void ViewCurve::ScaleBox2Changed(double value)
     return;
   }
 
-  mainwindow->signalcomp[signal_nr]->screen_offset = -(value / (mainwindow->y_pixelsizefactor * mainwindow->signalcomp[signal_nr]->voltpercm));
+  mainwindow->signalcomp[signal_nr]->screen_offset_unit = value;
+
+  mainwindow->signalcomp[signal_nr]->screen_offset_pix = -value / (mainwindow->y_pixelsizefactor * mainwindow->signalcomp[signal_nr]->voltpercm);
 
   drawCurve_stage_1();
 }
@@ -672,7 +676,9 @@ void ViewCurve::ScaleBoxChanged(double value)
 
   mainwindow->signalcomp[signal_nr]->voltpercm = value;
 
-  mainwindow->signalcomp[signal_nr]->screen_offset *= (original_value / value);
+  mainwindow->signalcomp[signal_nr]->screen_offset_pix *= (original_value / value);
+
+  mainwindow->signalcomp[signal_nr]->screen_offset_unit *= (original_value / value);
 
   drawCurve_stage_1();
 }


=====================================
version.txt
=====================================
@@ -1,5 +1,15 @@
 
- version 2.11      August 24, 204
+ version 2.12      September 29, 2024
+ --------------
+
+ - When dragging the main window to another screen with a different resolution (dpi),
+   maintain the same offset for traces.
+
+ - Annotation editor: fixed a bug where, after deleting some annotations and then creating new annotations,
+   the new annotaions' duration overlay color was displayed wrong.
+
+
+ version 2.11      August 24, 2024
  --------------
 
  - Increased the maximum number of channels from 640 to 4096.


=====================================
view_montage_dialog.cpp
=====================================
@@ -107,7 +107,6 @@ void UI_ViewMontagewindow::SelectButtonClicked()
       fidfilter_cnt=0,
       islpf,
       signalcomps,
-      screen_offset,
       order,
       model,
       type,
@@ -140,7 +139,7 @@ void UI_ViewMontagewindow::SelectButtonClicked()
 
   double frequency,
          frequency2,
-         voltpercm,
+         voltpercm=1,
          ripple,
          d_tmp,
          velocity,
@@ -150,7 +149,9 @@ void UI_ViewMontagewindow::SelectButtonClicked()
          bp_min_hz=0,
          bp_max_hz=0,
          lp_hz=0,
-         scale_max_amp=0;
+         scale_max_amp=0,
+         screen_offset_pix=0,
+         screen_offset_unit=0;
 
   long long timescale=0LL;
 
@@ -248,20 +249,30 @@ void UI_ViewMontagewindow::SelectButtonClicked()
       return;
     }
     voltpercm = atof(result);
-
     xml_go_up(xml_hdl);
-    if(xml_goto_nth_element_inside(xml_hdl, "screen_offset", 0))
-    {
-      format_error(__FILE__, __LINE__, xml_hdl);
-      return;
-    }
-    if(xml_get_content_of_element(xml_hdl, result, XML_STRBUFLEN))
+
+    if(!xml_goto_nth_element_inside(xml_hdl, "screen_offset_unit", 0))
     {
-      format_error(__FILE__, __LINE__, xml_hdl);
-      return;
+      if(xml_get_content_of_element(xml_hdl, result, XML_STRBUFLEN))
+      {
+        format_error(__FILE__, __LINE__, xml_hdl);
+        return;
+      }
+      screen_offset_unit = atof(result);
+      screen_offset_pix = -screen_offset_unit / (mainwindow->y_pixelsizefactor * voltpercm);
+      xml_go_up(xml_hdl);
     }
-    screen_offset = atoi(result);
-    xml_go_up(xml_hdl);
+    else if(!xml_goto_nth_element_inside(xml_hdl, "screen_offset", 0))
+      {
+        if(xml_get_content_of_element(xml_hdl, result, XML_STRBUFLEN))
+        {
+          format_error(__FILE__, __LINE__, xml_hdl);
+          return;
+        }
+        screen_offset_pix = atof(result);
+        screen_offset_unit = -screen_offset_pix * mainwindow->y_pixelsizefactor * voltpercm;
+        xml_go_up(xml_hdl);
+      }
 
     if(!(xml_goto_nth_element_inside(xml_hdl, "polarity", 0)))
     {
@@ -467,7 +478,7 @@ void UI_ViewMontagewindow::SelectButtonClicked()
 
     remove_trailing_zeros(composition_txt_2048);
 
-    snprintf(composition_txt_2048 + strlen(composition_txt_2048), 2048 - strlen(composition_txt_2048), "/cm  offset: %f", (double)screen_offset * mainwindow->y_pixelsizefactor * voltpercm);
+    snprintf(composition_txt_2048 + strlen(composition_txt_2048), 2048 - strlen(composition_txt_2048), "/cm  offset: %f", screen_offset_unit);
 
     remove_trailing_zeros(composition_txt_2048);
 


=====================================
view_session_dialog.cpp
=====================================
@@ -107,7 +107,6 @@ void UI_ViewSessionwindow::SelectButtonClicked()
       fir_filter_cnt=0,
       islpf,
       signalcomps,
-      screen_offset,
       order,
       model,
       type,
@@ -151,7 +150,7 @@ void UI_ViewSessionwindow::SelectButtonClicked()
 
   double frequency,
          frequency2,
-         voltpercm,
+         voltpercm=1,
          ripple,
          d_tmp,
          velocity,
@@ -161,7 +160,9 @@ void UI_ViewSessionwindow::SelectButtonClicked()
          bp_min_hz=0,
          bp_max_hz=0,
          lp_hz=0,
-         scale_max_amp=0;
+         scale_max_amp=0,
+         screen_offset_pix=0,
+         screen_offset_unit=0;
 
   FILE *f_test=NULL;
 
@@ -472,20 +473,30 @@ void UI_ViewSessionwindow::SelectButtonClicked()
       return;
     }
     voltpercm = atof(result);
-
     xml_go_up(xml_hdl);
-    if(xml_goto_nth_element_inside(xml_hdl, "screen_offset", 0))
-    {
-      view_session_format_error(__FILE__, __LINE__, xml_hdl);
-      return;
-    }
-    if(xml_get_content_of_element(xml_hdl, result, XML_STRBUFLEN))
+
+    if(!xml_goto_nth_element_inside(xml_hdl, "screen_offset_unit", 0))
     {
-      view_session_format_error(__FILE__, __LINE__, xml_hdl);
-      return;
+      if(xml_get_content_of_element(xml_hdl, result, XML_STRBUFLEN))
+      {
+        view_session_format_error(__FILE__, __LINE__, xml_hdl);
+        return;
+      }
+      screen_offset_unit = atof(result);
+      screen_offset_pix = -screen_offset_unit / (mainwindow->y_pixelsizefactor * voltpercm);
+      xml_go_up(xml_hdl);
     }
-    screen_offset = atoi(result);
-    xml_go_up(xml_hdl);
+    else if(!xml_goto_nth_element_inside(xml_hdl, "screen_offset", 0))
+      {
+        if(xml_get_content_of_element(xml_hdl, result, XML_STRBUFLEN))
+        {
+          view_session_format_error(__FILE__, __LINE__, xml_hdl);
+          return;
+        }
+        screen_offset_pix = atof(result);
+        screen_offset_unit = -screen_offset_pix * mainwindow->y_pixelsizefactor * voltpercm;
+        xml_go_up(xml_hdl);
+      }
 
     if(!(xml_goto_nth_element_inside(xml_hdl, "polarity", 0)))
     {
@@ -691,7 +702,7 @@ void UI_ViewSessionwindow::SelectButtonClicked()
 
     remove_trailing_zeros(composition_txt_2048);
 
-    snprintf(composition_txt_2048 + strlen(composition_txt_2048), 2048 - strlen(composition_txt_2048), "/cm  offset: %f", (double)screen_offset * mainwindow->y_pixelsizefactor * voltpercm);
+    snprintf(composition_txt_2048 + strlen(composition_txt_2048), 2048 - strlen(composition_txt_2048), "/cm  offset: %f", screen_offset_unit);
 
     remove_trailing_zeros(composition_txt_2048);
 


=====================================
viewcurve.cpp
=====================================
@@ -566,7 +566,8 @@ void ViewCurve::mousePressEvent(QMouseEvent *press_event)
 
         if((m_y<(baseline-(2*h_scaling)))&&(m_y>( baseline-(2*h_scaling)-mainwindow->mono_font_pixel_height))&&(m_x>(2*w_scaling))&&(m_x<((signallabel_strlen * mainwindow->mono_font_pixel_width) + (5 * w_scaling))))
         {
-          original_screen_offset = signalcomp[i]->screen_offset;
+          original_screen_offset_pix = signalcomp[i]->screen_offset_pix;
+          original_screen_offset_unit = signalcomp[i]->screen_offset_unit;
           signalcomp[i]->hasoffsettracking = 1;
           signal_nr = i;
           pressed_on_label = i + 1;
@@ -618,7 +619,8 @@ void ViewCurve::mousePressEvent(QMouseEvent *press_event)
       if((m_y<(baseline-(2*h_scaling)))&&(m_y>( baseline-(2*h_scaling)-mainwindow->mono_font_pixel_height))&&(m_x>(2*w_scaling))&&(m_x<((signallabel_strlen * mainwindow->mono_font_pixel_width) + (5 * w_scaling))))
       {
         original_sensitivity = signalcomp[i]->sensitivity;
-        original_screen_offset = signalcomp[i]->screen_offset;
+        original_screen_offset_pix = signalcomp[i]->screen_offset_pix;
+        original_screen_offset_unit = signalcomp[i]->screen_offset_unit;
         signalcomp[i]->hasgaintracking = 1;
         use_move_events = 1;
         setMouseTracking(true);
@@ -856,7 +858,7 @@ void ViewCurve::mouseReleaseEvent(QMouseEvent *release_event)
   //
   //                 baseline = (h * mainwindow->mc_v_scrollarea_ratio) / (signalcomps + 1);
   //                 baseline *= (i + 1);
-  //                 baseline += signalcomp[i]->screen_offset;
+  //                 baseline += signalcomp[i]->screen_offset_pix;
 
                   if(signalcomp[i]->draw_rectangle_sum_cnt < 1)  continue;
 
@@ -903,8 +905,8 @@ void ViewCurve::mouseReleaseEvent(QMouseEvent *release_event)
             for(i=0; i<signalcomps; i++)
             {
               mainwindow->zoomhistory->voltpercm[mainwindow->zoomhistory->idx][i] = signalcomp[i]->voltpercm;
-              mainwindow->zoomhistory->screen_offset[mainwindow->zoomhistory->idx][i] = signalcomp[i]->screen_offset;
               mainwindow->zoomhistory->sensitivity[mainwindow->zoomhistory->idx][i] = signalcomp[i]->sensitivity;
+              mainwindow->zoomhistory->screen_offset_unit[mainwindow->zoomhistory->idx][i] = signalcomp[i]->screen_offset_unit;
             }
             mainwindow->zoomhistory->idx++;
             mainwindow->zoomhistory->idx %= MAXZOOMHISTORY;
@@ -931,11 +933,12 @@ void ViewCurve::mouseReleaseEvent(QMouseEvent *release_event)
 
             for(i=0; i<signalcomps; i++)
             {
-              mainwindow->signalcomp[i]->screen_offset *= v_zoomfactor;
-              mainwindow->signalcomp[i]->screen_offset += ((h * mainwindow->mc_v_scrollarea_ratio * (v_zoomfactor - 1) * (double)(i + 1)) / (signalcomps + 1));
-              mainwindow->signalcomp[i]->screen_offset -= (sig_rect_select.y1 * v_zoomfactor) + (scroll_h_offset * (v_zoomfactor - 1));
+              mainwindow->signalcomp[i]->screen_offset_pix *= v_zoomfactor;
+              mainwindow->signalcomp[i]->screen_offset_pix += ((h * mainwindow->mc_v_scrollarea_ratio * (v_zoomfactor - 1) * (double)(i + 1)) / (signalcomps + 1));
+              mainwindow->signalcomp[i]->screen_offset_pix -= (sig_rect_select.y1 * v_zoomfactor) + (scroll_h_offset * (v_zoomfactor - 1));
               mainwindow->signalcomp[i]->voltpercm /= v_zoomfactor;
               mainwindow->signalcomp[i]->sensitivity *= v_zoomfactor;
+              mainwindow->signalcomp[i]->screen_offset_unit = -mainwindow->signalcomp[i]->screen_offset_pix * mainwindow->y_pixelsizefactor * mainwindow->signalcomp[i]->voltpercm;
             }
 
             mainwindow->zoomhistory->history_size_tail++;
@@ -1148,7 +1151,9 @@ void ViewCurve::mouseMoveEvent(QMouseEvent *move_event)
     {
       if(signalcomp[i]->hasoffsettracking)
       {
-        signalcomp[i]->screen_offset = original_screen_offset + delta_y;
+        signalcomp[i]->screen_offset_pix = original_screen_offset_pix + delta_y;
+
+        signalcomp[i]->screen_offset_unit = -signalcomp[i]->screen_offset_pix * mainwindow->y_pixelsizefactor * signalcomp[i]->voltpercm;
       }
 
       if(signalcomp[i]->hasgaintracking)
@@ -1162,7 +1167,9 @@ void ViewCurve::mouseMoveEvent(QMouseEvent *move_event)
           signalcomp[i]->voltpercm = signalcomp[i]->edfparam_0->bitvalue / (signalcomp[i]->sensitivity * mainwindow->y_pixelsizefactor);
         }
 
-        signalcomp[i]->screen_offset = original_screen_offset * (signalcomp[i]->sensitivity / original_sensitivity);
+        signalcomp[i]->screen_offset_pix = original_screen_offset_pix * (signalcomp[i]->sensitivity / original_sensitivity);
+
+        signalcomp[i]->screen_offset_unit = -signalcomp[i]->screen_offset_pix * mainwindow->y_pixelsizefactor * signalcomp[i]->voltpercm;
       }
     }
 
@@ -1759,7 +1766,7 @@ void ViewCurve::drawCurve_stage_1(QPainter *painter, int w_width, int w_height,
         if(((int)dig_value)>signalcomp[i]->max_dig_value)  signalcomp[i]->max_dig_value = dig_value;
         if(((int)dig_value)<signalcomp[i]->min_dig_value)  signalcomp[i]->min_dig_value = dig_value;
 
-        value = baseline - value + (signalcomp[i]->screen_offset * printsize_y_factor);
+        value = baseline - value + (signalcomp[i]->screen_offset_pix * printsize_y_factor);
 
         if(s>=signalcomp[i]->sample_start)
         {
@@ -2136,11 +2143,11 @@ void drawCurve_stage_1_thread::run()
 
       if(printing)
       {
-        value = baseline - value + (int)(signalcomp->screen_offset * printsize_y_factor);
+        value = baseline - value + (int)(signalcomp->screen_offset_pix * printsize_y_factor);
       }
       else
       {
-        value = baseline - value + signalcomp->screen_offset;
+        value = baseline - value + signalcomp->screen_offset_pix;
       }
 
       if(s>=signalcomp->sample_start)


=====================================
viewcurve.h
=====================================
@@ -170,7 +170,8 @@ public:
 
   long long pan_mov_start_viewtime[MAXFILES];
 
-  double original_screen_offset,
+  double original_screen_offset_pix,
+         original_screen_offset_unit,
          w_scaling,
          h_scaling;
 


=====================================
z_score_dialog.cpp
=====================================
@@ -317,7 +317,8 @@ void UI_ZScoreWindow::addTraceButtonClicked()
 
   signalcomp->zratio_crossoverfreq = crossoverSpinbox->value();
 
-  signalcomp->screen_offset = 0.0;
+  signalcomp->screen_offset_pix = 0.0;
+  signalcomp->screen_offset_unit = 0.0;
 
   mainwindow->setup_viewbuf();
 }



View it on GitLab: https://salsa.debian.org/med-team/edfbrowser/-/commit/06f42aed19b4f1b7f39013c38bd6f4c10e3c9e1a

-- 
View it on GitLab: https://salsa.debian.org/med-team/edfbrowser/-/commit/06f42aed19b4f1b7f39013c38bd6f4c10e3c9e1a
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20241009/57971858/attachment-0001.htm>


More information about the debian-med-commit mailing list