Logo Search packages:      
Sourcecode: edfbrowser version File versions  Download package

viewcurve.cpp

/*
***************************************************************************
*
* Author: Teunis van Beelen
*
* Copyright (C) 2007, 2008, 2009 Teunis van Beelen
*
* teuniz@gmail.com
*
***************************************************************************
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
***************************************************************************
*
* This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
***************************************************************************
*/



#include "viewcurve.h"


ViewCurve::ViewCurve(QWidget *parent) : QWidget(parent)
{
  setAttribute(Qt::WA_OpaquePaintEvent);

  mainwindow = (UI_Mainwindow *)parent;

  special_pen = new QPen(Qt::SolidPattern, 0, Qt::DotLine, Qt::SquareCap, Qt::BevelJoin);

  annot_marker_pen = new QPen(Qt::SolidPattern, 0, Qt::DashLine, Qt::SquareCap, Qt::BevelJoin);

  active_markers = (struct active_markersblock *)calloc(1, sizeof(struct active_markersblock));

  annot_marker_moving = 0;

  use_move_events = 0;
  sidemenu_active = 0;
  draw_zoom_rectangle = 0;
  printing = 0;

  original_sensitivity = (double *)calloc(1, sizeof(double[MAXSIGNALS]));

  backgroundcolor = Qt::gray;
  small_ruler_color = Qt::black;
  big_ruler_color = Qt::darkGray;
  mouse_rect_color = Qt::black;
  text_color = Qt::black;
  signal_color = Qt::blue;
  baseline_color = Qt::darkGray;
  crosshair_1_color = Qt::red;
  crosshair_2_color = Qt::cyan;
  floating_ruler_color = Qt::red;
  annot_marker_color = Qt::white;

  crosshair_1_active = 0;
  crosshair_2_active = 0;
  ruler_active = 0;
  crosshair_1_moving = 0;
  crosshair_2_moving = 0;
  ruler_moving = 0;

  crosshair_1_value = 0.0;
  crosshair_2_value = 0.0;

  printsize_x_factor=1.0,
  printsize_y_factor=1.0;

  printfont = new QFont;
  printfont->setFamily("Arial");

  screensamples = (int *)calloc(1, sizeof(int[MAXSIGNALS]));

  graphicBuf = NULL;
  printBuf = NULL;
  graphicBufWidth = 0;
  blackwhite_printing = 1;
  floating_ruler_value = 0;
}



void ViewCurve::mousePressEvent(QMouseEvent *event)
{
  int i, j, w, h,
      baseline,
      signalcomps,
      m_x,
      m_y,
      pressed_on_label=0,
      h_size;

  struct signalcompblock **signalcomp;

  if(!mainwindow->files_open)  return;
  if(!mainwindow->signalcomps)  return;

  w = width();
  h = height();
  signalcomps = mainwindow->signalcomps;
  signalcomp = mainwindow->signalcomp;
  m_x = event->x();
  m_y = event->y();

  mouse_press_coordinate_x = m_x;
  mouse_press_coordinate_y = m_y;

  h_size = (int)(4.0 / mainwindow->pixelsizefactor);

  setFocus(Qt::MouseFocusReason);

  if(event->button()==Qt::LeftButton)
  {
    crosshair_1_moving = 0;
    crosshair_2_moving = 0;
    ruler_moving = 0;

    use_move_events = 1;
    setMouseTracking(TRUE);

    mouse_old_x = m_x;
    mouse_old_y = m_y;

    if(ruler_active)
    {
      if((m_y>(ruler_y_position + h_size + 10))&&(m_y<(ruler_y_position  + h_size + 30))&&(m_x>ruler_x_position)&&(m_x<(ruler_x_position + 60)))
      {
        if(floating_ruler_value)
        {
          floating_ruler_value = 0;
        }
        else
        {
          floating_ruler_value = 1;
        }

        update();

        return;
      }
      else if((m_y>ruler_y_position)&&(m_y<(ruler_y_position + ((int)(4.0 / mainwindow->pixelsizefactor))))&&(m_x>ruler_x_position)&&(m_x<(ruler_x_position + 150 + (w / 5))))
      {
        ruler_moving = 1;
      }
    }

    if(!ruler_moving)
    {
      if(crosshair_1_active)
      {
        if((m_y<crosshair_1_y_position)&&(m_y>(crosshair_1_y_position - 51))&&(m_x>crosshair_1_x_position)&&(m_x<(crosshair_1_x_position + 171)))
        {
          crosshair_1_moving = 1;
        }

        if(m_x>(crosshair_1_x_position-10)&&(m_x<(crosshair_1_x_position + 10)))
        {
          crosshair_1_moving = 1;
        }
      }
    }

    if((!ruler_moving)&&(!crosshair_1_moving))
    {
      if(crosshair_2_active)
      {
        if((m_y<crosshair_2_y_position)&&(m_y>(crosshair_2_y_position - 80))&&(m_x>crosshair_2_x_position)&&(m_x<(crosshair_2_x_position + 171)))
        {
          crosshair_2_moving = 1;
        }

        if(m_x>(crosshair_2_x_position-10)&&(m_x<(crosshair_2_x_position + 10)))
        {
          crosshair_2_moving = 1;
        }
      }
    }

    if(mainwindow->annot_editor_active)
    {
      if((!ruler_moving)&&(!crosshair_1_moving)&&(!crosshair_2_moving))
      {
        for(i=0; i<active_markers->count; i++)
        {
          if(m_x>(active_markers->list[i]->x_pos-5)&&(m_x<(active_markers->list[i]->x_pos+5)))
          {
            active_markers->selected = i;

            annot_marker_moving = 1;

            active_markers->list[i]->selected = 1;

            break;
          }
        }
      }
    }

    if((!ruler_moving)&&(!crosshair_1_moving)&&(!crosshair_2_moving)&&(!annot_marker_moving))
    {
      for(i=0; i<signalcomps; i++)
      {
        baseline = h / (signalcomps + 1);
        baseline *= (i + 1);

        if((m_y<(baseline-5))&&(m_y>(baseline-24))&&(m_x>3)&&(m_x<110))
        {
          original_screen_offset = signalcomp[i]->screen_offset;
          signalcomp[i]->hasoffsettracking = 1;
          signal_nr = i;
          pressed_on_label = 1;

          break;
        }
      }
    }

    if((!pressed_on_label)&&(!ruler_moving)&&(!crosshair_1_moving)&&(!crosshair_2_moving)&&(!annot_marker_moving))
    {
      draw_zoom_rectangle = 1;
    }
  }

  if(event->button()==Qt::RightButton)
  {
    for(i=0; i<signalcomps; i++)
    {
      signalcomp[i]->hascursor1 = 0;
      signalcomp[i]->hascursor2 = 0;
      signalcomp[i]->hasoffsettracking = 0;
    }
    crosshair_1_active = 0;
    crosshair_2_active = 0;
    crosshair_1_moving = 0;
    crosshair_2_moving = 0;
    use_move_events = 0;
    setMouseTracking(FALSE);

    for(i=0; i<signalcomps; i++)
    {
      baseline = h / (signalcomps + 1);
      baseline *= (i + 1);

      if((m_y<(baseline-5))&&(m_y>(baseline-24))&&(m_x>3)&&(m_x<110))
      {
        for(j=0; j<signalcomp[i]->num_of_signals; j++)
        {
          original_sensitivity[j] = signalcomp[i]->sensitivity[j];
        }
        original_screen_offset = signalcomp[i]->screen_offset;
        signalcomp[i]->hasgaintracking = 1;
        use_move_events = 1;
        setMouseTracking(TRUE);
        signal_nr = i;

        break;
      }
    }

    if(!use_move_events)
    {
      for(i=0; i<signalcomps; i++)
      {
        signalcomp[i]->hasruler = 0;
      }
      ruler_active = 0;
      ruler_moving = 0;

      update();
    }
  }
}


