#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 <QCursor>
#include <QTextEdit>
#include <QLabel>
#include <QToolButton>
#include <QMenu>
#include <QTimer>
#include <QCheckBox>
#include <QTextDocument>
#include <QMessageBox>
#include <QPropertyAnimation>
#include <QMultiMap>

#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 6
#define HANDLE_MOVE_WIDTH  16
#define H_GRAD             5
#define ITEM_HIT_H         26
#define ITEM_HIT_NBTOVIEW  8
#define HIT_TOOL_H         165
#define HIT_W_MMASCN       300
/*
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();
}

//====================================== 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_HitList())
           {
            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_Comma      || key==Qt::Key_Period ||
                     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  ||
                     key==Qt::Key_Minus
                     )
                  )
               {e->accept();
                return true;
               }
            switch (key)
               {
                case Qt::Key_Down:
                     pC_Frm_Posologie->get_HitList()->setWidgetEditFocus(C_Frm_PosologieHitList::NEXT);
                     e->accept();
                     return true;

                case Qt::Key_Up:
                     pC_Frm_Posologie->get_HitList()->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_PosologieHitList ==========================================================================================
C_Frm_PosologieHitList::C_Frm_PosologieHitList (const QStringList   &grammarList   ,          // la liste des favoris
                                                QString              cur_grammar,             // la posologie en cours
                                                const QRect         &geometry_rect ,
                                                int                  h_button      ,
                                                const QColor        &backGroundColor,
                                                C_BitMapCollection  *pC_BitMapCollection, // il nous faut des icones
                                                C_BDM_Api           *pC_BDM_Api,          // un pointeur sur l'API medicamenteuse
                                                QWidget*             parent        , /* = 0 */
                                                const char*          name            /* = 0 */
                                               )
   : QFrame (parent), QStringList(grammarList)
{  m_cur_grammar         = cur_grammar;
   m_pC_BitMapCollection = pC_BitMapCollection;
   m_pC_BDM_Api          = pC_BDM_Api;
   m_Grid_H              = ITEM_HIT_H;
   m_FocusWidget         = 0;
   m_grammarList         = grammarList;
   m_background_color    = backGroundColor;
   m_marge               = 2;
   m_buttonH             = h_button;
   int nbItem            = grammarList.count();
   int ofs_butt          = HIT_TOOL_H;

   setObjectName(name);
   pC_BitMapCollection->resize_back_repart(HIT_W_MMASCN, m_buttonH*8); // 269x105
   //........................................................................................................
   //................ largeur de la graduation ...........................
   QFont  fGrd            = font(); fGrd.setPixelSize(10); fGrd.setBold(false); fGrd.setItalic(false);
   QFontMetrics fntMetGrd = QFontMetrics(fGrd);


   //................... fenetre principale ....................................................................
   setGeometry(geometry_rect);

   //................... la machine a scroller .................................................................
   m_ScrollArea       = new QScrollArea(this);
   m_ScrollArea->setGeometry(QRect(m_marge,
                                   ofs_butt  + h_button,                                // ofset Y apres la zone de boutons
                                   geometry_rect.width()  - m_marge * 2,
                                   geometry_rect.height() - h_button - ofs_butt - m_marge));    // hauteur - cet ofset Y de la zone de bouton

   m_ScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);;
   //................... la surface qui doit scroller dans la machine a scroller ...............................
   m_QFrameWidgetList = new QFrame(this);
   QRect rect(0, m_ScrollArea->y(), m_ScrollArea->width()-15, m_Grid_H*nbItem );
   m_QFrameWidgetList->setGeometry(rect);
   m_ScrollArea->setWidget ( m_QFrameWidgetList ); // style=\"BACKGROUND-COLOR: yellow\"
   //................... le contenu de la surface qui doit scroller .............................................
   for (int i=0; i<nbItem; ++i)
       {CMyQTextEdit *pQTextEdit = new CMyQTextEdit(computeTextHit( grammarList[i], i ), m_QFrameWidgetList);
        pQTextEdit->setReadOnly ( true );
        pQTextEdit->setGeometry(0,i*m_Grid_H,rect.width()-1,m_Grid_H);
        pQTextEdit->setStyleSheet(QString("background-color: %1;").arg(palette().color(QPalette::Window).darker(150).name()));
        pQTextEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        pQTextEdit->document()->setDocumentMargin(0.0);
       }
   if (nbItem)
      { m_FocusWidget = setWidgetEditFocus((QWidget*)m_QFrameWidgetList->children()[0], m_FocusWidget);
      }
   //................... la zone des boutons des sequences ..............................................
   int pos_x            = m_marge;
   int pos_y            = m_marge ;
   rect                 = QRect(pos_x, pos_y, m_buttonH*2, m_buttonH);
   m_Button_Seq_0       = new CMyButton(rect,this, tr("1,m_Button_Seq_0")); m_Button_Seq_0->move(pos_x,pos_y);  pos_x += m_Button_Seq_0->width();
   m_Button_Seq_1       = new CMyButton(rect,this, tr("2,m_Button_Seq_1")); m_Button_Seq_1->move(pos_x,pos_y);  pos_x += m_Button_Seq_1->width();
   m_Button_Seq_2       = new CMyButton(rect,this, tr("3,m_Button_Seq_2")); m_Button_Seq_2->move(pos_x,pos_y);  pos_x += m_Button_Seq_2->width();
   m_Button_Seq_3       = new CMyButton(rect,this, tr("4,m_Button_Seq_3")); m_Button_Seq_3->move(pos_x,pos_y);  pos_x += m_Button_Seq_3->width();
   m_Button_Seq_4       = new CMyButton(rect,this, tr("5,m_Button_Seq_4")); m_Button_Seq_4->move(pos_x,pos_y);  pos_x += m_Button_Seq_4->width();
   rect                 = QRect(pos_x, pos_y, m_buttonH, m_buttonH);
   m_Button_Seq_plus    = new CMyButton(m_pC_BitMapCollection->m_ButtonSequenceAdd,rect,this, tr(",m_Button_Seq_plus")); m_Button_Seq_plus->setFlat(true);
   //......................... la zone de saisie de la repartition jour ...........................................
   pos_y  = m_marge + m_buttonH*3;
   pos_x  = m_marge;
   int edit_w = ((HIT_W_MMASCN-(m_marge*6))/6)-m_buttonH;
   rect       = QRect(pos_x, pos_y, edit_w, h_button);
   m_LineEditMatin      = new CMyQLineEdit(rect,"",this,"m_LineEditMatin",this);      m_LineEditMatin->move(pos_x,pos_y);     pos_x = ((HIT_W_MMASCN*1)/6)+m_marge+m_marge;// pos_x += rect.width()+m_marge; (HIT_W_MMASCN*0)/6
   m_LineEditMidi       = new CMyQLineEdit(rect,"",this,"m_LineEditMidi",this);       m_LineEditMidi->move(pos_x,pos_y);      pos_x = ((HIT_W_MMASCN*2)/6)+m_marge+m_marge;//pos_x += rect.width()+m_marge;
   m_LineEditAMidi      = new CMyQLineEdit(rect,"",this,"m_LineEditAMidi",this);      m_LineEditAMidi->move(pos_x,pos_y);     pos_x = ((HIT_W_MMASCN*3)/6)+m_marge+m_marge;//pos_x += rect.width()+m_marge;
   m_LineEditSoir       = new CMyQLineEdit(rect,"",this,"m_LineEditSoir",this);       m_LineEditSoir->move(pos_x,pos_y);      pos_x = ((HIT_W_MMASCN*4)/6)+m_marge+m_marge;//pos_x += rect.width()+m_marge;
   m_LineEditCoucher    = new CMyQLineEdit(rect,"",this,"m_LineEditCoucher",this);    m_LineEditCoucher->move(pos_x,pos_y);   pos_x = ((HIT_W_MMASCN*5)/6)+m_marge+m_marge;//pos_x += rect.width()+m_marge;
   m_LineEditNuit       = new CMyQLineEdit(rect,"",this,"m_LineEditNuit",this);       m_LineEditNuit->move(pos_x,pos_y);      pos_x = ((HIT_W_MMASCN*6)/6)+m_marge+m_marge;//pos_x += rect.width()+m_marge;

   m_Button_MenuMatin     = new CMyButton(m_pC_BitMapCollection->m_ButtonDeploy,QRect(m_LineEditMatin->x()+m_LineEditMatin->width(),         pos_y,m_buttonH,m_buttonH),this, tr(",m_Button_MenuMatin"));
   m_Button_MenuMidi      = new CMyButton(m_pC_BitMapCollection->m_ButtonDeploy,QRect(m_LineEditMidi->x()+m_LineEditMidi->width(),           pos_y,m_buttonH,m_buttonH),this, tr(",m_Button_MenuMidi"));
   m_Button_MenuAMidi     = new CMyButton(m_pC_BitMapCollection->m_ButtonDeploy,QRect(m_LineEditAMidi->x()+m_LineEditAMidi->width(),         pos_y,m_buttonH,m_buttonH),this, tr(",m_Button_MenuAMidi"));
   m_Button_MenuSoir      = new CMyButton(m_pC_BitMapCollection->m_ButtonDeploy,QRect(m_LineEditSoir->x()+m_LineEditSoir->width(),           pos_y,m_buttonH,m_buttonH),this, tr(",m_Button_MenuSoir"));
   m_Button_MenuCoucher   = new CMyButton(m_pC_BitMapCollection->m_ButtonDeploy,QRect(m_LineEditCoucher->x()+m_LineEditCoucher->width(),     pos_y,m_buttonH,m_buttonH),this, tr(",m_Button_MenuCoucher"));
   m_Button_MenuNuit      = new CMyButton(m_pC_BitMapCollection->m_ButtonDeploy,QRect(m_LineEditNuit->x()+m_LineEditNuit->width(),           pos_y,m_buttonH,m_buttonH),this, tr(",m_Button_MenuCoucher"));

   //................... la zone de saisie de la repartition libre ..............................................
   pos_x                = m_marge;
   pos_y                = m_marge + m_marge + m_buttonH;
   QString          txt = tr("total/J.");
   rect                 = QRect(pos_x, pos_y, m_Button_MenuAMidi->x()-m_marge, m_buttonH);
   QLabel      *pQlabel = new QLabel(txt, this); pQlabel->setGeometry(rect);

   pos_x                = m_LineEditMidi->x();
   rect                 = QRect(pos_x, pos_y, m_Button_MenuMidi->x()+m_Button_MenuMidi->width()+m_marge-pos_x, m_buttonH);
   m_LineEditFreeMoment = new CMyQLineEdit(rect,"",this,"m_LineEditFreeMoment",this);

   pos_x                = m_LineEditFreeMoment->x()+m_LineEditFreeMoment->width()+m_marge;
   rect                 = QRect(pos_x, pos_y, m_Button_MenuNuit->x()+m_marge-pos_x, m_buttonH);
                    txt = C_PosologieGrammar::unitPriseForm(m_cur_grammar)+"(s)";
                pQlabel = new QLabel(txt, this); pQlabel->setGeometry(rect);

   pos_x                = m_LineEditNuit->x();
   rect                 = QRect(pos_x, pos_y, 150, m_buttonH);
   m_Button_Repart      = new CMyButton(rect,this, tr("par jour,m_Button_Repart"));
   QMenu    *pQMenu = new QMenu(this);
   pQMenu->addAction(tr("1 - par jour "));
   pQMenu->addAction(tr("2 - matin"));
   pQMenu->addAction(tr("3 - matin midi"));
   pQMenu->addAction(tr("4 - midi soir"));
   pQMenu->addAction(tr("5 - matin midi soir"));
   m_Button_Repart->setMenu ( pQMenu );
   //................... la zone de saisie de la note .............................................................
   pos_y            = m_buttonH *10 + m_marge+m_marge+m_marge;
   pos_x            = m_marge;
   /*
   m_Button_Note    = new QToolButton(this);
   m_Button_Note->setText( tr("commentaire"));
   */
   pQMenu = new QMenu(this);
   pQMenu->addAction(tr("1 - si besoin "));
   pQMenu->addAction(tr("2 - en cas de douleurs "));
   pQMenu->addAction(tr("3 - à dissoudre dans un verre d'eau' "));
   pQMenu->addAction(tr("4 - à adapter selon I.N.R.' "));
   pQMenu->addAction(tr("5 - absorber avec un grand verre d'eau"));
   //m_Button_Note->move(pos_x,pos_y); pos_x += m_Button_Note->width()+m_marge;
   //m_Button_Note->setPopupMode ( QToolButton::MenuButtonPopup );

   m_Button_Note    = new CMyButton(this, tr("commentaire,m_Button_Note")); m_Button_Note->setGeometry(QRect(0,0,m_Button_Note->width(),m_buttonH)); m_Button_Note->move(pos_x,pos_y); pos_x += m_Button_Note->width()+m_marge;
   rect             = QRect(pos_x,pos_y,this->width()-pos_x-m_marge-m_marge,m_buttonH);
   m_LineEditNote   = new CMyQLineEdit(rect,"",this,"m_LineEditNote",this);
   m_Button_Note->setMenu ( pQMenu );
   //................... la zone de saisie de l'indication .............................................................
   pos_y            = m_LineEditNote->y()+ m_LineEditNote->height();
   pos_x            = m_marge;

   m_Button_Indic   = new CMyButton(this, tr("indication,m_Button_Note")); m_Button_Indic->setGeometry(QRect(0,0,m_Button_Indic->width(),m_buttonH)); m_Button_Indic->move(pos_x,pos_y); pos_x += m_Button_Indic->width()+m_marge;
   rect             = QRect(pos_x,pos_y,this->width()-pos_x-m_marge-m_marge,m_buttonH);
   m_LineEditIndic   = new CMyQLineEdit(rect,"",this,"m_LineEditIndic",this);
   pQMenu = new QMenu(this);
   pQMenu->addAction(tr("1 - Ajouter une indication CIM 10 ..."));
   pQMenu->addAction(tr("2 - Ajouter une indication CISP ..."));
   pQMenu->addAction(tr("3 - Ajouter une indication spécifique Thériaque ..."));
   pQMenu->addAction(tr("4 - Ajouter une indication spécifique Vidal ..."));
   pQMenu->addAction(tr("5 - Ajouter une indication de votre liste personnelle ..."));
   m_Button_Indic->setMenu ( pQMenu );
   //................... la zone de saisie de la repartition semaine ..............................................
   int maxW         = 0;
   pos_y            = m_buttonH*2 ;
   pos_x            = HIT_W_MMASCN + m_marge;
   //pos_x            = m_Button_MenuNuit->x() + m_Button_MenuNuit->width() + m_marge;
   m_check_Tout     = new QCheckBox (tr("tous les jours"), this ); m_check_Tout->setObjectName("m_check_Tout");         m_check_Tout->move(pos_x,pos_y);     pos_y += h_button; maxW = qMax(maxW,m_check_Tout->width());
   m_check_Lundi    = new QCheckBox (tr("lundi"), this );          m_check_Lundi->setObjectName("m_check_Lundi");       m_check_Lundi->move(pos_x,pos_y);    pos_y += h_button; maxW = qMax(maxW,m_check_Lundi->width());
   m_check_Mardi    = new QCheckBox (tr("mardi"), this );          m_check_Mardi->setObjectName("m_check_Mardi");       m_check_Mardi->move(pos_x,pos_y);    pos_y += h_button; maxW = qMax(maxW,m_check_Mardi->width());
   m_check_Mercredi = new QCheckBox (tr("mercredi"), this );       m_check_Mercredi->setObjectName("m_check_Mercredi"); m_check_Mercredi->move(pos_x,pos_y); pos_y += h_button; maxW = qMax(maxW,m_check_Mercredi->width());
   m_check_Jeudi    = new QCheckBox (tr("jeudi"), this );          m_check_Jeudi->setObjectName("m_check_Jeudi");       m_check_Jeudi->move(pos_x,pos_y);    pos_y += h_button; maxW = qMax(maxW,m_check_Jeudi->width());
   m_check_Vendredi = new QCheckBox (tr("vendredi"), this );       m_check_Vendredi->setObjectName("m_check_Vendredi"); m_check_Vendredi->move(pos_x,pos_y); pos_y += h_button; maxW = qMax(maxW,m_check_Vendredi->width());
   m_check_Samedi   = new QCheckBox (tr("samedi"), this );         m_check_Samedi->setObjectName("m_check_Samedi");     m_check_Samedi->move(pos_x,pos_y);   pos_y += h_button; maxW = qMax(maxW,m_check_Samedi->width());
   m_check_Dimanche = new QCheckBox (tr("dimanche"), this );       m_check_Dimanche->setObjectName("m_check_Dimanche"); m_check_Dimanche->move(pos_x,pos_y); pos_y += h_button; maxW = qMax(maxW,m_check_Dimanche->width());

   //m_LineEditPeriode    = new CMyQLineEdit(rect,"",this,"m_midi",this);  m_LineEditMidi->move(pos_x,pos_y); pos_x += rect.width()+m_marge;
   //................... les boutons ...................................................
   int but_w = (geometry_rect.width()-m_marge*2)/2 ;
   int but_x = m_marge;
   m_Button_Add = new CMyButton(this,tr("Ajouter un favoris"));
   m_Button_Add->setGeometry(but_x,ofs_butt,but_w,h_button);            but_x += but_w;
   m_Button_Del = new CMyButton(this,tr("Retirer un favoris"));
   m_Button_Del->setGeometry(but_x,ofs_butt,but_w,h_button);            but_x += but_w;
   //.............. le bouton de fermeture ..............................................
   m_ButtonHitClose = new CMyButton(pC_BitMapCollection->m_ButtonHitClose,this);
   m_ButtonHitClose->setGeometry(geometry_rect.width()-m_marge-pC_BitMapCollection->m_ButtonHitClose.width(),
                                 m_marge,
                                 pC_BitMapCollection->m_ButtonHitClose.width(),
                                 pC_BitMapCollection->m_ButtonHitClose.width());

   connect( m_ButtonHitClose, SIGNAL( clicked (bool)  ),  this , SLOT( Slot_ButtonHitCloseClicked(bool) ));
   connect( m_Button_Add,     SIGNAL( clicked (bool)  ),  this , SLOT( Slot_Button_AddClicked(bool) ));
   connect( m_Button_Del,     SIGNAL( clicked (bool)  ),  this , SLOT( Slot_Button_DelClicked(bool) ));

}
//------------------------------------------------------ grammarToInterface ---------------------------------------------------------------------------------
void C_Frm_PosologieHitList::grammarToInterface(const QString& grammar)
{

}

