#include "C_Frm_Prescription.h"
#include "../../MedinTuxTools-QT4/CGestIni.h"
#include "../../MedinTuxTools-QT4/Theme/ThemePopup.h"
#include "../../MedinTuxTools-QT4/medicabase/C_BDM_Api.h"

#include <QFont>
#include <QPainter>
#include <QFrame>
#include <QRubberBand>
#include <QMimeData>
#include <QDragEnterEvent>
#include <QDragMoveEvent>
#include <QTimer>
#include <QToolTip>
#include <QDebug>
#include <QTreeWidgetItem>
#include <QPalette>
#include <QScrollArea>
#include <QApplication>
#include <QPointer>
#include <QTextEdit>
#include <QTimer>
#include <QTextDocument>
#define SIZE_BORDER_DAY    8
#define W_PRODUIT          568
#define H_PRODUIT          100
#define FIRST_OBJ_POS_Y    2
#define FIRST_OBJ_POS_X    2
#define SPACE_BETWEEN_PROD 3
#define HANDLE_MOVE_WIDTH  16
#define H_GRAD             5
#define ITEM_HIT_H         40
#define ITEM_HIT_NBTOVIEW  8
/*
SIG ou MITTE : posologie
DIE ou QD : 1 fois par jour
BID : 2 fois par jour
TID : 3 fois par jour
QID : 4 fois par jour
QH : chaque heure
Q4H : toutes les 4 heures
Q4-6H : toutes les 4 à 6 heures
QSP (X jour(s)) : quantité suffisante pour X jour(s) > nombre de jour(s)
[modifier]Formes
ONG : onguent
LOT : lotion
CP : comprimé
CAP : capsule
CR : crème
AMP : ampoule
SUSP : suspension
SUPP : suppositoire
INJ : injection
SC : sous-cutané
IM : injection intra musculaire
IV : injection intra veineuse
CR VAG : crème vaginale
APPL : application
PO : par voie orale = per os
PRN : au besoin
ALD : à la demande
AU : aux 2 oreilles
AD : oreille droite
AS : oreille gauche
OU : aux 2 yeux
OS : ?il gauche
OD : ?il droit
CAT : cuillère à thé
CAS : cuillère à soupe
[modifier]Moment de la prise de la médication
HS : au coucher
CC : en mangeant
AC : avant les repas
PC : après les repas
AM : le matin
*/
//====================================== CMyQTextEdit ===================================================================================================
void  CMyQTextEdit::mousePressEvent ( QMouseEvent * e )
{e->ignore();
}

//====================================== C_Frm_PosologieHitList ==========================================================================================
C_Frm_PosologieHitList::C_Frm_PosologieHitList (const QStringList   &grammarList   ,
                                                const QRect         &geometry_rect ,
                                                QWidget*             parent        , /* = 0 */
                                                const char*          name            /* = 0 */
                                               )
   : QScrollArea (parent), QStringList(grammarList)
{  m_Grid_H      = ITEM_HIT_H;
   m_FocusWidget = 0;
   m_grammarList = grammarList;
   int nbItem    = grammarList.count();
   setObjectName(name);
   //................... la surface qui doit scroller ...............................
   m_MainQFrame = new QFrame(this);
   QRect rect(0,0, geometry_rect.width()-40, (m_Grid_H+1)  * nbItem);
   setGeometry(QRect(0,0,geometry_rect.width()+40,m_Grid_H * nbItem));
   m_MainQFrame->setGeometry(rect);
   setWidget ( m_MainQFrame );
   //................... le contenu de la surface qui doit scroller .................
   for (int i=0; i<nbItem; ++i)
       {CMyQTextEdit *pQTextEdit = new CMyQTextEdit(QString(" <b>%1</b> ").arg(QString::number(i))+C_PosologieGrammar::toString(grammarList[i],"", C_PosologieGrammar::UP_JUST_FRACTION ), m_MainQFrame);
        pQTextEdit->setReadOnly ( true );
        pQTextEdit->setGeometry(0,i*m_Grid_H,rect.width(),m_Grid_H);
        pQTextEdit->setStyleSheet(QString("background-color: %1;").arg(palette().color(QPalette::Window).name()));
        pQTextEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
       }
   if (nbItem)
      { m_FocusWidget = setWidgetEditFocus((QWidget*)m_MainQFrame->children()[0], m_FocusWidget);
      }
   //connect( this, SIGNAL( returnPressed ()  ),  this , SLOT( Slot_returnPressed() ));
}
//------------------------------------------------------ selectedGrammar ---------------------------------------------------------------------------------
QString C_Frm_PosologieHitList::selectedGrammar()
{if (m_FocusWidget==0)  return "";
 QList <QObject *> objList = m_MainQFrame->children();
 int index = objList.indexOf(m_FocusWidget);
 if (index == -1)       return "";
 return m_grammarList[index];
}

//------------------------------------------------------ nextEditWidget ---------------------------------------------------------------------------------
QWidget *C_Frm_PosologieHitList::nextEditWidget()
{QList <QObject *> objList = m_MainQFrame->children();
 int nbItem                = objList.count();
 if (nbItem == 0)                              // si pas de widget dans la liste mettre le courant a zero
    { return 0;
    }
 if (m_FocusWidget==0)                         // si le widget courant n'est pas note, noter le premier comme courant.
    { return (QWidget*)objList[0];
    }
 int index = objList.indexOf(m_FocusWidget)+1;
 if (index==-1 || index== nbItem)              // si le prochain depasse le max alors reprendre a zero
    { return (QWidget*)objList[0];
    }
 return (QWidget*)objList[index];     // retourner le prochain de la liste
}
//------------------------------------------------------ previousEditWidget ---------------------------------------------------------------------------------
QWidget *C_Frm_PosologieHitList::previousEditWidget()
{QList <QObject *> objList = m_MainQFrame->children();
 int nbItem                = objList.count();
 if (nbItem == 0)                                   // si pas de widget dans la liste mettre le courant a zero
    { return 0;
    }
 if (m_FocusWidget==0)                              // si le widget courant n'est pas note, noter le dernier comme courant.
    { return (QWidget*)objList[nbItem-1];
    }
 int index = objList.indexOf(m_FocusWidget)-1;
 if (index==-1)                        // si le precedent est en dessous du premier alors prendre le dernier
    { return  (QWidget*)objList[nbItem-1];
    }
 return (QWidget*)objList[index];          // retourner le precedent de la liste
}
//------------------------------------------------------ setWidgetEditFocus ---------------------------------------------------------------------------------
QWidget *C_Frm_PosologieHitList::setWidgetEditFocus(QWidget *pQWidgetNew, QWidget *pQWidgetOld)
{CMyQTextEdit  *pQTextEdit = 0;
 if (pQWidgetOld)
    { pQTextEdit             = (CMyQTextEdit*)pQWidgetOld; //setTextBackgroundColor (QColor("#d5d5d5"));
      pQTextEdit->setStyleSheet(QString("background-color: %1;").arg(palette().color(QPalette::Window).name()));
    }
 if (pQWidgetNew==0) return 0;
 pQTextEdit = (CMyQTextEdit*)pQWidgetNew;
 //pQTextEdit->setFocus(); pas de focus !!!! sinon le prend au QLine edit du matin
 ensureVisible(pQTextEdit->x(),pQTextEdit->y());//+m_Grid_H/2
 pQTextEdit->setStyleSheet(QString("background-color: %1").arg(palette().color(QPalette::Base).name()));
 return pQWidgetNew;
}
//------------------------------------------------------ setWidgetEditFocus ---------------------------------------------------------------------------------
void C_Frm_PosologieHitList::setWidgetEditFocus(int direction)
{if (direction == C_Frm_PosologieHitList::NEXT)  m_FocusWidget = setWidgetEditFocus(nextEditWidget(),     m_FocusWidget);
 else                                            m_FocusWidget = setWidgetEditFocus(previousEditWidget(), m_FocusWidget);
}

//------------------------------------------------------ mousePressEvent ---------------------------------------------------------------------------------
void C_Frm_PosologieHitList::mousePressEvent ( QMouseEvent * ev )
{
    QList <QObject *> objList = m_MainQFrame->children();
    int nbItem                = objList.count();
    for (int i=0; i<nbItem; ++i)
        {QWidget* pQWidget = (QWidget*)objList[i];
         if (pQWidget->underMouse())
            {int index = objList.indexOf(pQWidget);
             emit Sign_HitList_ItemSelected( m_grammarList[index] , index);
             ev->accept();
             return ;
            }
        }
}

//------------------------------------------------------ event ---------------------------------------------------------------------------------
bool C_Frm_PosologieHitList::event ( QEvent * ev )
{
 if ( ev->type() ==  QEvent::KeyRelease )
    {
     QKeyEvent                    *k = (QKeyEvent *)ev;
     Qt::KeyboardModifiers modifiers = k->modifiers();
     switch (k->key())
         {case Qt::Key_Down:
               setWidgetEditFocus(C_Frm_PosologieHitList::NEXT);
               break;
          case Qt::Key_Up:
               setWidgetEditFocus(C_Frm_PosologieHitList::PREVIOUS);
               break;
         case Qt::Key_Return:
         case Qt::Key_Enter:
               QList <QObject *> objList = m_MainQFrame->children();
               int nbItem                = objList.count();
               if (m_FocusWidget && nbItem && (modifiers&Qt::AltModifier || modifiers&Qt::ControlModifier))
                  {int index = objList.indexOf(m_FocusWidget);
                   emit Sign_HitList_ItemSelected( m_grammarList[index] ,index );
                   ev->accept();
                   return true;
                  }
         } // end switch (key()) c = IsCarValid(m_Valid[m_CursPos].latin1(), k->text()[0].latin1());
    }
 return QScrollArea::event (ev);
}
//====================================== CMyQLineEdit ==========================================================================================
//------------------------------------------------------ event ---------------------------------------------------------------------------------
bool CMyQLineEdit::event ( QEvent * e )
{
    if ( e->type() ==  QEvent::KeyPress )
       {C_Frm_Posologie *pC_Frm_Posologie = (C_Frm_Posologie*)m_ptr;
        if (pC_Frm_Posologie && pC_Frm_Posologie->get_C_Frm_PosologieHitList())
           {
            QKeyEvent                    *k = (QKeyEvent *)e;
            int                         key = k->key();
            Qt::KeyboardModifiers modifiers = k->modifiers();
            if (m_caractersMask[0]=='9' &&                                // ultra crade mais pour l'instant on fait avec
                ! ( (key>=Qt::Key_0 && key<=Qt::Key_9)              ||
                     key==Qt::Key_Return     || key==Qt::Key_Enter  ||
                     key==Qt::Key_Down       || key==Qt::Key_Up     ||
                     key==Qt::Key_Back       || key==Qt::Key_Tab    ||
                     key==Qt::Key_Backspace  || key==Qt::Key_Delete ||
                     key==Qt::Key_Left       || key==Qt::Key_Right) )
               {e->accept();
                return true;
               }
            switch (key)
               {
                case Qt::Key_Down:
                     pC_Frm_Posologie->get_C_Frm_PosologieHitList()->setWidgetEditFocus(C_Frm_PosologieHitList::NEXT);
                     e->accept();
                     return true;

                case Qt::Key_Up:
                     pC_Frm_Posologie->get_C_Frm_PosologieHitList()->setWidgetEditFocus(C_Frm_PosologieHitList::PREVIOUS);
                     e->accept();
                     return true;

               case Qt::Key_Return:
               case Qt::Key_Enter:
                     emit Sign_returnPressed( objectName(), this, m_ptr , modifiers);
                     e->accept();
                     return true;
               } // end switch (key()) c = IsCarValid(m_Valid[m_CursPos].latin1(), k->text()[0].latin1());
          }
       }
    return QLineEdit::event (e);
}

//------------------------------------------------------ mousePressEvent -----------------------------------------------------------------------
void CMyQLineEdit::mousePressEvent ( QMouseEvent * e )
{   QLineEdit::mousePressEvent ( e );
}
//------------------------------------------------------ focusOutEvent --------------------------------------------------------------------------
void CMyQLineEdit::focusOutEvent ( QFocusEvent * e )
{   QLineEdit::focusOutEvent(e);
    emit Sign_focusOut ( objectName(), this, m_ptr);
}
//------------------------------------------------------ focusInEvent --------------------------------------------------------------------------
void CMyQLineEdit::focusInEvent ( QFocusEvent * e )
{   QTimer::singleShot(1,this, SLOT(selectAll()));
    emit Sign_focusIn  ( objectName(), this, m_ptr);
    QLineEdit::focusInEvent(e);
}
//------------------------------------------------------ setCaractersMask --------------------------------------------------------------------------
void CMyQLineEdit::setCaractersMask(const QString &mask)
{m_caractersMask = mask;
}