void ViewCurve::mouseReleaseEvent(QMouseEvent *event)
{
  int i, j, w, h, baseline, signalcomps,
      m_x,
      m_y;

  double zoomfactor;

  struct signalcompblock **signalcomp;

  if(!mainwindow->files_open)  return;
  if(!mainwindow->signalcomps)  return;

  w = width();
  h = height();
  signalcomps = mainwindow->signalcomps;
  signalcomp = mainwindow->signalcomp;
  m_x = event->x();
  m_y = event->y();

  if(event->button()==Qt::LeftButton)
  {
    if(crosshair_1_moving)
    {
      mainwindow->annotationEditDock->annotEditSetOnset(crosshair_1_time_relative);
    }

    if(crosshair_2_moving)
    {
      mainwindow->annotationEditDock->annotEditSetDuration(crosshair_2_time_relative - crosshair_1_time_relative);
    }

    if(annot_marker_moving)
    {
      active_markers->list[active_markers->selected]->x_pos = m_x;

      active_markers->list[active_markers->selected]->onset = ((long long)((((double)m_x) / w) * mainwindow->pagetime))
                                                               + mainwindow->edfheaderlist[active_markers->file_num]->viewtime;

      active_markers->list[active_markers->selected]->modified = 1;

      active_markers->list[active_markers->selected]->selected = 1;

      mainwindow->annotationEditDock->set_selected_annotation(active_markers->list[active_markers->selected]);

      mainwindow->annotations_dock[active_markers->file_num]->updateList(active_markers->file_num);

      mainwindow->annotations_edited = 1;

      update();
    }

    ruler_moving = 0;
    crosshair_1_moving = 0;
    crosshair_2_moving = 0;
    annot_marker_moving = 0;
    use_move_events = 0;
    setMouseTracking(FALSE);

    if(draw_zoom_rectangle)
    {
      draw_zoom_rectangle = 0;

      if((m_x>(mouse_press_coordinate_x + 50))&&(m_y > mouse_press_coordinate_y + 50))
      {
        for(i=0; i<mainwindow->files_open; i++)
        {
          mainwindow->zoomhistory->viewtime[mainwindow->zoomhistory->pntr][i] = mainwindow->edfheaderlist[i]->viewtime;
        }
        mainwindow->zoomhistory->pagetime[mainwindow->zoomhistory->pntr] = mainwindow->pagetime;
        for(i=0; i<signalcomps; i++)
        {
          mainwindow->zoomhistory->voltpercm[mainwindow->zoomhistory->pntr][i] = signalcomp[i]->voltpercm;
          mainwindow->zoomhistory->screen_offset[mainwindow->zoomhistory->pntr][i] = signalcomp[i]->screen_offset;

          for(j=0; j<signalcomp[i]->num_of_signals; j++)
          {
            mainwindow->zoomhistory->sensitivity[mainwindow->zoomhistory->pntr][i][j] = signalcomp[i]->sensitivity[j];
          }
        }
        mainwindow->zoomhistory->pntr++;
        mainwindow->zoomhistory->pntr %= 64;

        for(i=0; i<mainwindow->files_open; i++)
        {
          mainwindow->edfheaderlist[i]->viewtime += (long long)(((double)mainwindow->pagetime / (double)w) * (double)mouse_press_coordinate_x);
        }
        mainwindow->pagetime = (long long)((double)mainwindow->pagetime / ((double)w / (double)(m_x - mouse_press_coordinate_x)));
        if(mainwindow->pagetime<1)  mainwindow->pagetime = 1;

        zoomfactor = (double)h / (double)(m_y - mouse_press_coordinate_y);

        for(i=0; i<signalcomps; i++)
        {
          mainwindow->signalcomp[i]->screen_offset = (int)((double)mainwindow->signalcomp[i]->screen_offset * zoomfactor);
          mainwindow->signalcomp[i]->screen_offset += (int)(((double)h * (zoomfactor - 1.0) * (double)(i + 1)) / (double)(signalcomps + 1));
          mainwindow->signalcomp[i]->screen_offset -= (int)((double)mouse_press_coordinate_y * zoomfactor);

          mainwindow->signalcomp[i]->voltpercm = (int)((double)mainwindow->signalcomp[i]->voltpercm / ((double)h / (double)(m_y - mouse_press_coordinate_y)));

          for(j=0; j<mainwindow->signalcomp[i]->num_of_signals; j++)
          {
            mainwindow->signalcomp[i]->sensitivity[j] =  mainwindow->signalcomp[i]->sensitivity[j] * ((double)h / (double)(m_y - mouse_press_coordinate_y));
          }
        }

        mainwindow->zoomhistory->history_size_tail++;
        mainwindow->zoomhistory->history_size_front = 0;

        mainwindow->setup_viewbuf();
      }
      else
      {
        update();
      }
    }

    for(i=0; i<signalcomps; i++)
    {
      if(signalcomp[i]->hasoffsettracking)
      {
        signalcomp[i]->hasoffsettracking = 0;
        use_move_events = 0;
        setMouseTracking(FALSE);
        update();
      }
    }

    for(i=0; i<signalcomps; i++)
    {
      baseline = h / (signalcomps + 1);
      baseline *= (i + 1);

      if((m_y<(baseline-5))&&(m_y>(baseline-24))&&(m_x>3)&&(m_x<110))
      {
        use_move_events = 0;
        setMouseTracking(FALSE);
        update();

        signal_nr = i;
        exec_sidemenu(i);

        break;
      }
    }
  }

  if(event->button()==Qt::RightButton)
  {
    for(i=0; i<signalcomps; i++)
    {
      if(signalcomp[i]->hasgaintracking)
      {
        signalcomp[i]->hasgaintracking = 0;
        use_move_events = 0;
        setMouseTracking(FALSE);
        update();
      }
    }
  }
}


void ViewCurve::mouseMoveEvent(QMouseEvent *event)
{
  int i, j, signalcomps, delta_y;

  double d_temp;

  struct signalcompblock **signalcomp;

  if(!mainwindow->files_open)  return;
  if(!mainwindow->signalcomps)  return;

  if(use_move_events)
  {
    signalcomps = mainwindow->signalcomps;
    signalcomp = mainwindow->signalcomp;
    mouse_x = event->x();
    mouse_y = event->y();

    if(crosshair_1_moving)
    {
      if(mouse_x<(w-100))
      {
        crosshair_1_x_position += (mouse_x - mouse_old_x);
        mouse_old_x = mouse_x;
        if(crosshair_1_x_position<1)
        {
          crosshair_1_x_position = 1;
        }
      }

      if((mouse_y<(h-30))&&(mouse_y>30))
      {
        crosshair_1_y_position += (mouse_y - mouse_old_y);
        mouse_old_y = mouse_y;
        if(crosshair_1_y_position<1)
        {
          crosshair_1_y_position = 1;
        }
      }
    }

    if(crosshair_2_moving)
    {
      if(mouse_x<(w-100))
      {
        crosshair_2_x_position += (mouse_x - mouse_old_x);
        mouse_old_x = mouse_x;
        if(crosshair_2_x_position<1)
        {
          crosshair_2_x_position = 1;
        }
      }

      if((mouse_y<(h-30))&&(mouse_y>30))
      {
        crosshair_2_y_position += (mouse_y - mouse_old_y);
        mouse_old_y = mouse_y;
        if(crosshair_2_y_position<1)
        {
          crosshair_2_y_position = 1;
        }
      }
    }

    if(ruler_moving)
    {
      if(mouse_x<(w-100))
      {
        ruler_x_position += (mouse_x - mouse_old_x);
        mouse_old_x = mouse_x;
        if(ruler_x_position<1)
        {
          ruler_x_position = 1;
        }
      }

      if(mouse_y<(h-100))
      {
        ruler_y_position += (mouse_y - mouse_old_y);
        mouse_old_y = mouse_y;
        if(ruler_y_position<1)
        {
          ruler_y_position = 1;
        }
      }
    }

    if(annot_marker_moving)
    {
      active_markers->list[active_markers->selected]->x_pos = mouse_x;

      active_markers->list[active_markers->selected]->onset = ((long long)((((double)mouse_x) / w) * mainwindow->pagetime))
                                                               + mainwindow->edfheaderlist[active_markers->file_num]->viewtime;
    }

    delta_y = mouse_y - mouse_press_coordinate_y;

    for(i=0; i<signalcomps; i++)
    {
      if(signalcomp[i]->hasoffsettracking)
      {
        signalcomp[i]->screen_offset = original_screen_offset + delta_y;
      }

      if(signalcomp[i]->hasgaintracking)
      {
        for(j=0; j<signalcomp[i]->num_of_signals; j++)
        {
          d_temp = original_sensitivity[j] * (1.0 + ((double)(-delta_y) / 50.0));

          if(d_temp>0.000001)
          {
            signalcomp[i]->sensitivity[j] = d_temp;

            d_temp = signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].bitvalue / (signalcomp[i]->sensitivity[j] * mainwindow->pixelsizefactor);

            signalcomp[i]->voltpercm = d_temp;
          }
        }

        signalcomp[i]->screen_offset = (int)((double)original_screen_offset * (signalcomp[i]->sensitivity[0] / original_sensitivity[0]));
      }
    }

    if(draw_zoom_rectangle||annot_marker_moving)
    {
      update();
    }
    else
    {
      drawCurve_stage_1();
    }
  }
}


void ViewCurve::paintEvent(QPaintEvent *)
{
  QPainter paint(this);
  drawCurve_stage_2(&paint);
}


void ViewCurve::print_to_printer()
{
  int i, j,
      len;

  char path[1024];

  double height_factor;

  struct date_time_struct date_time;


  if(!mainwindow->files_open)  return;
  if(!mainwindow->signalcomps)  return;

  QPrinter printer(QPrinter::HighResolution);

  printer.setOutputFormat(QPrinter::NativeFormat);
  printer.setPageSize(QPrinter::A4);
  printer.setOrientation(QPrinter::Landscape);
  printer.setCreator(PROGRAM_NAME);

  QPrintDialog printerdialog(&printer, this);
  printerdialog.setWindowTitle("Print");

  if(printerdialog.exec()==QDialog::Accepted)
  {
    if(blackwhite_printing)
    {
      backup_colors_for_printing();
    }

    height_factor = ((double)printer.pageRect().height()) / 9000.0;

    QPainter paint(&printer);

    paint.translate(0, (int)(260.0 * height_factor));

    drawCurve_stage_1(&paint, printer.pageRect().width(), (int)((double)printer.pageRect().height() - (260.0 * height_factor)));

    paint.translate(0, -(int)(260.0 * height_factor));

    len = strlen(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename);
    for(i=len-1; i>=0; i--)
    {
      if((mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename[i] == '/')||(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename[i] == '\\'))  break;
    }
    i++;

    printfont->setPixelSize((int)((double)printer.pageRect().width() / 104.0));
    paint.setPen(text_color);
    paint.setFont(*printfont);

    strcpy(path, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename + i);
    strcat(path, "     ");
    strcat(path, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->patient);
    len = strlen(path);
    for(j=0; j<len; j++)
    {
      if(path[j]=='_')
      {
        path[j] = ' ';
      }
    }

    paint.drawText(0, (int)(160.0 * height_factor), path);

    utc_to_date_time(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->utc_starttime, &date_time);

    date_time.month_str[0] += 32;
    date_time.month_str[1] += 32;
    date_time.month_str[2] += 32;

    sprintf(path, "     %i %s %i    ",
            date_time.day,
            date_time.month_str,
            date_time.year);

    if(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->edfplus||mainwindow->edfheaderlist[mainwindow->sel_viewtime]->bdfplus)
    {
      strcat(path, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->recording + 22);
    }
    else
    {
      strcat(path, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->recording);
    }

    len = strlen(path);
    for(j=0; j<len; j++)
    {
      if(path[j]=='_')
      {
        path[j] = ' ';
      }
    }

    paint.drawText(printer.pageRect().width() / 2, (int)(160.0 * height_factor), path);

    if(blackwhite_printing)
    {
      restore_colors_after_printing();
    }

    drawCurve_stage_1();
  }
}