//------------------------------------------------------ computeTextHit ---------------------------------------------------------------------------------
QString C_Frm_PosologieHitList::computeTextHit( const QString &grammar, int index )
{QString indication = C_PosologieGrammar::get_indication(grammar,  index, C_PosologieGrammar::LIBELLE).trimmed();
 return QString("<font color=\"#FF0000\" size=\"3px\" ><b>%1&nbsp;&nbsp;</b></font><font color=\"#0000FF\" size=\"3px\" >Indication : %2&nbsp;&nbsp;&nbsp;&nbsp;</font>"
         "</font><font color=\"#000000\" size=\"3px\" >%3</font>"
        )
        .arg(QString::number(index+1), indication, C_PosologieGrammar::toString(grammar,"", C_PosologieGrammar::UP_JUST_FRACTION ));
}

//------------------------------------------------------ Slot_ButtonHitCloseClicked ---------------------------------------------------------------------------------
void C_Frm_PosologieHitList::Slot_ButtonHitCloseClicked(bool)
{ emit Sign_ButtonHitCloseClicked();
}

//------------------------------------------------------ Slot_Button_AddClicked ---------------------------------------------------------------------------------
void C_Frm_PosologieHitList::Slot_Button_AddClicked(bool)
{   QString grammar = "";
    QString     cip = "";
    emit Sign_HitList_ButtonAppend(grammar);
    if (grammar.length())
       { //................... si ce favoris existe deja cassos ................
         int index = isExistsThisHit(grammar);
         if (index)
            { QToolTip::showText (QCursor::pos(), tr("Ce favoris existe déjà en %1, et ne sera donc pas rajouté.").arg(QString::number(index)), this) ;
              return;
            }
         cip = C_PosologieGrammar::get_cip_pk(grammar);
         //......... on fait la place du nouveau ................................
         QRect rect = geometry();
         rect.setHeight(rect.height()+m_Grid_H);
         setGeometry(rect);

         rect = m_ScrollArea->geometry();
         rect.setHeight(rect.height()+m_Grid_H);
         m_ScrollArea->setGeometry(rect);

         rect = m_QFrameWidgetList->geometry();
         rect.setHeight(rect.height()+m_Grid_H);
         m_QFrameWidgetList->setGeometry(rect);
         //........... on rajoute le nouveau .................
         CMyQTextEdit *pQTextEdit = new CMyQTextEdit(computeTextHit( grammar, m_grammarList.size() ), m_QFrameWidgetList);

         pQTextEdit->setReadOnly ( true );
         pQTextEdit->setGeometry(0,(m_grammarList.size())*m_Grid_H,geometry().width()-1,m_Grid_H);
         pQTextEdit->setStyleSheet(QString("background-color: %1;").arg(palette().color(QPalette::Window).darker(150).name()));
         pQTextEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
         pQTextEdit->document()->setDocumentMargin(0.0);
         pQTextEdit->show();
         m_FocusWidget = setWidgetEditFocus((QWidget*)pQTextEdit, m_FocusWidget);
         m_grammarList.append(grammar);
         m_pC_BDM_Api->increasePosologieHit(grammar, cip);
       }
}
//------------------------------------------------------ isExistsThisHit ---------------------------------------------------------------------------------
int C_Frm_PosologieHitList::isExistsThisHit(QString grammar)
{

 int     nbItem = m_grammarList.count();
 QString toCompareHeader        = "";
 QString toCompareSequences     = "";
 QString toCompareindicStr      = "";
 QString toCompareindicComment  = "";

 int  nextPos      = 0;
 QString header    = CGestIni::getXmlData("gph", grammar, &nextPos);
 QString sequences = CGestIni::getXmlData("gps", grammar, &nextPos).remove('\n').trimmed();
 nextPos           = 0;
 QString indicStr  = CGestIni::getXmlData("gph_in", header, &nextPos).remove('\n').trimmed();
 QString comment   = CGestIni::getXmlData("gph_co", header, &nextPos).trimmed();

 for (int i=0; i<nbItem; ++i)
    { nextPos                 = 0;
      toCompareHeader         = CGestIni::getXmlData("gph", m_grammarList[i], &nextPos);
      toCompareSequences      = CGestIni::getXmlData("gps", m_grammarList[i], &nextPos).remove('\n').trimmed();
      nextPos                 = 0;
      toCompareindicStr       = CGestIni::getXmlData("gph_in", toCompareHeader, &nextPos).remove('\n').trimmed();
      toCompareindicComment   = CGestIni::getXmlData("gph_co", toCompareHeader, &nextPos).trimmed();

     if (toCompareSequences    == sequences &&
         toCompareindicStr     == indicStr  &&
         toCompareindicComment == comment)  return i+1;
    }
 return 0;
}