//====================================================== C_Frm_Posologie ======================================================================
//------------------------------------------------------ C_Frm_Posologie ----------------------------------------------------------------------
C_Frm_Posologie::C_Frm_Posologie (  C_BDM_Api           *pC_BDM_Api,          // pointeur sur l'API medicamenteuse
                                    C_Frm_Produit       *pC_Frm_Produit,      // on differencie le produit a traiter du parent (permet d'avoir pour parent n'importe quel autre objet)
                                    C_BitMapCollection  *pC_BitMapCollection, // il nous faut des icones
                                    QRect                geometry_rect,       // c'est le parent qui decide de la geiometrie
                                    QWidget             *parent,              // le pere
                                    bool                 gridvisibility, /* = false */ // visibilite de la grille horizontale
                                    int                  viewProfil      /* = C_Frm_Posologie::ALL_WIDGETS */
                                 )

         : QFrame(parent), C_PosologieGrammar(pC_Frm_Produit->schema_posologique())
{
  //setGrammar("comprimé[125;m|265;M|445;s]/8\n"
  //           "[0.75;m|155.122;M15r|2;sr30|3;h10-13]/4\n"
  //           "[0.5;M|1;s]/3");                             // pour test
  setGrammar("");                             // pour test
  setLiteral(C_PosologieGrammar::UP_JUST_FRACTION);        // tout laisser en numerique sauf les partie fractionnaire de 0.25 0.50 0.75 des unites de prise
  m_pC_BDM_Api          = pC_BDM_Api;
  m_pC_Frm_Produit      = pC_Frm_Produit;
  m_pC_BitMapCollection = pC_BitMapCollection;
  m_GrabIsOn            = 0;
  m_Hdeb_mn             = 0*60;
  m_Hfin_mn             = 24*60;
  m_first_time          = 7*60;
  m_rightMarg           = 90;
  m_grad_pos_y          = geometry_rect.height();
  m_grad_h              = gridvisibility?H_GRAD:0;
  m_viewProfil          = viewProfil;
  m_HitList             = 0;
  m_MomentMealMap.clear();      // a initialiser avec gammaire d'entree
  //............... rectangle du composant .............................
  setGeometry(geometry_rect);
  //................ largeur de la graduation ...........................
  QFont  fGrd            = font(); fGrd.setPixelSize(10); fGrd.setBold(false); fGrd.setItalic(false);
  QFontMetrics fntMetGrd = QFontMetrics(fGrd);
  QRect        boundRect = fntMetGrd.boundingRect ("X");
  m_grad_w               = geometry_rect.width() - m_rightMarg; //m_pC_BitMapCollection->m_ButtonSequenceList.width()*3; //-boundRect.width()*3;  // 24 pour laisser la place des icones a droite
  if (m_grad_h)
      m_grad_pos_y       = geometry_rect.height()- boundRect.height() - m_grad_h; //-16;  // ligne de graduation 16 pixels au dessus de la ligne basse

  //................ on cree juste les objets les positions seront  ..............................
  //                 ajustées a part dans la fonction Slot_adjustViewToProfil()
  //                 boundRect sera donc utilise de facon arbitaire avec des valeurs
  //                 sans signification
  //..................... bouton matin ..........................................................
  m_ButtonMatin     =  new CMyButton(boundRect, this, tr("matin"), this);       m_ButtonMatin->setFont(fGrd);
  connect( m_ButtonMatin, SIGNAL( Sign_ButtonClickedPtr (const QString &, void *)  ),  this , SLOT( Slot_ButtonMatinClicked(const QString &, void *) ));
  //..................... bouton midi ..........................................................
  m_ButtonMidi      =  new CMyButton(boundRect, this, tr("midi"), this);        m_ButtonMidi->setFont(fGrd);
  connect( m_ButtonMidi, SIGNAL( Sign_ButtonClickedPtr (const QString &, void *)  ),  this , SLOT( Slot_ButtonMidiClicked(const QString &, void *) ));
  //..................... bouton A.midi ..........................................................
  m_ButtonApresMidi =  new CMyButton(boundRect, this, tr("après-midi"), this);  m_ButtonApresMidi->setFont(fGrd);
  connect( m_ButtonApresMidi, SIGNAL( Sign_ButtonClickedPtr (const QString &, void *)  ),  this , SLOT( Slot_ButtonApresMidiClicked(const QString &, void *) ));
  //..................... bouton soir ..........................................................
  m_ButtonSoir      =  new CMyButton(boundRect, this, tr("soir"), this);        m_ButtonSoir->setFont(fGrd);
  connect( m_ButtonSoir, SIGNAL( Sign_ButtonClickedPtr (const QString &, void *)  ),  this , SLOT( Slot_ButtonSoirClicked(const QString &, void *) ));
  //..................... bouton coucher ..........................................................
  m_ButtonCoucher      =  new CMyButton(boundRect, this, tr("coucher"), this);  m_ButtonCoucher->setFont(fGrd);
  connect( m_ButtonCoucher, SIGNAL( Sign_ButtonClickedPtr (const QString &, void *)  ),  this , SLOT( Slot_ButtonCoucherClicked(const QString &, void *) ));
  //..................... bouton nuit ..........................................................
  m_ButtonNuit      =  new CMyButton(boundRect, this, tr("nuit"), this);        m_ButtonNuit->setFont(fGrd);
  connect( m_ButtonNuit, SIGNAL( Sign_ButtonClickedPtr (const QString &, void *)  ),  this , SLOT( Slot_ButtonNuitClicked(const QString &, void *) ));

  //..................... editeur de texte ......................................................
  m_textEdit     =  new QTextEdit(this);   m_textEdit->setFont(fGrd);
  m_textEdit->setVerticalScrollBarPolicy   ( Qt::ScrollBarAlwaysOff );
  m_textEdit->setHorizontalScrollBarPolicy ( Qt::ScrollBarAlwaysOff );
  m_textEdit->setTabChangesFocus ( true );
  m_textEdit->raise();
  m_textEdit->setText(toString(pC_Frm_Produit->forme_galenique()));

  //..................... boutonSequencelist ..........................................................
  m_ButtonSequencelist      =  new CMyButton(m_pC_BitMapCollection->m_ButtonSequenceList,  QRect(0,0,boundRect.height(),boundRect.height()),
                                             this, tr(",m_ButtonSequencelist"), this);      m_ButtonSequencelist->setFont(fGrd);
  m_ButtonSequencelist->setFlat(true);
  connect( m_ButtonSequencelist, SIGNAL( Sign_ButtonClickedPtr (const QString &, void *)  ),  this , SLOT( Slot_ButtonSequencelistClicked(const QString &, void *) ));
  //..................... boutonSequenceAdd ..........................................................
  m_ButtonSequenceAdd      =  new CMyButton(m_pC_BitMapCollection->m_ButtonSequenceAdd,    QRect(0,0,boundRect.height(),boundRect.height()),
                                             this, tr(",m_ButtonSequenceAdd"), this);      m_ButtonSequenceAdd->setFont(fGrd);
  m_ButtonSequenceAdd->setFlat(true);
  connect( m_ButtonSequenceAdd, SIGNAL( Sign_ButtonClickedPtr (const QString &, void *)  ),  this , SLOT( Slot_ButtonSequenceAddClicked(const QString &, void *) ));
  //..................... boutonSequenceDel ..........................................................
  m_ButtonSequenceDel      =  new CMyButton(m_pC_BitMapCollection->m_ButtonSequenceDel,    QRect(0,0,boundRect.height(),boundRect.height()),
                                            this, tr(",m_ButtonSequenceDel"), this);       m_ButtonSequenceDel->setFont(fGrd);
  m_ButtonSequenceDel->setFlat(true);
  connect( m_ButtonSequenceDel, SIGNAL( Sign_ButtonClickedPtr (const QString &, void *)  ),  this , SLOT( Slot_ButtonSequenceDelClicked(const QString &, void *) ));

  //................... QLineEdit de saisie des quantites ........................................
  m_LineEditMatin     = new CMyQLineEdit(boundRect,"",this,"m_LineEditMatin",this);       m_LineEditMatin->setFont(fGrd);     m_LineEditMatin->setCaractersMask("99999999999");
  m_LineEditMidi      = new CMyQLineEdit(boundRect,"",this,"m_LineEditMidi",this);        m_LineEditMidi->setFont(fGrd);      m_LineEditMidi->setCaractersMask("99999999999");
  m_LineEditApresMidi = new CMyQLineEdit(boundRect,"",this,"m_LineEditApresMidi",this);   m_LineEditApresMidi->setFont(fGrd); m_LineEditApresMidi->setCaractersMask("99999999999");
  m_LineEditSoir      = new CMyQLineEdit(boundRect,"",this,"m_LineEditSoir",this);        m_LineEditSoir->setFont(fGrd);      m_LineEditSoir->setCaractersMask("99999999999");
  m_LineEditCoucher   = new CMyQLineEdit(boundRect,"",this,"m_LineEditCoucher",this);     m_LineEditCoucher->setFont(fGrd);   m_LineEditCoucher->setCaractersMask("99999999999");
  m_LineEditNuit      = new CMyQLineEdit(boundRect,"",this,"m_LineEditNuit",this);        m_LineEditNuit->setFont(fGrd);      m_LineEditNuit->setCaractersMask("99999999999");
  //................... bouton du menu de la période ........................................
  m_ButtonPeriode =  new CMyButton(QRect(0,0,10,10), this, tr("QSP"), this);   m_ButtonPeriode->setFont(fGrd);
  connect( m_ButtonPeriode, SIGNAL( Sign_ButtonClickedPtr (const QString &, void *)  ),  this , SLOT( Slot_ButtonPeriodeClicked(const QString &, void *) ));
  //................... QLineEdit de saisie de la période ........................................
  m_LineEditPeriode   = new CMyQLineEdit(QRect(0,0,10,10),"",this,"m_LineEditPeriode",this); m_LineEditPeriode->setFont(fGrd); m_LineEditPeriode->setCaractersMask("99999999999");

  m_ButtonPeriodeUnit = new CMyButton(QRect(0,0,10,10), this, tr("jour"), this);  m_ButtonPeriodeUnit->setFont(fGrd);
  connect( m_ButtonPeriodeUnit, SIGNAL( Sign_ButtonClickedPtr (const QString &, void *)  ),  this , SLOT( Slot_ButtonPeriodeUnitClicked(const QString &, void *) ));
  //.................... connection du return pressed .............................................
  connect( m_LineEditMatin,     SIGNAL( Sign_returnPressed(const QString &, CMyQLineEdit *, void *, Qt::KeyboardModifiers)  ),  this , SLOT( Slot_returnLineEditPressed(const QString &,  CMyQLineEdit *,void *, Qt::KeyboardModifiers) ));
  connect( m_LineEditMidi,      SIGNAL( Sign_returnPressed(const QString &, CMyQLineEdit *, void *, Qt::KeyboardModifiers)  ),  this , SLOT( Slot_returnLineEditPressed(const QString &,  CMyQLineEdit *,void *, Qt::KeyboardModifiers) ));
  connect( m_LineEditApresMidi, SIGNAL( Sign_returnPressed(const QString &, CMyQLineEdit *, void *, Qt::KeyboardModifiers)  ),  this , SLOT( Slot_returnLineEditPressed(const QString &,  CMyQLineEdit *,void *, Qt::KeyboardModifiers) ));
  connect( m_LineEditSoir,      SIGNAL( Sign_returnPressed(const QString &, CMyQLineEdit *, void *, Qt::KeyboardModifiers)  ),  this , SLOT( Slot_returnLineEditPressed(const QString &,  CMyQLineEdit *,void *, Qt::KeyboardModifiers) ));
  connect( m_LineEditCoucher,   SIGNAL( Sign_returnPressed(const QString &, CMyQLineEdit *, void *, Qt::KeyboardModifiers)  ),  this , SLOT( Slot_returnLineEditPressed(const QString &,  CMyQLineEdit *,void *, Qt::KeyboardModifiers) ));
  connect( m_LineEditPeriode,   SIGNAL( Sign_returnPressed(const QString &, CMyQLineEdit *, void *, Qt::KeyboardModifiers)  ),  this , SLOT( Slot_returnLineEditPressed(const QString &,  CMyQLineEdit *,void *, Qt::KeyboardModifiers) ));
  connect( m_LineEditNuit,      SIGNAL( Sign_returnPressed(const QString &, CMyQLineEdit *, void *, Qt::KeyboardModifiers)  ),  this , SLOT( Slot_returnLineEditPressed(const QString &,  CMyQLineEdit *,void *, Qt::KeyboardModifiers) ));

  connect( m_LineEditMatin,     SIGNAL( Sign_focusOut(const QString &, CMyQLineEdit *, void *)  ),  this , SLOT( Slot_LineEdit_focusOut(const QString &,  CMyQLineEdit *,void *) ));
  connect( m_LineEditMidi,      SIGNAL( Sign_focusOut(const QString &, CMyQLineEdit *, void *)  ),  this , SLOT( Slot_LineEdit_focusOut(const QString &,  CMyQLineEdit *,void *) ));
  connect( m_LineEditApresMidi, SIGNAL( Sign_focusOut(const QString &, CMyQLineEdit *, void *)  ),  this , SLOT( Slot_LineEdit_focusOut(const QString &,  CMyQLineEdit *,void *) ));
  connect( m_LineEditSoir,      SIGNAL( Sign_focusOut(const QString &, CMyQLineEdit *, void *)  ),  this , SLOT( Slot_LineEdit_focusOut(const QString &,  CMyQLineEdit *,void *) ));
  connect( m_LineEditCoucher,   SIGNAL( Sign_focusOut(const QString &, CMyQLineEdit *, void *)  ),  this , SLOT( Slot_LineEdit_focusOut(const QString &,  CMyQLineEdit *,void *) ));
  connect( m_LineEditPeriode,   SIGNAL( Sign_focusOut(const QString &, CMyQLineEdit *, void *)  ),  this , SLOT( Slot_LineEdit_focusOut(const QString &,  CMyQLineEdit *,void *) ));
  connect( m_LineEditNuit,      SIGNAL( Sign_focusOut(const QString &, CMyQLineEdit *, void *)  ),  this , SLOT( Slot_LineEdit_focusOut(const QString &,  CMyQLineEdit *,void *) ));

  connect( m_LineEditMatin,     SIGNAL( Sign_focusIn(const QString &, CMyQLineEdit *, void *)  ),  this , SLOT( Slot_LineEdit_focusIn(const QString &,  CMyQLineEdit *,void *) ));
  connect( m_LineEditMidi,      SIGNAL( Sign_focusIn(const QString &, CMyQLineEdit *, void *)  ),  this , SLOT( Slot_LineEdit_focusIn(const QString &,  CMyQLineEdit *,void *) ));
  connect( m_LineEditApresMidi, SIGNAL( Sign_focusIn(const QString &, CMyQLineEdit *, void *)  ),  this , SLOT( Slot_LineEdit_focusIn(const QString &,  CMyQLineEdit *,void *) ));
  connect( m_LineEditSoir,      SIGNAL( Sign_focusIn(const QString &, CMyQLineEdit *, void *)  ),  this , SLOT( Slot_LineEdit_focusIn(const QString &,  CMyQLineEdit *,void *) ));
  connect( m_LineEditCoucher,   SIGNAL( Sign_focusIn(const QString &, CMyQLineEdit *, void *)  ),  this , SLOT( Slot_LineEdit_focusIn(const QString &,  CMyQLineEdit *,void *) ));
  connect( m_LineEditPeriode,   SIGNAL( Sign_focusIn(const QString &, CMyQLineEdit *, void *)  ),  this , SLOT( Slot_LineEdit_focusIn(const QString &,  CMyQLineEdit *,void *) ));
  connect( m_LineEditNuit,      SIGNAL( Sign_focusIn(const QString &, CMyQLineEdit *, void *)  ),  this , SLOT( Slot_LineEdit_focusIn(const QString &,  CMyQLineEdit *,void *) ));

  connect( m_LineEditMatin,     SIGNAL( textChanged (const QString & ) ),  this , SLOT( Slot_LineEditMatin_textChanged(       const QString &) ));
  connect( m_LineEditMidi,      SIGNAL( textChanged (const QString & ) ),  this , SLOT( Slot_LineEditMidi_textChanged(        const QString &) ));
  connect( m_LineEditApresMidi, SIGNAL( textChanged (const QString & ) ),  this , SLOT( Slot_LineEditApresMidi_textChanged( const QString &) ));
  connect( m_LineEditSoir,      SIGNAL( textChanged (const QString & ) ),  this , SLOT( Slot_LineEditSoir_textChanged(      const QString &) ));
  connect( m_LineEditCoucher,   SIGNAL( textChanged (const QString & ) ),  this , SLOT( Slot_LineEditCoucher_textChanged(   const QString &) ));
  connect( m_LineEditPeriode,   SIGNAL( textChanged (const QString & ) ),  this , SLOT( Slot_LineEditPeriode_textChanged(   const QString &) ));
  connect( m_LineEditNuit,      SIGNAL( textChanged (const QString & ) ),  this , SLOT( Slot_LineEditNuit_textChanged(        const QString &) ));

  //....... construire la liste du focus .......................
  m_ListEnterFocusEdit.append(m_LineEditMatin);
  m_ListEnterFocusEdit.append(m_LineEditMidi);
  m_ListEnterFocusEdit.append(m_LineEditApresMidi);
  m_ListEnterFocusEdit.append(m_LineEditSoir);
  m_ListEnterFocusEdit.append(m_LineEditCoucher);
  m_ListEnterFocusEdit.append(m_LineEditNuit);
  m_ListEnterFocusEdit.append(m_LineEditPeriode);

  QTimer::singleShot(1, this, SLOT(Slot_adjustViewToProfil())); // indispensable de passer par le singleShot
  setMouseTracking (TRUE );
  show();
  m_LineEditMatin->setFocus();
}