void ViewCurve::print_to_postscript()
{
  double height_factor;

  int i, j,
      len;

  char path[1024];

  QFileDialog fchooser;

  QStringList fileNames;

  struct date_time_struct date_time;

  if(!mainwindow->files_open)  return;
  if(!mainwindow->signalcomps)  return;

  fchooser.setViewMode(QFileDialog::Detail);
  fchooser.setConfirmOverwrite(1);
  fchooser.setFileMode(QFileDialog::AnyFile);
  fchooser.setAcceptMode(QFileDialog::AcceptSave);
  fchooser.setWindowTitle("Print to PostScript");
  fchooser.setLabelText(QFileDialog::FileName, "File");
  fchooser.setDefaultSuffix("ps");
  fchooser.setDirectory(mainwindow->recent_savedir);
  fchooser.setFilter("PostScript files (*.ps *.PS)");

  len = strlen(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename);
  for(i=len-1; i>=0; i--)
  {
    if((mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename[i] == '/')||(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename[i] == '\\'))
    {
      break;
    }
  }
  i++;

  strcpy(path, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename + i);
  for(i=0; ; i++)
  {
    if(path[i]==0)  break;
    if(path[i]=='.')
    {
      path[i] = 0;
      break;
    }
  }
  strcat(path, ".ps");
  fchooser.selectFile(path);

  if(!(fchooser.exec() == QDialog::Accepted))
  {
    return;
  }

  strcpy(mainwindow->recent_savedir, fchooser.directory().absolutePath().toLatin1().data());

  fileNames = fchooser.selectedFiles();

  QPrinter printer(QPrinter::HighResolution);

  printer.setOutputFormat(QPrinter::PostScriptFormat);
  printer.setOutputFileName(fileNames.at(0));
  printer.setPageSize(QPrinter::A4);
  printer.setOrientation(QPrinter::Landscape);
  printer.setCreator(PROGRAM_NAME);

  if(blackwhite_printing)
  {
    backup_colors_for_printing();
  }

  height_factor = ((double)printer.pageRect().height()) / 9000.0;

  QPainter paint(&printer);

  paint.translate(0, (int)(260.0 * height_factor));

  drawCurve_stage_1(&paint, printer.pageRect().width(), (int)((double)printer.pageRect().height() - (260.0 * height_factor)));

  paint.translate(0, -(int)(260.0 * height_factor));

  len = strlen(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename);
  for(i=len; i>=0; i--)
  {
    if((mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename[i] == '/')||(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename[i] == '\\'))
    {
      break;
    }
  }
  i++;

  strcpy(path, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename + i);
  strcat(path, "     ");
  strcat(path, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->patient);
  len = strlen(path);
  for(j=0; j<len; j++)
  {
    if(path[j]=='_')
    {
      path[j] = ' ';
    }
  }

  printfont->setPixelSize((int)((double)printer.pageRect().width() / 104.0));

  paint.setPen(text_color);
  paint.setFont(*printfont);

  paint.drawText(0, (int)(160.0 * height_factor), path);

  utc_to_date_time(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->utc_starttime, &date_time);

  date_time.month_str[0] += 32;
  date_time.month_str[1] += 32;
  date_time.month_str[2] += 32;

  sprintf(path, "     %i %s %i    ",
          date_time.day,
          date_time.month_str,
          date_time.year);

  if(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->edfplus||mainwindow->edfheaderlist[mainwindow->sel_viewtime]->bdfplus)
  {
    strcat(path, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->recording + 22);
  }
  else
  {
    strcat(path, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->recording);
  }

  len = strlen(path);
  for(j=0; j<len; j++)
  {
    if(path[j]=='_')
    {
      path[j] = ' ';
    }
  }

  paint.drawText(printer.pageRect().width() / 2, (int)(160.0 * height_factor), path);

  if(blackwhite_printing)
  {
    restore_colors_after_printing();
  }

  drawCurve_stage_1();
}


void ViewCurve::print_to_pdf()
{
  double height_factor;

  int i, j,
      len;

  char path[1024];

  QFileDialog fchooser;

  QStringList fileNames;

  struct date_time_struct date_time;

  if(!mainwindow->files_open)  return;
  if(!mainwindow->signalcomps)  return;

  fchooser.setViewMode(QFileDialog::Detail);
  fchooser.setConfirmOverwrite(1);
  fchooser.setFileMode(QFileDialog::AnyFile);
  fchooser.setAcceptMode(QFileDialog::AcceptSave);
  fchooser.setWindowTitle("Print to PDF");
  fchooser.setLabelText(QFileDialog::FileName, "File");
  fchooser.setDefaultSuffix("pdf");
  fchooser.setDirectory(mainwindow->recent_savedir);
  fchooser.setFilter("PDF files (*.pdf *.PDF)");

  len = strlen(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename);
  for(i=len-1; i>=0; i--)
  {
    if((mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename[i] == '/')||(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename[i] == '\\'))
    {
      break;
    }
  }
  i++;

  strcpy(path, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename + i);
  for(i=0; ; i++)
  {
    if(path[i]==0)  break;
    if(path[i]=='.')
    {
      path[i] = 0;
      break;
    }
  }
  strcat(path, ".pdf");
  fchooser.selectFile(path);

  if(!(fchooser.exec() == QDialog::Accepted))
  {
    return;
  }

  strcpy(mainwindow->recent_savedir, fchooser.directory().absolutePath().toLatin1().data());

  fileNames = fchooser.selectedFiles();

  QPrinter printer(QPrinter::HighResolution);

  printer.setOutputFormat(QPrinter::PdfFormat);
  printer.setOutputFileName(fileNames.at(0));
  printer.setPageSize(QPrinter::A4);
  printer.setOrientation(QPrinter::Landscape);
  printer.setCreator(PROGRAM_NAME);

  if(blackwhite_printing)
  {
    backup_colors_for_printing();
  }

  height_factor = ((double)printer.pageRect().height()) / 9000.0;

  QPainter paint(&printer);

  paint.translate(0, (int)(260.0 * height_factor));

  drawCurve_stage_1(&paint, printer.pageRect().width(), (int)((double)printer.pageRect().height() - (260.0 * height_factor)));

  paint.translate(0, -(int)(260.0 * height_factor));

  len = strlen(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename);
  for(i=len; i>=0; i--)
  {
    if((mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename[i] == '/')||(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename[i] == '\\'))
    {
      break;
    }
  }
  i++;

  strcpy(path, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename + i);
  strcat(path, "     ");
  strcat(path, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->patient);
  len = strlen(path);
  for(j=0; j<len; j++)
  {
    if(path[j]=='_')
    {
      path[j] = ' ';
    }
  }

  printfont->setPixelSize((int)((double)printer.pageRect().width() / 104.0));

  paint.setPen(text_color);
  paint.setFont(*printfont);

  paint.drawText(0, (int)(160.0 * height_factor), path);

  utc_to_date_time(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->utc_starttime, &date_time);

  date_time.month_str[0] += 32;
  date_time.month_str[1] += 32;
  date_time.month_str[2] += 32;

  sprintf(path, "     %i %s %i    ",
          date_time.day,
          date_time.month_str,
          date_time.year);

  if(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->edfplus||mainwindow->edfheaderlist[mainwindow->sel_viewtime]->bdfplus)
  {
    strcat(path, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->recording + 22);
  }
  else
  {
    strcat(path, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->recording);
  }

  len = strlen(path);
  for(j=0; j<len; j++)
  {
    if(path[j]=='_')
    {
      path[j] = ' ';
    }
  }

  paint.drawText(printer.pageRect().width() / 2, (int)(160.0 * height_factor), path);

  if(blackwhite_printing)
  {
    restore_colors_after_printing();
  }

  drawCurve_stage_1();
}


void ViewCurve::print_to_image(int w, int h)
{
  int i, j, len;

  char path[1024];

  QFileDialog fchooser;

  QStringList fileNames;

  struct date_time_struct date_time;

  if(!mainwindow->files_open)  return;
  if(!mainwindow->signalcomps)  return;

  fchooser.setViewMode(QFileDialog::Detail);
  fchooser.setConfirmOverwrite(1);
  fchooser.setFileMode(QFileDialog::AnyFile);
  fchooser.setAcceptMode(QFileDialog::AcceptSave);
  fchooser.setWindowTitle("Print to Image");
  fchooser.setLabelText(QFileDialog::FileName, "File");
  fchooser.setDefaultSuffix("png");
  fchooser.setDirectory(mainwindow->recent_savedir);
  fchooser.setFilter("PNG files (*.png *.PNG)");

  len = strlen(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename);
  for(i=len-1; i>=0; i--)
  {
    if((mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename[i] == '/')||(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename[i] == '\\'))
    {
      break;
    }
  }
  i++;

  strcpy(path, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename + i);
  for(i=0; ; i++)
  {
    if(path[i]==0)  break;
    if(path[i]=='.')
    {
      path[i] = 0;
      break;
    }
  }
  strcat(path, ".png");
  fchooser.selectFile(path);

  if(!(fchooser.exec() == QDialog::Accepted))
  {
    return;
  }

  strcpy(mainwindow->recent_savedir, fchooser.directory().absolutePath().toLatin1().data());

  fileNames = fchooser.selectedFiles();

  QPixmap pixmap(w, h);

  QPainter paint(&pixmap);

  paint.fillRect(0, 0, w, h, backgroundcolor);

  paint.translate(0, 25);

  drawCurve_stage_1(&paint, w, h - 25);

  paint.translate(0, -25);

  len = strlen(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename);
  for(i=len; i>=0; i--)
  {
    if((mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename[i] == '/')||(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename[i] == '\\'))
    {
      break;
    }
  }
  i++;

  strcpy(path, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename + i);
  strcat(path, "     ");
  strcat(path, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->patient);
  len = strlen(path);
  for(j=0; j<len; j++)
  {
    if(path[j]=='_')
    {
      path[j] = ' ';
    }
  }

  printfont->setPixelSize((int)((double)w / 104.0));
  paint.setPen(text_color);
  paint.setFont(*printfont);

  paint.drawText(5, 15, path);

  utc_to_date_time(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->utc_starttime, &date_time);

  date_time.month_str[0] += 32;
  date_time.month_str[1] += 32;
  date_time.month_str[2] += 32;

  sprintf(path, "     %i %s %i    ",
          date_time.day,
          date_time.month_str,
          date_time.year);

  if(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->edfplus||mainwindow->edfheaderlist[mainwindow->sel_viewtime]->bdfplus)
  {
    strcat(path, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->recording + 22);
  }
  else
  {
    strcat(path, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->recording);
  }

  len = strlen(path);
  for(j=0; j<len; j++)
  {
    if(path[j]=='_')
    {
      path[j] = ' ';
    }
  }

  paint.drawText(320, 15, path);

  pixmap.save(fileNames.at(0), "PNG", 90);

  drawCurve_stage_1();
}