//------------------------------------------------------ Slot_Button_DelClicked ---------------------------------------------------------------------------------
void C_Frm_PosologieHitList::Slot_Button_DelClicked(bool)
{   /*
    if (m_FocusWidget==0)  return ;
    QList <QObject *> objList = m_QFrameWidgetList->children();
    int index = objList.indexOf(m_FocusWidget);
    if (index == -1)       return ;
    emit Sign_HitList_ButtonDelete     ( m_grammarList[index], index);
    */

}

//------------------------------------------------------ selectedGrammar ---------------------------------------------------------------------------------
QString C_Frm_PosologieHitList::selectedGrammar()
{if (m_FocusWidget==0)  return "";
 QList <QObject *> objList = m_QFrameWidgetList->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_QFrameWidgetList->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_QFrameWidgetList->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;
      pQTextEdit->setStyleSheet(QString("background-color: %1;").arg(palette().color(QPalette::Window).darker(150).name()));
    }
 if (pQWidgetNew==0) return 0;
 pQTextEdit = (CMyQTextEdit*)pQWidgetNew;
 //pQTextEdit->setFocus(); pas de focus !!!! sinon le prend au QLine edit du matin
 m_ScrollArea->ensureVisible(pQTextEdit->x(),pQTextEdit->y());
 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_QFrameWidgetList->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_QFrameWidgetList->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())
    }
 return QFrame::event (ev);
}

//------------------------------------------------------ paintEvent ----------------------------------------------------------------------
void C_Frm_PosologieHitList::paintEvent ( QPaintEvent * /*event*/ )
{   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

    p.setPen (m_background_color.darker(160));
    QPainterPath path;
    path.addRoundedRect (rect, 6, 6);
    p.setBrush(m_background_color);
    p.drawPath(path);
    p.drawPixmap (m_marge, m_marge + m_buttonH + m_buttonH + m_marge , m_pC_BitMapCollection->m_back_repart );

}
//====================================================== 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())
{ setUnitPriseForm( pC_Frm_Produit->forme_galenique() );
  setCip(pC_Frm_Produit->id());
  setDrugRoute(pC_BDM_Api->getDefinedDailyDoseFromCIP(pC_Frm_Produit->id()));
  //............. definir le mode de conversion literal ............................
  int must_be_literal = C_PosologieGrammar::UP_JUST_FRACTION;                                                  // toutes les valeurs 0.25 0.30 0.75 seront converties en un quart un demi et trois quart
  must_be_literal    |= pC_BDM_Api->isStupefiant( pC_Frm_Produit->id()) ? C_PosologieGrammar::ALL_LITERAL : 0; // si stupefiant on impose le mode literal complet
  setLiteralFlag(must_be_literal);

  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
  int           h_but    = 0;
  int           h_but2   = 0;
    //............... rectangle du composant .............................
  setGeometry(geometry_rect);
  //................ largeur de la graduation ...........................
  QLabel *pQLabel        = new QLabel(this);
  QRect rectLabel        = pQLabel->rect();
  QFont  fGrd            = font(); /*fGrd.setPixelSize(20);*/ fGrd.setBold(false); fGrd.setItalic(false);
  QFontMetrics fntMetGrd = QFontMetrics(fGrd);
  QRect        boundRect = fntMetGrd.boundingRect ("X");
  h_but                  = boundRect.top()-boundRect.bottom();
  h_but2                 = boundRect.height();
  fGrd.setPixelSize(h_but2);
  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_LineEditAMidi     = new CMyQLineEdit(boundRect,"",this,"m_LineEditAMidi",this);       m_LineEditAMidi->setFont(fGrd);     m_LineEditAMidi->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_LineEditAMidi,     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_LineEditAMidi,     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_LineEditAMidi,     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 *) ));

  connectControlsOnTextChanged();

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

  clearInterface();
  setMouseTracking (TRUE );
  show();
  //............. creer la liste des favoris .................................
  open_HitList();
  if (m_HitList)
     {//........... y placer la premiere posologie valide ...................
      QString grammar = m_HitList->selectedGrammar();
      C_PosologieGrammar::setUnitPriseForm(grammar, pC_Frm_Produit->forme_galenique());
      if (grammar.length())
         {setGrammar(grammar);
          m_HitList->setGrammar(grammar);
          grammarToInterface();
         }
     }
  QTimer::singleShot(1, this, SLOT(Slot_adjustViewToProfil())); // indispensable de passer par le singleShot
  m_LineEditMatin->setFocus();
}