//------------------------ ~C_Frm_Posologie ---------------------------------------
C_Frm_Posologie::~C_Frm_Posologie()
{delete m_HitList;
 m_HitList = 0;
}

//------------------------ clearInterface ---------------------------------------
void C_Frm_Posologie::clearInterface()
{   m_LineEditMatin->setText("");
    m_LineEditMidi->setText("");
    m_LineEditApresMidi->setText("");
    m_LineEditSoir->setText("");
    m_LineEditCoucher->setText("");
    m_LineEditPeriode->setText("");
    m_LineEditNuit->setText("");
    m_textEdit->setText("");
    m_MomentMealMap.clear();
}

//------------------------ grammarToInterface ---------------------------------------
void C_Frm_Posologie::grammarToInterface()
{QString grammar = this->grammar();
 m_textEdit->setText(toString(m_pC_Frm_Produit->forme_galenique()));
 int          pos    = grammar.indexOf('[');
 QString      header = "";
 int               i = 0;
 if (pos==-1)   { clearInterface();  return; }
 header               = grammar.left(pos);
 QStringList seqList  = grammar.mid(pos).split('\n');
 //for (i=0; i<seqList.count(); ++i)
     {sequenceToInterface(seqList[i], i);
     }

}
//------------------------ sequenceToInterface ---------------------------------------
//"[0.75;m|155.122;M15r|2;sr30|3;h10-13]/4\n"
void C_Frm_Posologie::sequenceToInterface(const QString &sequence, int index)
{int               pos = sequence.indexOf(']');
 if (pos==-1 ) return;
 QString seq_days      = sequence.mid(pos + 1);
 QString seq_time      = sequence.left(pos).remove("[").trimmed();
 QStringList   seqList = seq_time.split('|');
 for (int i=0; i<seqList.count(); ++i)
     {sequenceTimeToInterface(seqList[i], index);
     }
 sequenceDaysToInterface(seq_days, index);
}
//------------------------ sequenceTimeToInterface ---------------------------------------
//"155.122;M15r"
//"3;h10-13"
void C_Frm_Posologie::sequenceTimeToInterface(const QString &sequence, int index)
{
    QString r        = "";
    QString before   = "";
    QString after    = "";
    int          pos = sequence.indexOf(';');
    QString       qu = sequence.left(pos);    ++pos;  // recuperer quantite et passer le ';'
    QString        m = sequence.mid(pos,1);   ++pos;  // recupere le type de periode (m M a s c n h) et passer son symbole
    // m est une de ces valeurs : m M a s c n h
    if (m=="h")     //"3;h10-13" //"3;h10"
       {m    = sequence.mid(pos);  // h10-13   h10 M15r Mr15 Mr
        pos  = m.indexOf('-');
        if (pos != -1)
           {  before   = m.left(pos);
              after    = m.mid(pos+1);
              sequenceHoursToInterface(before, after, qu);
           }
        else
           {  sequenceHoursToInterface(m, "", qu);
           }
       }
    else   // m est une de ces valeurs  m M a s c n
       {r      = sequence.mid(pos);        // recuperer sequence du repas
        char c = m.toAscii()[0];
        switch(c)
           {
           case 'm':
                 m_LineEditMatin->setText(qu);
                 if (r.length()) m_MomentMealMap["matin"]=r;
                 break;
           case 'M':
                m_LineEditMidi->setText(qu);
                if (r.length()) m_MomentMealMap["midi"]=r;
                break;
           case 'a':
                m_LineEditApresMidi->setText(qu);
                if (r.length()) m_MomentMealMap["après-midi"]=r;
                break;
           case 's':
                m_LineEditSoir->setText(qu);
                if (r.length()) m_MomentMealMap["soir"]=r;
                break;
           case 'c':
                m_LineEditCoucher->setText(qu);
                if (r.length()) m_MomentMealMap["coucher"]=r;
                break;
           case 'n':
                m_LineEditNuit->setText(qu);
                if (r.length()) m_MomentMealMap["nuit"]=r;
                break;
           }
       }
}

//------------------------ sequenceHoursToInterface ---------------------------------------
//"/4"
int C_Frm_Posologie::sequenceHoursToInterface(const QString &before, const QString &after, const QString &value)
{int h_deb     = before.toInt();
 int h_fin     = after.toInt();
 QString hours = "";
 if (before.length() && after.length())
    {if (h_deb>=6 && h_fin<11)
        {m_LineEditMatin->setText(value);
        }
     else if (h_deb>=11 && h_fin<14)
       {m_LineEditMidi->setText(value);
       }
     else if (h_deb>=14 && h_fin<19)
       {m_LineEditApresMidi->setText(value);
       }
     else if (h_deb>=19 && h_fin<21)
       {m_LineEditSoir->setText(value);
       }
     else if (h_deb>=21 && h_fin<24)
       {m_LineEditCoucher->setText(value);
       }
     else if (h_deb>=0 && h_fin<6)
       {m_LineEditNuit->setText(value);
       }
     return 0;
    }
 else if (before.length())
   {hours = before;
   }
 else if (after.length())
   {hours = after;
   }
 if  (hours.length())
     {h_deb = hours.toInt();
      if (h_deb>=6 && h_deb<11)
         {m_LineEditMatin->setText(value);
         }
      else if (h_deb>=11 && h_deb<14)
        {m_LineEditMidi->setText(value);
        }
      else if (h_deb>=14 && h_deb<19)
        {m_LineEditApresMidi->setText(value);
        }
      else if (h_deb>=19 && h_deb<21)
        {m_LineEditSoir->setText(value);
        }
      else if (h_deb>=21 && h_deb<24)
        {m_LineEditCoucher->setText(value);
        }
      else if (h_deb>=0 && h_deb<6)
        {m_LineEditNuit->setText(value);
        }
     }
  return 0;
}

//------------------------ sequenceDaysToInterface ---------------------------------------
//"/4"
void C_Frm_Posologie::sequenceDaysToInterface(const QString &sequence, int index)
{   QString j = sequence.mid(1);
    m_LineEditPeriode->setText(j);
}
//------------------------ interfaceToGrammarString ---------------------------------------
//   "comprimé[125;m|265;M|445;s]/8\n"
//   "[0.75;m|155.122;M15r|2;sr30|3;h10-13]/4\n"
//   "[0.5;M|1;s]/3"
// m M a s c n h
// "345687/123!ALL_LITERAL=comprimé[1;m|2;M|4;s]/8\n[0.5;m|1;M15r|2;sr30|3;h10-13]/4\n[0.5;m|1;s]/3".
QString C_Frm_Posologie::interfaceToGrammarString()
{QString ret="";
 ret   += m_pC_Frm_Produit->forme_galenique();
 ret   += "[";
 if (m_LineEditMatin->isVisible() && m_LineEditMatin->text().length())
    {ret += m_LineEditMatin->text().trimmed()+";m"+ m_MomentMealMap["matin"]+"|";
    }
 if (m_LineEditMidi->isVisible() && m_LineEditMidi->text().length())
    {ret += m_LineEditMidi->text().trimmed()+";M"+ m_MomentMealMap["midi"]+"|";
    }
 if (m_LineEditApresMidi->isVisible() && m_LineEditApresMidi->text().length())
    {ret += m_LineEditApresMidi->text().trimmed()+";a"+ m_MomentMealMap["après-midi"]+"|";
    }
 if (m_LineEditSoir->isVisible() && m_LineEditSoir->text().length())
    {ret += m_LineEditSoir->text().trimmed()+";s"+ m_MomentMealMap["soir"]+"|";
    }
 if (m_LineEditCoucher->isVisible() && m_LineEditCoucher->text().length())
    {ret += m_LineEditCoucher->text().trimmed()+";c"+ m_MomentMealMap["coucher"]+"|";
    }
 if (m_LineEditNuit->isVisible() && m_LineEditNuit->text().length())
    {ret += m_LineEditNuit->text().trimmed()+";c"+ m_MomentMealMap["nuit"]+"|";
    }
 if (ret.endsWith('|')) ret = ret.left(ret.length()-1);
 ret +="]/";
 if (m_LineEditPeriode->text().length())
    {ret += m_LineEditPeriode->text().trimmed();
    }
 else
    {ret += "1";
    }
 return ret.prepend(m_pC_Frm_Produit->id()+"!ALL_LITERAL=");
}

//------------------------------- getHitsList -------------------------------------
QStringList C_Frm_Posologie::getHitsList()
{QStringList lst = m_pC_BDM_Api->selectPosologieHitList(m_pC_Frm_Produit->id());
 return lst;
}
//------------------------------- Slot_LineEdit_focusIn -------------------------------------
void C_Frm_Posologie::Slot_LineEdit_focusIn(const QString &name,  CMyQLineEdit * ,void *)
{if (name!="m_LineEditMatin")
    {if (m_HitList)
        {m_HitList->deleteLater();
         m_HitList = 0;
        }
     return;
    }
 if (m_HitList)                return;
 QStringList grammarList = getHitsList();

 QRect geometry( this->geometry().x() + timeToPos_x(0)          ,
                 parentWidget()->geometry().y() + parentWidget()->height(),
                 this->geometry().width()                       ,
                 qMin(ITEM_HIT_H * grammarList.count(),ITEM_HIT_H*ITEM_HIT_NBTOVIEW)                              // hauteur du popup
               );

 m_HitList = new C_Frm_PosologieHitList(grammarList, geometry , this->parentWidget()->parentWidget());
 connect( m_HitList,      SIGNAL( Sign_HitList_ItemSelected(const QString &, int)  ),  this , SLOT( Slot_HitList_ItemSelected(const QString &,  int) ));
 m_HitList ->setGeometry( geometry );
 m_HitList->show();
}
//------------------------------- Slot_LineEdit_focusOut -------------------------------------
void C_Frm_Posologie::Slot_LineEdit_focusOut(const QString &name,  CMyQLineEdit *,void *)
{
 if (m_HitList && name=="m_LineEditPeriode")
    {m_HitList->deleteLater();
     m_HitList = 0;
    }
}
//------------------------------- adjustToSize -------------------------------------
void C_Frm_Posologie::adjustToSize(const QRect &geometry_rect)
{  //............... rectangle du composant .............................
   setGeometry(geometry_rect);
   //................ nombre de visibles ................................
   int nb     = countVisiblesLineEdit()-1; // faut pas compter celui de la periode
   int but_w  = m_grad_w/nb;
   int but_h  = 0;  // defini plus loin apres calcul du bounding rect
   //................ largeur de la graduation ...........................
   QFont  fGrd  = font();
   fGrd.setPixelSize(10); fGrd.setBold(false); fGrd.setItalic(false);
   QFontMetrics fntMetGrd = QFontMetrics(fGrd);
   QRect        boundRect = fntMetGrd.boundingRect ("X");
   but_h                  = boundRect.height();
   m_grad_pos_y           = geometry_rect.height();
   if (m_grad_h)
       m_grad_pos_y       = geometry_rect.height()- but_h - m_grad_h;//-16;  // ligne de graduation 16 pixels au dessus de la ligne basse

   //..................... placer les objets ........................................................
   int pos_x         = timeToPos_x(0);
   int pos_y         = m_grad_pos_y-but_h*2;
   //..................... bouton matin midi soir..........................................................
   if (m_ButtonMatin->isVisible())     {m_ButtonMatin->setGeometry(      pos_x , pos_y, but_w, but_h);     pos_x += but_w;}
   if (m_ButtonMidi->isVisible())      {m_ButtonMidi->setGeometry(       pos_x , pos_y, but_w, but_h);     pos_x += but_w;}
   if (m_ButtonApresMidi->isVisible()) {m_ButtonApresMidi->setGeometry(  pos_x , pos_y, but_w, but_h);     pos_x += but_w;}
   if (m_ButtonSoir->isVisible())      {m_ButtonSoir->setGeometry(       pos_x , pos_y, but_w, but_h);     pos_x += but_w;}
   if (m_ButtonCoucher->isVisible())   {m_ButtonCoucher->setGeometry(    pos_x , pos_y, but_w, but_h);     pos_x += but_w;}
   if (m_ButtonNuit->isVisible())      {m_ButtonNuit->setGeometry(       pos_x , pos_y, but_w, but_h);     pos_x += but_w;}
   //..................... editeur de texte..........................................................
   m_textEdit->setGeometry(0,0,m_grad_w, pos_y);
   //..................... gestion des sequences..........................................................
   m_ButtonSequencelist->move( pos_x ,  pos_y); pos_x += m_ButtonSequencelist->rect().width();
   m_ButtonSequenceAdd ->move( pos_x ,  pos_y); pos_x += m_ButtonSequenceAdd->rect().width();
   m_ButtonSequenceDel ->move( pos_x ,  pos_y); pos_x += m_ButtonSequenceDel->rect().width();

   pos_x    = timeToPos_x(0);
   pos_y   += but_h;
   //..................... saisie des quantites..........................................................
   if (m_LineEditMatin->isVisible())     {m_LineEditMatin     ->setGeometry( pos_x , pos_y, but_w, but_h); pos_x += but_w;}
   if (m_LineEditMidi->isVisible())      {m_LineEditMidi      ->setGeometry( pos_x , pos_y, but_w, but_h); pos_x += but_w;}
   if (m_LineEditApresMidi->isVisible()) {m_LineEditApresMidi ->setGeometry( pos_x , pos_y, but_w, but_h); pos_x += but_w;}
   if (m_LineEditSoir->isVisible())      {m_LineEditSoir      ->setGeometry( pos_x , pos_y, but_w, but_h); pos_x += but_w;}
   if (m_LineEditCoucher->isVisible())   {m_LineEditCoucher   ->setGeometry( pos_x , pos_y, but_w, but_h); pos_x += but_w;}
   if (m_LineEditNuit->isVisible())      {m_LineEditNuit      ->setGeometry( pos_x , pos_y, but_w, but_h); pos_x += but_w;}
   //................... bouton du menu de la période ........................................
   m_ButtonPeriode     ->setGeometry(pos_x , pos_y, m_rightMarg-50,boundRect.height());                pos_x += m_ButtonPeriode->width();
   //..................... saisie de la periode ..........................................................
   m_LineEditPeriode   ->setGeometry(pos_x , pos_y, 30,boundRect.height());                            pos_x += m_LineEditPeriode->width();
   //..................... unite de la periode (jours mois etc..) ........................................
   m_ButtonPeriodeUnit ->setGeometry(pos_x,  pos_y, geometry_rect.width()-pos_x-1,boundRect.height()); pos_x += m_ButtonPeriodeUnit->width();
   if (m_HitList)
      {m_HitList ->setGeometry( geometry_rect.x() + timeToPos_x(0)          ,
                                parentWidget()->geometry().y() + parentWidget()->height(),
                                geometry_rect.width()                       ,
                                m_HitList->height()
                              );
      }
}