void ViewCurve::drawCurve_stage_2(QPainter *painter, int w_width, int w_height)
{
  int i, j, x=0,
      signalcomps,
      baseline,
      m_pagetime,
      vert_ruler_offset,
      vertical_distance,
      marker_x;

  char *viewbuf,
       string[256],
       str2[32];

  long long time_ppixel,
            elapsed_time,
            l_time,
            l_tmp;

  struct signalcompblock **signalcomp;

  struct annotationblock *annot;

  QFont paintersfont;

  signalcomps = mainwindow->signalcomps;
  signalcomp = mainwindow->signalcomp;
  viewbuf = mainwindow->viewbuf;

  painter_pixelsizefactor = 1.0 / mainwindow->pixelsizefactor;

  if(!w_width||!w_height)
  {
    w = width();
    h = height();

    paintersfont = *mainwindow->myfont;
    paintersfont.setBold(TRUE);
    paintersfont.setWeight(QFont::Black);
    painter->setFont(paintersfont);

    printing = 0;
  }
  else
  {
    w = w_width;
    h = w_height;

#ifdef Q_WS_X11
    printfont->setPixelSize((int)((double)w / 104.0));
#endif

#ifdef Q_WS_MAC
    printfont->setPixelSize((int)((double)w / 104.0));
#endif

#ifdef Q_WS_WIN
    printfont->setPixelSize((int)((double)w / 104.0));
#endif

    painter->setFont(*printfont);

    printsize_x_factor = ((double)w_width) / ((double)width());
    printsize_y_factor = ((double)w_height) / ((double)height());

    painter_pixelsizefactor *= printsize_y_factor;

    printing = 1;
  }

  for(i=0; i<signalcomps; i++)
  {
    signalcomp[i]->sample_pixel_ratio = (double)signalcomp[i]->samples_on_screen / (double)w;
  }

  painter->fillRect(0, 0, w, h, backgroundcolor);

  m_pagetime = (int)(mainwindow->pagetime / TIME_DIMENSION);

  time_ppixel = mainwindow->pagetime / w;

  if(mainwindow->files_open&&mainwindow->signalcomps)
  {
    elapsed_time = mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime;
  }
  else
  {
    elapsed_time = 0;
  }

  if(m_pagetime<=20)
  {
    painter->setPen(small_ruler_color);

    for(x=0; x<w; x++)
    {
      if((elapsed_time / (TIME_DIMENSION / 10))!=((elapsed_time + time_ppixel) / (TIME_DIMENSION / 10)))
      {
        painter->drawLine(x, 0, x, 4);
      }

      if((elapsed_time / TIME_DIMENSION)!=((elapsed_time + time_ppixel) / TIME_DIMENSION))
      {
        if(x)
        {
          painter->setPen(big_ruler_color);
          painter->drawLine(x, 0, x, h);
          painter->setPen(small_ruler_color);
        }
        painter->drawLine(x, 0, x, 7);
      }

      elapsed_time += time_ppixel;
    }
  }

  if((m_pagetime>20)&&(m_pagetime<100))
  {
    painter->setPen(small_ruler_color);

    for(x=0; x<w; x++)
    {
      if((elapsed_time / (TIME_DIMENSION / 5))!=((elapsed_time + time_ppixel) / (TIME_DIMENSION / 5)))
      {
        painter->drawLine(x, 0, x, 4);
      }

      if((elapsed_time / TIME_DIMENSION)!=((elapsed_time + time_ppixel) / TIME_DIMENSION))
      {
        if(x)
        {
          painter->setPen(big_ruler_color);
          painter->drawLine(x, 0, x, h);
          painter->setPen(small_ruler_color);
        }
        painter->drawLine(x, 0, x, 7);
      }

      elapsed_time += time_ppixel;
    }
  }

  if((m_pagetime>=100)&&(m_pagetime<1000))
  {
    painter->setPen(small_ruler_color);

    for(x=0; x<w; x++)
    {
      if((elapsed_time / 33333333LL)!=((elapsed_time + time_ppixel) / 33333333LL))
      {
        painter->drawLine(x, 0, x, 4);
      }

      if((elapsed_time / (TIME_DIMENSION * 10))!=((elapsed_time + time_ppixel) / (TIME_DIMENSION * 10)))
      {
        if(x)
        {
          painter->setPen(big_ruler_color);
          painter->drawLine(x, 0, x, h);
          painter->setPen(small_ruler_color);
        }
        painter->drawLine(x, 0, x, 7);
      }

      elapsed_time += time_ppixel;
    }
  }

  if((m_pagetime>=1000)&&(m_pagetime<5000))
  {
    painter->setPen(small_ruler_color);

    for(x=0; x<w; x++)
    {
      if((elapsed_time / (TIME_DIMENSION * 10))!=((elapsed_time + time_ppixel) / (TIME_DIMENSION * 10)))
      {
        painter->drawLine(x, 0, x, 4);
      }

      if((elapsed_time / (TIME_DIMENSION * 60))!=((elapsed_time + time_ppixel) / (TIME_DIMENSION * 60)))
      {
        if(x)
        {
          painter->setPen(big_ruler_color);
          painter->drawLine(x, 0, x, h);
          painter->setPen(small_ruler_color);
        }
        painter->drawLine(x, 0, x, 7);
      }

      elapsed_time += time_ppixel;
    }
  }

  if((viewbuf==NULL)||(graphicBuf==NULL)||(screensamples==NULL))
  {
    return;
  }

  if(mainwindow->show_annot_markers)
  {
    annot_marker_pen->setColor(annot_marker_color);

    painter->setPen(*annot_marker_pen);

    if(!annot_marker_moving)
    {
      active_markers->count = 0;
    }

    for(i=0; i<mainwindow->files_open; i++)
    {
      annot = mainwindow->annotationlist[i];

      while(annot!=NULL)
      {
        if(annot->onset > mainwindow->edfheaderlist[i]->viewtime)
        {
          if(annot->onset > (mainwindow->edfheaderlist[i]->viewtime + mainwindow->pagetime))
          {
            break;
          }

          l_tmp = annot->onset - mainwindow->edfheaderlist[i]->viewtime;

          marker_x = (int)((((double)w) / mainwindow->pagetime) * l_tmp);

          painter->drawLine(marker_x, 0, marker_x, h);

          snprintf(string, 32, "%2i:%02i:%02i.%04i",
                  (int)((annot->onset / TIME_DIMENSION)/ 3600LL),
                  (int)(((annot->onset / TIME_DIMENSION) % 3600LL) / 60LL),
                  (int)((annot->onset / TIME_DIMENSION) % 60LL),
                  (int)(((annot->onset % TIME_DIMENSION) / 1000LL)));

          if(printing)
          {
            painter->drawText(marker_x + (5  * printsize_x_factor), h - (25  * printsize_y_factor), string);
          }
          else
          {
            painter->drawText(marker_x + 5, h - 25, string);
          }

          strncpy(string, annot->annotation, 20);

          string[20] = 0;

          if(printing)
          {
            painter->drawText(marker_x + (5  * printsize_x_factor), h - (40  * printsize_y_factor), string);
          }
          else
          {
            painter->drawText(marker_x + 5, h - 40, string);
          }

          if(!annot_marker_moving)
          {
            if(active_markers->count<MAX_ACTIVE_ANNOT_MARKERS)
            {
              annot->x_pos = marker_x;

              active_markers->list[active_markers->count] = annot;

              active_markers->count++;
            }
          }
        }

        annot = annot->next_annotation;
      }
    }
  }

  if(mainwindow->show_baselines)
  {
    vertical_distance = h / (signalcomps + 1);

    painter->setPen(baseline_color);

    for(i=0; i<signalcomps; i++)
    {
      baseline = vertical_distance * (i + 1);

      painter->drawLine(0, baseline, w, baseline);

      if(signalcomp[i]->voltpercm < 0.1)
      {
        strcpy(str2, "%+.3f ");
      }
      else if(signalcomp[i]->voltpercm < 1.0)
            {
              strcpy(str2, "%+.2f ");
            }
            else if(signalcomp[i]->voltpercm < 10.0)
                {
                  strcpy(str2, "%+.1f ");
                }
                else
                {
                  strcpy(str2, "%+.0f ");
                }

      strcat(str2, signalcomp[i]->physdimension);

      for(j=1; j<18; j++)
      {
        vert_ruler_offset = j * painter_pixelsizefactor;

        if(signalcomps!=1)
        {
          if(vert_ruler_offset>((vertical_distance / 2)) - 8)
          {
            break;
          }
        }

        painter->drawLine(0, baseline - vert_ruler_offset, w, baseline - vert_ruler_offset);

        snprintf(string, 128, str2,
          (signalcomp[i]->voltpercm * j) + (((double)signalcomp[i]->screen_offset * signalcomp[i]->voltpercm) / painter_pixelsizefactor));

        painter->drawText(5 * printsize_x_factor, baseline - vert_ruler_offset - (4 * printsize_y_factor), string);

        painter->drawLine(0, baseline + vert_ruler_offset, w, baseline + vert_ruler_offset);

        snprintf(string, 128, str2,
          (((double)signalcomp[i]->screen_offset * signalcomp[i]->voltpercm) / painter_pixelsizefactor) - (signalcomp[i]->voltpercm * j));

        painter->drawText(5 * printsize_x_factor, baseline + vert_ruler_offset - (4 * printsize_y_factor), string);
      }
    }
  }

  for(i=0; i<signalcomps; i++)
  {
    painter->setPen((Qt::GlobalColor)signalcomp[i]->color);

    for(j=0; j<screensamples[i]; j++)
    {
      painter->drawLine(graphicBuf[j].graphicLine[i].x1,
                        graphicBuf[j].graphicLine[i].y1,
                        graphicBuf[j].graphicLine[i].x2,
                        graphicBuf[j].graphicLine[i].y2);
    }
  }

  for(i=0; i<signalcomps; i++)
  {
    baseline = h / (signalcomps + 1);
    baseline *= (i + 1);

    painter->setPen((Qt::GlobalColor)signalcomp[i]->color);

    if(signalcomp[i]->hascursor1)
    {
      if(printing)
      {
        painter->setPen((Qt::GlobalColor)crosshair_1_color);
        painter->drawLine(0, crosshair_1_y_value, w, crosshair_1_y_value);
        painter->drawLine((int)((double)crosshair_1_x_position * printsize_x_factor), 0, (int)((double)crosshair_1_x_position * printsize_x_factor), h);
        snprintf(string, 128, "%+f %s",
                        crosshair_1_value,
                        signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].physdimension);
        painter->drawText((int)(((double)crosshair_1_x_position + 5.0) * printsize_x_factor), (int)(((double)crosshair_1_y_position - 40.0) * printsize_y_factor), string);
        snprintf(string, 128, "%2i:%02i:%02i.%04i",
                        (int)(((crosshair_1_time / TIME_DIMENSION)/ 3600LL) % 24LL),
                        (int)(((crosshair_1_time / TIME_DIMENSION) % 3600LL) / 60LL),
                        (int)((crosshair_1_time / TIME_DIMENSION) % 60LL),
                        (int)((crosshair_1_time % TIME_DIMENSION) / 1000LL));
        painter->drawText((int)(((double)crosshair_1_x_position + 5.0) * printsize_x_factor), (int)(((double)crosshair_1_y_position - 25.0) * printsize_y_factor), string);
        painter->drawText((int)(((double)crosshair_1_x_position + 5.0) * printsize_x_factor), (int)(((double)crosshair_1_y_position - 10.0) * printsize_y_factor), signalcomp[i]->signallabel);
        painter->setPen((Qt::GlobalColor)signalcomp[i]->color);
      }
      else
      {
        painter->setPen((Qt::GlobalColor)crosshair_1_color);
        painter->drawLine(0, crosshair_1_y_value, w, crosshair_1_y_value);
        painter->drawLine(crosshair_1_x_position, 0, crosshair_1_x_position, h);
        snprintf(string, 128, "%+f %s",
                        crosshair_1_value,
                        signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].physdimension);
        painter->drawText(crosshair_1_x_position + 5, crosshair_1_y_position - 40, string);
        snprintf(string, 128, "%2i:%02i:%02i.%04i",
                        (int)(((crosshair_1_time / TIME_DIMENSION)/ 3600LL) % 24LL),
                        (int)(((crosshair_1_time / TIME_DIMENSION) % 3600LL) / 60LL),
                        (int)((crosshair_1_time / TIME_DIMENSION) % 60LL),
                        (int)((crosshair_1_time % TIME_DIMENSION) / 1000LL));
        snprintf(string + strlen(string), 32, " (%i:%02i:%02i.%04i)",
                (int)((crosshair_1_time_relative / TIME_DIMENSION)/ 3600LL),
                (int)(((crosshair_1_time_relative / TIME_DIMENSION) % 3600LL) / 60LL),
                (int)((crosshair_1_time_relative / TIME_DIMENSION) % 60LL),
                (int)((crosshair_1_time_relative % TIME_DIMENSION) / 1000LL));

        painter->drawText(crosshair_1_x_position + 5, crosshair_1_y_position - 25, string);
        painter->drawText(crosshair_1_x_position + 5, crosshair_1_y_position - 10, signalcomp[i]->signallabel);
        painter->setPen((Qt::GlobalColor)signalcomp[i]->color);
      }
    }

    if(signalcomp[i]->hascursor2)
    {
      if(printing)
      {
        painter->setPen((Qt::GlobalColor)crosshair_2_color);
        painter->drawLine(0, crosshair_2_y_value, w, crosshair_2_y_value);
        painter->drawLine((int)((double)crosshair_2_x_position * printsize_x_factor), 0, (int)((double)crosshair_2_x_position * printsize_x_factor), h);
        snprintf(string, 128, "%+f %s",
                        crosshair_2_value,
                        signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].physdimension);
        painter->drawText((int)(((double)crosshair_2_x_position + 5.0) * printsize_x_factor), (int)(((double)crosshair_2_y_position - 70.0) * printsize_y_factor), string);
        snprintf(string, 128, "%2i:%02i:%02i.%04i",
                        (int)(((crosshair_2_time / TIME_DIMENSION)/ 3600LL) % 24LL),
                        (int)(((crosshair_2_time / TIME_DIMENSION) % 3600LL) / 60LL),
                        (int)((crosshair_2_time / TIME_DIMENSION) % 60LL),
                        (int)((crosshair_2_time % TIME_DIMENSION) / 1000LL));
        painter->drawText((int)(((double)crosshair_2_x_position + 5.0) * printsize_x_factor), (int)(((double)crosshair_2_y_position - 55.0) * printsize_y_factor), string);
        snprintf(string, 128, "delta %+f %s",
                        crosshair_2_value - crosshair_1_value,
                        signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].physdimension);
        painter->drawText((int)(((double)crosshair_2_x_position + 5.0) * printsize_x_factor), (int)(((double)crosshair_2_y_position - 40.0) * printsize_y_factor), string);
        l_time = crosshair_2_time - crosshair_1_time;
        if(l_time<0) l_time = -l_time;
        snprintf(string, 128, "delta %i:%02i:%02i.%04i",
                        (int)((l_time / TIME_DIMENSION)/ 3600LL),
                        (int)(((l_time / TIME_DIMENSION) % 3600LL) / 60LL),
                        (int)((l_time / TIME_DIMENSION) % 60LL),
                        (int)((l_time % TIME_DIMENSION) / 1000LL));
        painter->drawText((int)(((double)crosshair_2_x_position + 5.0) * printsize_x_factor), (int)(((double)crosshair_2_y_position - 25.0) * printsize_y_factor), string);
        painter->drawText((int)(((double)crosshair_2_x_position + 5.0) * printsize_x_factor), (int)(((double)crosshair_2_y_position - 10.0) * printsize_y_factor), signalcomp[i]->signallabel);
        painter->setPen((Qt::GlobalColor)signalcomp[i]->color);
      }
      else
      {
        painter->setPen((Qt::GlobalColor)crosshair_2_color);
        painter->drawLine(0, crosshair_2_y_value, w, crosshair_2_y_value);
        painter->drawLine(crosshair_2_x_position, 0, crosshair_2_x_position, h);
        snprintf(string, 128, "%+f %s",
                        crosshair_2_value,
                        signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].physdimension);
        painter->drawText(crosshair_2_x_position + 5, crosshair_2_y_position - 70, string);
        snprintf(string, 128, "%2i:%02i:%02i.%04i",
                        (int)(((crosshair_2_time / TIME_DIMENSION)/ 3600LL) % 24LL),
                        (int)(((crosshair_2_time / TIME_DIMENSION) % 3600LL) / 60LL),
                        (int)((crosshair_2_time / TIME_DIMENSION) % 60LL),
                        (int)((crosshair_2_time % TIME_DIMENSION) / 1000LL));
        snprintf(string + strlen(string), 32, " (%i:%02i:%02i.%04i)",
                (int)((crosshair_2_time_relative / TIME_DIMENSION)/ 3600LL),
                (int)(((crosshair_2_time_relative / TIME_DIMENSION) % 3600LL) / 60LL),
                (int)((crosshair_2_time_relative / TIME_DIMENSION) % 60LL),
                (int)((crosshair_2_time_relative % TIME_DIMENSION) / 1000LL));

        painter->drawText(crosshair_2_x_position + 5, crosshair_2_y_position - 55, string);
        snprintf(string, 128, "delta %+f %s",
                        crosshair_2_value - crosshair_1_value,
                        signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].physdimension);
        painter->drawText(crosshair_2_x_position + 5, crosshair_2_y_position - 40, string);
        l_time = crosshair_2_time - crosshair_1_time;
        if(l_time<0) l_time = -l_time;
        snprintf(string, 128, "delta %i:%02i:%02i.%04i",
                        (int)((l_time / TIME_DIMENSION)/ 3600LL),
                        (int)(((l_time / TIME_DIMENSION) % 3600LL) / 60LL),
                        (int)((l_time / TIME_DIMENSION) % 60LL),
                        (int)((l_time % TIME_DIMENSION) / 1000LL));
        painter->drawText(crosshair_2_x_position + 5, crosshair_2_y_position - 25, string);
        painter->drawText(crosshair_2_x_position + 5, crosshair_2_y_position - 10, signalcomp[i]->signallabel);
        painter->setPen((Qt::GlobalColor)signalcomp[i]->color);
      }
    }

    if(signalcomp[i]->hasoffsettracking)
    {
      snprintf(string, 128, "offset: %f %s",
        -(double)signalcomp[i]->screen_offset * mainwindow->pixelsizefactor * signalcomp[i]->voltpercm,
        signalcomp[i]->physdimension);
      painter->fillRect(92, baseline, 190, 12, backgroundcolor);
      painter->setPen((Qt::GlobalColor)signalcomp[i]->color);
      painter->drawText(95, baseline + 10, string);
    }

    if(signalcomp[i]->hasgaintracking)
    {
      snprintf(string, 128, "gain: %f %s/cm",
        signalcomp[i]->voltpercm,
        signalcomp[i]->physdimension);
      painter->fillRect(92, baseline, 190, 12, backgroundcolor);
      painter->setPen((Qt::GlobalColor)signalcomp[i]->color);
      painter->drawText(95, baseline + 10, string);
    }
  }

  vertical_distance = h / (signalcomps + 1);

  for(i=0; i<signalcomps; i++)
  {
    baseline = vertical_distance * (i + 1);

    painter->fillRect(2, baseline - 20, strlen(signalcomp[i]->signallabel) * 7 + 6, 12, backgroundcolor);

    painter->setPen((Qt::GlobalColor)signalcomp[i]->color);

    painter->drawText(5, baseline - 10, signalcomp[i]->signallabel);

    if(signalcomp[i]->hasruler)
    {
      floating_ruler(painter, ruler_x_position, ruler_y_position, signalcomp[i]);
    }
  }

  if(draw_zoom_rectangle)
  {
    special_pen->setColor(mouse_rect_color);

    painter->setPen(*special_pen);

    painter->drawRect(mouse_press_coordinate_x, mouse_press_coordinate_y, mouse_x - mouse_press_coordinate_x, mouse_y - mouse_press_coordinate_y);
  }

  painter->setPen(text_color);

  if(printing)
  {
    painter->drawText((int)(8.0 * printsize_y_factor), h - (int)(4.0 * printsize_y_factor), mainwindow->viewtime_string);
    painter->drawText(w - (int)(60.0 * printsize_y_factor), h - (int)(4.0 * printsize_y_factor), mainwindow->pagetime_string);
  }
  else
  {
    painter->fillRect(5, h - 14, 180, 12, backgroundcolor);
    painter->drawText(8, h - 4, mainwindow->viewtime_string);
    painter->fillRect(w - 63, h - 14, 60, 12, backgroundcolor);
    painter->drawText(w - 60, h - 4, mainwindow->pagetime_string);
  }
}