//------------------------ ~C_Frm_Posologie ---------------------------------------
C_Frm_Posologie::~C_Frm_Posologie()
{delete m_HitList;
 m_HitList = 0;
}
//------------------------ connectControlsOnTextChanged ---------------------------------------
void C_Frm_Posologie::connectControlsOnTextChanged()
{   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_LineEditAMidi,     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 &) ));
}
//------------------------ disconnectControlsOnTextChanged ---------------------------------------
void C_Frm_Posologie::disconnectControlsOnTextChanged()
{   disconnect( m_LineEditMatin,     SIGNAL( textChanged (const QString & ) ),  this , SLOT( Slot_LineEditMatin_textChanged(       const QString &) ));
    disconnect( m_LineEditMidi,      SIGNAL( textChanged (const QString & ) ),  this , SLOT( Slot_LineEditMidi_textChanged(        const QString &) ));
    disconnect( m_LineEditAMidi,     SIGNAL( textChanged (const QString & ) ),  this , SLOT( Slot_LineEditApresMidi_textChanged( const QString &) ));
    disconnect( m_LineEditSoir,      SIGNAL( textChanged (const QString & ) ),  this , SLOT( Slot_LineEditSoir_textChanged(      const QString &) ));
    disconnect( m_LineEditCoucher,   SIGNAL( textChanged (const QString & ) ),  this , SLOT( Slot_LineEditCoucher_textChanged(   const QString &) ));
    disconnect( m_LineEditPeriode,   SIGNAL( textChanged (const QString & ) ),  this , SLOT( Slot_LineEditPeriode_textChanged(   const QString &) ));
    disconnect( m_LineEditNuit,      SIGNAL( textChanged (const QString & ) ),  this , SLOT( Slot_LineEditNuit_textChanged(        const QString &) ));
}
//------------------------ areInputsValid ---------------------------------------
bool C_Frm_Posologie::areInputsValid()
{ if (m_LineEditMatin->text().length())       return true;
  if (m_LineEditMidi->text().length())        return true;
  if (m_LineEditSoir->text().length())        return true;
  if (m_LineEditCoucher->text().length())     return true;
  if (m_LineEditAMidi->text().length())       return true;
  if (m_LineEditNuit->text().length())        return true;
  if (m_LineEditPeriode->text().length()==0)  return false;
  return false;
}

//------------------------ clearInterface ---------------------------------------
void C_Frm_Posologie::clearInterface()
{   m_LineEditMatin->setText("");
    m_LineEditMidi->setText("");
    m_LineEditAMidi->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();
 disconnectControlsOnTextChanged();

 QString sequences    = CGestIni::getXmlData("gps", grammar).remove('\n').trimmed();
 QStringList seqList  = CGestIni::getXmlDataList("gpp", sequences);
 if (seqList.count()==0) { clearInterface();  return; }
 int i=0;
 //for (i=0; i<seqList.count(); ++i)
     {sequenceToInterface(seqList[i], i);
     }
 m_textEdit->setText(toString(m_pC_Frm_Produit->forme_galenique()));
 connectControlsOnTextChanged();
}
//------------------------ sequenceToInterface ---------------------------------------
//"[0.75;m|155.122;d15r|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;d15r"
//"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_LineEditAMidi->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_LineEditAMidi->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_LineEditAMidi->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;d|445;s]/8\n"
//   "[0.75;m|155.122;d15r|2;sr30|3;h10-13]/4\n"
//   "[0.5;d|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".
/*   <gph>
         <gph_id>301546</gph_id>
         <gph_pk>123</gph_pk>
         <gph_uf>comprimé</gph_uf>
         <gph_cm>UP_QUANTITE DURATION</gph_cm>
         <gph_in>
             <gph_il>I13.1|CIP|insuffisance rénale et cardiopathie hypertensive</gph_il>
             <gph_il>P96.0|CIP|insuffisance rénale congénitale</gph_il>
         </gph_in>
         <gph_co>à prendre avec un grand verre d'eau sans respirer pendant 30 minutes</gph_co>
      </gph>
      <gps>
         <gpp>[1;m|2;d|4;s]J8</gpp>
         <gpp>[0.5;m|1;d15r|2;sr30|3;h10-13]J4\</gpp>
         <gpp>[0.5;m|1;s]J3</gpp>
      </gps>
 */

QString C_Frm_Posologie::interfaceToGrammarString()
{QString ret= QString ("<gph>\n"
                       " <gph_id>%1</gph_id>\n"
                       " <gph_pk></gph_pk>\n"
                       " <gph_uf>%2</gph_uf>\n"
                       " <gph_cm>ALL_LITERAL</gph_cm>\n"
                       " <gph_in></gph_in>\n"
                       " <gph_co></gph_co>\n"
                       "</gph>\n"
                       "<gps>\n"
                       "%3"
                       "</gps>\n").arg(m_pC_Frm_Produit->id(),m_pC_Frm_Produit->forme_galenique(),interfaceToXmlSequence());
 return ret;
}
//------------------------ interfaceToXmlSequence ---------------------------------------
QString C_Frm_Posologie::interfaceToXmlSequence()
{QString tagDeb = " <gpp>";
 QString tagEnd = "</gpp>\n";
 QString   ret  = tagDeb;
 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()+";d"+ m_MomentMealMap["midi"]+"|";
    }
 if (m_LineEditAMidi->isVisible() && m_LineEditAMidi->text().length())
    {ret += m_LineEditAMidi->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()+";n"+ m_MomentMealMap["nuit"]+"|";
    }
 if (ret.endsWith('|')) ret = ret.left(ret.length()-1);
 ret +="]";
 if      (m_ButtonPeriodeUnit->text().startsWith(tr("jour")))    ret +="J";
 else if (m_ButtonPeriodeUnit->text().startsWith(tr("semaine"))) ret +="S";
 else if (m_ButtonPeriodeUnit->text().startsWith(tr("mois")))    ret +="M";
 else if (m_ButtonPeriodeUnit->text().startsWith(tr("an")))      ret +="A";
 if (m_LineEditPeriode->text().length())
    {ret += m_LineEditPeriode->text().trimmed();
    }
 else
    {ret += "1";
    }
 ret += tagEnd;
 return ret;
}

//------------------------------- 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 *)
{
}
//------------------------------- Slot_LineEdit_focusOut -------------------------------------
void C_Frm_Posologie::Slot_LineEdit_focusOut(const QString & /*name*/,  CMyQLineEdit *,void *)
{
}
//------------------------------- Slot_HitList_ButtonAppend -------------------------------------
// appelé par le composant C_Frm_PosologieHitList lors d'un clic sur le bouton ajouter, pour lui fournir la grammaire du produit en cours d'édition.
void C_Frm_Posologie::Slot_HitList_ButtonAppend(QString &grammar)
{if (areInputsValid()==false)
    { //....... ne pas utiliser QMessageBox car modifie le focus .................
      //QMessageBox::warning (this, tr("Saisies non exploitables"), tr("Saisies non expoitables car les indications saisies sont incomplètes"));
      QToolTip::showText (QCursor::pos(), tr("Saisies non expoitables<br>car les indications saisies sont incomplètes"), this) ;
      grammar    = ""; // annule l'opération par l'objet SIGNAL appelant
      return;
    }
 grammar = interfaceToGrammarString();
}

//------------------------------- open_HitList -------------------------------------
void C_Frm_Posologie::open_HitList()
{
    QStringList grammarList = getHitsList();
    QRect geometry( this->geometry().x() + timeToPos_x(0)          ,
                    parentWidget()->geometry().y() + parentWidget()->height(),
                    this->geometry().width()-40                       ,
                    qMin((ITEM_HIT_H * grammarList.count()) + m_LineEditMatin->height() + 10 + HIT_TOOL_H,  // le minimum est la hauteur du bandeau de bouton soit : m_LineEditMatin->height()
                          ITEM_HIT_H * ITEM_HIT_NBTOVIEW + HIT_TOOL_H)                                    // hauteur maxi du popup
                  );
    if (m_HitList)
       {m_HitList->raise();
        if (m_HitList->height()<10)  // si deja deploye ne pas le redeployer
           {//............ animer l'apparition du dialogue ..........................
            QRect animRect(geometry);
            animRect.setHeight (0);
            m_animation->setDuration(700);
            m_animation->setEasingCurve ( QEasingCurve ( QEasingCurve::OutCubic ));
            m_animation->setStartValue(animRect);
            m_animation->setEndValue(geometry);
            m_animation->start();
           }
        return;
       }
    m_HitList = new C_Frm_PosologieHitList(grammarList,
                                           grammar(),
                                           geometry, m_ButtonMatin->height(),
                                           m_pC_Frm_Produit->backGroundColor(),
                                           m_pC_BitMapCollection,
                                           m_pC_BDM_Api,
                                           this->parentWidget()->parentWidget());
    connect( m_HitList,      SIGNAL( Sign_HitList_ItemSelected(const QString &, int)  ),   this , SLOT( Slot_HitList_ItemSelected(const QString &,  int) ));
    connect( m_HitList,      SIGNAL( Sign_HitList_ButtonAppend(QString &)  ),              this , SLOT( Slot_HitList_ButtonAppend(QString &) ));
    connect( m_HitList,      SIGNAL( Sign_ButtonHitCloseClicked()),                        this , SLOT( Slot_ButtonHitCloseClicked() ));
    m_HitList ->setGeometry( geometry );
    m_HitList->show();
    //............ animer l'apparition du dialogue ..........................
    m_animation = new QPropertyAnimation(m_HitList, "geometry",this);
    QRect animRect(geometry);
    animRect.setHeight (0);
    m_animation->setDuration(700);
    m_animation->setEasingCurve ( QEasingCurve ( QEasingCurve::OutCubic ));
    m_animation->setStartValue(animRect);
    m_animation->setEndValue(geometry);
    m_animation->start();
}
//------------------------------- Slot_ButtonHitCloseClicked -------------------------------------
void C_Frm_Posologie::Slot_ButtonHitCloseClicked()
{close_HitList();
}