//------------------------------- Slot_adjustViewToProfil -------------------------------------
void     C_Frm_Posologie::Slot_adjustViewToProfil()
{adjustViewToProfil(m_viewProfil);
}

//------------------------------- adjustViewToProfil -------------------------------------
void     C_Frm_Posologie::adjustViewToProfil(int viewProfil)
{
if ( ! (viewProfil & A_MIDI))
   { m_LineEditApresMidi->hide();
     m_ButtonApresMidi->hide();
   }
else
   { m_LineEditApresMidi->show();
     m_ButtonApresMidi->show();
   }
/*
if ( ! (viewProfil & SOIR))
   { m_LineEditSoir->hide();
     m_ButtonSoir->hide();
   }
else
   { m_LineEditSoir->show();
     m_ButtonSoir->show();
   }
*/
if ( ! (viewProfil & COUCHER))
   { m_LineEditCoucher->hide();
     m_ButtonCoucher->hide();
   }
else
   { m_LineEditCoucher->show();
     m_ButtonCoucher->show();
   }

if ( ! (viewProfil & NUIT))
   { m_LineEditNuit->hide();
     m_ButtonNuit->hide();
   }
else
   { m_LineEditNuit->show();
     m_ButtonNuit->show();
   }
adjustToSize(this->geometry());
}
//------------------------------- setViewProfil -------------------------------------
void     C_Frm_Posologie::setViewProfil(int viewProfil  /* = C_Frm_Posologie::ALL_WIDGETS */,
                                        int profilMode  /*=  C_Frm_Posologie::PROFIL_SET */)
{ if      (profilMode == C_Frm_Posologie::PROFIL_SET) m_viewProfil = viewProfil;
  else if (profilMode == C_Frm_Posologie::PROFIL_ADD) m_viewProfil = m_viewProfil | viewProfil;
  else if (profilMode == C_Frm_Posologie::PROFIL_DEL) m_viewProfil = m_viewProfil & (~viewProfil);
  adjustViewToProfil(viewProfil);
}
//------------------------------- nextEnterFocus -------------------------------------
CMyQLineEdit *C_Frm_Posologie::nextEnterFocus(CMyQLineEdit *pCMyQLineEdit)
{int index = m_ListEnterFocusEdit.indexOf ( pCMyQLineEdit )+1;

 while (index < m_ListEnterFocusEdit.count())
    {if ( m_ListEnterFocusEdit[index]->isVisible() ) return m_ListEnterFocusEdit[index];
     ++index;
    }
 return   m_ListEnterFocusEdit[0];   // matin
}
//------------------------ countVisiblesLineEdit --------------------------------------------
int C_Frm_Posologie::countVisiblesLineEdit()
{   int index = 0;
    int    nb = 0;
    while (index < m_ListEnterFocusEdit.count())
       {if ( m_ListEnterFocusEdit[index]->isVisible() ) ++nb;
        ++index;
       }
    return   nb;
}

//------------------------------- setGridVisibility -------------------------------------
void C_Frm_Posologie::setGridVisibility(bool gridvisibility /* = false */)
{m_grad_h = gridvisibility?H_GRAD:0;
 adjustToSize(this->geometry());
}

//------------------------ doMenuButtonTimeMeal ---------------------------------------
int C_Frm_Posologie::doMenuButtonTimeMeal(const QString &name)
{   QString str  = name;
    if     (str==tr("midi"))       str.prepend(tr("de "));
    else if(str==tr("matin"))      str = (tr("du petit déjeuner"));
    else if(str==tr("après-midi")) str = (tr("du goûter"));
    else if(str==tr("soir"))       str.prepend(tr("du "));

    QStringList optionList;

    optionList<<"=99=#medicatux/45-before_meal.png#"+tr("mention inutile");
    optionList<<"=-45=#medicatux/45-before_meal.png#"+tr("45 minutes avant le repas %1").arg(str);
    optionList<<"=-30=#medicatux/30-before_meal.png#"+tr("30 minutes avant le repas %1").arg(str);
    optionList<<"=-15=#medicatux/15-before_meal.png#"+tr("15 minutes avant le repas %1").arg(str);
    optionList<<"=0=#medicatux/during_meal.png#"+tr("pendant le repas %1").arg(str);
    optionList<<"=15=#medicatux/15-after_meal.png#"+tr("15 minutes après le repas %1").arg(str);
    optionList<<"=30=#medicatux/30-after_meal.png#"+tr("30 minutes après le repas %1").arg(str);
    optionList<<"=45=#medicatux/45-after_meal.png#"+tr("45 minutes après le repas %1").arg(str);
    return ThemePopup(optionList,this).DoPopupList().trimmed().toInt();
}
//------------------------ retPopupMomentMealToGrammarString ---------------------------------------
QString  C_Frm_Posologie::retPopupMomentMealToGrammarString(int retPopup)
{if (retPopup==99)
    {return "";
    }
 else if (retPopup==0)
    {return "r";
    }
 else if (retPopup<0)
    {return QString::number(qAbs(retPopup))+"r";
    }
 else
    {
     return QString("r")+QString::number(retPopup);
    }
}
//---------------------------- Slot_HitList_ItemSelected ------------------------------------------------
void C_Frm_Posologie::Slot_HitList_ItemSelected(const QString &grammar,  int index)
{   qDebug()<< QString::number(index)+"\n   "+grammar;
    setGrammar(grammar);
    grammarToInterface();
    m_pC_BDM_Api->increasePosologieHit(grammar, m_pC_Frm_Produit->id());
    m_HitList->deleteLater();
    m_HitList = 0;
}
//------------------------ Slot_returnLineEditPressed ---------------------------------------
void C_Frm_Posologie::Slot_returnLineEditPressed(const QString & /* name */,  CMyQLineEdit *pCMyQLineEdit, void *, Qt::KeyboardModifiers modifiers)
{ if (modifiers&Qt::AltModifier || modifiers&Qt::ControlModifier)
     {if (m_HitList)
         {   qDebug() << m_HitList->selectedGrammar();
             QString grammar = m_HitList->selectedGrammar();
             m_HitList->deleteLater();
             m_HitList = 0;
             setGrammar(grammar);
             grammarToInterface();
             m_pC_BDM_Api->increasePosologieHit(grammar, m_pC_Frm_Produit->id());
         }
     }
  pCMyQLineEdit = nextEnterFocus(pCMyQLineEdit);
  if (pCMyQLineEdit == m_LineEditMatin)     emit     Sign_child_LeaveLastEditZone();
  else                                      pCMyQLineEdit->setFocus();
}
//------------------------ Slot_LineEditMatin_textChanged ---------------------------------------
void C_Frm_Posologie::Slot_LineEditMatin_textChanged(       const QString &)
{ setGrammar(interfaceToGrammarString());
  m_textEdit->setText(toString());
}
//------------------------ Slot_LineEditMidi_textChanged ---------------------------------------
void C_Frm_Posologie::Slot_LineEditMidi_textChanged(        const QString &)
{ setGrammar(interfaceToGrammarString());
  m_textEdit->setText(toString());
}
//------------------------ Slot_LineEditApresMidi_textChanged ---------------------------------------
void C_Frm_Posologie::Slot_LineEditApresMidi_textChanged( const QString &)
{ setGrammar(interfaceToGrammarString());
  m_textEdit->setText(toString());
}
//------------------------ Slot_LineEditSoir_textChanged ---------------------------------------
void C_Frm_Posologie::Slot_LineEditSoir_textChanged(      const QString &)
{ setGrammar(interfaceToGrammarString());
  m_textEdit->setText(toString());
}
//------------------------ Slot_LineEditCoucher_textChanged ---------------------------------------
void C_Frm_Posologie::Slot_LineEditCoucher_textChanged(   const QString  &)
{ setGrammar(interfaceToGrammarString());
  m_textEdit->setText(toString());
}
//------------------------ Slot_LineEditPeriode_textChanged ---------------------------------------
void C_Frm_Posologie::Slot_LineEditPeriode_textChanged(   const QString  &)
{ setGrammar(interfaceToGrammarString());
  m_textEdit->setText(toString());
}
//------------------------ Slot_LineEditNuit_textChanged ---------------------------------------
void C_Frm_Posologie::Slot_LineEditNuit_textChanged(       const QString  &)
{ setGrammar(interfaceToGrammarString());
  m_textEdit->setText(toString());
}

//------------------------ Slot_ButtonMatinClicked ---------------------------------------
void C_Frm_Posologie::Slot_ButtonMatinClicked(const QString &name, void* )
{int retPopup =  doMenuButtonTimeMeal(name);
 m_MomentMealMap[name]=retPopupMomentMealToGrammarString(retPopup);
 setGrammar(interfaceToGrammarString());
 m_textEdit->setText(toString());
}
//------------------------ Slot_ButtonMidiClicked ---------------------------------------
void C_Frm_Posologie::Slot_ButtonMidiClicked(const QString &name, void* )
{int retPopup = doMenuButtonTimeMeal(name);
 m_MomentMealMap[name]=retPopupMomentMealToGrammarString(retPopup);
 setGrammar(interfaceToGrammarString());
 m_textEdit->setText(toString());
}
//------------------------ Slot_ButtonApresMidiClicked ---------------------------------------
void C_Frm_Posologie::Slot_ButtonApresMidiClicked(const QString &name, void* )
{int retPopup =  doMenuButtonTimeMeal(name);
 m_MomentMealMap[name]=retPopupMomentMealToGrammarString(retPopup);
 setGrammar(interfaceToGrammarString());
 m_textEdit->setText(toString());
}
//------------------------ Slot_ButtonSoirClicked ---------------------------------------
void C_Frm_Posologie::Slot_ButtonSoirClicked(const QString &name, void* )
{ int retPopup =  doMenuButtonTimeMeal(name);
  m_MomentMealMap[name]=retPopupMomentMealToGrammarString(retPopup);
  setGrammar(interfaceToGrammarString());
  m_textEdit->setText(toString());
}
//------------------------ Slot_ButtonCoucherClicked ---------------------------------------
void C_Frm_Posologie::Slot_ButtonCoucherClicked(const QString &, void* )
{
}
//------------------------ Slot_ButtonNuitClicked ---------------------------------------
void C_Frm_Posologie::Slot_ButtonNuitClicked(const QString &, void* )
{
}
//------------------------ Slot_ButtonSequencelistClicked ---------------------------------------
void C_Frm_Posologie::Slot_ButtonSequencelistClicked(const QString &, void *)
{

}
//------------------------ Slot_ButtonSequenceAddClicked ---------------------------------------
void C_Frm_Posologie::Slot_ButtonSequenceAddClicked(const QString &, void *)
{

}
//------------------------ Slot_ButtonSequenceDelClicked ---------------------------------------
void C_Frm_Posologie::Slot_ButtonSequenceDelClicked(const QString &, void *)
{

}
//------------------------ Slot_ButtonPeriodeClicked ---------------------------------------
void C_Frm_Posologie::Slot_ButtonPeriodeClicked(const QString &, void *)
{

}
//------------------------ Slot_ButtonPeriodeUnitClicked ---------------------------------------
void C_Frm_Posologie::Slot_ButtonPeriodeUnitClicked(const QString &, void *)
{   QStringList optionList;
    optionList<<"=1=#medicatux/45-before_meal.png#"+tr("jour");
    optionList<<"=2=#medicatux/30-before_meal.png#"+tr("semaine");
    optionList<<"=3=#medicatux/15-before_meal.png#"+tr("mois");
    optionList<<"=4=#medicatux/during_meal.png#"+tr("ans");
    int ret = ThemePopup(optionList,this).DoPopupList().trimmed().toInt();
         if (ret==1) m_ButtonPeriodeUnit->setText(tr("jour"));
    else if (ret==2) m_ButtonPeriodeUnit->setText(tr("semaine"));
    else if (ret==3) m_ButtonPeriodeUnit->setText(tr("mois"));
    else if (ret==4) m_ButtonPeriodeUnit->setText(tr("ans"));
}

//------------------------ timeToPos_x ---------------------------------------
int C_Frm_Posologie::timeToPos_x(int nb_mn)
{  return (nb_mn*m_grad_w)/(m_Hfin_mn - m_Hdeb_mn);
}

//------------------------ paintEvent ---------------------------------------
void C_Frm_Posologie::paintEvent ( QPaintEvent * /*event*/ )
{   if (m_grad_h==0) return;
    QPainter p(this);
    //........... cadre a bords ronds .................................
    QRect rect = this->rect();
    rect.setWidth  (this->rect().width() -1); // -1 car bord droit et bas masques par le widget
    rect.setHeight (this->rect().height()-1); // -1 car bord droit et bas masques par le widget
    /*
    QColor background_color = m_pC_Frm_Produit->backGroundColor();
    p.setPen (background_color.darker(160));
    QPainterPath path;
    path.addRoundedRect (rect, 6, 6);
    p.setBrush(background_color);
    p.drawPath(path);
    */
    //............ dessin de la ligne graduee horizontale ...............

    QFont            fGrd  = font();
    fGrd.setPixelSize(8); fGrd.setBold(false); fGrd.setItalic(false); p.setFont ( fGrd );
    QFontMetrics fntMetGrd = QFontMetrics(fGrd);
    QRect        boundRect = fntMetGrd.boundingRect ("X");

    //QColor grad_color   = palette().color(QPalette::Dark);
    int grad_w  = m_grad_w -2; // 1 petit ajustage de 2 pixels
    int pos_y   = m_grad_pos_y;
    int pos_x   = 0;
    int time    = 0;
    int nb_mn   = m_Hfin_mn-m_Hdeb_mn;
    for (int i = 0; i<=nb_mn; i+=30)
        {pos_x = (i*grad_w)/nb_mn;
         p.drawLine (  pos_x, pos_y, pos_x, pos_y+2);
        }    //p.drawLine ( 0, pos_y, grad_w , pos_y);    // ligne horizontale
    for (int i = 0; i<nb_mn; i+=60)
        {pos_x = (i*grad_w)/nb_mn;
         time  = i;
         if (m_first_time != m_Hdeb_mn)
            { time = m_first_time + i;
              if (time>=(24*60)) time -= (24*60);
            }
         p.setPen (QColor("#ff0000"));
         p.drawLine (  pos_x, pos_y, pos_x, pos_y+H_GRAD );
         if (i==0)             pos_x  = 0;
         else if (time>=10)    pos_x -= boundRect.width()/2;
         else                  pos_x += 1;
         p.setPen (palette().color(QPalette::Dark).darker(160));
         p.drawText ( pos_x, pos_y+boundRect.height()+H_GRAD,QString::number((time)/60));
        }

    // QFrame::paintEvent(event); surtout pas !!
}

//---------------------------- mouseMoveEvent ------------------------------------------------
void    C_Frm_Posologie::mouseMoveEvent ( QMouseEvent * event )
{mouseMoveEvent ( event , 0 );
}