void ViewCurve::drawCurve_stage_1(QPainter *painter, int w_width, int w_height)
{
  int i, j, k, x1, y1, x2, y2,
      temp=0,
      signalcomps,
      baseline,
      value,
      dig_value=0,
      minimum,
      maximum;

  char *viewbuf;

  long long elapsed_time,
            s,
            s2;

  struct signalcompblock **signalcomp;

  union {
          unsigned int one;
          signed int one_signed;
          unsigned short two[2];
          signed short two_signed[2];
          unsigned char four[4];
        } var;

  for(i=0; i<MAXSIGNALS; i++)
  {
    screensamples[i] = 0;
  }

  signalcomps = mainwindow->signalcomps;
  signalcomp = mainwindow->signalcomp;
  viewbuf = mainwindow->viewbuf;

  painter_pixelsizefactor = 1.0 / mainwindow->pixelsizefactor;

  if(!w_width||!w_height)
  {
    w = width();
    h = height();

    printsize_x_factor = 1.0;
    printsize_y_factor = 1.0;

    printing = 0;
  }
  else
  {
    w = w_width;
    h = w_height;

    printsize_x_factor = ((double)w_width) / ((double)width());
    printsize_y_factor = ((double)w_height) / ((double)height());

    painter_pixelsizefactor *= printsize_y_factor;

    printing = 1;
  }

  for(i=0; i<signalcomps; i++)
  {
    signalcomp[i]->sample_pixel_ratio = (double)signalcomp[i]->samples_on_screen / (double)w;
  }

  if(mainwindow->files_open&&mainwindow->signalcomps)
  {
    elapsed_time = mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime;
  }
  else
  {
    elapsed_time = 0;
  }

  if((viewbuf==NULL)||(screensamples==NULL))
  {
    if(graphicBuf!=NULL)
    {
      free(graphicBuf);

      graphicBuf = NULL;
    }

    return;
  }

  if((graphicBuf==NULL)||(graphicBufWidth!=w))
  {
    if(graphicBuf!=NULL)
    {
      free(graphicBuf);
    }

    graphicBuf = (struct graphicBufStruct *)malloc(sizeof(struct graphicBufStruct) * w * 2 + 4);

    graphicBufWidth = w;
  }

  if(graphicBuf==NULL)
  {
    UI_Messagewindow popuperror("Error", "The system was not able to provide enough resources (memory) to perform the requested action.");
    return;
  }

  for(i=0; i<signalcomps; i++)
  {
    signalcomp[i]->max_dig_value = -2147483647;
    signalcomp[i]->min_dig_value = 2147483647;

    baseline = h / (signalcomps + 1);
    baseline *= (i + 1);

    for(s=signalcomp[i]->sample_start; s<signalcomp[i]->samples_on_screen; s++)
    {
      if(s>signalcomp[i]->sample_stop)  break;

      value = 0;
      dig_value = 0;
      s2 = s + signalcomp[i]->sample_timeoffset - signalcomp[i]->sample_start;

      for(j=0; j<signalcomp[i]->num_of_signals; j++)
      {
        if(signalcomp[i]->edfhdr->bdf)
        {
          var.two[0] = *((unsigned short *)(
            viewbuf
            + signalcomp[i]->viewbufoffset
            + (signalcomp[i]->edfhdr->recordsize * (s2 / signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].smp_per_record))
            + signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].buf_offset
            + ((s2 % signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].smp_per_record) * 3)));

          var.four[2] = *((unsigned char *)(
            viewbuf
            + signalcomp[i]->viewbufoffset
            + (signalcomp[i]->edfhdr->recordsize * (s2 / signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].smp_per_record))
            + signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].buf_offset
            + ((s2 % signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].smp_per_record) * 3)
            + 2));

          if(var.four[2]&0x80)
          {
            var.four[3] = 0xff;
          }
          else
          {
            var.four[3] = 0x00;
          }

          temp = var.one_signed;
        }

        if(signalcomp[i]->edfhdr->edf)
        {
          temp = *(((short *)(
            viewbuf
            + signalcomp[i]->viewbufoffset
            + (signalcomp[i]->edfhdr->recordsize * (s2 / signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].smp_per_record))
            + signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].buf_offset))
            + (s2 % signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].smp_per_record));
        }

        temp += signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].offset;
        temp *= signalcomp[i]->factor[j];

        dig_value += temp;
      }

      for(k=0; k<signalcomp[i]->filter_cnt; k++)
      {
        if(s==signalcomp[i]->sample_start)
        {
          if(mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime==0)
          {
            reset_filter(dig_value, signalcomp[i]->filter[k]);
          }
          else
          {
            signalcomp[i]->filter[k]->old_input = signalcomp[i]->filterpreset_a[k];
            signalcomp[i]->filter[k]->old_output = signalcomp[i]->filterpreset_b[k];
          }
        }

        dig_value = first_order_filter(dig_value, signalcomp[i]->filter[k]);
      }

      if(printing)
      {
        value += (int)((double)dig_value * signalcomp[i]->sensitivity[0] * printsize_y_factor);
      }
      else
      {
        value += (int)((double)dig_value * signalcomp[i]->sensitivity[0]);
      }

      if(dig_value>signalcomp[i]->max_dig_value)  signalcomp[i]->max_dig_value = dig_value;
      if(dig_value<signalcomp[i]->min_dig_value)  signalcomp[i]->min_dig_value = dig_value;

      if(printing)
      {
        value = baseline - value + (int)((double)signalcomp[i]->screen_offset * printsize_y_factor);
      }
      else
      {
        value = baseline - value + signalcomp[i]->screen_offset;
      }

      if(s>signalcomp[i]->sample_start)
      {
        x1 = (int)((double)s / signalcomp[i]->sample_pixel_ratio);
        y1 = signalcomp[i]->oldvalue;
        x2 = (int)(((double)s + 1.0) / signalcomp[i]->sample_pixel_ratio);
        y2 = value;

        if(!screensamples[i])
        {
          graphicBuf[screensamples[i]].graphicLine[i].x1 = x1;
          graphicBuf[screensamples[i]].graphicLine[i].y1 = y1;
          graphicBuf[screensamples[i]].graphicLine[i].x2 = x2;
          graphicBuf[screensamples[i]].graphicLine[i].y2 = y2;

          screensamples[i]++;
        }
        else
        {
          if((x1==x2)&&(x1==graphicBuf[screensamples[i]-1].graphicLine[i].x1)&&
             (graphicBuf[screensamples[i]-1].graphicLine[i].x1==graphicBuf[screensamples[i]-1].graphicLine[i].x2))
          {
            maximum = y1;
            if(y2>maximum)  maximum = y2;
            if(graphicBuf[screensamples[i]-1].graphicLine[i].y1>maximum)  maximum = graphicBuf[screensamples[i]-1].graphicLine[i].y1;
            if(graphicBuf[screensamples[i]-1].graphicLine[i].y2>maximum)  maximum = graphicBuf[screensamples[i]-1].graphicLine[i].y2;

            minimum = y1;
            if(y2<minimum)  minimum = y2;
            if(graphicBuf[screensamples[i]-1].graphicLine[i].y1<minimum)  minimum = graphicBuf[screensamples[i]-1].graphicLine[i].y1;
            if(graphicBuf[screensamples[i]-1].graphicLine[i].y2<minimum)  minimum = graphicBuf[screensamples[i]-1].graphicLine[i].y2;

            graphicBuf[screensamples[i]-1].graphicLine[i].y1 = maximum;
            graphicBuf[screensamples[i]-1].graphicLine[i].y2 = minimum;
          }
          else
          {
            graphicBuf[screensamples[i]].graphicLine[i].x1 = x1;
            graphicBuf[screensamples[i]].graphicLine[i].y1 = y1;
            graphicBuf[screensamples[i]].graphicLine[i].x2 = x2;
            graphicBuf[screensamples[i]].graphicLine[i].y2 = y2;

            if(screensamples[i]<(w * 2))  screensamples[i]++;
          }
        }
      }

      signalcomp[i]->oldvalue = value;

      if(signalcomp[i]->hascursor1)
      {
        if(printing)
        {
          if(s==((int)((double)crosshair_1_x_position * signalcomp[i]->sample_pixel_ratio * printsize_x_factor)))
          {
            crosshair_1_y_value = value;
            crosshair_1_value = dig_value * signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].bitvalue;
            crosshair_1_time = mainwindow->edfheaderlist[signalcomp[i]->filenum]->l_starttime + mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime + signalcomp[i]->edfhdr->starttime_offset + (long long)(((double)mainwindow->pagetime / ((double)w / printsize_x_factor)) * (double)crosshair_1_x_position);
            crosshair_1_time_relative = mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime + signalcomp[i]->edfhdr->starttime_offset + (long long)(((double)mainwindow->pagetime / ((double)w / printsize_x_factor)) * (double)crosshair_1_x_position);
          }
        }
        else
        {
          if(s==((int)((double)crosshair_1_x_position * signalcomp[i]->sample_pixel_ratio)))
          {
            crosshair_1_y_value = value;
            crosshair_1_value = dig_value * signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].bitvalue;
            crosshair_1_time = mainwindow->edfheaderlist[signalcomp[i]->filenum]->l_starttime + mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime + signalcomp[i]->edfhdr->starttime_offset + (long long)(((double)mainwindow->pagetime / (double)w) * (double)crosshair_1_x_position);
            crosshair_1_time_relative = mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime + signalcomp[i]->edfhdr->starttime_offset + (long long)(((double)mainwindow->pagetime / (double)w) * (double)crosshair_1_x_position);
          }
        }
      }

      if(signalcomp[i]->hascursor2)
      {
        if(printing)
        {
          if(s==((int)((double)crosshair_2_x_position * signalcomp[i]->sample_pixel_ratio * printsize_x_factor)))
          {
            crosshair_2_y_value = value;
            crosshair_2_value = dig_value * signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].bitvalue;
            crosshair_2_time = mainwindow->edfheaderlist[signalcomp[i]->filenum]->l_starttime + mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime + signalcomp[i]->edfhdr->starttime_offset + (long long)(((double)mainwindow->pagetime / ((double)w / printsize_x_factor)) * (double)crosshair_2_x_position);
            crosshair_2_time_relative = mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime + signalcomp[i]->edfhdr->starttime_offset + (long long)(((double)mainwindow->pagetime / ((double)w / printsize_x_factor)) * (double)crosshair_2_x_position);
          }
        }
        else
        {
          if(s==((int)((double)crosshair_2_x_position * signalcomp[i]->sample_pixel_ratio)))
          {
            crosshair_2_y_value = value;
            crosshair_2_value = dig_value * signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].bitvalue;
            crosshair_2_time = mainwindow->edfheaderlist[signalcomp[i]->filenum]->l_starttime + mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime + signalcomp[i]->edfhdr->starttime_offset + (long long)(((double)mainwindow->pagetime / (double)w) * (double)crosshair_2_x_position);
            crosshair_2_time_relative = mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime + signalcomp[i]->edfhdr->starttime_offset + (long long)(((double)mainwindow->pagetime / (double)w) * (double)crosshair_2_x_position);
          }
        }
      }
    }
  }

  if(printing)
  {
    drawCurve_stage_2(painter, w_width, w_height);
  }
  else
  {
    update();
  }
}