//------------------------------- close_HitList -------------------------------------
void C_Frm_Posologie::close_HitList()
{if (m_HitList==0) return;
 //............ animer la fermeture du dialogue ..........................
 QRect animRect(m_HitList->geometry());
 animRect.setHeight (0);
 m_animation->setDuration(700);
 m_animation->setEasingCurve ( QEasingCurve ( QEasingCurve::OutCubic ));
 m_animation->setStartValue(m_HitList->geometry());
 m_animation->setEndValue(animRect);
 m_animation->start();

 //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_LineEditAMidi->isVisible()) {m_LineEditAMidi ->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()  - 40                 ,
                                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_LineEditAMidi->hide();
     m_ButtonApresMidi->hide();
   }
else
   { m_LineEditAMidi->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/99-before_meal.png#"+tr("Annuler les autres options");
    optionList<<"=98=#medicatux/98-before_meal.png#"+tr("n'importe quand dans la journée");
    optionList<<"=97=#medicatux/98-before_meal.png#"+tr("n'importe quand dans la semaine");
    optionList<<"=96=#medicatux/98-before_meal.png#"+tr("n'importe quand dans le mois");
    optionList<<"=95=#medicatux/98-before_meal.png#"+tr("n'importe quand dans l'année");
    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*/)
{   setGrammar(grammar);
    grammarToInterface();
    m_pC_BDM_Api->increasePosologieHit(grammar, m_pC_Frm_Produit->id());
    close_HitList();
}
//------------------------ 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();
             setGrammar(grammar);
             grammarToInterface();
             m_pC_BDM_Api->increasePosologieHit(grammar, m_pC_Frm_Produit->id());
             close_HitList();
         }
     }
  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);
 switch(retPopup)
 {
  case 98:     // J par jour
  case 97:     // S par semaine
  case 96:     // M par mois
  case 95:     // A par an
  return;
  }

 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"));
    setGrammar(interfaceToGrammarString());
    m_textEdit->setText(toString());
}

//------------------------ 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

    //............ 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,
                                C_BitMapCollection  *pC_BitMapCollection,
                                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_interactionMedLevel              = 0;
  m_interactionTerrainLevel          = 0;
  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;
  m_pC_BitMapCollection              = pC_BitMapCollection;
  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 - 50;
  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);
  //..................... bouton alarmes Interactions..........................................................
  m_ButtonInteractions = new CMyButton(this, "", this);
  m_ButtonInteractions->setGeometry(m_ButtonDelete->x(),
                                    m_ButtonDelete->y()+m_ButtonDelete->height()+2,
                                    m_ButtonDelete->width(),
                                    m_ButtonDelete->height());
  m_ButtonInteractions->setFlat(true);
  connect( m_ButtonInteractions, SIGNAL( Sign_ButtonClickedPtr (const QString&, void *)  ),  this , SLOT( Slot_ButtonInteractions(const QString&, void *) ));
  m_ButtonInteractions->hide();
  //..................... bouton alarmes Allergies..........................................................
  m_ButtonAllergies= new CMyButton(this, "", this);
  m_ButtonAllergies->setGeometry   (m_ButtonDelete->x(),
                                    m_ButtonDelete->y()+m_ButtonDelete->height()+2 + m_ButtonInteractions->height(),
                                    m_ButtonDelete->width(),
                                    m_ButtonDelete->height());
  m_ButtonAllergies->setFlat(true);
  m_ButtonAllergies->setIcon(m_pC_BitMapCollection->m_ButtonAllergies);
  connect( m_ButtonAllergies, SIGNAL( Sign_ButtonClickedPtr (const QString&, void *)  ),  this , SLOT( Slot_ButtonAllergies(const QString&, void *) ));
  m_ButtonAllergies->hide();
  //..................... bouton alarmes Terrain..........................................................
  m_ButtonTerrainInter= new CMyButton(this, "", this);
  m_ButtonTerrainInter->setGeometry   (m_ButtonDelete->x(),
                                       m_ButtonDelete->y()+m_ButtonDelete->height()+2 + m_ButtonInteractions->height() + m_ButtonAllergies->height(),
                                       m_ButtonDelete->width(),
                                       m_ButtonDelete->height());
  m_ButtonTerrainInter->setFlat(true);
  connect( m_ButtonTerrainInter, SIGNAL( Sign_ButtonClickedPtr (const QString&, void *)  ),  this , SLOT( Slot_ButtonInteractionsTerrain(const QString&, void *) ));
  m_ButtonTerrainInter->hide();


  setFocusPolicy(Qt::ClickFocus);
  connect( qApp, SIGNAL( focusChanged(QWidget * , QWidget * )  ),  this , SLOT( Slot_focusChanged(QWidget * , QWidget * ) ));

  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()
{
}

//------------------------ Slot_focusChanged ---------------------------------------
void C_Frm_Produit::Slot_focusChanged(QWidget * /*old*/, QWidget * now)
{   C_Frm_PosologieHitList *pHitList = 0;
    if (m_pC_Frm_Posologie) pHitList = m_pC_Frm_Posologie->get_HitList();

    if (! isAncestorOf(now) )
       {if (pHitList && !pHitList->isAncestorOf(now))
           {m_pC_Frm_Posologie->close_HitList();
            // qDebug()<< tr("close hitlist : %1").arg(this->commercialName());
           }
       }
    else
       {if (m_pC_Frm_Posologie) m_pC_Frm_Posologie->open_HitList();
       }
}

//------------------------------- setInteractionTerrainAlarms -----------------------------------------------------------------
int  C_Frm_Produit::setInteractionTerrainAlarms(const QList<C_InterResultPair> &interactionsList)
{   C_InterResultPair interResultPair;
    for (int i=0; i<interactionsList.count();++i)
        {interResultPair  = interactionsList.at(i);
         if (interResultPair.Code2()==id() && interResultPair.Typ()=="IT_CIM")
            {setInteractionTerrainLevel(interResultPair.Level().toInt());
            }
        }
    return setInteractionTerrainLevelPixmap(m_interactionTerrainLevel);
}
//------------------------------- setInteractionTerrainLevel -----------------------------------------------------------------
int C_Frm_Produit::setInteractionTerrainLevel(int level)
{          if (level==0) m_interactionTerrainLevel = 0;
           else          m_interactionTerrainLevel = qMax(m_interactionTerrainLevel, level);     // on prend le minimum des deux CAD  l'alerte maximum (bravo l'afssaps)                          // on le met au maximum CAD pas d'inreaction
           return        m_interactionTerrainLevel;
}
//------------------------------- setInteractionTerrainLevelPixmap -----------------------------------------------------------------
int C_Frm_Produit::setInteractionTerrainLevelPixmap(int level /* = 0 */)
{   if (level==0)                  // si pas d'interaction effacer la signalétique correspondante
       {m_ButtonTerrainInter->hide();
       }
    else                                            // sinon il y a interaction afficher la signalétique correspondante
       { m_ButtonTerrainInter->setIcon(m_pC_BitMapCollection->terrainLevelToPixmap(level));
         m_ButtonTerrainInter->show();
       }
    return level;
}

//------------------------------- interactionTerrainText -----------------------------------------------------------------
QString  C_Frm_Produit::interactionTerrainText()
{
    //.............. tester interactions de toute la liste de medicaments ....................................
    QList<C_InterResultPair> interResultPairList = m_pC_BDM_Api->getInteractionCim10( id(), commercialName() );
    interResultPairList                         += m_pC_BDM_Api->getInteractionAgeSexePoidsSportVigil(id(), commercialName() );

    if (interResultPairList.count()==0) return "";
    QString text = "";
    for (int i = 0; i < interResultPairList.size(); ++i)
        {   text += interactionTerrainText(interResultPairList.at(i));
        }
    return text;
}
//------------------------------- interactionTerrainText -----------------------------------------------------------------
QString  C_Frm_Produit::interactionTerrainText(const C_InterResultPair  &interResultPair)
{   return interactionTerrainText(interResultPair, m_pC_BitMapCollection);
}
//------------------------------- interactionTerrainText -----------------------------------------------------------------
QString  C_Frm_Produit::interactionTerrainText(const C_InterResultPair  &interResultPair, C_BitMapCollection *pC_BitMapCollection)
{   QString iconeAnnexe = "";
    int     level       = interResultPair.Level().toInt();
    if      (interResultPair.Typ()=="IT_GRO")       iconeAnnexe = QString("<img src=\"")+pC_BitMapCollection->terrainLevelToPixmapPath(6)+"\" />";
    else if (interResultPair.Typ()=="IT_ALL")       iconeAnnexe = QString("<img src=\"")+pC_BitMapCollection->terrainLevelToPixmapPath(7)+"\" />";
    else if (interResultPair.Typ()=="IT_VIG")       iconeAnnexe = QString("<img src=\"")+pC_BitMapCollection->terrainLevelToPixmapPath(6+level)+"\" />";
    else if (interResultPair.Typ()=="IT_DOPE")      iconeAnnexe = QString("<img src=\"")+pC_BitMapCollection->terrainLevelToPixmapPath(11)+"\" />";
    QString text = QString("<b>%6</b><hr/><u>Pathologie interagissante</u> : <b>%1</b> avec <b>%2</b> <br/><img src=\"%3\" />%5<br/>%4")
                    .arg( interResultPair.Term1(),
                          interResultPair.Term2(),
                          pC_BitMapCollection->terrainLevelToPixmapPath(level),
                          interResultPair.Info(),
                          iconeAnnexe,
                          interactionTerrainNiveauToTexte(level)
                        );

    if (text.length()==0) return "";
    QString tm_str =  QString ("<table cellSpacing=\"0\"  cellpadding=\"4\" width=100% border=\"1\">"    // #FF8000
                               "<tbody>"
                               "<tr>"
                               "<td width=300% align=\"left\" bgcolor=\"#FEFFDD\">")+
                               text +
                               "</td>"
                               "</tbody>"
                               "</table>";
    return tm_str;
}
//------------------------------- interactionTerrainNiveauToTexte -----------------------------------------------------------------
QString  C_Frm_Produit::interactionTerrainNiveauToTexte(int niveau)
{switch(niveau)
 {case 0:  return tr("Terrain : Information");
  case 1:  return tr("Mise en garde");
  case 2:  return tr("Precautions d'emploi");
  case 3:  return tr("CONTRE-INDICATION UTILISATION DECONSEILLEE");
  case 4:  return tr("CONTRE-INDICATION ABSOLUE");
  default: return tr("Niveau inconnu");
 }
}
//------------------------------- interactionMedNiveauToTexte -----------------------------------------------------------------
QString  C_Frm_Produit::interactionMedNiveauToTexte(int niveau)
{switch(niveau)
 { case 0:  return tr("Interaction : Information");
   case 1:  return tr("Effets indésirables");
   case 2:  return tr("Précautions d'emploi' ");
   case 3:  return tr("Association DECONSEILLEE");
   case 4:  return tr("Contre-indication ABSOLUE");
   default: return tr("Niveau inconnu");
  }
}