//---------------------------- mouseMoveEvent ------------------------------------------------
void    C_Frm_Posologie::mouseMoveEvent ( QMouseEvent * event , QWidget * /* pQWidget */)
{if (m_GrabIsOn)
    {if ( m_GrabIsOn==MIDLE_START)
        {//pC_Frm_Prescription->objectDoMoving(this);
        }
    }
  else
    { /*
      if (event->x()<10)
         { setCursor(Qt::OpenHandCursor);
         }
      else
         {setCursor(Qt::ArrowCursor);
         }
       */
    }
  QFrame::mouseMoveEvent ( event );
}

//---------------------------- mouseReleaseEvent ------------------------------------------------
void C_Frm_Posologie::mouseReleaseEvent ( QMouseEvent * /*event*/ )
{releaseMouse();                // degraber la souris
 if (m_GrabIsOn==0) return;     // cassos si rien a faire
 m_GrabIsOn  = 0;
}

//---------------------------- mousePressEvent ------------------------------------------------
void C_Frm_Posologie::mousePressEvent(QMouseEvent *event)
{   if  (event->button() == Qt::LeftButton)
        {if (m_GrabIsOn==0)
            {
             m_startPosY       = event->pos().y();
             /*
             if (event->pos().x()<10)
                { //grabMouse(QCursor(Qt::ClosedHandCursor));
                  m_GrabIsOn = MIDLE_START;
                  //pC_Frm_Prescription->objectStartsMoving(this);
                  update();
                }
              */
             }
         else
             {/*
              QDrag *drag         = new QDrag(this);
              QMimeData *mimeData = new QMimeData;
              QRect rect(-4,0,width(),height());

              QPixmap pix = QPixmap::grabWidget (this, rect );
              mimeData->setText("Drag day");
              mimeData->setImageData(pix);
              drag->setMimeData(mimeData);
              drag->setPixmap(pix);
              Qt::DropAction dropAction = drag->exec();
              */
             }
         }
    else if ( event->button() == Qt::RightButton  && m_GrabIsOn==0)
         { //................ menu ....................
           /*
           ((C_Frm_Day*)parent())->Slot_StopTimer(1);   // le timer ser debloque lors du release button
           QString       ret =  ((C_Frm_Prescription*)parent())->doProduitMenu(this->Produit_instance(),1);
           // "Copy" "Replace" "Cut" "Type :" "Status :"  "Modify"  "Open" "Create" "Anomymize" "Quit"
           if (ret.length())
              {
                if (ret.indexOf("Modify") != -1)
                   {emit Sign_RendezVousChangeClicked(this);
                   }
               else if (ret.indexOf("Status :") != -1)
                  { QString statut = ret.remove("Status :");
                    m_State = statut.trimmed();
                    setWidgetOnRdv(*this);                // on reajuste le widget sur les nouvelles donn\303\251es
                    setWidgetStyleOnRdv(*this);
                    RDV_Update();
                  }
               else if (ret.indexOf("Type :") != -1)
                  { QString type = ret.remove("Type :");
                    m_Type = type.trimmed();
                    setWidgetOnRdv(*this);                // on reajuste le widget sur les nouvelles donn\303\251es
                    setWidgetStyleOnRdv(*this);
                    RDV_Update();
                  }
               else if (ret.indexOf("Cut") != -1)  // il ne  peut pas se detruire lui meme et sortir ensuite de sa fonction donc QTIMER
                  {QTimer::singleShot(10, this, SLOT(Slot_cut()) );
                  }
               else if (ret.indexOf("Copy") != -1)
                    Slot_copy();
               else if (ret.indexOf("Replace") != -1)
                    replaceWithCopy();
               else if (ret.indexOf("Modify") != -1)
                  {emit Sign_RendezVousChangeClicked(this);
                  }
               else if (ret.indexOf("Anomymize") != -1)
                  {m_Nom="";
                   m_Prenom="";
                   m_GUID="";
                   m_Tel="";
                   m_Note="";
                   m_Where="";
                   setWidgetOnRdv(*this);                // on reajuste le widget sur les nouvelles donn\303\251es
                   setWidgetStyleOnRdv(*this);
                   RDV_Update();
                  }
               else if (ret.indexOf("Delete") != -1)
                  {QTimer::singleShot(10, this, SLOT(Slot_delete()) );
                  }
               else if (ret.indexOf("Open") != -1)
                  {((C_Frm_Day*)parent())->Slot_ButtonAccederClicked(0, this);
                  }
               else if (ret.indexOf("Create") != -1)
                  {((C_Frm_Day*)parent())->Slot_ButtonAccederClicked(0, this);
                  }
               else if (ret.indexOf("Find Appointments") != -1)
                  {((C_Frm_Day*)parent())->Chercher_les_RDV_dun_patient();
                  }
               else if (ret.startsWith("AppointmentsListFor"))
                  {((C_Frm_Day*)parent())->Chercher_les_RDV_dun_patient(ret.mid(19));
                  }
               // CZF deb
               else if (ret.startsWith("PrintAppointments"))
                  {QDateTime Dtrdv = QDateTime::fromString(ret.mid(17,10) + " 00:00:00","yyyy-MM-dd hh:mm:ss");
                   ((C_Frm_Day*)parent())->Imprimer_les_RDV_dun_medecin(Dtrdv, ret.mid(28));
                  }
               // CZF fin
              }
           */
         event->accept();
         // ((C_Frm_Day*)parent())->Slot_StopTimer(0);
        }
 }

//====================================================== C_Frm_Produit ======================================================================
//------------------------------------------------------ C_Frm_Produit ----------------------------------------------------------------------
C_Frm_Produit::C_Frm_Produit (  C_OrdoLineRecord  const  &ordoLineRecord     ,       // data
                                C_BDM_Api           *pC_BDM_Api,
                                QRect                geometry_rect  ,
                                QWidget             *parent       ,
                                const QString       &str_background_noALD, /* = "#ffe3be" */
                                const QString       &str_background_isALD, /* = "#f5ffbe" */
                                bool                 gridvisibility, /* = false*/  // visibilite de la grille horizontale
                                int                  viewProfil      /* = C_Frm_Posologie::all */
                             )

         : QFrame(parent), C_OrdoLineRecord(ordoLineRecord)
{
  m_pC_BDM_Api                       = pC_BDM_Api;
  m_background_noALD                 = QColor(str_background_noALD);
  m_background_isALD                 = QColor(str_background_isALD);
  m_GrabIsOn                         = 0;
  m_pC_Frm_Posologie                 = 0;
  this->setObjectName("C_Frm_Produit");      // pour le reperer ensuite
  //................. completer les informations ........................
  complete_C_OrdoLineRecord();
  //................ on initialise les positions graphiques .............
  setGeometry(geometry_rect);
  //..................... recuperer parent qui maintient la collection de bitmap .....................
  C_Frm_Prescription *pC_Frm_Prescription = (C_Frm_Prescription*)this->parentWidget();   // parent; :: adjust_Vertical_PositionToGrid();
  if (pC_Frm_Prescription==0) return;
  //..................... bouton effacement ..........................................................
  m_ButtonDelete    = new CMyButton(pC_Frm_Prescription->m_objectsDel, this, "", this);
  QRect     rect    =  pC_Frm_Prescription->m_objectsDel.rect(); // rectangle icone
  m_ButtonDelete->setGeometry(geometry_rect.width()-rect.width()-3,2,rect.width(),rect.height());
  connect( m_ButtonDelete, SIGNAL( Sign_ButtonClickedPtr (const QString&, void *)  ),  pC_Frm_Prescription , SLOT( Slot_ButtonDeleteClicked(const QString&, void *) ));
  setMouseTracking (TRUE );
  //..................... bouton numero ..........................................................
  m_ButtonNumber    = new CMyButton(this, "", this);
  m_ButtonNumber->setGeometry(0,0,16,16);
  m_ButtonNumber->setText(numOrdre());
  connect( m_ButtonNumber, SIGNAL( Sign_ButtonClickedPtr (const QString&, void *)  ),  pC_Frm_Prescription , SLOT( Slot_ButtonNumberClicked(const QString&, void *) ));
  //..................... l'editeur de posologie .....................................................
  int h_posoEdit = geometry_rect.height()-m_ButtonNumber->height()+2;
  int w_posoEdit = geometry_rect.width()-HANDLE_MOVE_WIDTH;
  m_pC_Frm_Posologie = new C_Frm_Posologie( pC_BDM_Api,
                                            this,
                                            pC_Frm_Prescription,
                                            QRect( HANDLE_MOVE_WIDTH,
                                                   geometry_rect.height()-h_posoEdit,
                                                   w_posoEdit,
                                                   h_posoEdit),
                                                   this,
                                                   gridvisibility,
                                                   viewProfil);
  setMouseTracking (TRUE );
  show();
}
//------------------------ C_Frm_Produit ---------------------------------------
C_Frm_Produit::C_Frm_Produit(  C_Frm_Produit  const  &c_Frm_Produit)
    : QFrame(c_Frm_Produit.parentWidget()), C_OrdoLineRecord(c_Frm_Produit.ordoLineRecord())
{ m_pC_BDM_Api = c_Frm_Produit.m_pC_BDM_Api;
  setGeometry(c_Frm_Produit.rect());
}

//------------------------ ~C_Frm_Produit -----------------------------------------------------------------
C_Frm_Produit::~C_Frm_Produit()
{
}

//------------------------------- adjustToSize -----------------------------------------------------------------
void C_Frm_Produit::adjustToSize(const QRect &rect)
{   setGeometry(rect);
    //..................... l'editeur de posologie .....................................................
    int h_posoEdit = rect.height()- m_ButtonNumber->height()+2;
    int w_posoEdit = rect.width() - HANDLE_MOVE_WIDTH;
    if (m_pC_Frm_Posologie) m_pC_Frm_Posologie->adjustToSize(QRect( HANDLE_MOVE_WIDTH, rect.height()-h_posoEdit,  w_posoEdit,  h_posoEdit ));
}

//------------------------------- setColors -----------------------------------------------------------------
void   C_Frm_Produit::setColors(const QString &_std_color, const QString &_ald_color)
{QString std_color = _std_color;
 QString ald_color = _ald_color;
 std_color         = std_color.remove('#');
 ald_color         = ald_color.remove('#');
 if (std_color.length()) m_background_noALD = QColor(std_color.prepend('#'));
 if (ald_color.length()) m_background_isALD = QColor(ald_color.prepend('#'));
 update();
}

//------------------------------- setGridVisibility -----------------------------------------------------------------
void   C_Frm_Produit::setGridVisibility(bool visibility /* = false */)
{if (m_pC_Frm_Posologie) m_pC_Frm_Posologie->setGridVisibility(visibility);
}

//------------------------ complete_C_OrdoLineRecord -----------------------------------------------------
void C_Frm_Produit::complete_C_OrdoLineRecord()
{
    set_ordo_key("")                  ;
    set_numOrdre("")                  ;
    set_secureState("")               ;
    //set_date_debut("")                ;
    //set_date_fin( "")                 ;
    set_pk_patient("")                ;
    set_guid_patient("")              ;
    set_code_indication("")           ;
    set_type_code_indication("")      ;
    set_smr("")                       ;
    set_smr_indication("")            ;
    set_voie_admin("")                ;
    //set_ald("")                       ;
    set_substituable("")              ;
    set_renouvelable("")              ;
    set_quantite_totale("")           ;
    if (forme_galenique().length()==0) set_forme_galenique(m_pC_BDM_Api->getPriseUnitFormFromCIP(id()/*,commercialName()*/)); // comprimes ml sachets mg UAntiXa
    set_unite_de_prise("")            ;
    set_quantite_par_up("")           ;
    set_unite_quantite("")            ;
    set_note_textuelle_libre("")      ;
    set_schema_posologique("")        ;
    //...... trois fondammentaux de la posologie .................
    // QString   unite_de_prise,
    // QString   quantite_par_up,
    // QString   unite_quantite,
   }
//------------------------ ordoLineRecord ---------------------------------------
C_OrdoLineRecord C_Frm_Produit::ordoLineRecord() const
{return C_OrdoLineRecord   ( id(),
                             id_type(),
                             commercialName(),
                             dci_1Name(),
                             dci_2Name(),
                             dci_3Name(),
                             owner(),
                             lang(),
                             ucd(),
                             ucd_price(),
                             atc(),
                             generique(),
                             statut(),
                             //........ C_OrdoLineRecord .............
                             ordo_key(),
                             numOrdre(),
                             secureState(),
                             date_debut(),
                             date_fin(),
                             pk_patient(),
                             guid_patient(),
                             code_indication(),
                             type_code_indication(),
                             smr(),
                             smr_indication(),
                             voie_admin(),
                             ald(),
                             substituable(),
                             renouvelable(),
                             quantite_totale(),
                             forme_galenique(),
                             unite_de_prise(),
                             quantite_par_up(),
                             unite_quantite(),
                             note_textuelle_libre(),
                             schema_posologique()
                            );
}

//------------------------ setOrderNumber ---------------------------------------
void     C_Frm_Produit::setOrderNumber(int num)
{QString txt = QString::number(num);
 m_ButtonNumber->setText(QString::number(num));
 set_numOrdre(txt);
}

//------------------------ paintEvent ---------------------------------------
void C_Frm_Produit::paintEvent ( QPaintEvent * /*event*/ )
{   QPainter p(this);
    QColor   background_color = backGroundColor();

    p.setPen (background_color.darker(160));
    QPainterPath path;
    QRect rect = this->rect();
    rect.setWidth  (this->rect().width() -1); // -1 car bord droit et bas masques par le widget
    rect.setHeight (this->rect().height()-1); // -1 car bord droit et bas masques par le widget
    path.addRoundedRect (rect, 6, 6);
    p.setBrush(background_color);
    p.drawPath(path);
    //............ dessin de la poignee de deplacement a gauche ...............
    p.setPen (QColor("#000000"));
    p.fillRect ( 1, 4, HANDLE_MOVE_WIDTH-1, height()-8, background_color.lighter(118) );
    //............ dessin du titre ............................................
    p.drawText (18,11, QString(commercialName()+" ("+dci_1Name()+")").replace("&NBSP;","&nbsp;").replace("&nbsp;"," ") );
    // QFrame::paintEvent(event); surtout pas !!
}

//---------------------------- mouseMoveEvent ------------------------------------------------
void    C_Frm_Produit::mouseMoveEvent ( QMouseEvent * event )
{mouseMoveEvent ( event , 0 );
}

//---------------------------- mouseMoveEvent ------------------------------------------------
void    C_Frm_Produit::mouseMoveEvent ( QMouseEvent * event , QWidget * /* pQWidget */)
{C_Frm_Prescription *pC_Frm_Prescription = (C_Frm_Prescription*)this->parentWidget();   // parent; :: adjust_Vertical_PositionToGrid();
 if (pC_Frm_Prescription==0) return;
 if (m_GrabIsOn)
    {if ( m_GrabIsOn==MIDLE_START)
        {pC_Frm_Prescription->objectDoMoving(this);
        }
    }
  else
    { if (event->x()<HANDLE_MOVE_WIDTH-1)
         { setCursor(Qt::OpenHandCursor);
         }
      else
         {setCursor(Qt::ArrowCursor);
         }
    }
  QFrame::mouseMoveEvent ( event );
}