void ViewCurve::exec_sidemenu(int signal_nr_intern)
{
  int i;

  char str[32];

  signal_nr = signal_nr_intern;

  sidemenu = new QDialog(this);

  sidemenu->setMinimumSize(QSize(190, 255));
  sidemenu->setMaximumSize(QSize(190, 255));
  sidemenu->setWindowTitle("Signal");
  sidemenu->setModal(TRUE);
  sidemenu->setAttribute(Qt::WA_DeleteOnClose, TRUE);

  SidemenuLabel = new QLabel(sidemenu);
  SidemenuLabel->setGeometry(QRect(45, 5, 100, 20));
  SidemenuLabel->setText(mainwindow->signalcomp[signal_nr]->signallabel);

  AmpLabel = new QLabel(sidemenu);
  AmpLabel->setGeometry(QRect(5, 30, 35, 20));
  AmpLabel->setText("Ampl.");

  OffsetLabel = new QLabel(sidemenu);
  OffsetLabel->setGeometry(QRect(5, 55, 35, 20));
  OffsetLabel->setText("Offset");

  ScaleBox = new QDoubleSpinBox(sidemenu);
  ScaleBox->setGeometry(QRect(45, 30, 140, 20));
  ScaleBox->setDecimals(8);
  ScaleBox->setMaximum(1000000.0);
  ScaleBox->setMinimum(0.0000001);
  ScaleBox->setValue(mainwindow->signalcomp[signal_nr]->voltpercm);
  strcpy(str, mainwindow->signalcomp[signal_nr]->edfhdr->edfparam[mainwindow->signalcomp[signal_nr]->edfsignal[0]].physdimension);
  for(i=1; i<4; i++)
  {
    if(str[i]==' ')  break;
  }
  strcpy(str + i, "/cm");
  ScaleBox->setSuffix(str);

  ScaleBox2 = new QDoubleSpinBox(sidemenu);
  ScaleBox2->setGeometry(QRect(45, 55, 140, 20));
  ScaleBox2->setDecimals(8);
  ScaleBox2->setMaximum(1000000.0);
  ScaleBox2->setMinimum(-1000000.0);
  ScaleBox2->setValue(-(double)mainwindow->signalcomp[signal_nr]->screen_offset * mainwindow->pixelsizefactor * mainwindow->signalcomp[signal_nr]->voltpercm);
  ScaleBox2->setSuffix(mainwindow->signalcomp[signal_nr]->edfhdr->edfparam[mainwindow->signalcomp[signal_nr]->edfsignal[0]].physdimension);

  sidemenuButton1 = new QPushButton(sidemenu);
  sidemenuButton1->setGeometry(QRect(45, 80, 100, 20));
  sidemenuButton1->setText("Ruler");

  sidemenuButton2 = new QPushButton(sidemenu);
  sidemenuButton2->setGeometry(QRect(45, 105, 100, 20));
  sidemenuButton2->setText("Crosshair");

  sidemenuButton3 = new QPushButton(sidemenu);
  sidemenuButton3->setGeometry(QRect(45, 130, 100, 20));
  sidemenuButton3->setText("Fit to pane");

  sidemenuButton4 = new QPushButton(sidemenu);
  sidemenuButton4->setGeometry(QRect(45, 155, 100, 20));
  sidemenuButton4->setText("Color");

  sidemenuButton5 = new QPushButton(sidemenu);
  sidemenuButton5->setGeometry(QRect(45, 180, 100, 20));
  sidemenuButton5->setText("Remove filter");

  sidemenuButton6 = new QPushButton(sidemenu);
  sidemenuButton6->setGeometry(QRect(45, 205, 100, 20));
  sidemenuButton6->setText("Remove signal");

  sidemenuButton7 = new QPushButton(sidemenu);
  sidemenuButton7->setGeometry(QRect(45, 230, 100, 20));
  sidemenuButton7->setText("Close");

  QObject::connect(ScaleBox,         SIGNAL(valueChanged(double)),     this,     SLOT(ScaleBoxChanged(double)));
  QObject::connect(ScaleBox2,        SIGNAL(valueChanged(double)),     this,     SLOT(ScaleBox2Changed(double)));
  QObject::connect(sidemenuButton1,  SIGNAL(clicked()),                this,     SLOT(RulerButton()));
  QObject::connect(sidemenuButton2,  SIGNAL(clicked()),                this,     SLOT(CrosshairButton()));
  QObject::connect(sidemenuButton3,  SIGNAL(clicked()),                this,     SLOT(FittopaneButton()));
  QObject::connect(sidemenuButton4,  SIGNAL(clicked()),                this,     SLOT(ColorButton()));
  QObject::connect(sidemenuButton5,  SIGNAL(clicked()),                this,     SLOT(RemovefilterButton()));
  QObject::connect(sidemenuButton6,  SIGNAL(clicked()),                this,     SLOT(RemovesignalButton()));
  QObject::connect(sidemenuButton7,  SIGNAL(clicked()),                sidemenu, SLOT(close()));

  sidemenu->exec();
}