//------------------------------- showInteractionTerrainText -----------------------------------------------------------------
void C_Frm_Produit::showInteractionTerrainText()
{
    C_Frm_Prescription *pC_Frm_Prescription = (C_Frm_Prescription*)this->parentWidget();   // parent; :: adjust_Vertical_PositionToGrid();
    if (pC_Frm_Prescription==0) return;
    QPoint pos = QCursor::pos(); pos.setX(pos.x()+30);
    pC_Frm_Prescription->displayInfo(interactionTerrainText(), tr("interactions pour : %1").arg(this->commercialName()),pos.x(),pos.y(),500,400);
}
//------------------------------- setInteractionMedAlarms -----------------------------------------------------------------
/*
Les quatres niveaux d'intéractions médicamenteuses classées par l'AFSSAPS sont:
 1. Le niveau le plus grave qui est la « contre-indication ». Celle-ci revêt un caractère absolu, et ne doit pas être
    transgressée. Elle peut avoir un effet toxique qui entre dans ce que l?on appelle l?iatrogénie
    (conséquence négative due à un traitement ou un acte médical).
 2. L'« association déconseillée » qui doit être le plus souvent évitée. Si les deux médicaments sont nécessaires,
    et après examen approfondi du rapport bénéfice/risque, une surveillance étroite du patient s?impose.
 3. Le cas le plus fréquent est la « précaution d?emploi ». L?association est possible dès lors que sont respectées,
    notamment en début de traitement, les recommandations simples permettant d?éviter la survenue de l?interaction :
    adaptation des doses, renforcement de la surveillance clinique, biologique, électrocardiogramme?
 4. Au quatrième niveau, il n?existe pas de recommandation pratique. Pourtant, le risque d?interaction médicamenteuse
    existe, et correspond le plus souvent à une addition d?effets indésirables.

     *   each interaction line is a xml structure where :
     *   <itli>           </itli> delimits each interaction line structured as follows.
     *   <itli_code1>     </itli_code1>       delimits first  term code (if exists)
     *   <itli_typcode1>  </itli_typcode1>    delimits first  term codetyp examples "CIP ATC CIM10 CISP NONE AL PO"
     *   <itli_terme1>    </itli_terme1>      delimits first  term libelle text
     *   <itli_code2>     </itli_code2>       delimits second term code (if exists)
     *   <itli_typcode2>  </itli_typcode2>    delimits second term codetyp examples "CIP ATC CIM10 CISP NONE"
     *   <itli_terme2>    </itli_terme2>      delimits second term libelle text
     *   <itli_terme2>    </itli_terme2>      delimits second term libelle text
     *   <itli_texte>     </itli_texte>       delimits text interaction information
     *   <itli_ityp>      </itli_ityp>        delimits interaction type (RESERVED)
     *   <itli_level>     </itli_level>       interraction level

     QPixmap m_ci_assinterdit;
     QPixmap m_ci_deconseille;
     QPixmap m_ci_precautions;
     QPixmap m_ci_eff_indesir;
 */
//------------------------------- setInteractionMedAlarms -----------------------------------------------------------------
int    C_Frm_Produit::setInteractionMedAlarms(const QList<C_InterResultPair> &interactionsList)
{ QString cip     = id();
  C_InterResultPair interResultPair;
  QString cip_i1  = "";
  QString cip_i2  = "";
  int     level   = 0;
  for (int i=0; i<interactionsList.count();++i)
      {interResultPair  = interactionsList.at(i);
       cip_i1   = interResultPair.Code1();    // attention l'ordre de recuperation des infos doit se faire
       cip_i2   = interResultPair.Code2();
       if ((cip_i1==cip||cip_i2==cip) && interResultPair.Typ()=="AFSSAPS")
          {level = qMax(level, interResultPair.Level().toInt());
          }
      }
  return setInteractionMedLevelPixmap(level);
}

//------------------------------- setInteractionMedLevel -----------------------------------------------------------------
int C_Frm_Produit::setInteractionMedLevel(int level)
{
    if (level==0) m_interactionMedLevel = 0;
    else          m_interactionMedLevel = qMax(m_interactionMedLevel, level);     // on prend le minimum des deux CAD  l'alerte maximum (bravo l'afssaps)                          // on le met au maximum CAD pas d'inreaction
    return        m_interactionMedLevel;
}
//------------------------------- setInteractionMedLevelPixmap -----------------------------------------------------------------
int C_Frm_Produit::setInteractionMedLevelPixmap(int level)
{   setInteractionMedLevel(level);                     // proceder aux ajustements necessaires (m_interactionMedLevel est ajuste)
    if (m_interactionMedLevel==0)                  // si pas d'interaction effacer la signalétique correspondante
       {m_ButtonInteractions->hide();
       }
    else                                            // sinon il y a interaction afficher la signalétique correspondante
       { m_ButtonInteractions->setIcon(m_pC_BitMapCollection->afssapsLevelToPixmap(m_interactionMedLevel));
         m_ButtonInteractions->show();
       }
    return m_interactionMedLevel;
}

//------------------------------- Slot_ButtonInteractionsTerrain -----------------------------------------------------------------
void C_Frm_Produit::Slot_ButtonInteractionsTerrain(const QString&, void *)
{showInteractionTerrainText();
}
//------------------------------- Slot_ButtonInteractions -----------------------------------------------------------------
void C_Frm_Produit::Slot_ButtonInteractions(const QString&, void *)
{showInteractionMedText();
}
//------------------------------- Slot_ButtonAllergies -----------------------------------------------------------------
void C_Frm_Produit::Slot_ButtonAllergies(const QString&, void *)
{showAllergieText();
}
//------------------------------- setAllergie -----------------------------------------------------------------
void C_Frm_Produit::setAllergie(bool state /* = false */)
{ if (state)
    {m_ButtonAllergies->show();
    }
 else
    {m_ButtonAllergies->hide();
    }
}

//------------------------------- showAllergieText -----------------------------------------------------------------
void C_Frm_Produit::showAllergieText()
{
    C_Frm_Prescription *pC_Frm_Prescription = (C_Frm_Prescription*)this->parentWidget();   // parent; :: adjust_Vertical_PositionToGrid();
    if (pC_Frm_Prescription==0) return;
    QPoint pos = QCursor::pos(); pos.setX(pos.x()+30);
    pC_Frm_Prescription->displayInfo(allergieText(), tr("interactions pour : %1").arg(this->commercialName()),pos.x(),pos.y(),500,400);
}