//---------------------------- mouseReleaseEvent ------------------------------------------------
void C_Frm_Produit::mouseReleaseEvent ( QMouseEvent * /*event*/ )
{releaseMouse();                // degraber la souris
 if (m_GrabIsOn==0) return;     // cassos si rien a faire
 //................. appel du parent pour terminer le move ..............................
 C_Frm_Prescription *pC_Frm_Prescription = (C_Frm_Prescription*)this->parentWidget();
 if (pC_Frm_Prescription==0) return;
 pC_Frm_Prescription->objectStopsMoving(this);
 m_GrabIsOn  = 0;
}

//---------------------------- mousePressEvent ------------------------------------------------
void C_Frm_Produit::mousePressEvent(QMouseEvent *event)
{   C_Frm_Prescription *pC_Frm_Prescription = (C_Frm_Prescription*)this->parentWidget();
    if (pC_Frm_Prescription==0) return;

    if  (event->button() == Qt::LeftButton)
        {if (m_GrabIsOn==0)
            {
             m_startPosY       = event->pos().y();
             if (event->pos().x()<HANDLE_MOVE_WIDTH-1)
                { //grabMouse(QCursor(Qt::ClosedHandCursor));
                  m_GrabIsOn = MIDLE_START;
                  pC_Frm_Prescription->objectStartsMoving(this);
                  update();
                }
             }
         else
             {/*
              QDrag *drag         = new QDrag(this);
              QMimeData *mimeData = new QMimeData;
              QRect rect(-4,0,width(),height());

              QPixmap pix = QPixmap::grabWidget (this, rect );
              mimeData->setText("Drag day");
              mimeData->setImageData(pix);
              drag->setMimeData(mimeData);
              drag->setPixmap(pix);
              Qt::DropAction dropAction = drag->exec();
              */
             }
         }
    else if ( event->button() == Qt::RightButton  && m_GrabIsOn==0)
         { //................ menu ....................
           /*
           ((C_Frm_Day*)parent())->Slot_StopTimer(1);   // le timer ser debloque lors du release button
           QString       ret =  ((C_Frm_Prescription*)parent())->doProduitMenu(this->Produit_instance(),1);
           // "Copy" "Replace" "Cut" "Type :" "Status :"  "Modify"  "Open" "Create" "Anomymize" "Quit"
           if (ret.length())
              {
                if (ret.indexOf("Modify") != -1)
                   {emit Sign_RendezVousChangeClicked(this);
                   }
               else if (ret.indexOf("Status :") != -1)
                  { QString statut = ret.remove("Status :");
                    m_State = statut.trimmed();
                    setWidgetOnRdv(*this);                // on reajuste le widget sur les nouvelles donn\303\251es
                    setWidgetStyleOnRdv(*this);
                    RDV_Update();
                  }
               else if (ret.indexOf("Type :") != -1)
                  { QString type = ret.remove("Type :");
                    m_Type = type.trimmed();
                    setWidgetOnRdv(*this);                // on reajuste le widget sur les nouvelles donn\303\251es
                    setWidgetStyleOnRdv(*this);
                    RDV_Update();
                  }
               else if (ret.indexOf("Cut") != -1)  // il ne  peut pas se detruire lui meme et sortir ensuite de sa fonction donc QTIMER
                  {QTimer::singleShot(10, this, SLOT(Slot_cut()) );
                  }
               else if (ret.indexOf("Copy") != -1)
                    Slot_copy();
               else if (ret.indexOf("Replace") != -1)
                    replaceWithCopy();
               else if (ret.indexOf("Modify") != -1)
                  {emit Sign_RendezVousChangeClicked(this);
                  }
               else if (ret.indexOf("Anomymize") != -1)
                  {m_Nom="";
                   m_Prenom="";
                   m_GUID="";
                   m_Tel="";
                   m_Note="";
                   m_Where="";
                   setWidgetOnRdv(*this);                // on reajuste le widget sur les nouvelles donn\303\251es
                   setWidgetStyleOnRdv(*this);
                   RDV_Update();
                  }
               else if (ret.indexOf("Delete") != -1)
                  {QTimer::singleShot(10, this, SLOT(Slot_delete()) );
                  }
               else if (ret.indexOf("Open") != -1)
                  {((C_Frm_Day*)parent())->Slot_ButtonAccederClicked(0, this);
                  }
               else if (ret.indexOf("Create") != -1)
                  {((C_Frm_Day*)parent())->Slot_ButtonAccederClicked(0, this);
                  }
               else if (ret.indexOf("Find Appointments") != -1)
                  {((C_Frm_Day*)parent())->Chercher_les_RDV_dun_patient();
                  }
               else if (ret.startsWith("AppointmentsListFor"))
                  {((C_Frm_Day*)parent())->Chercher_les_RDV_dun_patient(ret.mid(19));
                  }
               // CZF deb
               else if (ret.startsWith("PrintAppointments"))
                  {QDateTime Dtrdv = QDateTime::fromString(ret.mid(17,10) + " 00:00:00","yyyy-MM-dd hh:mm:ss");
                   ((C_Frm_Day*)parent())->Imprimer_les_RDV_dun_medecin(Dtrdv, ret.mid(28));
                  }
               // CZF fin
              }
           */
         event->accept();
         // ((C_Frm_Day*)parent())->Slot_StopTimer(0);
        }
 }

// =================================== C_Frm_Prescription ================================================
//------------------------------------ C_Frm_Prescription ------------------------------------------------
C_Frm_Prescription::C_Frm_Prescription(const QString &imagePath, C_BDM_Api *pC_BDM_Api , QScrollArea *pQScrollArea , QWidget *parent /*=0 */)
    : QFrame(parent), C_BitMapCollection(imagePath)
{m_pC_BDM_Api           = pC_BDM_Api;
 m_pQScrollArea         = pQScrollArea;
 m_C_Frm_Produit_H      = H_PRODUIT;
 m_C_Frm_Produit_W      = W_PRODUIT;
 m_SpaceBetweenProduits = SPACE_BETWEEN_PROD;
 m_Grid_H               = m_C_Frm_Produit_H + m_SpaceBetweenProduits;
 m_Nb_Grid_H            = 60;
 m_mimeType             = "text/medintux_prd_drag";
 m_mimeTypeIconPath     = "";
 setGeometry(0, 0, m_C_Frm_Produit_W + 20, m_Grid_H * m_Nb_Grid_H + FIRST_OBJ_POS_Y);
 setMouseTracking (TRUE );
 setAcceptDrops (TRUE);
}

//----------------------------------------- setZoom ----------------------------------------------------------
void C_Frm_Prescription::setZoom(int steep)
{//................... ajuster la feuille de stockage des objets .................................
 m_C_Frm_Produit_H += steep;
 setChildsSize(0, m_C_Frm_Produit_H);
}

//------------------------------- getChildsSize -----------------------------------------------------------------
QSize C_Frm_Prescription::getChildsSize()
{return QSize(m_C_Frm_Produit_W, m_C_Frm_Produit_H);
}
//------------------------------- setChildsColors -----------------------------------------------------------------
void   C_Frm_Prescription::setChildsColors(const QString &_std_color, const QString &_ald_color)
{QString std_color = _std_color;
 QString ald_color = _ald_color;
 std_color = std_color.remove('#').prepend('#');      // on s'assure que '#' est correctement mis
 ald_color = ald_color.remove('#').prepend('#');      // on s'assure que '#' est correctement mis

 if (std_color.length()>1) m_str_background_noALD = std_color;
 if (ald_color.length()>1) m_str_background_isALD = ald_color;

 QList <C_Frm_Produit*> childsList = C_Frm_ProduitList();
 for (int i = 0; i < childsList.size(); ++i)
     { C_Frm_Produit *pC_Frm_Produit = childsList.at(i);
       pC_Frm_Produit->setColors(m_str_background_noALD, m_str_background_isALD);
     }
}
//------------------------------- setChildsGridVisibility -----------------------------------------------------------------
void  C_Frm_Prescription::setChildsGridVisibility(bool visibility /* = false */)
{   m_childs_HGridVisibility = visibility;
    QList <C_Frm_Produit*> childsList = C_Frm_ProduitList();
    for (int i = 0; i < childsList.size(); ++i)
        { C_Frm_Produit *pC_Frm_Produit = childsList.at(i);
          pC_Frm_Produit->setGridVisibility(visibility);
        }
}
//------------------------------- setChildsSize -----------------------------------------------------------------
void C_Frm_Prescription::setChildsSize(int childs_w, int childs_h)
{   if (childs_h) m_C_Frm_Produit_H  = childs_h;
    if (childs_w) m_C_Frm_Produit_W  = childs_w;

    m_Grid_H           = m_C_Frm_Produit_H + m_SpaceBetweenProduits;
    setGeometry(0, 0, m_C_Frm_Produit_W + 20, m_Grid_H * m_Nb_Grid_H + FIRST_OBJ_POS_Y);
    //................. repositionner tous les fils ..................................................
    QList <C_Frm_Produit*> childsList = C_Frm_ProduitList();
    //......... trier la liste selon le numero d'ordre ...............................................
    //          avec l'astuce de la QMap
    QMap<int, C_Frm_Produit*> map;
    foreach (C_Frm_Produit* pC_Frm_Produit, childsList)
         { map.insert(pC_Frm_Produit->numOrdre().toInt(), pC_Frm_Produit);
         }
    //......... recuperer la liste triee .............................................................
    //          et redimenssionner les fils
    int pos_y  = FIRST_OBJ_POS_Y;
    childsList = map.values();
    for (int i = 0; i < childsList.size(); ++i)
        { C_Frm_Produit *pC_Frm_Produit = childsList.at(i);
          if (i==0 && pC_Frm_Produit->ald().length()==0) pos_y += m_Grid_H;
          pC_Frm_Produit->adjustToSize(QRect(FIRST_OBJ_POS_X, pos_y, m_C_Frm_Produit_W, m_C_Frm_Produit_H));
          pos_y += m_Grid_H;
        }
}
//------------------------------- setChildsViewProfil -----------------------------------------------------------------
int C_Frm_Prescription::setChildsViewProfil( int viewProfil,       /* = C_Frm_Posologie::ALL_WIDGETS */
                                             int profilMode        /* = C_Frm_Posologie::PROFIL_SET) */
                                           )
{   if      (profilMode == C_Frm_Posologie::PROFIL_SET)       m_childs_ViewProfil = viewProfil;
    else if (profilMode == C_Frm_Posologie::PROFIL_ADD)       m_childs_ViewProfil = m_childs_ViewProfil |   viewProfil;
    else if (profilMode == C_Frm_Posologie::PROFIL_DEL)       m_childs_ViewProfil = m_childs_ViewProfil & (~viewProfil);
    else return  m_childs_ViewProfil;
    QList <C_Frm_Produit*> childsList = C_Frm_ProduitList();
    for (int i = 0; i < childsList.size(); ++i)
        { C_Frm_Produit *pC_Frm_Produit = childsList.at(i);
          pC_Frm_Produit->setViewProfil(m_childs_ViewProfil, C_Frm_Posologie::PROFIL_SET);
        }
    return  m_childs_ViewProfil;
}

//-------------------------------- mouseMoveEvent ---------------------------------------------------------
void C_Frm_Prescription::mouseMoveEvent(QMouseEvent *event)
{    /*
    if (event->buttons() & Qt::LeftButton)
       {
        int distance = (event->pos() - m_startDragPos).manhattanLength();
        if (distance >= QApplication::startDragDistance())
           {//QTreeWidgetItem *item = getFirstSelectedItem();
            //if (item)
               {QString data = m_mimeDatas;
                //emit Sign_giveMeDatas(data, item);
                if (data.length())
                   {
                    QMimeData *mimeData = new QMimeData;
                    QDrag *drag         = new QDrag(this);
                    //if (m_mimeTypeIconPath.length())   drag->setDragCursor ( QPixmap (m_mimeTypeIconPath), Qt::CopyAction);  // marche po
                    mimeData->setData(m_mimeType, data.toAscii());
                    drag->setMimeData(mimeData);
                    if (m_mimeTypeIconPath.length()) drag->setPixmap(QPixmap(m_mimeTypeIconPath));
                    if (drag->exec(Qt::CopyAction) == Qt::CopyAction)
                       {event->accept();
                        //return;
                       }
                  }
             }
           }
        }
     */
    QFrame::mouseMoveEvent(event);
}

//---------------------------- dragEnterEvent ------------------------------------------------
void C_Frm_Prescription::dragEnterEvent(QDragEnterEvent *event)
{if (event->mimeData()->hasFormat("text/medintux_prd_drag"))
    {//................ recuperer la chaine xml dropee .................................
     set_DropedXmlDatas (QString(event->mimeData()->data ( "text/medintux_prd_drag" ))); // recuperer les donnees venant du drag and drop
     event->acceptProposedAction ();
    }
 }