void ViewCurve::FittopaneButton()
{
  int j,
      pane_size,
      signalcomps;

  struct signalcompblock **signalcomp;


  signalcomps = mainwindow->signalcomps;
  signalcomp = mainwindow->signalcomp;

  if(!signalcomps)
  {
    sidemenu->close();

    return;
  }

  if(signal_nr>(signalcomps - 1))
  {
    sidemenu->close();

    return;
  }

  pane_size = (int)(((double)height() * 0.95) / signalcomps);

  for(j=0; j<signalcomp[signal_nr]->num_of_signals; j++)
  {
    if(signalcomp[signal_nr]->max_dig_value!=signalcomp[signal_nr]->min_dig_value)
    {
      signalcomp[signal_nr]->sensitivity[j] = (double)pane_size / (double)(signalcomp[signal_nr]->max_dig_value - signalcomp[signal_nr]->min_dig_value);
    }
    else
    {
      signalcomp[signal_nr]->sensitivity[j] = pane_size;
    }

    signalcomp[signal_nr]->voltpercm =
     signalcomp[signal_nr]->edfhdr->edfparam[signalcomp[signal_nr]->edfsignal[0]].bitvalue
     / (signalcomp[signal_nr]->sensitivity[0] * mainwindow->pixelsizefactor);

    signalcomp[signal_nr]->screen_offset = (int)(((signalcomp[signal_nr]->max_dig_value + signalcomp[signal_nr]->min_dig_value) / 2.0) * signalcomp[signal_nr]->sensitivity[0]);
  }

  drawCurve_stage_1();

  sidemenu->close();
}



void ViewCurve::ColorButton()
{
  sidemenu->hide();

  UI_ColorMenuDialog colormenudialog(this, &mainwindow->signalcomp[signal_nr]->color);

  sidemenu->close();
}



void ViewCurve::ScaleBox2Changed(double value)
{
  mainwindow->signalcomp[signal_nr]->screen_offset = -(int)(value / (mainwindow->pixelsizefactor * mainwindow->signalcomp[signal_nr]->voltpercm));

  drawCurve_stage_1();
}



void ViewCurve::ScaleBoxChanged(double value)
{
  int i;

  for(i=0; i<mainwindow->signalcomp[signal_nr]->num_of_signals; i++)
  {
    mainwindow->signalcomp[signal_nr]->sensitivity[i] = mainwindow->signalcomp[signal_nr]->edfhdr->edfparam[mainwindow->signalcomp[signal_nr]->edfsignal[i]].bitvalue / value / mainwindow->pixelsizefactor;
  }

  mainwindow->signalcomp[signal_nr]->voltpercm = value;

  drawCurve_stage_1();
}



void ViewCurve::RemovefilterButton()
{
  int j;

  if(!mainwindow->signalcomps)
  {
    sidemenu->close();

    return;
  }

  if(signal_nr>(mainwindow->signalcomps - 1))
  {
    sidemenu->close();

    return;
  }

  for(j=0; j<mainwindow->signalcomp[signal_nr]->filter_cnt; j++)
  {
    free(mainwindow->signalcomp[signal_nr]->filter[j]);
  }

  mainwindow->signalcomp[signal_nr]->filter_cnt = 0;

  mainwindow->signalcomp[signal_nr]->signallabel[mainwindow->signalcomp[signal_nr]->signallabellen] = 0;

  drawCurve_stage_1();

  sidemenu->close();
}



void ViewCurve::RemovesignalButton()
{
  int i, j;

  if(!mainwindow->signalcomps)
  {
    sidemenu->close();

    return;
  }

  if(signal_nr>(mainwindow->signalcomps - 1))
  {
    sidemenu->close();

    return;
  }

  if(mainwindow->signalcomp[signal_nr]->hascursor2)
  {
    crosshair_2_active = 0;
    crosshair_2_moving = 0;
  }

  if(mainwindow->signalcomp[signal_nr]->hascursor1)
  {
    crosshair_1_active = 0;
    crosshair_2_active = 0;
    crosshair_1_moving = 0;
    crosshair_2_moving = 0;

    for(i=0; i<mainwindow->signalcomps; i++)
    {
      mainwindow->signalcomp[i]->hascursor2 = 0;
    }
  }

  if(mainwindow->signalcomp[signal_nr]->hasruler)
  {
    ruler_active = 0;
    ruler_moving = 0;
  }

  for(j=0; j<mainwindow->signalcomp[signal_nr]->filter_cnt; j++)
  {
    free(mainwindow->signalcomp[signal_nr]->filter[j]);
  }

  mainwindow->signalcomp[signal_nr]->filter_cnt = 0;

  free(mainwindow->signalcomp[signal_nr]);

  for(i=signal_nr; i<mainwindow->signalcomps - 1; i++)
  {
    mainwindow->signalcomp[i] = mainwindow->signalcomp[i + 1];
  }

  mainwindow->signalcomps--;

  drawCurve_stage_1();

  sidemenu->close();
}