//------------------------------- allergieText -----------------------------------------------------------------
QString  C_Frm_Produit::allergieText()
{
    //.............. tester interactions de toute la liste de medicaments ....................................
    QList<C_InterResultPair> interResultPairList = m_pC_BDM_Api->getInteractionAllergies ( id(), commercialName() );
    if (interResultPairList.count()==0) return "";

    C_InterResultPair        interResultPair;
    QString text = "";
    int        i = 0;
    for (i = 0; i < interResultPairList.size(); ++i)
        {   interResultPair = interResultPairList.at(i);
            text += QString("<hr/><b><u>Allergie %1  %2 </u></b><br/><img src=\"%3\" /><br/>%4")
                    .arg( interResultPair.Term1(),
                          interResultPair.Term2(),
                          m_pC_BitMapCollection->allergieLevelToPixmapPath(interResultPair.Level().toInt()),
                          interResultPair.Info()
                        );
        }
    if (text.length()==0) return "";
    QString tm_str =  QString ("<table cellSpacing=\"0\"  cellpadding=\"4\" width=100% border=\"1\">"    // #FF8000
                               "<tbody>"
                               "<tr>"
                               "<td width=300% align=\"left\" bgcolor=\"#FEFFDD\">")+
                               text +
                               "</td>"
                               "</tbody>"
                               "</table>";
    return tm_str;
}
//------------------------------- interactionMedText -----------------------------------------------------------------
QString  C_Frm_Produit::interactionMedText()
{   C_Frm_Prescription *pC_Frm_Prescription = (C_Frm_Prescription*)this->parentWidget();   // parent; :: adjust_Vertical_PositionToGrid();
    if (pC_Frm_Prescription==0)         return "";

    //.............. tester interactions de toute la liste de medicaments ................................................
    //               on filtrera ensuite celles qui ne concernent que le produit en cours
    //               ce qui doit tenir compte de A<-->B et B<-->A  sont identiques
    QList<C_InterResultPair> interResultPairList = m_pC_BDM_Api->getInteractionPairFromCipList (pC_Frm_Prescription->cipList());
    if (interResultPairList.count()==0) return "";
    C_InterResultPair        interResultPair;
    QMap <QString, QString>  mapText;
    QString cip      = id();
    QString cip_i1   = "";
    QString cip_i2   = "";
    QString text     = "";
    QString keycode  = "";
    for (int i = 0; i < interResultPairList.size(); ++i)
        { interResultPair = interResultPairList.at(i);
          cip_i1          = interResultPair.Code1();
          cip_i2          = interResultPair.Code2();
          if ( (cip_i1==cip||cip_i2==cip)/* && interResultPair.Typ()=="AFSSAPS"*/)           // filtrer sur "AFSSAPS" est inutile car la fonction getInteractionFromCipList() ne ramene que ce qu'il faut
             { keycode         = (cip_i1<cip_i2) ? cip_i1+" "+cip_i2 : cip_i2+" "+cip_i1;    // astuce pour eviter les redondances A<-->B et B<-->A
               keycode        += " "+interResultPair.Level();                                // on cree un pseudo code pour eviter les redondances
               mapText[keycode]= interactionMedText(interResultPair);
             }
        }
    //............ on reprend le map qui devrait etre sans redondance ................
    QMapIterator<QString, QString> it(mapText);
    while (it.hasNext())
       {it.next();
        text +=  it.value();
       }
    return text;
}
//------------------------------- interactionMedText -----------------------------------------------------------------
QString  C_Frm_Produit::interactionMedText(const C_InterResultPair  &interResultPair, C_BitMapCollection *pC_BitMapCollection)
{   int     level       = interResultPair.Level().toInt();
    QString text = QString("<b>%6</b><hr/><b><u>Interaction entre %1 et %2 </u></b><br/><img src=\"%3\" /><br/>%4")
                           .arg( interResultPair.Term1(),
                                 interResultPair.Term2(),
                                 pC_BitMapCollection->afssapsLevelToPixmapPath(level)  ,
                                 interResultPair.Info(),
                                 interactionTerrainNiveauToTexte(level)

                          );
    if (text.length()==0) return "";
    QString tm_str =  QString ("<table cellSpacing=\"0\"  cellpadding=\"4\" width=100% border=\"1\">"    // #FF8000
                               "<tbody>"
                               "<tr>"
                               "<td width=300% align=\"left\" bgcolor=\"#FEFFDD\">")+
                               text +
                               "</td>"
                               "</tbody>"
                               "</table>";
    return tm_str;
}
//------------------------------- interactionMedText -----------------------------------------------------------------
QString  C_Frm_Produit::interactionMedText(const C_InterResultPair  &interResultPair)
{   return interactionMedText(interResultPair, m_pC_BitMapCollection);
}
//------------------------------- showInteractionMedText -----------------------------------------------------------------
void C_Frm_Produit::showInteractionMedText()
{   QString tm_str = interactionMedText();
    if (tm_str.length()==0)             return;
    C_Frm_Prescription *pC_Frm_Prescription = (C_Frm_Prescription*)this->parentWidget();   // parent; :: adjust_Vertical_PositionToGrid();
    if (pC_Frm_Prescription==0)         return ;
    QPoint pos     = QCursor::pos(); pos.setX(pos.x()+30);
    pC_Frm_Prescription->displayInfo(tm_str, tr("interactions pour : %1").arg(this->commercialName()),pos.x(),pos.y(),500,400);
}

//------------------------------- 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.fillRect ( 1, 4, HANDLE_MOVE_WIDTH-1, height()-8, background_color.lighter(118) );
    //............ dessin du titre ............................................
    QString title = QString(commercialName()+" ("+dci_1Name()+")").replace("&NBSP;","&nbsp;").replace("&nbsp;"," ");
    p.setPen (background_color.lighter(118));
    p.drawText (21,12, title );
    p.setPen (QColor("#000000"));
    p.drawText (18,11, title );
    // 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);
        }
 }
//------------------------------------ move ------------------------------------------------
void     C_Frm_Produit::move(int x, int y)
{ QFrame::move(x,y);                         // on bouge le composant lui meme
  if ( m_pC_Frm_Posologie )                  // on bouge eventuellement son dialogue associe
     { C_Frm_PosologieHitList*   hitList = m_pC_Frm_Posologie->get_HitList();
       if (hitList)
          {hitList->setBackGround(backGroundColor());       // la couleur peut avoir change selon ald ou non ald
           hitList->moveY( geometry().y() + height() );
          }
     }
}
//------------------------------------ set_ald ------------------------------------------------
void     C_Frm_Produit::set_ald(const QString &ald)
{  C_OrdoLineRecord::set_ald(ald);
   if ( m_pC_Frm_Posologie )                  // on bouge eventuellement son dialogue associe
      { C_Frm_PosologieHitList*   hitList = m_pC_Frm_Posologie->get_HitList();
        if (hitList)
           {hitList->setBackGround(backGroundColor());       // la couleur peut avoir change selon ald ou non ald
            hitList->update();
           }
      }
}

// =================================== 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_infoTexEdit          = 0;
 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);
 //connect( this, SIGNAL( close () ),  this , SLOT( Slot_close() ));
}
//----------------------------------------- ~C_Frm_Prescription ----------------------------------------------------------
C_Frm_Prescription::~C_Frm_Prescription()
{if (m_infoTexEdit)
    {m_infoTexEdit->close();
     m_infoTexEdit->deleteLater();
    }
}
//----------------------------------------- Slot_close  ----------------------------------------------------------
void C_Frm_Prescription::Slot_close()
{if (m_infoTexEdit)
    {m_infoTexEdit->close();
     m_infoTexEdit->deleteLater();
     m_infoTexEdit = 0;
    }
}
//----------------------------------------- displayInfo ----------------------------------------------------------
void C_Frm_Prescription::displayInfo(const  QString &info, const  QString &title, int x, int y , int w, int h)
{QRect rect;
 if (m_infoTexEdit==0)
    {   m_infoTexEdit = new QTextEdit(0);
        emit Sign_PrescriptionWantGeometry(rect);
        x = rect.x() + rect.width();
        y = rect.y();
        h = rect.height();
        m_infoTexEdit->setGeometry(x,y,w,h);
        m_infoTexEdit->setWindowIcon(Theme::getIcon("22x22/interact.png"));
        m_infoTexEdit->setWindowFlags(Qt::WindowStaysOnTopHint);
        m_infoTexEdit->show();
    }
 if (m_infoTexEdit->isHidden()) m_infoTexEdit->show();
 m_infoTexEdit->setText(info);
 m_infoTexEdit->setWindowTitle(title);
}

//----------------------------------------- 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;
}
//-------------------------------- event ---------------------------------------------------------
bool     C_Frm_Prescription::event ( QEvent * e )
{
  return QFrame::event(e);
}

//-------------------------------- 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);
}

//------------------------ idExists ----------------------------------------------------
QList <C_Frm_Produit*>  C_Frm_Prescription::idExists(const QString &id)
{   QList <C_Frm_Produit*> retChildsList;
    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);
         if (pC_Frm_Produit->id()==id)retChildsList.append(pC_Frm_Produit);
        }
    return retChildsList;
}

//------------------------ 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)
{   C_OrdoLineRecord  ordoLine(xmlData);
    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;

    //.................. verifier si ce medicament n'est pas deja present .................................
    if ( idExists(ordoLine.id()).size())
       { if (QMessageBox::question ( this,
                                     tr("Redondance"),
                                     tr("Ce produit : <b>%1</b> <br>"
                                        "est déjà présent, confirmez vous son ajout").arg(ordoLine.commercialName()),
                                     QMessageBox::Cancel | QMessageBox::Ok,
                                     QMessageBox::Cancel
                                   ) == QMessageBox::Cancel) return;
       }
    //.................. 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;
       }

    // ..................calcul de la position la plus basse avant de creer l'objet ....................
    int nb_Prd;
    int nb_Ald = count_ALD(&nb_Prd); // au moins une case ALD vide
    if (nb_Ald==0) ++nb_Ald;         // car si pas d'ald on decale tout de 1 vers le bas
    pos_y = qMin(pos_y, (nb_Ald + nb_Prd) * m_Grid_H + FIRST_OBJ_POS_Y + m_SpaceBetweenProduits/2);
    if (is_in_Ald) ordoLine.set_ald("ALD");
    //.................. creer le nouvel arrivant  dans la place faite .................................
    pC_Frm_Produit= new C_Frm_Produit(ordoLine,
                                      m_pC_BDM_Api,
                                      this,
                                      // QRect(FIRST_OBJ_POS_X, pos_y, m_C_Frm_Produit_W, m_C_Frm_Produit_H),
                                      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
    QStringList listPoso = m_pC_BDM_Api->getPosologiesFromCIP ( ordoLine.id() );
    //.............. tester interactions de toute la liste de medicaments ....................................
    QTimer::singleShot(10, this, SLOT(Slot_evaluateAllInteractions()));
    //Slot_evaluateAllInteractions();
}