//---------------------------- dragMoveEvent ------------------------------------------------
void C_Frm_Prescription::dragMoveEvent(QDragMoveEvent * event)
 {
    if (event->mimeData()->hasFormat("text/medintux_prd_drag"))
    {
        //........... faire scroller si besoin .......................................
        QPoint pos_g = mapFromGlobal ( QCursor::pos() );
        m_pQScrollArea->ensureVisible(10,pos_g.y());
        //........... afficher tool tip du D&D ASTUCE ................................
        //            pour que le tool tip suive la souris il faut
        //            qu'il se rafraichisse continuellement, pour cela
        //            seul le changement de contenu textuel opère ce rafraichissement
        //            donc pour ce faire j'affiche la position de la souris avec la
        //            couleur du fond, afin de masquer cet affichage changeant continuellement.
        QColor backColor   = QToolTip::palette ().color(QPalette::ToolTipBase);                                     // recuperer couleur fond du tool tip
        QPoint     pos     = QCursor::pos(); pos.setX(pos.x()+30);                                                  // positionner le tool tip
        QString    tm_str  = CGestIni::getXmlData("m_commercialName", get_DropedXmlDatas()).replace(" ","&nbsp;")+  // affichage du nom du medoc
                             "<font color=\""+backColor.name()+"\">" +QString::number(pos.y()+pos.x())+"</font>";   // affichage invisible de la position
        //QToolTip::showText (pos,  tm_str, this, rect() );

        event->acceptProposedAction ();
       }
    /*
    if (event->mimeData()->hasFormat("application/x-qabstractitemmodeldatalist"))
       {QPoint          pos = mapFromGlobal ( QCursor::pos() );
        QTreeWidget   *tree = dynamic_cast<QTreeWidget *>(event->source());
        QByteArray itemData = event->mimeData()->data("application/x-qabstractitemmodeldatalist");
        QString      tm_str = "";
        QDataStream stream(&itemData, QIODevice::ReadOnly);

        int r, c;
        QMap<int, QVariant> v;
        stream >> r >> c >> v;
        QTreeWidgetItem *item = tree->topLevelItem(r);
        if( item )
          { // qDebug()<<"dropEventItem : "<< item->text(0);
            tm_str = item->text(0);
            //itemDropped(item);
          }
       */
        /*
        C_RendezVous rdv; rdv.m_Duree = -2;
        if (isDayExpand())
           { QTime  tm   =  posY_toTime(pos.y());
             tm_str      =  tm.toString("hh:mm");
           }
        else
           { rdv         = getResumeRdvFromXY (  pos.x(),  pos.y() );;
             int mn      = XYToMinutesInResume ( pos.x(),pos.y());
             if (mn==-1) {QToolTip::hideText();      // cassos si pas dans une zone exploitable
                          event->ignore();
                          m_DropedRdv.m_GUID = "";   // effacer les donnees du rdv venant du drag and drop
                          return;
                         }
             int h       = mn/60;
             mn          = mn - (h*60);
             tm_str      = QString("%1:%2").arg(QString::number(h).rightJustified (2, '0'),QString::number(mn).rightJustified (2, '0'));
           }
        m_DropedRdv  = C_RendezVous::unSerialize(QString(event->mimeData()->data ( "text/medintux_rdv_drag" ))); // intialiser le rdv sur les donnees venant du drag and drop

        if (rdv.m_GUID.length()||rdv.m_Nom.length()||rdv.m_Prenom.length())
           {tm_str = "<table cellSpacing=\"0\"  cellpadding=\"4\" width=100% border=\"1\">"    // #FF8000
                        "<tbody>"
                        "<tr>"
                        "<td width=100% align=\"left\" bgcolor=\"#FEFFDD\">"+
                        QString(tr("On")+"&nbsp;<b><font color=\"#0000FF\">%1</font></b>&nbsp;"+tr("at")+"&nbsp;<b><font color=\"#e80d0d\">%2</font></b>&nbsp;"+tr("(duration")+"&nbsp;:&nbsp;<b><font color=\"#e80d0d\">%3</b></font>&nbsp;mn) <b>"+tr("Occupied")+"</b>&nbsp;par&nbsp;<font color=\"#FF8000\"><b>%4</b></font></b>"
                        "</TD>"
                        "</TBODY>"
                        "</TABLE>").arg(m_Date.toString("dd-MM-yyyy"),rdv.m_date.time().toString("hh:mm"), QString::number(rdv.m_Duree), rdv.m_Nom.replace(" ","&nbsp;")+"&nbsp;"+rdv.m_Prenom.replace(" ","&nbsp;")) ;
           }
        else if (rdv.m_PrimKey.length())
           {tm_str = "<TABLE cellSpacing=\"0\"  cellpadding=\"4\" width=100% border=\"1\">"
                        "<TBODY>"
                        "<TR>"
                        "<TD width=100% align=\"left\" bgcolor=\"#FEFFDD\">"+
                        QString(tr("The")+"&nbsp;<b><font color=\"#0000FF\">%1</font></b>&nbsp;"+tr("at")+"&nbsp;<b><font color=\"#e80d0d\">%2</font></b>&nbsp;"+tr("(duration")+"&nbsp;:&nbsp;<b><font color=\"#e80d0d\">%3</b></font>&nbsp;mn <b>"+tr("available")+"</b>&nbsp;pour&nbsp;"
                        "<font color=\"#FF8000\"><b>%4</b></font>&nbsp;"+tr("with")+"&nbsp;<b><font color=\"#0000FF\">%5</font></b>"
                        "</TD>"
                        "</TBODY>"
                        "</TABLE>").arg( m_Date.toString("dd-MM-yyyy"), rdv.m_date.time().toString("hh:mm"), QString::number(rdv.m_Duree), m_DropedRdv.m_Nom.replace(" ","&nbsp;") + "&nbsp;" + m_DropedRdv.m_Prenom.replace(" ","&nbsp;") ,m_UserNomPrenom.replace(" ","&nbsp;")) ;
           }
        else
           {tm_str = "<TABLE cellSpacing=\"0\"  cellpadding=\"4\" width=100% border=\"1\">"
                        "<TBODY>"
                        "<TR>"
                        "<TD width=100% align=\"left\" bgcolor=\"#FEFFDD\">"+
                        tr("The")+QString("&nbsp;<b><font color=\"#0000FF\">%1</font></b>&nbsp;"+tr("at")+"&nbsp;<b><font color=\"#e80d0d\">%2</font> "+tr("Creation")+"</b>&nbsp;"+tr("for")+"&nbsp;<font color=\"#FF8000\"><b>%3</b></font>"
                        "&nbsp;"+tr("with")+"&nbsp;<b><font color=\"#0000FF\">%4</font></b> "
                        "</TD>"
                        "</TBODY>"
                        "</TABLE>").arg(m_Date.toString("dd-MM-yyyy"),tm_str, m_DropedRdv.m_Nom.replace(" ","&nbsp;") + "&nbsp;" + m_DropedRdv.m_Prenom.replace(" ","&nbsp;"), m_UserNomPrenom.replace(" ","&nbsp;")) ;
           }
        //qDebug() << tm_str;
        */
        /*
        //tm_str = tr("DD move on prescription");
        pos = QCursor::pos(); pos.setX(pos.x()+30);
        QToolTip::showText (pos,  tm_str, this, this->rect() );
        event->acceptProposedAction ();
       }
       */
 }

//---------------------------- dragLeaveEvent ------------------------------------------------
void C_Frm_Prescription::dragLeaveEvent ( QDragLeaveEvent *  )
{   QToolTip::hideText();
}
//---------------------------- dropEvent ------------------------------------------------
void C_Frm_Prescription::dropEvent(QDropEvent *event)
{   //qDebug()<<"dropEvent : "<< event->format();
    if (event->mimeData()->hasFormat("text/medintux_prd_drag"))
       {event->acceptProposedAction ();
        QToolTip::hideText();
        QTimer::singleShot(10, this, SLOT(Slot_Drop_Prd ()));
       }
    /*
    if (event->mimeData()->hasFormat("application/x-qabstractitemmodeldatalist"))      // "application/x-qabstractitemmodeldatalist"
        { event->acceptProposedAction ();
          QToolTip::hideText();
          QTreeWidget   *tree = dynamic_cast<QTreeWidget *>(event->source());
          QByteArray itemData = event->mimeData()->data("application/x-qabstractitemmodeldatalist");
          QDataStream stream(&itemData, QIODevice::ReadOnly);

          int r, c;
          QMap<int, QVariant> v;
          stream >> r >> c >> v;
          QTreeWidgetItem *item = tree->topLevelItem(r);
          if( item )
            {  qDebug()<<"dropEventItem : "<< item->text(0);
              //itemDropped(item);
            }
         QTimer::singleShot(10, this, SLOT(Slot_Drop_Prd ()));
        }
     */
 }
//------------------------ Slot_Drop_Prd -----------------------------------------------------
void C_Frm_Prescription::Slot_Drop_Prd ()
{   QPoint         pos            = mapFromGlobal ( QCursor::pos() );
    int            pos_y          = pos.y();
    pos_y                         = adjust_Vertical_PositionToGrid(pos_y);
    appendNewObject(get_DropedXmlDatas(), pos_y);
}

//------------------------ appendNewObject -----------------------------------------------------
void C_Frm_Prescription::appendNewObject(const QString &xmlData)
{   QList <C_Frm_Produit*> childsList = C_Frm_ProduitList();
    int                    pos_y      = FIRST_OBJ_POS_Y + (childsList.size() * m_Grid_H) + m_Grid_H / 2;
    appendNewObject(xmlData,  pos_y);
}
//------------------------ appendNewObject -----------------------------------------------------
void C_Frm_Prescription::appendNewObject(const QString &xmlData, int pos_y)
{
    bool           is_in_Ald      = is_posY_in_ALD_Zone(pos_y);
    pos_y                         = adjust_Vertical_PositionToGrid(pos_y);
    C_Frm_Produit *pC_Frm_Produit = 0;
    //.................. faire la place du nouvel arrivant .................................
    //                   detecter si relache sur la premiere case ALD vide
    //                   auquel cas ne pas deplacer les sous jacents vers le bas
    QList <C_Frm_Produit*> listObjects = objectListAt(pos_y, C_Frm_Prescription::JUST_ONE_POSITION_UNDER_Y);  // liste des objets deja présents sur cette case (exclusion de celui en cours de deplacement)

    if (listObjects.count())   // si un objet sous la souris déplacer tous ceux sous jacent vers le bas pour faire la place du nouveau arrivant
       {pC_Frm_Produit = listObjects.at(0);
        deplace_Objects(pos_y + m_Grid_H,                  // on deplace tout ce qui se situe apres ca
                                m_Grid_H);                 // d'une hauteur de grille vers le bas
        pos_y =  pC_Frm_Produit->y() + m_Grid_H;
       }

    //.................. creer le nouvel arrivant  dans la place faite .................................
    pC_Frm_Produit= new C_Frm_Produit(C_OrdoLineRecord(xmlData),
                                      m_pC_BDM_Api,
                                      QRect(FIRST_OBJ_POS_X, pos_y, m_C_Frm_Produit_W, m_C_Frm_Produit_H),
                                      this,
                                      m_str_background_noALD,
                                      m_str_background_isALD,
                                      m_childs_HGridVisibility,
                                      m_childs_ViewProfil);


    //.................. placer si besoin le caractere ALD selon emplacement............................
    //                   dans lequel le nouvel arrivant se met
    if ( pC_Frm_Produit )
       {if (pC_Frm_Produit->m_pC_Frm_Posologie)
           {connect( pC_Frm_Produit->m_pC_Frm_Posologie, SIGNAL( Sign_child_LeaveLastEditZone ()  ),  this , SIGNAL( Sign_child_LeaveLastEditZone() ));
           }

        if (is_in_Ald)
           {pC_Frm_Produit->set_ald("ALD");
           }
        else  //..... uniquement si objet non ald verifier si pas plus bas que la derniere position ..........
           {int nb          = count_GridToDraw()-1;
            int pos_Y_max   = nb * m_Grid_H + FIRST_OBJ_POS_Y + m_SpaceBetweenProduits/2;
            if ( pC_Frm_Produit->y() > pos_Y_max) pC_Frm_Produit->move(pC_Frm_Produit->x(),pos_Y_max );
           }
       }
    rearangeAllNumberOrder();
    update();
    clear_DropedXmlDatas ();  // effacer les donnees venant du drag and drop
}

//------------------------------------ objectStartsMoving ------------------------------------------------
void C_Frm_Prescription::objectStartsMoving(C_Frm_Produit *pC_Frm_Produit)
{int  pos_y     = adjust_Vertical_PositionToGrid(pC_Frm_Produit);
 m_startDragPos = QPoint(pC_Frm_Produit->x(), pos_y);
 m_lastDragPosY = pos_y;
 pC_Frm_Produit->raise ();    // mettre l'objet en avant plan
 // echoListObjects("objectStartsMoving");
}
//------------------------------------ objectDoMoving ------------------------------------------------
void C_Frm_Prescription::objectDoMoving(C_Frm_Produit *pC_Frm_Produit)
{int pos_y = adjust_Vertical_PositionToGrid(pC_Frm_Produit, true);
 if (pos_y == m_lastDragPosY) return;
 //............. combler le trou laisse par le deplacement en .............................
 //              deplacant les objets sous jacents vers le haut
 int  nb_ald  = count_ALD();
 bool to_move = true;        // a priori il faut deplacer tous les objets sous jacents vers le haut pour combler la place libre de celui a deplacer
 if ( m_lastDragPosY == adjust_Vertical_PositionToGrid(FIRST_OBJ_POS_Y) && nb_ald<=1) to_move = false; // sauf si il est seul sur la premiere case ALD (la laisser alors vide)
 if (to_move) deplace_Objects( m_lastDragPosY + m_Grid_H,  // on deplace tout ce qui se situe apres (+ m_Grid_H) notre objet.
                                               -m_Grid_H); // d'une hauteur de grille vers le haut
 m_lastDragPosY = pos_y;
 //............. faire le trou de la nouvelle place .............................
 //              deplacant les objets sous jacents vers le bas
 int  final_Y = pC_Frm_Produit->y();                                 // on recupere la place de l'objet avant qu'elle ne bouge lors des deplacements ulterieurs
 to_move = true;
 //.......... detecter si relache sur la premiere case ALD vide ............................
 //           auquel cas ne pas deplacer les sous jacents vers le bas
 QList <C_Frm_Produit*> excludedObjects;
 excludedObjects.append(pC_Frm_Produit);          // ne pas tenir compte de celui en cours (car on teste ce qu'il y a AVANT son larguage)
 if ( pos_y == adjust_Vertical_PositionToGrid(FIRST_OBJ_POS_Y) )                                                                     // si relache sur premiere case (case ALD) verifier si vide
    { QList <C_Frm_Produit*> listAldObjects = objectListAt(pos_y, C_Frm_Prescription::JUST_ONE_POSITION_UNDER_Y, &excludedObjects);  // liste des objets deja présents sur cette case (exclusion de celui en cours de deplacement)
      if (listAldObjects.count() == 0) to_move = false;
    }
 //.......... taguer le caractere ALD ou non de l'objet ...............
 //           selon sa zone d'aterrissage
 if (is_posY_in_ALD_Zone()) pC_Frm_Produit->set_ald("ALD");
 else                       pC_Frm_Produit->set_ald("");

 //........... deplacer les sous jacents vers le bas ......................
 if (to_move) deplace_Objects( pos_y  ,  m_Grid_H);                 // on deplace tout ce qui se situe apres ca d'une hauteur de grille vers le bas

 //............ ne pas depasser la derniere position basse possible .......................
 pC_Frm_Produit->move(pC_Frm_Produit->x(), final_Y);
 /* //....... lors vers bas mauvaise numérotation pourquoi ??? .............
 echoListObjects("objectDoMoving");
 while (QCoreApplication::hasPendingEvents ())
   {QCoreApplication::processEvents ( QEventLoop::ExcludeUserInputEvents );
   }
 */
 rearangeAllNumberOrder();  // marche pas si deplacement vers le bas !!!
 update();

}
//------------------------------------ objectStopsMoving ------------------------------------------------
void C_Frm_Prescription::objectStopsMoving(C_Frm_Produit *pC_Frm_Produit)
{//............ ne pas depasser la derniere position basse possible .......................
 int nb          = count_GridToDraw() - 1 ;
 int pos_Y_max   = nb * m_Grid_H + FIRST_OBJ_POS_Y + m_SpaceBetweenProduits/2;
 if ( pC_Frm_Produit->y() > pos_Y_max) pC_Frm_Produit->move(pC_Frm_Produit->x(),pos_Y_max );
 rearangeAllNumberOrder();
 update();
}

//------------------------------------ C_Frm_ProduitList ------------------------------------------------
QList <C_Frm_Produit*> C_Frm_Prescription::C_Frm_ProduitList()
{ QList <QObject*>        objectList = this->children();
  QList <C_Frm_Produit*>  childsList;
  QObject *obj = 0;
  for (int i = 0; i < objectList.size(); ++i)
      {obj = objectList.at(i);
       if (obj->objectName()=="C_Frm_Produit") childsList.append((C_Frm_Produit*)obj);
      }
  return  childsList;
}