void ViewCurve::RulerButton()
{
  int i;


  crosshair_1_moving = 0;
  crosshair_2_moving = 0;
  ruler_active = 0;
  ruler_moving = 0;
  use_move_events = 0;
  setMouseTracking(FALSE);

  for(i=0; i<mainwindow->signalcomps; i++)
  {
    mainwindow->signalcomp[i]->hasruler = 0;
  }

  if(width() < 400)
  {
    return;
  }

  if(height() < 400)
  {
    return;
  }

  if((mainwindow->pagetime / TIME_DIMENSION) < 2LL)
  {
    return;
  }

  if((mainwindow->pagetime / TIME_DIMENSION) > 60LL)
  {
    return;
  }

  if(mainwindow->signalcomp[signal_nr]->voltpercm < 1.0)
  {
    return;
  }

  if(mainwindow->signalcomp[signal_nr]->voltpercm > 2000.0)
  {
    return;
  }

  ruler_x_position = 200;
  ruler_y_position = 200;
  mainwindow->signalcomp[signal_nr]->hasruler = 1;
  ruler_active = 1;

  update();

  sidemenu->close();
}


void ViewCurve::CrosshairButton()
{
  int i;

  if(!crosshair_1_active)
  {
    for(i=0; i<mainwindow->signalcomps; i++)
    {
      mainwindow->signalcomp[i]->hascursor1 = 0;
      mainwindow->signalcomp[i]->hascursor2 = 0;
    }
    crosshair_1_value = 0.0;
    crosshair_2_value = 0.0;
    mainwindow->signalcomp[signal_nr]->hascursor1 = 1;
    use_move_events = 0;
    setMouseTracking(TRUE);
    crosshair_1_active = 1;
    crosshair_2_active = 0;
    crosshair_1_moving = 0;
    crosshair_2_moving = 0;
    crosshair_1_file_num = mainwindow->signalcomp[signal_nr]->filenum;

    crosshair_1_x_position = w * 0.3;
    crosshair_1_y_position = h * 0.7;

    drawCurve_stage_1();
  }
  else
  {
    if(!crosshair_2_active)
    {
      for(i=0; i<mainwindow->signalcomps; i++)
      {
        mainwindow->signalcomp[i]->hascursor2 = 0;
      }
      crosshair_2_value = 0.0;
      mainwindow->signalcomp[signal_nr]->hascursor2 = 1;
      use_move_events = 0;
      setMouseTracking(TRUE);
      crosshair_2_active = 1;
      crosshair_1_moving = 0;
      crosshair_2_moving = 0;
      crosshair_2_file_num = mainwindow->signalcomp[signal_nr]->filenum;

      crosshair_2_x_position = w * 0.3;
      crosshair_2_y_position = h * 0.7;

      drawCurve_stage_1();
    }
  }

  sidemenu->close();
}


void ViewCurve::resizeEvent(QResizeEvent *event)
{
  mainwindow->setup_viewbuf();

  QWidget::resizeEvent(event);
}



inline void ViewCurve::floating_ruler(QPainter *painter, int x, int y, struct signalcompblock *signalcomp)
{
  int i, j;

  double d_tmp,
         d_tmp2,
         h_size,
         w_size,
         pixels_per_second;

  char str_hz[7][16]={" 9", "10", "11", "12", "13", "14", "15"};

  char str_uv[5][16]={"200", "150", "100", "50", "0"};

  char str_s[4][16]={"1.00", "0.75", "0.50", "0.25"};


  if(w < 400)
  {
    return;
  }

  if((mainwindow->pagetime / TIME_DIMENSION) < 2LL)
  {
    return;
  }

  if((mainwindow->pagetime / TIME_DIMENSION) > 60LL)
  {
    return;
  }

  if(signalcomp->voltpercm < 1.0)
  {
    return;
  }

  if(signalcomp->voltpercm > 2000.0)
  {
    return;
  }

  x *= printsize_x_factor;
  y *= printsize_y_factor;

  pixels_per_second = ((double)w) / (((double)mainwindow->pagetime) / ((double)TIME_DIMENSION));

  h_size = 4.0 * painter_pixelsizefactor;

  w_size = (double)w / 10.0;

  d_tmp = h_size / 7.0;

  d_tmp2 = h_size / 14.0;

  if(floating_ruler_value)
  {
    for(i=0; i<7; i++)
    {
      snprintf(str_hz[i], 15, "%.1f",  (w_size / pixels_per_second) * (2.0 + i));

      str_hz[i][15] = 0;
    }

    for(i=0; i<5; i++)
    {
      snprintf(str_uv[i], 15, "%i", (int)(signalcomp->voltpercm * i));

      str_uv[i][15] = 0;
    }
  }
  else
  {
    for(i=0; i<7; i++)
    {
      snprintf(str_hz[i], 15, "%.1f",  (w_size / pixels_per_second) * (9.0 + i));

      str_hz[i][15] = 0;
    }

    for(i=0; i<5; i++)
    {
      snprintf(str_uv[i], 15, "%i", (int)(signalcomp->voltpercm * (4 - i)));

      str_uv[i][15] = 0;
    }
  }

  for(i=0; i<4; i++)
  {
    snprintf(str_s[i], 15, "%.2f",  ((w / 40.0) / pixels_per_second) * (4 - i));

    str_uv[i][15] = 0;
  }

  painter->setPen((Qt::GlobalColor)floating_ruler_color);

  painter->drawText(x, y - ((double)h / 80.0), "Hz");

  for(i=0; i<7; i++)
  {
    painter->drawText(x - ((double)w / 30.0), y + ((double)h / 204.8) + d_tmp2 + (d_tmp * i), str_hz[i]);
  }

  for(i=1; i<7; i++)
  {
    painter->drawLine(x, y + (d_tmp * i), x + w_size, y + (d_tmp * i));
  }

  painter->drawRect(x, y, w_size, h_size);

  if(floating_ruler_value)
  {
    for(j=2; j<9; j++)
    {
      d_tmp2 = w_size / j;

      for(i=1; i<j; i++)
      {
        painter->drawLine(x + (d_tmp2 * i), y + (d_tmp * (j - 2)), x + (d_tmp2 * i), y + (d_tmp * (j - 1)));
      }
    }
  }
  else
  {
    for(j=9; j<16; j++)
    {
      d_tmp2 = w_size / j;

      for(i=1; i<j; i++)
      {
        painter->drawLine(x + (d_tmp2 * i), y + (d_tmp * (j - 9)), x + (d_tmp2 * i), y + (d_tmp * (j - 8)));
      }
    }
  }

  painter->drawText(x + (3.0 * printsize_x_factor), y + h_size + (25.0 * printsize_y_factor), "more...");

  x += (w_size + ((double)w / 18.0));

  d_tmp = h_size / 4.0;

  painter->drawText(x - ((double)w / 45.0), y - ((double)h / 80.0), signalcomp->physdimension);

  for(i=0; i<5; i++)
  {
    painter->drawText(x - ((double)w / 45.0), y + ((double)h / 204.8) + (d_tmp * i), str_uv[i]);

    painter->drawLine(x + ((double)w / 160.0), y + (d_tmp * i), x + ((double)w / 45.7), y + (d_tmp * i));
  }

  painter->drawLine(x + ((double)w / 45.7), y, x + ((double)w / 45.7), y + h_size);

  d_tmp = h_size / 20.0;

  for(i=1; i<20; i++)
  {
    painter->drawLine(x + ((double)w / 71.1), y + (d_tmp * i), x + ((double)w / 45.7), y + (d_tmp * i));
  }

  x += ((double)w / 10.0);

  painter->drawLine(x, y, x + (w_size / 2.0), y + h_size);
  painter->drawLine(x + w_size, y, x + (w_size / 2.0), y + h_size);

  d_tmp = h_size / 4.0;
  d_tmp2 = w_size / 8.0;

  for(i=0; i<4; i++)
  {
    painter->drawLine(x + (d_tmp2 * i), y + (d_tmp * i), x + w_size - (d_tmp2 * i), y + (d_tmp * i));
  }

  for(i=0; i<4; i++)
  {
    painter->drawText(x - ((double)w / 25.0) + (d_tmp2 * i), y + ((double)h / 204.8) + (d_tmp * i), str_s[i]);
  }

  painter->drawText(x + ((double)w / 125.0) + w_size, y + ((double)h / 204.8), "S");

  special_pen->setColor((Qt::GlobalColor)floating_ruler_color);

  painter->setPen(*special_pen);

  d_tmp = h_size / 20.0;
  d_tmp2 = w_size / 40.0;

  for(i=1; i<20; i++)
  {
    painter->drawLine(x + (d_tmp2 * i), y + (d_tmp * i), x + w_size - (d_tmp2 * i), y + (d_tmp * i));
  }
}


void ViewCurve::backup_colors_for_printing()
{
  int i;

  backup_color_1 = backgroundcolor;
  backgroundcolor = Qt::white;
  backup_color_2 = small_ruler_color;
  small_ruler_color = Qt::black;
  backup_color_3 = big_ruler_color;
  big_ruler_color = Qt::gray;
  backup_color_4 = mouse_rect_color;
  mouse_rect_color = Qt::black;
  backup_color_5 = text_color;
  text_color = Qt::black;
  backup_color_14 = floating_ruler_color;
  floating_ruler_color = Qt::black;

  for(i=0; i<mainwindow->signalcomps; i++)
  {
    backup_color_10[i] = mainwindow->signalcomp[i]->color;
    mainwindow->signalcomp[i]->color = Qt::black;
  }
  backup_color_11 = crosshair_1_color;
  crosshair_1_color = Qt::black;
  backup_color_12 = crosshair_2_color;
  crosshair_2_color = Qt::black;
  backup_color_13 = baseline_color;
  baseline_color = Qt::gray;
  backup_color_15 = annot_marker_color;
  annot_marker_color = Qt::black;
}


void ViewCurve::restore_colors_after_printing()
{
  int i;

  backgroundcolor = backup_color_1;
  small_ruler_color = backup_color_2;
  big_ruler_color = backup_color_3;
  mouse_rect_color = backup_color_4;
  text_color = backup_color_5;
  floating_ruler_color = backup_color_14;

  for(i=0; i<mainwindow->signalcomps; i++)
  {
    mainwindow->signalcomp[i]->color = backup_color_10[i];
  }
  crosshair_1_color = backup_color_11;
  crosshair_2_color = backup_color_12;
  baseline_color = backup_color_13;
  annot_marker_color = backup_color_15;
}



void ViewCurve::setCrosshair_1_center(void)
{
  crosshair_1_x_position = width() / 2;
}


























Generated by  Doxygen 1.6.0   Back to index