//------------------------------------ Slot_evaluateAllInteractions ------------------------------------------------
void C_Frm_Prescription::Slot_evaluateAllInteractions()
{
    //................ methode 1 on part de la liste des interactions................................................
    //                 et pour chaque element trouve on place le niveau
    //                 dans les produits correspondants a chaque cip de la paire
    QStringList                       cipList;
    C_Frm_Produit            *pC_Frm_Produit     = 0;
    QString                              cip     = "";
    int                                 level    = 0;
    QString                          allerg_Text = "";
    QString                          pathol_Text = "";
    QString                                  ret = "";
    //................ on mape tous les produits avec leur cip ........................
    //                 permet de les rechercher ensuite avec leur cip
    //                 au passage on remet a zero l'indicateur d'interaction
    //                 au passage on cree la liste des cip pour requeter l'interaction
    QMultiMap  <QString , C_Frm_Produit*> cip_prod_map;
    QList <C_Frm_Produit*> childsList  = C_Frm_ProduitList();
    for (int i = 0; i < childsList.size(); ++i)
        {   pC_Frm_Produit = childsList.at(i);
            if (pC_Frm_Produit->id_type()=="CIP")
               {  pC_Frm_Produit->setInteractionMedLevelPixmap(0);  // on efface le niveau d'interraction
                  pC_Frm_Produit->setInteractionMedLevel(0);
                  pC_Frm_Produit->setInteractionTerrainLevelPixmap(0);
                  pC_Frm_Produit->setInteractionTerrainLevel(0);
                  pC_Frm_Produit->setAllergie(false);
                  cip = pC_Frm_Produit->id();
                  cipList.append( cip );                         // on ajoute a la liste des cip
                  cip_prod_map.insert(cip, pC_Frm_Produit);      // on mape le cip avec le produit permetra de rechercher par la suite les pC_Frm_Produit par leur cip
               }
        }
    //.................. pour chaque paire d'interaction ...............................
    bool isInteractionMed = false;
    QList<C_InterResultPair> interResultPairList = m_pC_BDM_Api->getInteractionPairFromCipList ( cipList );
    interResultPairList                         += m_pC_BDM_Api->getInteractionCim10FromCipList( cipList );
    interResultPairList                         += m_pC_BDM_Api->getInteractionAgeSexePoidsSportVigil( cipList );
    C_InterResultPair        interResultPair;
    int  i = 0;
    for (i = 0; i < interResultPairList.size(); ++i)
        {   interResultPair = interResultPairList.at(i);
            level           = interResultPair.Level().toInt();
            if (interResultPair.Typ()=="AFSSAPS")
               {QList<C_Frm_Produit*> pC_Frm_ProduitList;
                //......... on place le niveau pour le premier cip de la paire....................
                pC_Frm_ProduitList = cip_prod_map.values(interResultPair.Code1());    // recuperer dans la map la liste des produits avec ce cip
                for (int p = 0; p < pC_Frm_ProduitList.size(); ++p)
                    { pC_Frm_Produit = pC_Frm_ProduitList.at(p);
                      pC_Frm_Produit->setInteractionMedLevelPixmap( pC_Frm_Produit->setInteractionMedLevel(level) );
                    }
                //......... on place le niveau pour le deuxième cip de la paire ....................
                pC_Frm_ProduitList = cip_prod_map.values(interResultPair.Code2());
                for (int p = 0; p < pC_Frm_ProduitList.size(); ++p)
                    { pC_Frm_Produit = pC_Frm_ProduitList.at(p);
                      pC_Frm_Produit->setInteractionMedLevelPixmap( pC_Frm_Produit->setInteractionMedLevel(level)  );
                    }
                isInteractionMed = true;
               }   // if (interResultPair.Typ()=="AFSSAPS")
            else if (interResultPair.Typ().startsWith("IT_"))
               {QList<C_Frm_Produit*> pC_Frm_ProduitList;
                pC_Frm_ProduitList = cip_prod_map.values(interResultPair.Code2());    // recuperer dans la map la liste des produits avec ce cip
                for (int p = 0; p < pC_Frm_ProduitList.size(); ++p)
                    { pC_Frm_Produit = pC_Frm_ProduitList.at(p);
                      pC_Frm_Produit->setInteractionTerrainLevelPixmap( pC_Frm_Produit->setInteractionTerrainLevel(level) );
                      pathol_Text   += pC_Frm_Produit->interactionTerrainText(interResultPair);
                    }
               } // if (interResultPair.Typ()=="IT_CIM")
        } // for (int i = 0; i < interResultPairList.size(); ++i)

    //.............. tester allergies de toute la liste de medicaments ....................................
    for (int i = 0; i < childsList.size(); ++i)
        {   pC_Frm_Produit = childsList.at(i);
            if (pC_Frm_Produit->id_type() != "CIP") continue;
            ret = pC_Frm_Produit->allergieText();
            if (ret.length())
               {pC_Frm_Produit->setAllergie( true );
                allerg_Text += ret;
               }
        }

    if (isInteractionMed || allerg_Text.length() || pathol_Text.length())
       { QPoint pos = QCursor::pos(); pos.setX(pos.x()+30);
         displayInfo(getAllInteractionMedInfo(interResultPairList) + allerg_Text + pathol_Text, tr("interactions globales"),pos.x(),pos.y(),500,400);
       }
    else
       { if (m_infoTexEdit) m_infoTexEdit->hide();
       }
}
//------------------------------------ getAllInteractionMedInfo() ------------------------------------------------
QString C_Frm_Prescription::getAllInteractionMedInfo(const QStringList &ciplist /*=0*/ )
{   //.............. tester interactions de la liste de medicaments ....................................
    QList<C_InterResultPair> interResultPairList;
    if (ciplist.count() )    interResultPairList = m_pC_BDM_Api->getInteractionPairFromCipList ( ciplist );       // on prend la liste donnee en entree
    else                     interResultPairList = m_pC_BDM_Api->getInteractionPairFromCipList ( cipList() );     // on va chercher pour tout le monde
    return                   getAllInteractionMedInfo(interResultPairList);
}
//------------------------------------ getAllInteractionMedInfo() ------------------------------------------------
QString C_Frm_Prescription::getAllInteractionMedInfo(const QList<C_InterResultPair> &interResultPairList)
{   QString keycode = "";
    QString cip_i1  = "";
    QString cip_i2  = "";
    QString text    = "";
    QString s_level = "";

    //.............. tester interactions de la liste de medicaments ....................................
    C_InterResultPair     interResultPair;
    QMap <QString, QString> mapText;
    for (int i = 0; i < interResultPairList.size(); ++i)
        { interResultPair = interResultPairList.at(i);

         cip_i1   = interResultPair.Code1(); // attention l'ordre de recuperation des infos doit se faire
         cip_i2   = interResultPair.Code2();
         if (interResultPair.CodeTyp1()=="CIP" && interResultPair.Typ()=="AFSSAPS")
            { keycode  = (cip_i1<cip_i2) ? cip_i1+" "+cip_i2 : cip_i2+" "+cip_i1;      // astuce pour eviter les redondances on cree un couple CIP1 CIP2 le meme meme si code
              s_level  = interResultPair.Level();
              keycode += " "+s_level;   // on cree un pseudo code pour eviter les redondances
              if ( ! mapText.contains(keycode))
                 { mapText[keycode] = C_Frm_Produit::interactionMedText(interResultPair, this);  // rappel pour le this : C_Frm_Prescription derive de C_BitMapCollection
                 }
            }
        }
     //............ on reprend le map qui devrait etre sans redondance de texte................
     //             on construit le texte aditionnant tous ceux des interactions
     QMapIterator<QString, QString> it(mapText);
     while (it.hasNext())
        { it.next();
          text +=  it.value();
        }
    return text;
}

//------------------------------------ cipList ------------------------------------------------
QStringList C_Frm_Prescription::cipList()
{ QList <C_Frm_Produit*> childsList  = C_Frm_ProduitList();
  QStringList cipList;
  C_Frm_Produit *pC_Frm_Produit;
  for (int i = 0; i < childsList.size(); ++i)
      {   pC_Frm_Produit = childsList.at(i);
          if (pC_Frm_Produit->id().length()&&pC_Frm_Produit->id_type()=="CIP") cipList.append(pC_Frm_Produit->id());
      }
  return cipList;
}

//------------------------------------ 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
}
//------------------------------------ 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;          // noter le deplacement vertical
 //............. 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);

 rearangeAllNumberOrder();  // marche pas en temps reel si deplacement vers le bas !!!
 update();
}
//------------------------------------ objectStopsMoving ------------------------------------------------
void C_Frm_Prescription::objectStopsMoving(C_Frm_Produit *pC_Frm_Produit)
{//............ ajuster a 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)                       // si depassement on ajuste
    { 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();
    QTimer::singleShot(10, this, SLOT(Slot_evaluateAllInteractions()));
}