//------------------------------------ echoListObjects ------------------------------------------------
void C_Frm_Prescription::echoListObjects(const QString txt)
{   QList <C_Frm_Produit*> childsList = C_Frm_ProduitList();
    qDebug()<<tr("============== LIST OBJECTS nb_objects:%1 %2=============").arg(QString::number(childsList.size()),txt);
    for (int i = 0; i < childsList.size(); ++i)
        {C_Frm_Produit *pC_Frm_Produit = childsList.at(i);
         qDebug()<<tr("* top>> %3|=|%4 bottom<< OBJECT:%1 num:%2 ").arg(pC_Frm_Produit->commercialName(),pC_Frm_Produit->numOrdre(),
                                                                 QString::number(pC_Frm_Produit->y()),
                                                                 QString::number(pC_Frm_Produit->y()+pC_Frm_Produit->height()));
        }

}

//------------------------------------ rearangeNumberOrder ------------------------------------------------
void C_Frm_Prescription::rearangeAllNumberOrder(QList<C_Frm_Produit*> *pListProduitExcluded  /* = 0 */)
{   //............... on cree la liste des objets sous jacents a y_ref .................
    int nb_Prd = 0;
    int nb     = 0;
    int nb_Ald = count_ALD(&nb_Prd );             // relever le nombre de produits
    int  pos_y = FIRST_OBJ_POS_Y + m_Grid_H/2;    // partir du debut de la grille
    int last_y = 0;
    int  end_y = (nb_Ald+nb_Prd+1) * m_Grid_H;    // calculer la fin des cases
    //qDebug()<<tr("==================== %1 ========================").arg(QString::number(nb_Ald+nb_Prd+1));

    while(pos_y < end_y)
      { //.......... on examine tous les objets fils (sauf ceux exclus) .....................
        //           et on les stocke si concernes par la position pos_y
        QList <C_Frm_Produit*> childsList = C_Frm_ProduitList();
        //qDebug()<<tr("---------- pos_y:%1 end_y:%2 nb_objects:%3---------------").arg(QString::number(pos_y),QString::number(end_y),QString::number(childsList.size()));
        for (int i = 0; i < childsList.size(); ++i)
            {C_Frm_Produit *pC_Frm_Produit = childsList.at(i);
             //............. si objet exclu ne pas le traiter ...............
             if (pListProduitExcluded && pListProduitExcluded->contains(pC_Frm_Produit) )
                {continue;      // objet exclu passer au suivant
                }
             //qDebug()<<tr("* OBJECT:%1 num:%2 top:%3 bottom:%4").arg(pC_Frm_Produit->commercialName(),pC_Frm_Produit->numOrdre(),
             //                                                        QString::number(pC_Frm_Produit->y()),
             //                                                        QString::number(pC_Frm_Produit->y()+pC_Frm_Produit->height()));
             if ( pos_y >= pC_Frm_Produit->y() && pos_y <= pC_Frm_Produit->y() + pC_Frm_Produit->height() )
                { if ( pos_y != last_y)
                     { ++nb;
                       last_y = pos_y;
                     }
                 //qDebug()<<tr(".   before num:%2 top:%3 bottom:%4").arg(pC_Frm_Produit->numOrdre(),
                 //                                                                 QString::number(pC_Frm_Produit->y()),
                 //                                                                 QString::number(pC_Frm_Produit->y()+pC_Frm_Produit->height()));
                 pC_Frm_Produit->setOrderNumber(nb);
                 //qDebug()<<tr(".   after  num:%2 top:%3 bottom:%4").arg(pC_Frm_Produit->numOrdre(),
                 //                                                                 QString::number(pC_Frm_Produit->y()),
                 //                                                                 QString::number(pC_Frm_Produit->y()+pC_Frm_Produit->height()));
                }
            }
        pos_y +=  m_Grid_H;
      }
}

//------------------------------------ objectListAt ------------------------------------------------
/*! \brief return objects list under y_ref to y_end positions
 *  \param  y_ref start Y position.
 *  \param  y_end end   Y position. if -1 then alls positions below y_ref, if zero just one position under y_ref
 *  \param  QList<C_Frm_Produit*> *pListProduitExcluded if not zero this objects from this list will be excluded from result list.
 *  \return QList <C_Frm_Produit*>  result list
 */
QList <C_Frm_Produit*> C_Frm_Prescription::objectListAt(int y_ref, int y_end /*= 0*/, QList<C_Frm_Produit*> *pListProduitExcluded  /* = 0 */)
{   //............... on cree la liste des objets sous jacents a y_ref .................
    int nb_Prd = 0;
    int nb_Ald = count_ALD(&nb_Prd );                                // relever le nombre de produits
    int  pos_y = y_ref + m_Grid_H/2;                                 // partir du milieu de la grille
    int  end_y = y_end;
    if      (end_y ==-1)  end_y = (nb_Ald+nb_Prd+1) * m_Grid_H;   // calculer la fin des cases
    else if (end_y == 0)  end_y = pos_y+1;                        // juste position sous la souris
    QList <C_Frm_Produit*> C_Frm_ProduitList;
    while(pos_y < end_y)
      { //.......... on examine tous les objets fils (sauf ceux exclus) .....................
        //           et on les stocke si concernes par la position pos_y
        QList <C_Frm_Produit*> childsList = this->C_Frm_ProduitList();
        for (int i = 0; i < childsList.size(); ++i)
            {C_Frm_Produit *pC_Frm_Produit = childsList.at(i);
             //............. si objet exclu ne pas l'ajouter ...............
             if (pListProduitExcluded && pListProduitExcluded->contains(pC_Frm_Produit) )
                {continue;      // objet exclu passer au suivant
                }
             if ( pos_y >= pC_Frm_Produit->y() && pos_y <= pC_Frm_Produit->y() + pC_Frm_Produit->height() )
                {C_Frm_ProduitList.append(pC_Frm_Produit);
                }
            }
        pos_y +=  m_Grid_H;
      }
    return C_Frm_ProduitList;
}

//------------------------------------ deplace_Objects ------------------------------------------------
void C_Frm_Prescription::deplace_Objects(int y_ref, int ofset_y)
{   C_Frm_Produit          *pC_Frm_Produit   = 0;
    //................. recuperer la liste des objets sous jacents ..................................
    QList <C_Frm_Produit*> C_Frm_ProduitList = objectListAt( y_ref, C_Frm_Prescription::ALL_POSITIONS_BELOW_Y); // -1 pour toutes les position
    //............... on deplace les objets de la liste .................
    for (int i = 0; i < C_Frm_ProduitList.size(); ++i)
        {   pC_Frm_Produit = C_Frm_ProduitList.at(i);
            pC_Frm_Produit->move(pC_Frm_Produit->x(),pC_Frm_Produit->y()+ofset_y);
        }
}

//------------------------------------ is_posY_in_ALD_Zone -----------------------------------------------
bool C_Frm_Prescription::is_posY_in_ALD_Zone()
{QPoint pos = mapFromGlobal ( QCursor::pos() );
 return is_posY_in_ALD_Zone( pos.y() );
}
//------------------------------------ is_posY_in_ALD_Zone -----------------------------------------------
bool C_Frm_Prescription::is_posY_in_ALD_Zone(int y)
{int nb_Ald = qMax(1,count_ALD());
 if (y<nb_Ald*m_Grid_H+FIRST_OBJ_POS_Y && y>0)  return true;
 return false;
}

//------------------------------------ adjust_Vertical_PositionToGrid -----------------------------------------------
int C_Frm_Prescription::adjust_Vertical_PositionToGrid(C_Frm_Produit *pC_Frm_Produit /* = 0 */, bool scroll_if_out_limits /*=false */)
{ QPoint pos = mapFromGlobal ( QCursor::pos() );
  if (scroll_if_out_limits)
     {m_pQScrollArea->ensureVisible(10,pos.y());
     }
  return adjust_Vertical_PositionToGrid(pos.y() , pC_Frm_Produit );
}

//------------------------------------ adjust_Vertical_PositionToGrid -----------------------------------------------
int C_Frm_Prescription::adjust_Vertical_PositionToGrid(int y, C_Frm_Produit *pC_Frm_Produit /* =0 */)
{y -=  FIRST_OBJ_POS_Y;
 y  =  y / m_Grid_H;
 y *=  m_Grid_H;
 y +=  m_SpaceBetweenProduits/2;
 if (pC_Frm_Produit)
    {pC_Frm_Produit->move(pC_Frm_Produit->x(), y + FIRST_OBJ_POS_Y);
    }
 return y + FIRST_OBJ_POS_Y;
}

//------------------------------------ count_ALD -----------------------------------------------
int C_Frm_Prescription::count_ALD(int *nb_Prd /* = 0 */)
{   QList <C_Frm_Produit*> childsList  = C_Frm_ProduitList();
    int nb_Ald                         = 0;
    C_Frm_Produit *pC_Frm_Produit;
    for (int i = 0; i < childsList.size(); ++i)
        {   pC_Frm_Produit = childsList.at(i);
            if (pC_Frm_Produit->ald().length()) ++nb_Ald;
        }
    if (nb_Prd) *nb_Prd = childsList.size()-nb_Ald;
    return nb_Ald;
}

//------------------------------------ count_GridToDraw ------------------------------------------------
int C_Frm_Prescription::count_GridToDraw(int *nb_ald_toRet /* = 0 */)
{int nb_Prd;
 int nb_Ald = qMax(1,count_ALD(&nb_Prd )); // au moins une case ALD vide
     nb_Prd = qMax(1,nb_Prd);              // au moins une case non ALD vide
 if (nb_ald_toRet) *nb_ald_toRet = nb_Ald;
 return       nb_Prd + nb_Ald;
}

//------------------------------------ paintEvent -----------------------------------------------
void  C_Frm_Prescription::paintEvent ( QPaintEvent * /* event */ )
{
QPainter p(this);
QFont  fGrd  = font();
int w        = width();
int ofs_y    = FIRST_OBJ_POS_Y ;
int h_pixFnt = qMin(m_Grid_H-m_Grid_H/4,30);

QColor grad_color   = palette ().color(QPalette::Dark);
QFontMetrics fntMetGrd(fGrd);
QRect        boundRect;
QString      text;
int          h_txt;
int          x_txt = FIRST_OBJ_POS_X+2;

//............. dessiner les cases ....................
int nb_Ald = 0;
int nb     = count_GridToDraw(&nb_Ald);
int y_end  = nb * m_Grid_H + ofs_y;
int pos_y  = ofs_y;

//for (int i     = 0; i < nb; ++i)                    // *getResoPixByMinutes())
//    {    pos_y = i * m_Grid_H + ofs_y;              //  y+FIRST_DAY_POS_Y+m_BaseDayHeight;
while (pos_y <= y_end)
      {  p.setPen   ( grad_color);
         //if (i==nb_Ald)
         //   {p.drawLine ( 0, pos_y-dy, w, pos_y-dy);
         //    p.drawLine ( 0, pos_y+dy, w, pos_y+dy);
             //p.setPen   ( text_color);
             //fGrd.setPixelSize(7); fGrd.setBold(false); fGrd.setItalic(true);    p.setFont ( fGrd );
             //p.drawText ( QPoint(posGrdX+4,pos_y+dy-1 ), tr("Prescriptions SANS RAPPORT avec une affection de longue durée") );
             //fGrd.setPixelSize(10); fGrd.setBold(true); fGrd.setItalic(false); p.setFont ( fGrd );
         //   }
         //else
         //   {
             p.drawLine ( 0, pos_y, w, pos_y);
         //   }
         //p.setPen   ( text_color);
         //p.drawText ( QPoint(0,pos_y + (grd_size.height())), QString::number(i+1) );
         pos_y += m_Grid_H;
    }  //endfor (int y = 0; y < y_der; y += 15)

//......... tracer le texte de la premiere case ALD .....................
fGrd.setPixelSize(h_pixFnt); fGrd.setBold(true); fGrd.setItalic(true); p.setFont ( fGrd );
fntMetGrd = QFontMetrics(fGrd);

text      = tr("zone ALD");
boundRect = fntMetGrd.boundingRect ( text );
h_txt     = boundRect.height();

pos_y = ofs_y +h_txt +(m_Grid_H-h_txt)/2;
p.setPen (grad_color.darker(160));
p.drawText ( QPoint(x_txt,  pos_y),   text );
p.setPen (grad_color.darker(90));
//p.setPen (grad_color.lighter ( 150 ));
p.drawText ( QPoint(x_txt+2,  pos_y+2), text );
fGrd.setPixelSize(11); p.setFont ( fGrd );
p.setPen (grad_color.darker(160));
p.drawText ( QPoint(x_txt+2+boundRect.width(),  pos_y ), tr("(glissez les médicaments ALD ici)") );

//............ se deplacer a la derniere case ..............................
int  nb_Prd;
count_ALD( &nb_Prd );
nb = nb_Prd+nb_Ald;
pos_y = qMax(1,nb)*m_Grid_H+ofs_y  +h_txt+(m_Grid_H-h_txt)/2;


//......... tracer le texte de la derniere case non ALD .....................
fGrd.setPixelSize(h_pixFnt); fGrd.setBold(true); fGrd.setItalic(true); p.setFont ( fGrd );
text      = tr("hors ALD");
boundRect = fntMetGrd.boundingRect ( text );
h_txt     = boundRect.height();

p.setPen (grad_color.darker(160));
p.drawText ( QPoint(x_txt,  pos_y), text );
p.setPen (grad_color.darker(90));
//p.setPen (grad_color.lighter ( 150 ));
p.drawText ( QPoint(x_txt+2,  pos_y+2), text );
fGrd.setPixelSize(11); p.setFont ( fGrd );
p.setPen (grad_color.darker(160));
p.drawText ( QPoint(x_txt+2+boundRect.width(),  pos_y ), tr("(glissez les médicaments hors ALD ici)") );

}
//------------------------ Slot_ButtonNumberClicked ---------------------------------------
void C_Frm_Prescription::Slot_ButtonNumberClicked(const QString&, void*)
{
}

//------------------------ Slot_ButtonDeleteClicked ---------------------------------------
void C_Frm_Prescription::Slot_ButtonDeleteClicked(const QString&, void *ptr)
{   if (ptr==0) return;
    C_Frm_Produit *pC_Frm_Produit = (C_Frm_Produit*)ptr;
    int  pos_y   = adjust_Vertical_PositionToGrid(pC_Frm_Produit->y()); // ajuster position d'aterrissage a la case de la grille
    bool to_move = true;                                                // a priori faut deplacer les sous jacents vers le bas pour faire la place
    //.......... detecter si effacement sur la premiere case ............................
    //           auquel cas ne pas deplacer les sous jacents vers le haut
    //           car cette case doit rester vide
    if ( pos_y == adjust_Vertical_PositionToGrid(FIRST_OBJ_POS_Y) && count_ALD()==1)  to_move = false;
    //........... deplacer les sous jacents vers le bas ......................
    if (to_move) deplace_Objects( pos_y  ,                  // on deplace tout ce qui se situe apres ca
                                 -m_Grid_H);                // d'une hauteur de grille vers le haut
    pC_Frm_Produit->deleteLater();
    QList <C_Frm_Produit*> excludedObjects;
    excludedObjects.append(pC_Frm_Produit);   // ne pas tenir compte de celui en cours (car pas encore delete le sera qu'apres retour event)
    rearangeAllNumberOrder(&excludedObjects);
    update();
}
