
/*********************************** C_TokenInterpret.cpp ***************************
 *                                                                                *
 *   #include "CDevilCrucible.h"                                                  *
 *   Project: MedinTux                                                            *
 *   Copyright (C) 2003 2004 2005 by Sevin Roland  and Data Medical Design        *
 *   E-Mail: data.medical.design@club-internet.fr                                 *
 *   Eric MAEKER 2007 2008 eric.maeker@free.fr                                    *
 *                                                                                *
 *   This program is free software; you can redistribute it and/or modify         *
 *   it under the terms of the CeCILL Version 1 du 21/06/2004                     *
 *   License (GPL compatible)                                                     *
 *                              http://www.cecill.info/                           *
 *   as published by :                                                            *
 *                                                                                *
 *   Commissariat à l'Energie Atomique                                            *
 *   - CEA,                                                                       *
 *                            31-33 rue de la Fédération, 75752 PARIS cedex 15.   *
 *                            FRANCE                                              *
 *   Centre National de la Recherche Scientifique                                 *
 *   - CNRS,                                                                      *
 *                            3 rue Michel-Ange, 75794 Paris cedex 16.            *
 *                            FRANCE                                              *
 *   Institut National de Recherche en Informatique et en Automatique             *
 *   - INRIA,                                                                     *
 *                            Domaine de Voluceau, Rocquencourt, BP 105, 78153    *
 *                            FRANCE                                              *
 *                                                                                *
 *         This program is distributed in the hope that it will be useful,        *
 *         but WITHOUT ANY WARRANTY; without even the implied warranty of         *
 *         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                   *
 *         CeCILL  License (GPL compatible) for more details.                     *
 *                                                                                *
 **********************************************************************************/

#include "C_TokenInterpret.h"
#include "CDevilCrucible.h"
#include "CApp.h"
#include "../../MedinTuxTools/CHtmlTools.h"
#include "../../MedinTuxTools/DLG_InsertList.h"
#include "../../MedinTuxTools/C_Organiseur.h"
#include "../../MedinTuxTools/CGenTools.h"
#include "../../MedinTuxTools/CMedicaBase.h"
#include "../../MedinTuxTools/CGestIni.h"
#include "../../MedinTuxTools/Calendar/Dlg_Calendar.h"

#include "MyEditText.h"
#include "CMDI_Generic.h"
#include "CMDI_Documents.h"
#include "CDevilFormPDF.h"
#include "CDevilGraph.h"
#include "CDevilCalc.h"
#include "CRubList.h"
#include "CMoteur_Base.h"
#include "Rubriques.h"
#include "C_Dlg_Pendule.h"

#include "drtux.h"
#include <qprocess.h>
#include <qmessagebox.h>
#include <qdir.h>
#include <qprocess.h>
#include <qmime.h>
#include <qpixmap.h>
#include <qimage.h>
#include <qeventloop.h>
#include <qthread.h>
#include <qfiledialog.h>
#include <stdlib.h>

#ifdef Q_WS_WIN
   #define F_EXE ".exe"
   #include <windows.h>
#else
   #define F_EXE ""
#endif

#define TR QObject::tr

static  CDevilCrucible        *G_mCDC = 0;
static QString            G_PluginRun = "";

//====================================== C_TokenInterpret ==============================================================
//-------------------------- C_TokenInterpret -------------------------------------------
C_TokenInterpret::C_TokenInterpret()
{

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

//-------------------------- init -------------------------------------------
void C_TokenInterpret::init(CDevilCrucible *pCDevil)
{G_mCDC = pCDevil;
}
//---------------------------- ResolvScriptTokenSyntax ----------------------------------------
/*! \brief Interpréteur des fonctions de scripts ().
 * Les fonctions de scripts permettent de faire des actions au sein du document passé en paramètre.
 * L'appel de fonctions de scripts se présente de la sorte :
 * \code {{:: FONCTION_DE_SCRIPT ( Param1, param2 ....) }} \endcode
 * Appel la fonction exeFunction().
 * \sa exeFunction()
 */
int C_TokenInterpret::ResolvMacroToken(CDevilCrucible *pCDC, QString &resolvToken, QString token, QString &)
{ //CDevilCrucible *sav_pCDC = G_mCDC;    // sauvegarder pour assurer eventuelle recursivite
                    G_mCDC = pCDC;
  //............. separer eventuels argumens du token .................
  QStringList arg_list;
  int       ret = 0;
  resolvToken   = "";
  int       pos = token.find('=');
  if (pos != -1)
     {arg_list.append(token.mid(pos+1));
      token = token.left(pos).stripWhiteSpace();
     }
  token = token.replace(' ','_').upper();

  //................. batir la structure de comparaison .......................
  KEY_MACRO toTest;
            toTest.m_Token     = (char*)(const char*)token;
  //        toTest.m_Function  = 0;

  //............... recuperer le tableau de fonctions correspondant à la première lettre du token.............................
  int i = (int)toTest.m_Token[0]-'A';
  if (i<0 || i>25)                   return ret;
  KEY_MACRO_TAB_DEF *p_MACRO_LIST = &G_MacroTab_List[i];

  //................. rechercher la fonction du token ...............................................................
  KEY_MACRO *pKEY_MACRO = (KEY_MACRO*) bsearch(&toTest, p_MACRO_LIST->m_MacroTab, p_MACRO_LIST->m_size , sizeof(KEY_MACRO), C_TokenInterpret::comparatorMacro);
  if (pKEY_MACRO)
     {resolvToken = (*(pKEY_MACRO->m_Function))(arg_list);
      ret = 1;
     }
 //G_mCDC  = sav_pCDC;
 return ret;
}

//-------------------------- exeFunction -------------------------------------------
int C_TokenInterpret::exeFunction(QString token, const QString& args, QString &resolvToken)
{ QStringList arg_list;
  int       ret = 0;
  extractArgList(arg_list, args);
  token = token.replace(' ','_').upper();
  //................. batir la structure de comparaison .......................
  KEY_MACRO toTest;
            toTest.m_Token     = (char*)(const char*)token;
  //        toTest.m_Function  = 0;

  //............... recuperer le tableau de fonctions correspondant à la première lettre du token.............................
  int i = (int)toTest.m_Token[0]-'A';
  if (i<0 || i>25)                   return ret;
  KEY_MACRO_TAB_DEF *p_MACRO_LIST = &G_MacroTab_List[i];

  //................. rechercher la fonction du token .........................
  KEY_MACRO *pKEY_MACRO = (KEY_MACRO*) bsearch(&toTest, p_MACRO_LIST->m_MacroTab, p_MACRO_LIST->m_size , sizeof(KEY_MACRO), C_TokenInterpret::comparatorMacro);
  if (pKEY_MACRO)
     {resolvToken = (*(pKEY_MACRO->m_Function))(arg_list);
      ret = 1;
     }
  return ret;
}

//---------------------------- ResolvScriptTokenSyntax ----------------------------------------
/*! \brief Interpréteur des fonctions de scripts ().
 * Les fonctions de scripts permettent de faire des actions au sein du document passé en paramètre.
 * L'appel de fonctions de scripts se présente de la sorte :
 * \code {{:: FONCTION_DE_SCRIPT ( Param1, param2 ....) }} \endcode
 * Appel la fonction exeFunction().
 * \sa exeFunction()
 */
int C_TokenInterpret::ResolvFunctionToken(CDevilCrucible *pCDC, QString &resolvToken, QString token)
{//CDevilCrucible *sav_pCDC = G_mCDC;    // sauvegarder pour assurer eventuelle recursivite
                   G_mCDC = pCDC;
 resolvToken   = "";
 if (token[0] !='#')   CHtmlTools::HtmlToAscii(token);
 else                  token.remove (0, 1);
 int pos_prem_p =  token.find('(');
 if (pos_prem_p ==-1)  {resolvToken = TR("C_TokenInterpret::ResolvScriptTokenSyntax() Syntax Error first '(' not found in : ") + token; return 0;}
 int pos_last_p =  findLastDelimiter(token, ')');
 if (pos_last_p ==-1)  {resolvToken = TR("C_TokenInterpret::ResolvScriptTokenSyntax() Syntax Error last  ')' not found in : ")  + token; return 0;}
 int ret = exeFunction(token.left(pos_prem_p).stripWhiteSpace().upper(), token.mid(pos_prem_p + 1, pos_last_p-pos_prem_p - 1), resolvToken);
 //G_mCDC  = sav_pCDC;
 return ret;
}

//-------------------------- comparatorMacro -------------------------------------------
int C_TokenInterpret::comparatorMacro (const void *a, const void *b)
{//KEY_MACRO *pA =  (KEY_MACRO*)a;
 //KEY_MACRO *pB =  (KEY_MACRO*)b;
 //return strcmp(pA->m_Token, pB->m_Token);
 return strcmp(((KEY_MACRO*)a)->m_Token+1,((KEY_MACRO*)b)->m_Token+1);  // +1 car tri alphabérique déjà fait sur le premier caractère.
}


///////////////////////////// FONCTIONS CALL BACK /////////////////////////////////////////////
//-------------------------- APPEND_DOC_IN_CLASSEUR -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::APPEND_DOC_IN_CLASSEUR(QStringList &arg_list)
{ if (G_mCDC->m_isJustForWatch==CDevilCrucible::JustForWatch) return QString("");
  if (G_mCDC->m_pCRubCurrentRecord)
     {if (G_pCApp->m_pDrTux->m_pDock_Organiseur)
         {return G_pCApp->m_pDrTux->m_pC_Organiseur->Append_Doc_In_Hierarchie(G_mCDC->m_pCRubCurrentRecord, arg_list[0], arg_list[1].toInt());
         }
      }
  return QString("");
}

//-------------------------- BASE_THERAPEUTIQUE -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::BASE_THERAPEUTIQUE(QStringList &)
{  G_pCApp->m_pDrTux->LancerVidal(10);
   return QString("");
}

//-------------------------- CALC -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::CALC(QStringList &arg_list)
    {int nb = arg_list.count();
     QString ret = "";
     if (nb<4) //  completer la liste si < 5
        {int i;
         for( i=nb; i<=3; ++i) arg_list.append("");
        }
     CDevilCalc *pCalc = new CDevilCalc(G_mCDC);
     if (pCalc)
        {ret =  pCalc->Calc(arg_list[0], arg_list[1], arg_list[2]);
         delete pCalc;
        }
     return ret;
    }
//-------------------------- CADRE -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::CADRE(QStringList &arg_list)
{int deb_width       = -1;
 int end_width       = -1;
 int nb              = arg_list.count();
 if (nb<=6)           return QString::null;
 QString width       = arg_list[0].stripWhiteSpace();
 QString border      = arg_list[1].stripWhiteSpace();
 QString cellpadding = arg_list[2].stripWhiteSpace();
 QString cellspacing = arg_list[3].stripWhiteSpace();
 QString justif      = arg_list[4].stripWhiteSpace();
 QString rnTobr      = arg_list[5].stripWhiteSpace();
 //<p align="right">
 //...................................... definition du cadre global ..................................................
 QString ret =QString("</p><p align=\"") + justif + QString("\"><table border=%1 cellpadding=%2 cellspacing=%3 width=%4 >\r\n<tr>").arg(border,cellpadding,cellspacing,width);
 width = QString::number(width.toInt()/(nb-6));
 for (int i=6; i<nb; ++i)
     {QString cadreStr = arg_list[i].remove("\r").replace("\n",rnTobr);
      if ( (deb_width  = cadreStr.find("$WIDTH")) !=-1)
         {deb_width += 6;
          if ( (end_width  = cadreStr.find("$END_WIDTH",deb_width )) !=-1)
             {width        = cadreStr.mid(deb_width,end_width-deb_width).stripWhiteSpace();
              cadreStr     = cadreStr.remove(deb_width-6,end_width-deb_width+16);
             }
         }
      ret += QString("<td width=%1>\r\n").arg(width);
      ret += cadreStr;
      ret += "</td>";
     }
 ret += "</tr></table></p><p>";
 return ret;
}

//-------------------------- COPY_FILE -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::COPY_FILE(QStringList &arg_list)
    {if (G_mCDC->m_isJustForWatch==CDevilCrucible::JustForWatch) return QString("");

     QString ret = "";
     int      nb = arg_list.count();
     if (nb<1)          return TR("::copy_file() 1er  argument du nom du fichier source manquant");
     if (nb<2)          return TR("::copy_file() 2ème argument du nom de fichier ou répertoire de destination manquant");
     QString            action   = "";
     QString            imageSrc = arg_list[0].stripWhiteSpace().replace("$Glossaire",G_pCApp->m_PathGlossaire);
     QString            imageDst = arg_list[1].stripWhiteSpace().replace("$Glossaire",G_pCApp->m_PathGlossaire);
     QString            imgName  = QFileInfo(imageSrc).fileName();
     if (nb>=3)         imgName  = arg_list[2].stripWhiteSpace();
     if (nb>=4)         action   = arg_list[4].stripWhiteSpace();

     if ( !QFileInfo(imageDst).isDir ()) imgName = QFileInfo(imageDst).fileName();   // si le fichier de destination n'est pas un répertoire en extraire le nom du fichier de destination

     if ( QDir::isRelativePath ( imageSrc ) ) imageSrc  = QDir::cleanDirPath (imageSrc.prepend(G_pCApp->m_PathAppli) );
     if ( QDir::isRelativePath ( imageDst ) ) imageDst  = QDir::cleanDirPath (imageDst.prepend(G_pCApp->m_PathAppli) );

     CHtmlTools::Copy_File(imageSrc, QFileInfo(imageDst).dirPath(), &imgName);
     if (action.find("remove_src")!= -1) QDir().remove(imageSrc);
     return ret;
    }

//-------------------------- DO_LISTE -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::DO_LISTE(QStringList &arg_list)
    {QString ret("");
     QString sep;
     QString titre         = TR("Choisissez un item de la liste");
     int nbFieldsToDisplay = -1;
     int nb                = arg_list.count();
     if (nb<1) return TR("::Do_Liste() 1er  argument ( liste des items) manquant");
     if (nb>=2)            titre   = arg_list[1];
     if (nb>=3)              sep   = arg_list[2];
     else                    sep   = "|";
     if (nb>=5)  nbFieldsToDisplay = arg_list[4].stripWhiteSpace().toInt();
     // if (nb>=4)      nomVar  = arg_list[3];

     QStringList fieldList   = QStringList::split(sep,arg_list[0]);
     if (fieldList.count()<=0) return ret;
     Dlg_InsertList *dlg = new Dlg_InsertList(0, "InsertList", TRUE);
     if (dlg == 0)                  return TR("::Do_Liste() le dialogue n'a pas pu etre cree");
     dlg->setCaption(titre);
     dlg->initDialogField( fieldList, nbFieldsToDisplay);
     if (dlg->exec() != QDialog::Accepted)
        {if (nb>=4) G_mCDC->m_pVariables->insert (arg_list[3].stripWhiteSpace(),"Rejected");
         delete dlg;
         return ret;
        }
     if (nb>=4) G_mCDC->m_pVariables->insert (arg_list[3].stripWhiteSpace(),"Accepted");
     QListBoxItem *pQListBoxItem  = dlg->listBox_InsertList->selectedItem();

     if (pQListBoxItem)
        {int index  = dlg->listBox_InsertList->index( pQListBoxItem );
         //ret =  pQListBoxItem->text().replace("","::") ;
         ret =  fieldList[index];
        }
     delete dlg;
     return ret;
    }
//-------------------------- DAYSTO -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::DAYSTO(QStringList &arg_list)
    {int nb = arg_list.count();
     if (nb==0) return QString::null;
     if (nb==1) return CGenTools::daysTo(arg_list[0],"");
     else       return CGenTools::daysTo(arg_list[0], arg_list[1]);
    }

//-------------------------- DELETE_FILE -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::DELETE_FILE(QStringList &arg_list)
    {if (G_mCDC->m_isJustForWatch==CDevilCrucible::JustForWatch) return QString("");

     QString    ret = "";
     if (G_mCDC->m_isJustForWatch==CDevilCrucible::JustForWatch) return ret;
     QString action = "";
     int         nb = arg_list.count();
     if (nb<1)          return TR("::delete_file() 1er argument du nom du fichier source manquant");
     QString            path = arg_list[0].stripWhiteSpace();
     if (nb>1)        action = arg_list[1].stripWhiteSpace();
     if (QDir::isRelativePath ( path ) )  path = QDir::cleanDirPath ( path.prepend(G_pCApp->m_PathAppli) );
     if (action.length() && action.find("clear") != -1)
        {QFile qfile(path);
         if (qfile.open(IO_WriteOnly)==TRUE)
            {qfile.close();
            }
        }
     else
        {QDir().remove(RelPathToAbsPath(path));
        }
     return ret;
    }

//-------------------------- EXE_PROCESS -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::EXE_PROCESS(QStringList &arg_list)
    {//............. récupère les arguments passés à la fonction ................
     QString ret      = "";
     QString arg      = "";
     bool      addExe = TRUE;
     //QString debug = "";
     bool   isComm = FALSE;
     int        nb = arg_list.count();
     if (nb>=2) //  completer la liste si < 5
        {int i;
         QProcess proc(0,"CDevilCrucibleProcess");
         QString pathExe = arg_list[1].stripWhiteSpace();

         QString mode    = arg_list[0].stripWhiteSpace().lower();            // waitEnd ou pass
         if ( pathExe.find("$IsAbsPath") != -1 )
           {  pathExe  = pathExe.remove("$IsAbsPath").stripWhiteSpace();
              isComm   = TRUE;
           }
         else if ( QDir::isRelativePath ( pathExe ) )
           {  pathExe  = QDir::cleanDirPath (pathExe.prepend(G_pCApp->m_PathAppli) );
           }
         if ( pathExe.find("$IsBinPath") != -1 )
            {pathExe   = pathExe.remove("$IsBinPath").stripWhiteSpace();
            }
         if (pathExe.find("$NoAddExe") != -1)
            {addExe  = FALSE;
             pathExe = pathExe.remove("$NoAddExe");
            }
         #ifdef Q_WS_MAC
         else
            {if (addExe)   pathExe  +=  ".app/Contents/MacOS/" + QFileInfo(pathExe).baseName() ;                   // 0  Chemin de l'executable plugin à actionner
            }
         #else
             if (addExe)   pathExe  +=  F_EXT;                     // 0  Chemin de l'executable plugin à actionner
         #endif
         if ( isComm || QFile::exists(pathExe ) )
            {   proc.addArgument( pathExe );                   // 0  Chemin de l'executable plugin a actionner
                //debug  += pathExe + "\r\n";
                for( i=2; i<nb; ++i)
                   { arg         = arg_list[i];
                     proc.addArgument( RelPathToAbsPath(arg) );
                   }
                if ( G_PluginRun == "" && proc.start() )
                   { G_PluginRun = pathExe;
                     G_pCApp->processEvents ();
                     while (mode == "waitend" && proc.isRunning ())
                        {
                          #ifdef Q_WS_WIN
                            Sleep (1);
                          #endif
                          #ifdef Q_WS_X11
                            sleep (1);
                          #endif
                          #ifdef Q_WS_MAC
                          #endif

                          QTimer timer;               // pour etre sur qu'un evenement se produise
                          timer.start(100, FALSE);    // sinon boucle sans fin dans    processEvents ( QEventLoop::WaitForMore )
                          QApplication::eventLoop()->processEvents ( QEventLoop::WaitForMore );
                        }
                     G_PluginRun = "";
                    }  // endif ( proc.start() )
                else
                    {QMessageBox::warning ( 0, TR ("ERREUR : EXE_PROCESS") ,
                                                  TR("Le processus : \r\n%1\r\n n'a pas démarré. ").arg(pathExe),
                                                  TR ("&Annuler"), 0, 0,
                                                  1, 1 );
                    }
           } // endif (QFile::exists( pathExe ) )
        else
           {QMessageBox::warning ( 0, TR ("ERREUR : EXE_PROCESS") ,
                                                  TR("Le processus : \r\n%1\r\n n'a pas été trouvé. ").arg(pathExe),
                                                  TR ("&Annuler"), 0, 0,
                                                  1, 1 );
           }
       }   //endif (nb>=2)
    return ret;
   }
//-------------------------- EXTRACT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::EXTRACT(QStringList &arg_list)
    {int nb = arg_list.count();
     if (nb<5) //  completer la liste si < 5
        {int i;
         for( i=nb; i<=6; ++i) arg_list.append("");
        }
     return Func_Extract(arg_list[0], arg_list[1], arg_list[2], arg_list[3], arg_list[4],arg_list[5]);
    }
//-------------------------- EXTRACT_ATCD -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::EXTRACT_ATCD(QStringList &arg_list)
    {int nb = arg_list.count();
     if (nb<6) //  completer la liste si < 5
        {int i;
         for( i=nb; i<=6; ++i) arg_list.append("");
        }
     return Func_Extract_ATCD(arg_list[0], arg_list[1], arg_list[2], arg_list[3], arg_list[4], arg_list[5]);
    }

//-------------------------- EXTRACT_TABLE -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::EXTRACT_TABLE(QStringList &arg_list)
    {int nb = arg_list.count();
     if (nb<10) //  completer la liste si < 5
        {int i;
         for( i=nb; i<=10; ++i) arg_list.append("");
        }
     return Func_Extract_Table(arg_list[0], arg_list[1], arg_list[2], arg_list[3], arg_list[4],
                               arg_list[5], arg_list[6], arg_list[7], arg_list[8], arg_list[9]);
    }
//-------------------------- EXTRACT_TRAITEMENT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::EXTRACT_TRAITEMENT(QStringList &arg_list)
    {int nb = arg_list.count();
     if (nb<6) //  completer la liste si < 5
        {int i;
         for( i=nb; i<=6; ++i) arg_list.append("");
        }
     return Func_Extract_TTT(arg_list[0], arg_list[1], arg_list[2], arg_list[3], arg_list[4], arg_list[5]);
    }
//-------------------------- EXTRACT_VAR -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::EXTRACT_VAR(QStringList &arg_list)
    {int nb = arg_list.count();
     if (nb<5) //  completer la liste si < 5
        {int i;
         for( i=nb; i<=5; ++i) arg_list.append("");
        }
     return Func_Extract_VAR(arg_list[0], arg_list[1], arg_list[2], arg_list[3], arg_list[4]);
    }
//-------------------------- FILL -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::FILL(QStringList &arg_list)
    {//............. récupère les arguments passés à la fonction ................
     int        nb = arg_list.count();
     QString motif = " ";
     if (nb==0) return QString::null;
     if (nb==2) motif = arg_list[1].stripWhiteSpace();
     nb = arg_list[0].toInt();
     QString ret = "";
     motif       = motif.replace("spc"," ");
     for (int i=0; i<nb; ++i)
         {ret += motif;
         }
     return ret;
    }
//-------------------------- FORM_DATE_HEURE -------------------------------------------
QString C_TokenInterpret::FORM_DATE_HEURE (QStringList &arg_list)
{       int      nb = arg_list.count();
        QString ret = "";

        QString    txt_date  = QDate::currentDate().toString("dd-MM-yyyy");
        if (nb>=1) txt_date  = arg_list[0].stripWhiteSpace();
        QString    txt_heure = QTime::currentTime().toString("hh-mm-ss");
        if (nb>=2) txt_heure = arg_list[1].stripWhiteSpace();
        QString    titre     = TR("Choix dans la date et heure");
        if (nb>=3) titre     = arg_list[2].stripWhiteSpace();
        QString    formatD   = "dd-MM-yyyy";
        if (nb>=4) formatD   = arg_list[3].stripWhiteSpace();
        QString    formatH   = "hh:mm:ss";
        if (nb>=5) formatH   = arg_list[4].stripWhiteSpace();
        QString    sepDH     = " ";
        if (nb>=6) sepDH     = arg_list[5];

        Dlg_Calendar          *dlg  = new Dlg_Calendar(0, "Calendar_Dial", FALSE);
        if (dlg ==0)                                                   return ret;
        dlg->move(QCursor::pos());
        dlg->setCaption(titre);

        if ( ! dlg->setDateTimeNatural_jjMMyyyy_Order(txt_date+txt_heure ))
           {dlg->setDate  (QDate::currentDate());
            dlg->setHeure (QTime::currentTime());
           }
        if (dlg->exec()== QDialog::Accepted )
           {ret = dlg->getDate().toString(formatD) + sepDH + dlg->timeEdit_Heure->time ().toString(formatH);
           }
        delete dlg;
        return ret;
}
//-------------------------- FORM_DATE -------------------------------------------
QString C_TokenInterpret::FORM_DATE (QStringList &arg_list)
{       int        nb = arg_list.count();
        QString   ret = "";
        int isInvalid = 0;
        QString    txt_date = QDate::currentDate().toString("dd-MM-yyyy");
        if (nb>=1) txt_date = arg_list[0].stripWhiteSpace();
        QString    titre    = TR("Choix dans la date");
        if (nb>=2) titre    = arg_list[1].stripWhiteSpace();
        QString    format   = "dd-MM-yyyy";
        if (nb>=3) format   = arg_list[2].stripWhiteSpace();

        Dlg_Calendar          *dlg  = new Dlg_Calendar(0, "Calendar_Dial", FALSE);
        if (dlg ==0)                                                   return ret;
        dlg->move(QCursor::pos());
        dlg->setCaption(titre);
        dlg->setDate  (CGenTools::setDate(txt_date , isInvalid));
        if (dlg->exec()== QDialog::Accepted )
           {ret = dlg->getDate().toString(format);
           }
        delete dlg;
        return ret;
}
//-------------------------- FORM_HEURE -------------------------------------------
QString C_TokenInterpret::FORM_HEURE (QStringList &arg_list)
{    QString        ret = "";
     int             nb = arg_list.count();
     C_Dlg_Pendule* dlg = new C_Dlg_Pendule(0);
     if (dlg==0)                  return ret;
     dlg->move(QCursor::pos());
     dlg->setCaption(TR("Heure"));
     QString    txt_heure = QTime::currentTime().toString("hh:mm:ss");
     if (nb>=1) txt_heure = arg_list[0].stripWhiteSpace();
     QString    formatH   = "hh:mm:ss";
     if (nb>=2) formatH   = arg_list[1].stripWhiteSpace();

     QTime time  = hhmmssToQTime(txt_heure );    if ( !time.isValid () || txt_heure.length()==0) { time = QTime::currentTime(); }
     dlg->setTime(time);
     if (dlg->exec() == QDialog::Accepted)
        { ret =  dlg->getTime().toString(formatH);
        }
     delete dlg;
     return ret;
}
//---------------------------------------- hhmmssToQTime ---------------------------------------
QTime C_TokenInterpret::hhmmssToQTime(const QString & heure )
{ int h=0; int m=0; int s=0; int ms=0; int len = heure.length();
  QString str = C_TokenInterpret::toNum(heure);
  len         = str.length();
  if (len>=2) h  = str.mid(0,2).toInt();  // hh
  if (len>=4) m  = str.mid(2,2).toInt();  // hhmm
  if (len>=6) s  = str.mid(4,2).toInt();  // hhmmss
  if (len>=9) ms = str.mid(6).toInt();    // hhmmss
  return QTime( h,  m,  s,  ms );
}

//-------------------------- FORM_PDF -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::FORM_PDF(QStringList &arg_list)
    {//............. récupère les arguments passés à la fonction ................
     if (G_mCDC->m_pCRubCurrentRecord) G_mCDC->m_pCRubCurrentRecord->m_LastErr = "__ERREUR Fusion :__";
     if (G_mCDC->m_isJustForWatch==CDevilCrucible::JustForWatch) return QString("");
     int      nb = arg_list.count();
     QString ret = "";
     if (nb<3) //  completer la liste si < 5
        {int i;
         for( i=nb; i<=2; ++i) arg_list.append("");
        }
     CDevilFormPDF *pPDF = new CDevilFormPDF (G_mCDC);
     if (ret!=0)
        {ret = pPDF->Form_PDF(arg_list[0]);
         delete pPDF;
        }
     return QString("");
}
// -------------------- GET_DOC_DATE_FIN -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::GET_DOC_DATE_FIN(QStringList &)
    {if (G_mCDC->m_pCRubCurrentRecord)
        {return G_mCDC->m_pCRubCurrentRecord->m_Fin;
        }
     return QString("");
    }
//-------------------------- GET_DOC_PROP_0 -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::GET_DOC_PROP_0(QStringList &)
    {if (G_mCDC->m_pCRubCurrentRecord)
        {return G_mCDC->m_pCRubCurrentRecord->m_Prop_0;
        }
     return QString("");
    }
//-------------------------- GET_DOC_PROP_1 -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::GET_DOC_PROP_1(QStringList &)
    {if (G_mCDC->m_pCRubCurrentRecord)
        {return G_mCDC->m_pCRubCurrentRecord->m_Prop_1;
        }
     return QString("");
    }
//-------------------------- GET_DOC_PROP_2 -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::GET_DOC_PROP_2(QStringList &)
    {if (G_mCDC->m_pCRubCurrentRecord)
        {return G_mCDC->m_pCRubCurrentRecord->m_Prop_2;
        }
     return QString("");
    }
//-------------------------- GET_DOC_PROP_3 -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::GET_DOC_PROP_3(QStringList &)
    {if (G_mCDC->m_pCRubCurrentRecord)
        {return G_mCDC->m_pCRubCurrentRecord->m_Prop_3;
        }
     return QString("");
    }
//-------------------------- GET_DOC_PROP_4 -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::GET_DOC_PROP_4(QStringList &)
    {if (G_mCDC->m_pCRubCurrentRecord)
        {return G_mCDC->m_pCRubCurrentRecord->m_Prop_4;
        }
     return QString("");
    }
//-------------------------- GET_SELECTION -------------------------------------------
 /*! \brief retourne le texte en cours de selection */
QString C_TokenInterpret::GET_SELECTION(QStringList &)
{    MyEditText      *pMyEditText   = 0; //G_pCApp->m_pDrTux->currentEditor();
     CMDI_Generic  *pCMDI_Generic   = G_pCApp->GetCurrentRubrique();
     if (pCMDI_Generic) pMyEditText = pCMDI_Generic->GetCurrentEditor();
     if (pMyEditText==0) return QString::null;
     return pMyEditText->selectedText();
}
//-------------------------- GRAPH -------------------------------------------
QString C_TokenInterpret::GRAPH(QStringList &arg_list)
    {//............. récupère les arguments passés à la fonction ................
     int nb = arg_list.count();
     if (nb<3) //  completer la liste si < 5
        {int i;
         for( i=nb; i<=2; ++i) arg_list.append("");
        }
     CDevilGraph *pGraph = new CDevilGraph ( G_mCDC );
     if (pGraph)
        {pGraph->Graph(arg_list[0]);
         delete pGraph;
        }
     return QString(" ");
    }
//-------------------------- INCLUDE -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::INCLUDE(QStringList &arg_list)
    {QString path;
     return INCLUDE(arg_list, path);
    }
//-------------------------- INCLUDE -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::INCLUDE(QStringList &arg_list, QString &path)
    {int                       nb = arg_list.count();  if (nb<1) return TR("::INCLUDE() 1er argument du fichier à importer manquant");
     QString                  ret = "";
     QString         typeAction   = "";
     QString            pathFile  = arg_list[0].stripWhiteSpace().replace("$Glossaire",G_pCApp->m_PathGlossaire);
                        pathFile  = pathFile.replace("$Vigie", G_pCApp->m_PathGlossaire + "Vigie");
     pathFile.replace("//","/");
     if ( QDir::isRelativePath ( pathFile ) ) pathFile  = QDir::cleanDirPath ( pathFile.prepend(G_pCApp->m_PathAppli) );
     if ( QFileInfo(pathFile).isDir ())                          return ret;
     path = pathFile;
     if (nb>1)         typeAction = arg_list[1].stripWhiteSpace();
     CGestIni::Param_UpdateFromDisk(pathFile, ret);
     if (typeAction.find("crlf2html")!=-1) {ret = ret.replace("\r\n", "<br>"); ret = ret.replace("\n", "<br>");ret = ret.replace("\r", "<br>");}
     return ret;
    }
//-------------------------- IMPORT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::IMPORT(QStringList &arg_list)
    {if (G_mCDC->m_isJustForWatch==CDevilCrucible::JustForWatch) return QString("");
     int                       nb = arg_list.count();  if (nb<1) return TR("::import() 1er argument du fichier à importer manquant");
     QString                 ret  = "";
     MyEditText     *pMyEditText  = 0; //G_pCApp->m_pDrTux->currentEditor();
     CMDI_Generic  *pCMDI_Generic = 0;
     QString        rubriqueCible = "";
     if (nb>2)      rubriqueCible = arg_list[2].stripWhiteSpace();

     if (rubriqueCible.length()==0)
        {pCMDI_Generic = G_pCApp->GetCurrentRubrique();
         if (pCMDI_Generic)    pMyEditText = pCMDI_Generic->GetCurrentEditor();
         if (pMyEditText==0) rubriqueCible = CMDI_Documents::S_GetRubName();         // si pas d'éditeur dans la rubrique courante ou pas de rubrique courante
         else                rubriqueCible = pCMDI_Generic->m_RubName;
        }
     if (pMyEditText==0)
        {pCMDI_Generic = (CMDI_Generic*) G_pCApp->m_pDrTux->IsExistRubrique(rubriqueCible);
         if (pCMDI_Generic==0) G_pCApp->m_pDrTux->OnActiverOrCreateRubrique(rubriqueCible);
         pCMDI_Generic = (CMDI_Generic*) G_pCApp->m_pDrTux->IsExistRubrique(rubriqueCible);
         if (pCMDI_Generic==0) return TR("::import() la rubrique de destination: \"") + rubriqueCible + TR("\" n'a pu être créé");
         pMyEditText = pCMDI_Generic->GetCurrentEditor();
        }

     if (pMyEditText)
        {QString            destPath  = "";
         QString            imageFile = arg_list[0].stripWhiteSpace().replace("$Glossaire",G_pCApp->m_PathGlossaire);
         QString         typeAction   = "new";
         if (nb>1)         typeAction = arg_list[1].stripWhiteSpace();
         if (nb>3)           destPath = arg_list[3].stripWhiteSpace().replace("$Glossaire",G_pCApp->m_PathGlossaire);
         bool                 verbose = (typeAction.find("verbose")!=-1);
         imageFile.replace("//","/");destPath.replace("//","/");
         if ( QDir::isRelativePath ( imageFile ) ) imageFile  = QDir::cleanDirPath ( imageFile.prepend(G_pCApp->m_PathAppli) );
         if ( QFileInfo(imageFile).isDir ())                                                 return ret;
         if ( ! QFile::exists( imageFile ) && typeAction.find("remove_src")== -1)            return verbose ? TR("::import() Fichier image : \"") + imageFile + TR("\" non trouvé") : "";
         QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) );
         if (QFileInfo(imageFile).size() <= 0)      {QApplication::restoreOverrideCursor();  return verbose ? TR("::import() Fichier image : \"") + imageFile + TR("\" vide") : "";  }              // si fichier vide on sort
         if (typeAction.length()==0) typeAction = "new";

         //.................. insertion html ............................................................
         QString toImport;
         CGestIni::Param_UpdateFromDisk(imageFile, toImport);
         if (typeAction.find("crlf2html")!=-1) {toImport = toImport.replace("\r\n", "<br>"); toImport = toImport.replace("\n", "<br>");toImport = toImport.replace("\r", "<br>");}
         if (destPath.length())
            {if ( QDir::isRelativePath ( destPath ) ) destPath  = QDir::cleanDirPath ( destPath.prepend(G_pCApp->m_PathAppli) );
             if ( !QFileInfo(destPath).exists() )
                {if (!QDir().mkdir ( destPath ) )
                    {QApplication::restoreOverrideCursor();
                     return verbose ? TR("::import() le répertoire de destination: \"") + destPath + TR("\" n'a pu être créé") : "";
                    }
                }
             CHtmlTools::Copy_File(imageFile, destPath);
             if (typeAction.find("clear_src") != -1)
                {QFile qfile(imageFile);
                 if (qfile.open(IO_WriteOnly)==TRUE)
                    {qfile.close();
                    }
                }
            }
         if (typeAction.find("remove_src")!= -1)
            {QDir().remove(imageFile);
            }
         if ( typeAction.find("insert") != -1)                 // si reference est la première creer l'icone de l'image
            {if (typeAction.find("no_html") != -1)  CHtmlTools::insertHtml(pMyEditText, toImport,1);        // html remove
             else                                   CHtmlTools::insertHtml(pMyEditText, toImport,0);        // keep html
            }
         else  if ( typeAction.find("replace") != -1)
            {pMyEditText->setText(toImport);
            }
         else  if ( typeAction.find("new") != -1)
            {pCMDI_Generic->AddNewDocument(toImport,  pCMDI_Generic->GetType(), imageFile,0,0,0, (typeAction.find("noInquire") != -1));
            }

         QApplication::restoreOverrideCursor();
        }
     return ret;
    }

//-------------------------- INSERT_IMAGE -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::INSERT_IMAGE(QStringList &arg_list)
    {if (G_mCDC->m_isJustForWatch==CDevilCrucible::JustForWatch) return QString("");
     QString ret = "";
     int      nb = arg_list.count();
     if (nb<1)                                        return TR("::insert_image() 1er argument du fichier image manquant");
     MyEditText *pMyEditText  = G_pCApp->m_pDrTux->currentEditor();
     if (pMyEditText)
        {QString            imageFile = arg_list[0].stripWhiteSpace();
         int                    max_w = 500;
         int                    max_h = -1;
         QString       renameAction   = 0;
         QString       destPath       = 0;
         if (nb>=2)             max_w = arg_list[1].toInt();
         if (nb>=3)             max_h = arg_list[2].toInt();
         if (nb>=4)      renameAction = arg_list[3].stripWhiteSpace();
         if (nb>=5)          destPath = arg_list[4].stripWhiteSpace();

         if ( QDir::isRelativePath ( imageFile ) ) imageFile  = QDir::cleanDirPath ( imageFile.prepend(G_pCApp->m_PathAppli) );
         if ( QFileInfo(imageFile).isDir ())                                                 return ret;
         if ( ! QFile::exists( imageFile ) && renameAction.find("remove_src")== -1)          return TR("::insert_image() Fichier image : \"") + imageFile + TR("\" non trouvé");
         QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) );
         if (QFileInfo(imageFile).size() <= 10)      {QApplication::restoreOverrideCursor(); return ret; }                // si fichier vide on sort
         QPixmap      img(imageFile);     // format image deviné car 'const char * format = 0'
         if ( img.isNull())                          {QApplication::restoreOverrideCursor(); return TR("::insert_image() l'image : \"") + imageFile + TR("\" n'a pu être créée");}
         //............... mise à l'echelle de l'image .....................................
         int w             = img.width ();
         int h             = img.height();
         float coefReduc_w = 1.00;
         float coefReduc_h = 1.00;
         if (max_h != -1 && w > max_w) coefReduc_w = (float)max_w / (float) w;
         if (max_h != -1 && h > max_h) coefReduc_h = (float)max_h / (float) h;
         if (coefReduc_w < 1.00 || coefReduc_h < 1.00)
            {if (coefReduc_h < coefReduc_w) coefReduc_w = coefReduc_h;         // on va se servir de coefReduc_w = au coeff de réduction le plus petit
             w = (int) ((float) w * coefReduc_w);
             h = (int) ((float) h * coefReduc_w);
             QImage   qi    = img.convertToImage().smoothScale (w, h );
             img            = QPixmap (qi );
            }
         //.................. insertion html ............................................................
         QString    imgName    = CMoteurBase::GUID_Create()+"-h"+ QString::number(h)+"w"+QString::number(w) + ".png";                  // nom et clef pour retrouver l'image
         if (renameAction.length())
            {if ( QDir::isRelativePath ( destPath ) ) destPath  = QDir::cleanDirPath ( destPath.prepend(G_pCApp->m_PathAppli) );
             if ( !QFileInfo(destPath).exists() )
                {if (!QDir().mkdir ( destPath ) )
                    {QApplication::restoreOverrideCursor();
                     return TR("::insert_image() le répertoire de destination: \"") + destPath + TR("\" n'a pu être créé");
                    }
                }
             CHtmlTools::Copy_File(imageFile, destPath, &imgName);
             if (renameAction.find("clear_src") != -1)
                {QFile qfile(imageFile);
                 if (qfile.open(IO_WriteOnly)==TRUE)
                    {qfile.close();
                    }
                }
             if (renameAction.find("remove_src")!= -1)
                {QDir().remove(imageFile);
                }
             imageFile = destPath + "/" + imgName;
            }
         if ( G_pCApp->m_C_ImageList.appendToList( &img , imgName, imageFile) == 1 )                 // si reference est la première creer l'icone de l'image
            {ret  = "<img src=\"";
             ret += imgName;
             ret += "\" width=\""  + QString::number(w);
             ret += "\" height=\"" + QString::number(h);
             ret += "\">";
            }
         QApplication::restoreOverrideCursor();
        }
     return ret;
    }
//-------------------------- INTITULE -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::INTITULE(QStringList &arg_list)
    {if (G_mCDC->m_isJustForWatch==CDevilCrucible::JustForWatch) return QString("");
     if (G_mCDC->m_pCRubCurrentRecord)
        {// Cette fonction ajoute ou remplace l'intitulé de l'observation en cours
         // UTILISATION =
         //  {{:: Intitule ( Intitulé du document , add  ) }}
         //  {{:: Intitule ( Intitulé du document , change  ) }}
         //  {{:: Intitule ( Intitulé du document ) (équivalent de "change") }}
         //............. récupère les arguments passés à la fonction ................
         QString libelle = arg_list[0].replace("&nbsp;"," ").stripWhiteSpace();
         int nb = arg_list.count();
         if (nb<6) //  completer la liste si < 5
            {int i;
             for( i=nb; i<=2; ++i) arg_list.append("");
            }

 //        arg_list[0] = arg_list[0];
         arg_list[1] = arg_list[1].stripWhiteSpace();
         // ......... modifie l'intutilé de l'observation
         if      (arg_list[1].lower() == "add")       {G_mCDC->m_pCRubCurrentRecord->m_Libelle.append(" " + libelle );}
         else /* if (arg_list[1].lower() == "change")  {G_mCDC->m_pCRubCurrentRecord->m_Libelle = libelle; }
         else if (arg_list[1].lower() == "") */       {G_mCDC->m_pCRubCurrentRecord->m_Libelle = libelle; }
         //.......... recharger le combo ..................................................................
         QString qstr = G_mCDC->m_pCRubCurrentRecord->m_Date.left(10) + " " + G_mCDC->m_pCRubCurrentRecord->m_Libelle;
         CMDI_Generic *pCMDI_Generic =  G_pCApp->GetCurrentRubrique();
         if (pCMDI_Generic) pCMDI_Generic->ChangeCurrentComboBoxItemName(qstr);
        }
     return QString("");
    }
//-------------------------- LIST_DIR -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::LIST_DIR(QStringList &arg_list)
{   QString        ret       = "";
    QString  start_dir       = "";
    QString  sep             = "|";
    QStringList filterList;
    QStringList extList;
    int nb = arg_list.count();
    if (nb>=4)  sep        = arg_list[3];
    if (nb>=1) {start_dir  = arg_list[0]; start_dir = RelPathToAbsPath(start_dir); start_dir= start_dir.replace("$Glossaire",G_pCApp->m_PathGlossaire);}
    if (nb>=2)  filterList = QStringList::split ( sep, arg_list[1]);
    if (nb>=3)  extList    = QStringList::split ( sep, arg_list[2]);

    //................ allons y  .....................................................
    QDir l_dir;
    l_dir.setPath ( start_dir );
    l_dir.convertToAbs();
    l_dir.setFilter( QDir::All | QDir::NoSymLinks );
    //............ exploration de la liste ......................
    const QFileInfoList * pQFileInfoList = l_dir.entryInfoList();
    if (pQFileInfoList==0) return 0;
    QFileInfoListIterator it( *pQFileInfoList );
    QFileInfo     *fi;

    while ( (fi = it.current()) != 0 )
          {QString fname = fi->fileName();
           QString ext   = QFileInfo(fname).extension().lower();
           QStringList::Iterator ut;
           if      (fname == "..")
                   {
                   }
           else if (fi->isDir() && fname[0] != '.' )
                   {
                   }
           else if (fi->isFile() && fname[0] != '.')
                   {bool ok = TRUE;

                    if (extList.count())
                       {ok = FALSE;
                        ut = extList.find(ext);
                        if (ut !=  extList.end()) ok = TRUE;
                       }
                    if (ok && filterList.count())
                       {ok = FALSE;
                        for ( ut = filterList.begin(); ut != filterList.end() && ok==FALSE; ++ut )
                            {if (fname.find(*ut) != -1) ok = TRUE;
                            }
                       }
                    if (ok) ret += fname+sep;
                   }
           ++it;
          }
  return ret;
}

//-------------------------- LOWER -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::LOWER(QStringList &arg_list)
    {int nb = arg_list.count();
     if (nb<1) return QString::null;
     return arg_list[0].lower();
    }

//-------------------------- NOP -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::NOP(QStringList &)
{ return "";
}

//-------------------------- MESSAGE_ALERT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::MESSAGE_ALERT(QStringList &arg_list)
{int          nb     = arg_list.count();
 QString   title     = TR("Informaton");
 QString message     = "";
 int           w     = -1;
 int           h     = -1;
 QString imagePath   = "";
 //QString s_ok        = "Ok";
 char*   button1     = (char*) (const char*) "Ok" ;
 char*   button2     = 0 ;
 char*   button3     = 0 ;
 char*   button4     = 0 ;
 if (nb>=1) message    = arg_list[0];
 if (nb>=2) title      = arg_list[1];
 if (nb>=3) button1    = (char*) (const char*)arg_list[2];
 if (nb>=4) button2    = (char*) (const char*)arg_list[3];
 if (nb>=5) button3    = (char*) (const char*)arg_list[4];
 if (nb>=6) button4    = (char*) (const char*)arg_list[5];
 if (nb>=7) w          = arg_list[6].toInt();
 if (nb>=8) h          = arg_list[7].toInt();
 if (nb>=9) {imagePath = arg_list[8].stripWhiteSpace().replace("$Glossaire",G_pCApp->m_PathGlossaire);
             imagePath = imagePath.replace("$Vigie", G_pCApp->m_PathGlossaire + "Vigie");
             imagePath.replace("//","/");
             if ( QDir::isRelativePath ( imagePath ) ) imagePath  = QDir::cleanDirPath ( imagePath.prepend(G_pCApp->m_PathAppli) );
            }
if (message.left(5)=="$File")
   {message=message.mid(5);
    QStringList lst;
    lst.append(message);
    QString finalPath;
    message = INCLUDE(lst, finalPath);
    if (imagePath.length()==0)
       {imagePath = QFileInfo(finalPath).dirPath();
       }
   }
 switch(CGenTools::MessageAlert(0, title,  message,  button1,  button2, button3, button4, w, h, imagePath))
    {case 100: return arg_list[2];
     case 200: return arg_list[3];
     case 300: return arg_list[4];
     case 400: return arg_list[5];
    }
 return QString::null;
}


//-------------------------- MESSAGE_POPUP -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::MESSAGE_POPUP(QStringList &arg_list)
{int          nb     = arg_list.count();
 QString message     = "";
 int     tempo       = 1000 ;
 QString imagePath   = Theme::getPath(TRUE)+"MessagePop.png";/* ="" */
 if (nb>=1) message    = arg_list[0];
 if (nb>=2) imagePath  = arg_list[1];
 if (nb>=3) tempo      = arg_list[2].toInt();
 G_pCApp->CouCou(message, imagePath, tempo );
 return QString::null;
}

//-------------------------- NOUVEAU_DOCUMENT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::NOUVEAU_DOCUMENT(QStringList &arg_list)
    {if (G_mCDC->m_isJustForWatch==CDevilCrucible::JustForWatch) return QString("");
     int nb = arg_list.count();
     if (nb<4) //  completer la liste si < 5
        {int i;
         for( i=nb; i<=3; ++i) arg_list.append("");
        }
     MyEditText     *pMyEditText  = 0; //G_pCApp->m_pDrTux->currentEditor();
     CMDI_Generic  *pCMDI_Generic = 0;
     QString        rubriqueCible = "";
     if (nb>=1)     rubriqueCible = arg_list[0].stripWhiteSpace();

     if (rubriqueCible.length()==0)
        {pCMDI_Generic = G_pCApp->GetCurrentRubrique();
         if (pCMDI_Generic)    pMyEditText = pCMDI_Generic->GetCurrentEditor();
         if (pMyEditText==0) rubriqueCible = CMDI_Documents::S_GetRubName();         // si pas d'éditeur dans la rubrique courante ou pas de rubrique courante
         else                rubriqueCible = pCMDI_Generic->m_RubName;
        }
     if (pMyEditText==0)
        {//pCMDI_Generic = (CMDI_Generic*) G_pCApp->m_pDrTux->IsExistRubrique(rubriqueCible);
         if (pCMDI_Generic==0) G_pCApp->m_pDrTux->OnActiverOrCreateRubrique(rubriqueCible);
         pCMDI_Generic = (CMDI_Generic*) G_pCApp->m_pDrTux->IsExistRubrique(rubriqueCible);
         if (pCMDI_Generic==0) return TR("::nouveau document() la rubrique de destination: \"") + rubriqueCible + TR("\" n'a pu être créé");
         pMyEditText = pCMDI_Generic->GetCurrentEditor();
        }

     if (pCMDI_Generic!=0) pCMDI_Generic->AddNewDocument(" ",  pCMDI_Generic->GetType() );
     return "";
    }
//-------------------------- OS -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::OS(QStringList &)
     {
       #ifdef Q_WS_WIN
            return QString("W");
       #endif
       #ifdef Q_WS_X11
            return QString("L");
       #endif
       #ifdef Q_WS_MAC
            return QString("M");
       #endif
     }

//-------------------------- PUT_VAR -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::PUT_VAR(QStringList &arg_list)
     {if (arg_list.count()<1) return TR("::PUT_VAR() nom de la vaiable non indiqué");
      return (*G_mCDC->m_pVariables)[arg_list[0].stripWhiteSpace()];
     }

//-------------------------- REINIT_CLASSEUR -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::REINIT_CLASSEUR(QStringList &)
    {if (G_mCDC->m_isJustForWatch==CDevilCrucible::JustForWatch) return QString("");
     if (G_pCApp->m_pDrTux->m_pDock_Organiseur)
        {G_pCApp->m_pDrTux->m_pC_Organiseur->makeListeMonitor();
        }
     return QString("");
    }
//-------------------------- REPLACE_IMAGE -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::REPLACE_IMAGE(QStringList &arg_list)
    {if (G_mCDC->m_isJustForWatch==CDevilCrucible::JustForWatch) return QString("");
     QString ret = "";
     int      nb = arg_list.count();
     if (nb<1)                                        return TR("::replace_image() argument du nom de l'image à remplacer manquant");        //{{GET LAST IMAGE NAME}}
     if (nb<2)                                        return TR("::replace_image() argument du fichier image de remplacement manquant");     //$ToAbsPath ../../tmp/{{GET LAST IMAGE NAME}}
     MyEditText *pMyEditText  = G_pCApp->m_pDrTux->currentEditor();
     if (pMyEditText)
        {QString            imageName = arg_list[0].stripWhiteSpace();         // nom de l'image à replacer
         QString            imageFile = arg_list[1].stripWhiteSpace();         // nom de du fichier image de remplacement
         int                    max_w = 550;
         int                    max_h = -1;
         QString             action   = 0;
         QString             srcName  = 0;
         if (nb>=2)             max_w = arg_list[2].toInt();
         if (nb>=3)             max_h = arg_list[3].toInt();
         if (nb>=4)            action = arg_list[4].stripWhiteSpace();
         QPixmap                  img;
         //................ recuperer dimenssions originales ...........................
         G_pCApp->m_C_ImageList.getPixmap(imageName, img);
         int ori_w                    = img.width ();
         int ori_h                    = img.height();

         if ( QDir::isRelativePath ( imageFile ) ) imageFile  = QDir::cleanDirPath ( imageFile.prepend(G_pCApp->m_PathAppli) );
         if ( QFileInfo(imageFile).isDir ())                                                 return ret;
         if ( ! QFile::exists( imageFile ) )                                                 return TR("::replace_image() Fichier image : \"") + imageFile + TR("\" non trouvé");
         QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) );
         if (QFileInfo(imageFile).size() <= 10)      {QApplication::restoreOverrideCursor(); return TR("::replace_image() Fichier image : \"") + imageFile + TR("\" vide"); }                // si fichier vide on sort
         img = QPixmap(imageFile);     // format image deviné car 'const char * format = 0'
         if ( img.isNull())                         {QApplication::restoreOverrideCursor();  return TR("::replace_image() l'image : \"")       + imageFile + TR("\" n'a pu être créée");}
         //............... mise à l'echelle de l'image .....................................
         if (action.find("keep_Original_W")!= -1 && ori_w>0) max_w = ori_w;
         if (action.find("keep_Original_H")!= -1 && ori_h>0) max_h = ori_h;
         int w             = img.width ();
         int h             = img.height();
         float coefReduc_w = 1.00;
         float coefReduc_h = 1.00;
         if (max_w != -1 && w > max_w) coefReduc_w = (float)max_w / (float) w;
         if (max_h != -1 && h > max_h) coefReduc_h = (float)max_h / (float) h;
         if (coefReduc_w < 1.00 || coefReduc_h < 1.00)
            {if (coefReduc_h < coefReduc_w) coefReduc_w = coefReduc_h;         // on va se servir de coefReduc_w = au coeff de réduction le plus petit
             w = (int) ((float) w * coefReduc_w);
             h = (int) ((float) h * coefReduc_w);
             QImage   qi    = img.convertToImage().smoothScale (w, h );
             img            = QPixmap (qi );
            }
         //...................... remplacer l'image d'origine de la liste des images ..............................................
         if (action.find("keep_src")!= -1)          srcName   = G_pCApp->m_C_ImageList.getSrcImageName(imageName);
         else                                       srcName   = imageFile;
         G_pCApp->m_C_ImageList.destroyFromList(imageName);                             // détruire dans la liste  tout ce qui concerne ce nom
         if ( G_pCApp->m_C_ImageList.appendToList( &img , imageName, srcName) == 1 )    // rajouter une l'image
            {QString t = pMyEditText->text (  );     // methode bourin pour forcer le redraw
             CHtmlTools::ReplaceImageTag(t, imageName, imageName,  w ,  h );
             pMyEditText->setText ( t );
             if (action.find("remove_src")!= -1)
                {QDir().remove(imageFile);
                }
            }
         QApplication::restoreOverrideCursor();
        }
     return ret;
    }
//-------------------------- SET_DOC_DATE_FIN -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::SET_DOC_DATE_FIN(QStringList &arg_list)
    {if (G_mCDC->m_isJustForWatch==CDevilCrucible::JustForWatch) return QString("");
     if (G_mCDC->m_pCRubCurrentRecord)
        {if (arg_list.count()>0) G_mCDC->m_pCRubCurrentRecord->m_Fin = arg_list[0];
        }
     return QString("");
    }
//-------------------------- SET_DOC_PROP_0 -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::SET_DOC_PROP_0(QStringList &arg_list)
    {if (G_mCDC->m_isJustForWatch==CDevilCrucible::JustForWatch) return QString("");
     if (G_mCDC->m_pCRubCurrentRecord)
        {if (arg_list.count()>0) G_mCDC->m_pCRubCurrentRecord->m_Prop_0 = arg_list[0];
         else                    G_mCDC->m_pCRubCurrentRecord->m_Prop_0 = "";
        }
     return QString("");
    }
//-------------------------- SET_DOC_PROP_1 -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::SET_DOC_PROP_1(QStringList &arg_list)
    {if (G_mCDC->m_isJustForWatch==CDevilCrucible::JustForWatch) return QString("");
     if (G_mCDC->m_pCRubCurrentRecord)
        {if (arg_list.count()>0) G_mCDC->m_pCRubCurrentRecord->m_Prop_1 = arg_list[0];
         else                    G_mCDC->m_pCRubCurrentRecord->m_Prop_1 = "";
        }
     return QString("");
    }
//-------------------------- SET_DOC_PROP_2 -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::SET_DOC_PROP_2(QStringList &arg_list)
    {if (G_mCDC->m_isJustForWatch==CDevilCrucible::JustForWatch) return QString("");
     if (G_mCDC->m_pCRubCurrentRecord)
        {if (arg_list.count()>0) G_mCDC->m_pCRubCurrentRecord->m_Prop_2 = arg_list[0];
         else                    G_mCDC->m_pCRubCurrentRecord->m_Prop_2 = "";
        }
     return QString("");
    }
//-------------------------- SET_DOC_PROP_3 -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::SET_DOC_PROP_3(QStringList &arg_list)
    {if (G_mCDC->m_isJustForWatch==CDevilCrucible::JustForWatch) return QString("");
     if (G_mCDC->m_pCRubCurrentRecord)
        {if (arg_list.count()>0) G_mCDC->m_pCRubCurrentRecord->m_Prop_3 = arg_list[0];
         else                    G_mCDC->m_pCRubCurrentRecord->m_Prop_3 = "";
        }
     return QString("");
    }
//-------------------------- SET_DOC_PROP_4 -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::SET_DOC_PROP_4(QStringList &arg_list)
    {if (G_mCDC->m_isJustForWatch==CDevilCrucible::JustForWatch) return QString("");
     if (G_mCDC->m_pCRubCurrentRecord)
        {if (arg_list.count()>0) G_mCDC->m_pCRubCurrentRecord->m_Prop_4 = arg_list[0];
         else                    G_mCDC->m_pCRubCurrentRecord->m_Prop_4 = "";
        }
     return QString("");
    }
//-------------------------- SET_VAR -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::SET_VAR(QStringList &arg_list)
    {int nb = arg_list.count();
     if (nb==0)  return QString::null;
     if (nb==1)  arg_list.append("");
     QString val = arg_list[1].stripWhiteSpace();
     G_mCDC->m_pVariables->insert (arg_list[0].stripWhiteSpace(),arg_list[1].stripWhiteSpace());
     return QString("");
    }
//-------------------------- VAR_LIST_CLEAR -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::VAR_LIST_CLEAR(QStringList &)
    {G_mCDC->m_pVariables->clear();
     return QString("");
    }
//-------------------------- VAR_SPLIT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::VAR_SPLIT(QStringList &arg_list)
    {int nb = arg_list.count();
     if (nb<2)  return TR("Erreur VAR_SPLIT() nombre d'arguments insuffisants" );
     QString  prefix = arg_list[0];
     QString  toSep  = arg_list[1];
     QString    sep  = "|";                // valeur par defaut
     if (nb>=3) sep  = arg_list[2];
     bool allowEmptyEntries = TRUE;        // valeur par defaut
     if (nb>=4 && arg_list[3].stripWhiteSpace()==FALSE) allowEmptyEntries = FALSE;
     QStringList listeSegments = QStringList::split(sep,toSep,allowEmptyEntries);
     int i = 0;
     for ( QStringList::Iterator it = listeSegments.begin(); it != listeSegments.end(); ++it )
         {G_mCDC->m_pVariables->insert (prefix+QString::number(i), listeSegments[i]);
          ++i;
         }
     return QString("");
    }

//-------------------------- SOUS_TYPE -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::SOUS_TYPE(QStringList &arg_list)
    {if (G_mCDC->m_isJustForWatch==CDevilCrucible::JustForWatch) return QString("");
     if (G_mCDC->m_pCRubCurrentRecord)
        {// Cette fonction ajoute ou remplace l'intitulé de l'observation en cours
         // UTILISATION =
         //  {{:: sous_type ( sous type du document , add  ) }}
         //  {{:: sous_type ( sous type du document , change  ) }}
         //  {{:: sous_type ( sous type du document ) (équivalent de "change") }}
         //............. récupère les arguments passés à la fonction ................
         int nb = arg_list.count();
         if (nb<1) return QString::null;
         if (nb<2) arg_list.append("");

         arg_list[0] = arg_list[0].stripWhiteSpace();
         arg_list[1] = arg_list[1].stripWhiteSpace();
         // ......... modifie l'intutilé de l'observation
         if      (arg_list[1].lower() == "add")       {G_mCDC->m_pCRubCurrentRecord->m_SubType.append(" " + arg_list[0]);}
         else /*if (arg_list[1].lower() == "change")  {G_mCDC->m_pCRubCurrentRecord->m_SubType = arg_list[0]; }
         else if (arg_list[1].lower() == "")    */    {G_mCDC->m_pCRubCurrentRecord->m_SubType = arg_list[0]; }
         //.......... recharge le combo
        }
     return QString("");
    }

//-------------------------- SQL_EXEC -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::SQL_EXEC(QStringList &arg_list)
    {if (G_mCDC->m_pMB->OpenBase()==0)
        { return TR("Base non ouverte ::sql_exec() ");
        }
     //............. récupère les arguments passés à la fonction ................
     QString ret = "";
     int      nb = arg_list.count();
     if (nb<1) //  completer la liste si < 5
        {return TR("Erreur de syntaxe ::sql_exec() cette fonction doit comporter  au moins 1 argument ");
        }
     QSqlQuery query(arg_list[0] , G_mCDC->m_pMB->m_DataBase );
     if ( !query.isActive() )
        {G_mCDC->m_pMB->OutSQL_error(query, " sql_exec() " , arg_list[0]);
        }
     G_mCDC->m_pMB->CloseBase();
     return ret;
    }

//-------------------------- SQL_GET_RUB_HEAD_PK -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::SQL_GET_RUB_HEAD_PK(QStringList &arg_list)
    { int nb          = arg_list.count();
      if (nb<1) //  completer la liste si < 5
        {if (G_mCDC->m_pCRubCurrentRecord) return G_mCDC->m_pCRubCurrentRecord->m_PrimKey;
         else                              return TR("Erreur de syntaxe ::SQL_GET_RUB_HEAD_PK() car m_pCRubCurrentRecord = 0  ");
        }
      CRubRecord *pCRubRecord = GetIDCurrentDoc(arg_list[0]);
      if (pCRubRecord) return pCRubRecord->m_PrimKey;
      return QString(TR("SQL_GET_RUB_HEAD_PK() not found for this Name : ")+arg_list[0]);
    }
//-------------------------- SQL_GET_DOSS_PK -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::SQL_GET_DOSS_PK(QStringList &)
    {return G_mCDC->m_IdentPrimKey;
    }
//-------------------------- SQL_GET_DOSS_GUID -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::SQL_GET_DOSS_GUID(QStringList &)
    {return G_pCApp->m_pDrTux->m_NumGUID;
    }

//-------------------------- SQL_SELECT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::SQL_SELECT(QStringList &arg_list)
    {// Cette fonction execute une requete SQL et retourne le resultat dans une liste
     // UTILISATION =
     //  {{:: SQL_SELECT ( table, liste des champs a recuperer separes par | , condition  , nbrMaxListe, separateur de champ, separateur de ligne) }}

     //............. récupère les arguments passés à la fonction ................
     int i, row;
     QString retMask = "";
     QString ret     = "";
     int nb          = arg_list.count();
     QStringList fieldList;
     if (nb<4) //  completer la liste si < 5
        {return TR("Erreur de syntaxe ::sql_select() cette fonction doit comporter  au moins 4 arguments ");
        }
     if (nb==7) retMask = arg_list[6];
     if (nb<4)  {for( i=nb; i<=7; ++i) arg_list.append("");}

     QString requete("SELECT ");
     int nb_c  = arg_list[1].contains('|') + 1;
     fieldList = QStringList::split('|',arg_list[1]);
     requete  += arg_list[1].replace('|',',');
     requete  += " FROM ";
     requete  += arg_list[0] + " ";
     requete  += arg_list[2];
     if (G_mCDC->m_pMB->OpenBase()==0)
        { return TR("Base non ouverte ::sql_select() ");
        }
    //qDebug(requete);
    QSqlQuery sqlQuery (requete , G_mCDC->m_pMB->m_DataBase );
    QString f_sep = arg_list[4];
    QString l_sep = arg_list[5];
    int     nb_l  = arg_list[3].toInt();    if (nb_l<=0) nb_l = 20;
    if (l_sep.length()==0) l_sep = " ";
    if (f_sep.length()==0) f_sep = "\n";
    if (sqlQuery.isActive())
       {row = 0;
        while (sqlQuery.next() && nb_l)
              {if (retMask.length()) retMask  = arg_list[6];  // recharger le masque
               for( i=0; i<nb_c; ++i)      // pour toutes les colones (champs de la base)
                  {if (f_sep=="$SET_VAR")
                      {QString varName = arg_list[0]+"."+fieldList[i]+QString::number(row);
                       G_mCDC->m_pVariables->insert (varName, sqlQuery.value(i).toString());
                      }
                   else if (retMask.length())
                      {retMask.replace(f_sep+QString::number(i), sqlQuery.value(i).toString());
                       if (i>=nb_c-1) ret += retMask + l_sep;
                      }
                   else
                      {ret += sqlQuery.value(i).toString();
                       if (i<nb_c-1) ret += f_sep;
                       else          ret += l_sep;
                      }
                  }
               ++row;
               --nb_l;
              }
       }
     G_mCDC->m_pMB->CloseBase();
     return ret;
    }

//-------------------------- TEST -------------------------------------------
// TEST (S,PATIENT,>=,ADRESSE,TESTISTRUE,TESTISFALSE, 1)
/*! \brief non documenté */
QString C_TokenInterpret::TEST(QStringList &arg_list)
    {if ( arg_list.count() <= 5 )  return TR("Erreur de syntaxe ::TEST() cette fonction doit comporter  au moins 5 arguments ");
     if ( arg_list.count() <= 6 )  arg_list.append("");
     QString op =  arg_list[2].stripWhiteSpace();
     int    iop = 0;
     bool    cs = TRUE;
     if      (op=="=" )  {iop = 1; }
     else if (op==">" )  {iop = 2; }
     else if (op=="<" )  {iop = 3; }
     else if (op==">=")  {iop = 4; }
     else if (op=="<=")  {iop = 5; }
     else if (op=="!=")  {iop = 6; }
     else if (op=="%=")  {iop = 7; }
     else if (op=="=%")  {iop = 8; }
     else if (op=="%%")  {iop = 9; }

     QString val1 = arg_list[1].stripWhiteSpace();
     QString val2 = arg_list[3].stripWhiteSpace();
     if (arg_list.count() == 7) cs = (bool)arg_list[6].toInt();
     if (arg_list[0][0]=='N') // on teste les valeurs numériques et si pas ok on continue mais avec les textes
        {double v1 = toNum(val1).toDouble();
         double v2 = toNum(val2).toDouble();
         switch (iop)
               {
                case 1:     // =
                    {if (v1==v2 ) return arg_list[4].stripWhiteSpace();
                     else         return arg_list[5].stripWhiteSpace();
                    }
                case 4:     // >=  si egal  ok
                    {if (v1==v2 ) return arg_list[4].stripWhiteSpace();
                    }
                case 2:     // >
                    {if (v1>v2)  return arg_list[4].stripWhiteSpace();
                     else        return arg_list[5].stripWhiteSpace();
                    }
                case 5:     // <=  si egal  ok
                    {if (v1==v2 ) return arg_list[4].stripWhiteSpace();
                    }
                case 3:     // <
                    {if (v1<v2)  return arg_list[4].stripWhiteSpace();
                     else        return arg_list[5].stripWhiteSpace();
                    }
                case 6:     // !=
                    {if (v1!=v2 ) return arg_list[4].stripWhiteSpace();
                     else         return arg_list[5].stripWhiteSpace();
                    }
               }
       }
     switch (iop)
               {case 1:     // =
                    {if (val1==val2 ) return arg_list[4].stripWhiteSpace();
                     else             return arg_list[5].stripWhiteSpace();
                    }
                case 4:     // >=  si egal  ok
                    {if (val1==val2 ) return arg_list[4].stripWhiteSpace();
                    }
                case 2:     // >
                    {if (QString::compare ( val1, val2 )>0)  return arg_list[4].stripWhiteSpace();
                     else                                    return arg_list[5].stripWhiteSpace();
                    }
                case 5:     // <=  si egal  ok
                    {if (val1==val2 ) return arg_list[4].stripWhiteSpace();
                    }
                case 3:     // <
                    {if (QString::compare ( val1, val2 )<0)  return arg_list[4].stripWhiteSpace();
                     else                                    return arg_list[5].stripWhiteSpace();
                    }
                case 6:     // !=
                    {if ( !(val1==val2) ) return arg_list[4].stripWhiteSpace();
                     else                 return arg_list[5].stripWhiteSpace();
                    }
                case 7:     // %=
                    {if (val1.startsWith(val2,cs))   return arg_list[4].stripWhiteSpace();
                     else                            return arg_list[5].stripWhiteSpace();
                    }
                case 8:    // =%
                    {if (val1.endsWith(val2,cs))  return arg_list[4].stripWhiteSpace();
                     else                         return arg_list[5].stripWhiteSpace();
                    }
                case 9:    // %%
                    {if (val1.contains(val2,cs)) return arg_list[4].stripWhiteSpace();
                     else                        return arg_list[5].stripWhiteSpace();
                    }
               } // endswitch (op)
    return QString::null;
    }

//-------------------------- TO_SCRIPT -------------------------------------------
// TO_TEXT (string,mode)
/*! \brief non documenté */
QString C_TokenInterpret::TO_SCRIPT(QStringList &arg_list)
{if ( arg_list.count() <= 0 )  return TR("Erreur de syntaxe ::TO_TEXT() cette fonction doit comporter  au moins 1 arguments (le texte à convertir) ");
 int mode = 10;      // strict ASCII ne conserve pas les <br>  mode&CHtmlTools::commaProtect|mode&CHtmlTools::StrictASCII
 if ( arg_list.count() == 2 )  mode = arg_list[1].toInt()|8;     // |8 pour protection des virgules
 QString str = arg_list[0];
 return CHtmlTools::HtmlToAscii(str,  mode);
}

//-------------------------- UPPER -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::UPPER(QStringList &arg_list)
    {if ( arg_list.count()==0) return QString::null;
     return arg_list[0].upper();
    }
//-------------------------- VALIDER_DOSSIER -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::VALIDER_DOSSIER(QStringList &arg_list)
    {/*
     if (G_pCApp==0)        return QString::null;
     if (G_pCApp->m_pDrTux==0)          {G_pCApp->CouCou(TR("Erreur VALIDER_DOSSIER() : DrTux non initialisé"));return QString::null;}
     if ( arg_list.count() <= 0 )        G_pCApp->m_pDrTux->SauverDossierAvantNouvelleAction(DrTux::NoInquire);
     else {if   (arg_list[0]=="Inquire") G_pCApp->m_pDrTux->SauverDossierAvantNouvelleAction(DrTux::Inquire);
           else                          G_pCApp->m_pDrTux->SauverDossierAvantNouvelleAction(DrTux::NoInquire);
          }
     */
     return QString::null;
    }
///////////////////////////// MACROS CALL BACK /////////////////////////////////////////////

QString      m_USER_IDENT_TEL_1;                               // Tel_1 de cet intervenant
   QString      m_USER_IDENT_TEL_2;                               // Tel_2 de cet intervenant
   QString      m_USER_IDENT_TEL_3;                               // Tel_3 de cet intervenant
   QString      m_USER_IDENT_EMAIL;                               // Email de cet intervenant
   QString      m_USER_IDENT_NOTE;                                // note de l'intervenant
   QString      m_USER_IDENT_CODE_REGIME;                         // code regime de l'intervenant
   QString      m_USER_IDENT_CHER;                                // Mention familli�e de intervenant Cher Ami Cher confrere
   QString      m_USER_IDENT_TEL_TYPE_1;                          // Tel_1 de cet intervenant
   QString      m_USER_IDENT_TEL_TYPE_2;                          // Tel_2 de cet intervenant
   QString      m_USER_IDENT_TEL_TYPE_3;                          // Tel_3 de cet intervenant
   QString      m_USER_IDENT_TEL_ABR_1;                           // Tel_1 de cet intervenant
   QString      m_USER_IDENT_TEL_ABR_2;                           // Tel_2 de cet intervenant
   QString      m_USER_IDENT_TEL_ABR_3;                           // Tel_3 de cet intervenant

//-------------------------- ADRESSE COMPLETE MEDECIN -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::ADRESSE_COMPLETE_MEDECIN(QStringList &)
{QString resolvToken("");
 resolvToken  = G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_RUE,       G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY ,       G_mCDC->m_UserDocPk)  + "\n";
 resolvToken += G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_CODE_POST, G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY ,       G_mCDC->m_UserDocPk)  + " ";
 resolvToken += G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_VILLE,     G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY ,       G_mCDC->m_UserDocPk) ;
 return resolvToken.replace("\n","<br />");
}
//-------------------------- EMAIL_MEDECIN -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::EMAIL_MEDECIN(QStringList &)
{return G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_EMAIL,       G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY ,       G_mCDC->m_UserDocPk);
}
//-------------------------- TEL_1_MEDECIN -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::TEL_1_MEDECIN(QStringList &)
{return G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_TEL_1,       G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY ,       G_mCDC->m_UserDocPk);
}
//-------------------------- TEL_2_MEDECIN -------------------------------------------//-------------------------- TEL_1_MEDECIN -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::TEL_2_MEDECIN(QStringList &)
{return G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_TEL_2,       G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY ,       G_mCDC->m_UserDocPk);
}
//-------------------------- TEL_3_MEDECIN -------------------------------------------//-------------------------- TEL_1_MEDECIN -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::TEL_3_MEDECIN(QStringList &)
{return G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_TEL_3,       G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY ,       G_mCDC->m_UserDocPk);
}

//-------------------------- ADRESSE COMPLETE PATIENT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::ADRESSE_COMPLETE_PATIENT(QStringList &)
    {QString resolvToken("");
     resolvToken  = G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_DOSS_IDENT_TBL_NAME, G_mCDC->m_pMB->m_DOSS_IDENT_RUE,       G_mCDC->m_pMB->m_DOSS_IDENT_REF_PK ,  G_mCDC->m_IdentPrimKey)+ "\n";
     resolvToken += G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_DOSS_IDENT_TBL_NAME, G_mCDC->m_pMB->m_DOSS_IDENT_CODE_POST, G_mCDC->m_pMB->m_DOSS_IDENT_REF_PK ,  G_mCDC->m_IdentPrimKey)+ " ";
     resolvToken += G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_DOSS_IDENT_TBL_NAME, G_mCDC->m_pMB->m_DOSS_IDENT_VILLE,     G_mCDC->m_pMB->m_DOSS_IDENT_REF_PK ,  G_mCDC->m_IdentPrimKey);
     return resolvToken.replace("\n","<br />");
    }

//-------------------------- ADRESSE MEDECIN -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::ADRESSE_MEDECIN(QStringList &)
    {QString resolvToken("");
     resolvToken  = G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_RUE, G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY , G_mCDC->m_UserDocPk);
     return resolvToken.replace("\n","<br />");
    }
//-------------------------- ADRESSE PATIENT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::ADRESSE_PATIENT(QStringList &)
    {return G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_DOSS_IDENT_TBL_NAME, G_mCDC->m_pMB->m_DOSS_IDENT_RUE,        G_mCDC->m_pMB->m_DOSS_IDENT_REF_PK , G_mCDC->m_IdentPrimKey);
    }
//-------------------------- ADRESSE PATIENT UNE LIGNE -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::ADRESSE_PATIENT_UNE_LIGNE(QStringList &)
    {QString resolvToken("");
     resolvToken  = G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_DOSS_IDENT_TBL_NAME, G_mCDC->m_pMB->m_DOSS_IDENT_RUE,       G_mCDC->m_pMB->m_DOSS_IDENT_REF_PK , G_mCDC->m_IdentPrimKey)+ " ";
     resolvToken += G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_DOSS_IDENT_TBL_NAME, G_mCDC->m_pMB->m_DOSS_IDENT_CODE_POST, G_mCDC->m_pMB->m_DOSS_IDENT_REF_PK , G_mCDC->m_IdentPrimKey)+ " ";
     resolvToken += G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_DOSS_IDENT_TBL_NAME, G_mCDC->m_pMB->m_DOSS_IDENT_VILLE,     G_mCDC->m_pMB->m_DOSS_IDENT_REF_PK , G_mCDC->m_IdentPrimKey);
     return resolvToken.replace("\n"," ");
    }

//-------------------------- AGE PATIENT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::AGE_PATIENT(QStringList &)
    {QVariant qvar;
     G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_DOSS_IDENT_TBL_NAME, G_mCDC->m_pMB->m_DOSS_IDENT_NSS, G_mCDC->m_pMB->m_DOSS_IDENT_REF_PK , G_mCDC->m_IdentPrimKey, &qvar);
     QDate qDteNss = qvar.toDate();
     return  G_mCDC->m_pMB->CalculeDiffAge(&qDteNss);
    }

//-------------------------- AGE PATIENT ABREGE -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::AGE_PATIENT_ABREGE(QStringList &)
    {QVariant qvar;
     G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_DOSS_IDENT_TBL_NAME, G_mCDC->m_pMB->m_DOSS_IDENT_NSS, G_mCDC->m_pMB->m_DOSS_IDENT_REF_PK , G_mCDC->m_IdentPrimKey, &qvar);
     QDate qDteNss = qvar.toDate();
     return G_mCDC->m_pMB->CalculeDiffAge(&qDteNss);
    }
//-------------------------- AGE PATIENT ANNEE ABREGE -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::AGE_PATIENT_ANNEE_ABREGE(QStringList &)
    {QString resolvToken("");
     QVariant qvar;
     G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_DOSS_IDENT_TBL_NAME, G_mCDC->m_pMB->m_DOSS_IDENT_NSS, G_mCDC->m_pMB->m_DOSS_IDENT_REF_PK , G_mCDC->m_IdentPrimKey, &qvar);
     QDate qDteNss = qvar.toDate();
     resolvToken   = G_mCDC->m_pMB->CalculeDiffAge(&qDteNss);
     return resolvToken.left(resolvToken.length()-5);
    }
//-------------------------- BMI PATIENT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::BMI_PATIENT(QStringList &)
    {   //....... Utilise la fonction calc pour renvoyer la bonne valeur
        QString resolvToken("");
        QString un      = "1";
        QString mult    = "*";
        QString demande = "BMI";
        CDevilCalc *pCalc = new CDevilCalc(G_mCDC);
        if (pCalc)
           {resolvToken = pCalc->Calc(un, mult, demande);
            delete pCalc;
           }
        return resolvToken;
    }
//-------------------------- CODE POSTAL PATIENT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::CODE_POSTAL_PATIENT(QStringList &)
    {return G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_DOSS_IDENT_TBL_NAME, G_mCDC->m_pMB->m_DOSS_IDENT_CODE_POST,  G_mCDC->m_pMB->m_DOSS_IDENT_REF_PK , G_mCDC->m_IdentPrimKey);
    }
//-------------------------- BMI PATIENT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::CONVENTION_MEDECIN(QStringList &)
    {return G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_CONVENTION, G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY , G_mCDC->m_UserDocPk);
    }

//-------------------------- BMI PATIENT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::CP_MEDECIN(QStringList &)
    {return G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_CODE_POST, G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY , G_mCDC->m_UserDocPk);
    }
//-------------------------- DATECOURANTE -------------------------------------------
// DATE TIRET DATE DD-MM-YYYY CURRENT DATE DATECOURANTE DT
/*! \brief non documenté */
QString C_TokenInterpret::DATECOURANTE(QStringList &arg_list)
{QString   frm = "dd-MM-yyyy";
 if (arg_list.count()>0) frm = arg_list[0].stripWhiteSpace();
 QDateTime qdt = QDateTime::currentDateTime ( Qt::LocalTime );
 return qdt.toString ( frm ).replace('|','h');
}

//-------------------------- DATE VISITE -------------------------------------------
//DATE OBSERVATION
/*! \brief non documenté */
QString C_TokenInterpret::DATE_VISITE(QStringList &)
    {CRubRecord  *pCRubRecord = GetIDCurrentDoc(TR("Observation"));
     if (pCRubRecord)
        {QString  dt = pCRubRecord->m_Date.left(10);
         return   dt.mid(8) + "-" + dt.mid(5,2) + "-" + dt.left(4);
        }
     return QString::null;
    }
//-------------------------- DATE_DOCUMENT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::DATE_DOCUMENT(QStringList &arg_list)
    {if (arg_list.count()==0) return TR("Syntax error in DATE DOCUMENT '=' not found");
     QString arg      = arg_list[0];
     int pos_deb      = 0;
     int pos_end      = arg.find("FORMAT");
     if (pos_end==-1)         return TR("Syntax error in DATE DOCUMENT 'FORMAT' not found");

     QString doc_typ  = arg.mid(pos_deb, pos_end - pos_deb).stripWhiteSpace();
     pos_deb          = arg.find('=', pos_end + 6);
     if (pos_deb==-1)         return TR ( "Syntax error in DATE DOCUMENT '=' after 'FORMAT' not found");

     ++pos_deb;    // passer le signe egal
     QString format   = arg.mid(pos_deb);

     if (doc_typ.length()==0) return TR("Syntax error in DATE DOCUMENT Document type missed after 'DATE DOCUMENT'");
     if (format.length()==0)  return TR("Syntax error in DATE DOCUMENT format date  missed after 'FORMAT'");
     //int  id = GetIDCurrentDoc(typ_doc.toLong());
     CRubRecord  *pCRubRecord;
     if (doc_typ.upper() == "THIS") pCRubRecord = G_mCDC->m_pCRubCurrentRecord;
     else                           pCRubRecord = GetIDCurrentDoc(doc_typ);
     if (pCRubRecord==0)      return TR("Syntax error in DATE DOCUMENT Document type : '") + doc_typ + "' not found";
     QDate    qdt =  QDate::fromString ( pCRubRecord->m_Date, Qt::ISODate );
     return  qdt.toString (format);
    }
//-------------------------- DATE_NAISSANCE_PATIENT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::DATE_NAISSANCE_PATIENT(QStringList &)
    {QVariant qvar;
     G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_DOSS_IDENT_TBL_NAME, G_mCDC->m_pMB->m_DOSS_IDENT_NSS, G_mCDC->m_pMB->m_DOSS_IDENT_REF_PK , G_mCDC->m_IdentPrimKey, &qvar);
     QDate qDteNss = qvar.toDate();
     return qDteNss.toString(QString("dd-MM-yyyy"));
    }
//-------------------------- DDR -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::DDR(QStringList &arg_list)
    {   QString ret = GetDDR();
        QString frm = "dddd dd MMM yyyy";
        if (arg_list.count()>0) frm = arg_list[0].stripWhiteSpace();
        if (ret != " ")
          {  QDate DDR;
             DDR = DDR.fromString(ret , Qt::ISODate);
             ret = DDR.toString( frm ).replace('|','h');
          }
        return ret;
    }

//-------------------------- EMAIL_PATIENT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::EMAIL_PATIENT(QStringList &)
    {return G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_DOSS_IDENT_TBL_NAME,
                                         G_mCDC->m_pMB->m_DOSS_IDENT_EMAIL, G_mCDC->m_pMB->m_DOSS_IDENT_REF_PK,
                                         G_mCDC->m_IdentPrimKey);
    }

//-------------------------- LINE_EDIT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::LINE_EDIT(QStringList &arg_list)
    {QString title = TR("Saisir du texte");
     QString text  = "";
     if (arg_list.count()>0) text  = arg_list[0];
     if (arg_list.count()>1) title = arg_list[1];
     if (CGenTools::DialogGetString(0, title, text)==QDialog::Accepted)
        {return text;
        }
     else return QString::null;
    }

//-------------------------- GET_LAST_IMAGE_NAME -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::GET_LAST_IMAGE_NAME(QStringList &)
    {QString resolvToken="";
     if (G_pCApp->m_pDrTux)
        {MyEditText *pMyEditText  = G_pCApp->m_pDrTux->currentEditor();
         if (pMyEditText)
            {resolvToken = pMyEditText->GetLastImageName();
             int     pos = resolvToken.findRev('.');
             if ( pos   != -1) {resolvToken = resolvToken.left(pos) + ".png";}
            }
        }
     return resolvToken;
    }
//-------------------------- GET_LAST_IMAGE_SRC_NAME -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::GET_LAST_IMAGE_SRC_NAME(QStringList &)
    {if (G_pCApp->m_pDrTux)
        {MyEditText *pMyEditText  = G_pCApp->m_pDrTux->currentEditor();
         if (pMyEditText) return G_pCApp->m_C_ImageList.getSrcImageName(pMyEditText->GetLastImageName());
        }
     return QString::null;
    }

//-------------------------- GET_SAVE_FILE_NAME -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::GET_SAVE_FILE_NAME(QStringList &arg_list)
    { if (arg_list.count()==0) return QString::null;
      QString   preselect = arg_list[0];
      QString      filter = TR("Tous fichiers (*)");
      int             pos = preselect.find(',');
      if (   pos != -1)
         {filter    = preselect.mid(pos+1).stripWhiteSpace();
          preselect.truncate(pos);
         }
      if ( QDir::isRelativePath ( preselect ) ) preselect  = QDir::cleanDirPath (preselect.prepend(G_pCApp->m_PathAppli) );
      return QFileDialog::getSaveFileName(preselect, filter, 0, TR("Enregistrer sous ..."), TR("Choisissez un nom de fichier pour enregistrer"));
    }
//-------------------------- HHHMM -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::HHHMM(QStringList &arg_list)
    {QDateTime qdt = QDateTime::currentDateTime ( Qt::LocalTime );
     QString frm = "hh:mm";
     if (arg_list.count()>0) frm = arg_list[0].stripWhiteSpace();
     return qdt.toString ( frm );
    }

//-------------------------- IDENTIFICATION_MEDECIN -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::IDENTIFICATION_MEDECIN(QStringList &)
    {return G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_NUM_ORDRE, G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY , G_mCDC->m_UserDocPk);
    }
//-------------------------- INTERVENANT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::INTERVENANT(QStringList &arg_list) //{{INTERVENANT = Médecine generale CHAMPS DESIRES = NPA DECALAGE= SEP=}}
    {if (arg_list.count()==0) return TR("Syntax error in INTERVENANT '=' not found");
     QStringList listData;
     QString sep = "";
     QString      token  = arg_list[0];
     int pos_end         = token.find("CHAMPS DESIRES");
     if (pos_end==-1)         return TR ("Syntax error in INTERVENANT 'CHAMPS DESIRES' not found");
     QString qualite     = token.mid(0, pos_end).stripWhiteSpace();
     int pos_deb         = token.find('=', pos_end + 14);
     if (pos_deb==-1)         return TR ("Syntax error in INTERVENANT '=' after 'CHAMPS DESIRES' not found");
     ++pos_deb;    // passer le signe egal
     pos_end          = token.find("DECALAGE", pos_deb);
     if (pos_end==-1)         return TR ("Syntax error in INTERVENANT 'DECALAGE' not found");
     QString validStr = token.mid(pos_deb, pos_end - pos_deb).stripWhiteSpace();
     pos_deb          = token.find('=', pos_end + 8);
     if (pos_deb==-1)         return TR ("Syntax error in INTERVENANT '=' after 'DECALAGE' not found");
     ++pos_deb;    // passer le signe egal
     pos_end          = token.find("SEP", pos_deb);
     QString decalage = "";
     if (pos_end == -1)  decalage = token.mid(pos_deb);
     else               {decalage = token.mid(pos_deb, pos_end - pos_deb).stripWhiteSpace();
                         pos_deb  = token.find('=', pos_end + 3);
                         if (pos_deb==-1)         return TR ("Syntax error in INTERVENANT '=' after 'SEP' not found");
                         ++pos_deb;
                         sep      = token.mid(pos_deb);
                        }
     G_mCDC->m_pMB->PatientIntervenantsGetData(G_mCDC->m_IdentPrimKey , listData, qualite, validStr, decalage);
     if (listData.count())
        {if (sep.length()==0) return listData[0];  // on prend le premier medecin traitant de la liste
         else                                      // on affiche toute la liste des infos en la separant par 'sep'
             {QStringList::Iterator it = listData.begin();
              QString resolvToken(*it);
              ++it;
              while  (it != listData.end() )
                  {resolvToken += sep + *it;
                   ++it;
                  }
              return resolvToken;
             }
        }
     return QString::null;
    }

//-------------------------- NOM_PATIENT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::NOM_PATIENT( QStringList&)
    {return G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_DOSS_INDEX_TBL_NAME,  G_mCDC->m_pMB->m_DOSS_INDEX_NOM,
                                         G_mCDC->m_pMB->m_DOSS_INDEX_PRIM_KEY , G_mCDC->m_IdentPrimKey);
    }
//-------------------------- NOM_PRENOM_PATIENT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::NOM_PRENOM_PATIENT(QStringList &)
    {return         G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_DOSS_INDEX_TBL_NAME,  G_mCDC->m_pMB->m_DOSS_INDEX_NOM,
                                                 G_mCDC->m_pMB->m_DOSS_INDEX_PRIM_KEY , G_mCDC->m_IdentPrimKey) +" " +
                    G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_DOSS_INDEX_TBL_NAME,  G_mCDC->m_pMB->m_DOSS_INDEX_PRENOM,
                                                 G_mCDC->m_pMB->m_DOSS_INDEX_PRIM_KEY , G_mCDC->m_IdentPrimKey);
    }
//-------------------------- NOM_PRENOM_MEDECIN -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::NOM_PRENOM_MEDECIN(QStringList &)
     {return        G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_NOM,
                                                 G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY , G_mCDC->m_UserDocPk) + " " +
                    G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_PRENOM,
                                                 G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY , G_mCDC->m_UserDocPk);
    }
//-------------------------- NOM_MEDECIN -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::NOM_MEDECIN(QStringList &)
    {return  G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME,    G_mCDC->m_pMB->m_USER_IDENT_NOM,
                                          G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY ,    G_mCDC->m_UserDocPk);
    }
//-------------------------- NOM_PRENOM_ASSURE -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::NOM_PRENOM_ASSURE(QStringList &)
    {return  G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_DOSS_IDENT_TBL_NAME, G_mCDC->m_pMB->m_DOSS_IDENT_NOM_ASS,
                                          G_mCDC->m_pMB->m_DOSS_IDENT_REF_PK ,  G_mCDC->m_IdentPrimKey)+" "+
             G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_DOSS_IDENT_TBL_NAME, G_mCDC->m_pMB->m_DOSS_IDENT_PRENOM_ASS,
                                          G_mCDC->m_pMB->m_DOSS_IDENT_REF_PK ,  G_mCDC->m_IdentPrimKey);
    }
//-------------------------- NOM_PRENOM_INTERVENANT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::NOM_PRENOM_INTERVENANT(QStringList &arg_list)
    {if (arg_list.count()==0) return TR("Syntax error in NOM_PRENOM_INTERVENANT '=' not found");
     QStringList listPraticiens;
     QString qualite = arg_list[0].stripWhiteSpace();
     G_mCDC->m_pMB->PatientIntervenantsGetData(G_mCDC->m_IdentPrimKey , listPraticiens, qualite,"NP", " ");   //  "NP"  pour nom prenom intervenant
     if (listPraticiens.count())
        {return listPraticiens[0];  // on prend le premier medecin traitant de la liste
        }
     return QString::null;
    }

//-------------------------- NOMBRE_D_ENFANT_PATIENT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::NOMBRE_D_ENFANT_PATIENT(QStringList &)
    {return  G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_DOSS_IDENT_TBL_NAME, G_mCDC->m_pMB->m_DOSS_IDENT_NB_ENF,
                                          G_mCDC->m_pMB->m_DOSS_IDENT_REF_PK ,  G_mCDC->m_IdentPrimKey);
    }

//-------------------------- NUM_TEL3_PATIENT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::NUM_TEL3_PATIENT(QStringList &)
    {return G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_DOSS_IDENT_TBL_NAME, G_mCDC->m_pMB->m_DOSS_IDENT_TEL3,
                                         G_mCDC->m_pMB->m_DOSS_IDENT_REF_PK ,  G_mCDC->m_IdentPrimKey);
    }
//-------------------------- NUM_TEL2_PATIENT -------------------------------------------
/*! \brief non documenté */
// HEURECOURANTE
QString C_TokenInterpret::NUM_TEL2_PATIENT(QStringList &)
    {return G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_DOSS_IDENT_TBL_NAME, G_mCDC->m_pMB->m_DOSS_IDENT_TEL2,
                                         G_mCDC->m_pMB->m_DOSS_IDENT_REF_PK ,  G_mCDC->m_IdentPrimKey);
    }
//-------------------------- NUM_TEL1_PATIENT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::NUM_TEL1_PATIENT( QStringList&)
    {return  G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_DOSS_IDENT_TBL_NAME, G_mCDC->m_pMB->m_DOSS_IDENT_TEL1,
                                          G_mCDC->m_pMB->m_DOSS_IDENT_REF_PK ,  G_mCDC->m_IdentPrimKey);
    }
//-------------------------- NUM_SECU_PATIENT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::NUM_SECU_PATIENT(QStringList &)
    {return G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_DOSS_IDENT_TBL_NAME,  G_mCDC->m_pMB->m_DOSS_IDENT_NUMSS,
                                         G_mCDC->m_pMB->m_DOSS_IDENT_REF_PK ,   G_mCDC->m_IdentPrimKey);
    }
//-------------------------- OPEN_FILE_NAME -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::OPEN_FILE_NAME(QStringList &arg_list)
    {QString preselect      = "";
     QString dirPresel      = "";
     if (arg_list.count()>=1)  preselect = arg_list[0].stripWhiteSpace();
     if (arg_list.count()>=2) {dirPresel = arg_list[1].stripWhiteSpace(); dirPresel = RelPathToAbsPath(dirPresel);}
     if (G_pCApp->m_pDrTux) return  G_pCApp->GetImageFileName(&dirPresel, preselect, 1);
     return QString::null;
    }

//-------------------------- POIDS_PATIENT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::POIDS_PATIENT(QStringList &)
    {   //....... Utilise la fonction calc pour renvoyer la bonne valeur
        QString un        = "1";
        QString mult      = "*";
        QString demande   = "POIDS";
        CDevilCalc calc(G_mCDC);
        return calc.Calc(un, mult, demande);
    }
//-------------------------- PRENOM_PATIENT -------------------------------------------
/*! \brief non documenté */
// HEURECOURANTE
QString C_TokenInterpret::PRENOM_PATIENT(QStringList &)
    {return  G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_DOSS_INDEX_TBL_NAME,  G_mCDC->m_pMB->m_DOSS_INDEX_PRENOM,
                                          G_mCDC->m_pMB->m_DOSS_INDEX_PRIM_KEY , G_mCDC->m_IdentPrimKey);
    }
//-------------------------- PRENOM_MEDECIN -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::PRENOM_MEDECIN(QStringList &)
    {return  G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_PRENOM,
                                          G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY , G_mCDC->m_UserDocPk);
    }
//-------------------------- PROFESSION_PATIENT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::PROFESSION_PATIENT(QStringList &)
    {return G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_DOSS_IDENT_TBL_NAME, G_mCDC->m_pMB->m_DOSS_IDENT_PROF,
                                         G_mCDC->m_pMB->m_DOSS_IDENT_REF_PK ,  G_mCDC->m_IdentPrimKey);
    }
//-------------------------- PROFESSION_PATIENT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::SEXE_MEDECIN(QStringList &)
    {return  G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_SEXE,
                                          G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY , G_mCDC->m_UserDocPk);
    }
//-------------------------- PROFESSION_PATIENT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::SEXE_PATIENT(QStringList &arg_list)
    {QString sexe = G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_DOSS_IDENT_TBL_NAME, G_mCDC->m_pMB->m_DOSS_IDENT_SEX,
                                                 G_mCDC->m_pMB->m_DOSS_IDENT_REF_PK ,  G_mCDC->m_IdentPrimKey);
     if (arg_list.count()>0) return sexe;
     if (sexe=="F")          return TR("Féminin");
     else                    return TR("Masculin");
    }
//-------------------------- PROFESSION_PATIENT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::SPECIALITE_MEDECIN(QStringList &)
    {return  G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_QUALITE,
                                          G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY , G_mCDC->m_UserDocPk);
    }
//-------------------------- PROFESSION_PATIENT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::SAVE_LAST_IMAGE_NAME(QStringList &arg_list)
    {     if (arg_list.count()==0) return TR("Syntax error in SAVE LAST IMAGE NAME '=' not found");
          QPixmap retPixMap;
          QString path = arg_list[0].stripWhiteSpace();
          if ( QDir::isRelativePath ( path ) ) path  = QDir::cleanDirPath (path.prepend(G_pCApp->m_PathAppli) );
          if ( !path.endsWith("/") ) path += "/";
          MyEditText *pMyEditText  = G_pCApp->m_pDrTux->currentEditor();
          if ( pMyEditText && QFile::exists( path ) ) // si repertoire existe
             {path   += pMyEditText->GetLastImageName();
              int pos = path.findRev('.');
              if ( pos != -1) {path = path.left(pos) + ".png"; }
              if (G_pCApp->m_C_ImageList.getPixmap( pMyEditText->GetLastImageName() , retPixMap))
                 { QImageIO iio;
                   QImage   im;
                   im = retPixMap; // convert to image
                   iio.setImage( im );
                   iio.setFileName( path );
                   iio.setFormat( "PNG" );
                   iio.write();
                 }
             }
          return QString::null;
    }
//-------------------------- PROFESSION_PATIENT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::SAVE_CURRENT_DOC(QStringList &arg_list)
    {     if (arg_list.count()==0) return TR("Syntax error in SAVE CURRENT DOC '=' not found");
          QString path = arg_list[0].stripWhiteSpace();
          if ( QDir::isRelativePath ( path ) ) path  = QDir::cleanDirPath (path.prepend(G_pCApp->m_PathAppli) );
          MyEditText *pMyEditText  = G_pCApp->m_pDrTux->currentEditor();
          if ( pMyEditText  ) // si repertoire existe
             {QString text = pMyEditText->text();
              CGestIni::Param_UpdateToDisk(path,text);
             }
          return QString::null;
    }
//-------------------------- PROFESSION_PATIENT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::SURFACE_PATIENT(QStringList &)
    {   //....... Utilise la fonction calc pour renvoyer la bonne valeur
        QString un      = "1";
        QString mult    = "*";
        QString demande = "SURFACE";
        CDevilCalc calc(G_mCDC);
        return calc.Calc(un, mult, demande);
    }   // Fin == S
//-------------------------- PROFESSION_PATIENT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::TITRE_PS(QStringList &)
    {return        G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_TITRE,
                                                G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY , G_mCDC->m_UserDocPk);
    }
//-------------------------- PROFESSION_PATIENT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::TITRE_PATIENT(QStringList &)
    {QString resolvToken = G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_DOSS_IDENT_TBL_NAME, G_mCDC->m_pMB->m_DOSS_IDENT_TITRE,
                                                        G_mCDC->m_pMB->m_DOSS_IDENT_REF_PK ,  G_mCDC->m_IdentPrimKey);
     if (resolvToken=="")
        {QVariant qvar;
         G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_DOSS_IDENT_TBL_NAME, G_mCDC->m_pMB->m_DOSS_IDENT_NSS,
                                      G_mCDC->m_pMB->m_DOSS_IDENT_REF_PK ,  G_mCDC->m_IdentPrimKey, &qvar);
         QDate qDteNss = qvar.toDate();
         int age = atoi(G_mCDC->m_pMB->CalculeDiffAge(&qDteNss, 0, FALSE, 2));
         if (age < 15)          resolvToken="L'enfant";
         if (age >= 15 && age <= 21)
            {QString sexe = G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_DOSS_IDENT_TBL_NAME, G_mCDC->m_pMB->m_DOSS_IDENT_SEX,
                                                         G_mCDC->m_pMB->m_DOSS_IDENT_REF_PK ,  G_mCDC->m_IdentPrimKey);
             if (sexe=="F")     resolvToken="Mademoiselle";
             else               resolvToken="M.";
            }
         if (age>21)
            {QString sexe = G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_DOSS_IDENT_TBL_NAME, G_mCDC->m_pMB->m_DOSS_IDENT_SEX,
                                                         G_mCDC->m_pMB->m_DOSS_IDENT_REF_PK ,  G_mCDC->m_IdentPrimKey);
             if (sexe=="F")     resolvToken="Mme";
             else               resolvToken="M.";
            }
        }
     return resolvToken;
    }
//-------------------------- TAILLE_PATIENT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::TAILLE_PATIENT(QStringList &)
    {   //....... Utilise la fonction calc pour renvoyer la bonne valeur
        QString un      = "1";
        QString mult    = "*";
        QString demande = "TAILLE";
        CDevilCalc calc(G_mCDC);
        return calc.Calc(un, mult, demande);
    }
//-------------------------- TERME_GROSSESSE -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::TERME_GROSSESSE(QStringList &)
    {   QString ret = "";
        ret = GetDDR();
        if (ret[0] == 'L')  return QString(" ");
        else                return Terme_Obst ( ret , QDate::currentDate());
    }
//-------------------------- USER_ADRESSE_COMPLETE_MEDECIN -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::USER_ADRESSE_COMPLETE_MEDECIN(QStringList &)
     {QString resolvToken;
      resolvToken  = G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME,       G_mCDC->m_pMB->m_USER_IDENT_RUE,
                                                  G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY ,       G_mCDC->m_UserActuelPk)  + "\n"+
                     G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME,       G_mCDC->m_pMB->m_USER_IDENT_CODE_POST,
                                                  G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY ,       G_mCDC->m_UserActuelPk)  + " " +
                     G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME,       G_mCDC->m_pMB->m_USER_IDENT_VILLE,
                                                  G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY ,       G_mCDC->m_UserActuelPk) ;
      return (resolvToken.replace("\n","<br />"));
     }
//-------------------------- USER_EMAIL_MEDECIN -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::USER_EMAIL_MEDECIN(QStringList &)
{return G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_EMAIL,       G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY ,       G_mCDC->m_UserActuelPk);
}
//-------------------------- USER_TEL_1_MEDECIN -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::USER_TEL_1_MEDECIN(QStringList &)
{return G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_TEL_1,       G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY ,       G_mCDC->m_UserActuelPk);
}
//-------------------------- USER_TEL_2_MEDECIN -------------------------------------------//-------------------------- TEL_1_MEDECIN -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::USER_TEL_2_MEDECIN(QStringList &)
{return G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_TEL_2,       G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY ,       G_mCDC->m_UserActuelPk);
}
//-------------------------- USER_TEL_3_MEDECIN -------------------------------------------//-------------------------- TEL_1_MEDECIN -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::USER_TEL_3_MEDECIN(QStringList &)
{return G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_TEL_3,       G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY ,       G_mCDC->m_UserActuelPk);
}

//-------------------------- USER_ADRESSE_MEDECIN -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::USER_ADRESSE_MEDECIN( QStringList&)
     {return G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_RUE,
                                          G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY , G_mCDC->m_UserActuelPk).replace("\n","<br />");
     }
//-------------------------- USER_CP_MEDECIN -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::USER_CP_MEDECIN(QStringList &)
     {return G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_CODE_POST,
                                          G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY , G_mCDC->m_UserActuelPk);
     }
//-------------------------- USER_CONVENTION_MEDECIN -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::USER_CONVENTION_MEDECIN(QStringList &)
     {return G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_CONVENTION,
                                          G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY , G_mCDC->m_UserActuelPk);
     }
//-------------------------- USER_NOM_PRENOM_MEDECIN -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::USER_NOM_PRENOM_MEDECIN(QStringList &)
     {return  G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_NOM,
                                           G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY , G_mCDC->m_UserActuelPk) + " " +
              G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_PRENOM,
                                           G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY , G_mCDC->m_UserActuelPk);
     }
//-------------------------- USER_NOM_MEDECIN -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::USER_NOM_MEDECIN(QStringList &)
     {return G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_NOM,
                                          G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY , G_mCDC->m_UserActuelPk);
     }
//-------------------------- USER_SEXE_MEDECIN -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::USER_SEXE_MEDECIN(QStringList &)
     {return  G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME,  G_mCDC->m_pMB->m_USER_IDENT_SEXE,
                                           G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY ,  G_mCDC->m_UserActuelPk);
     }
//-------------------------- USER_SPECIALITE_MEDECIN -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::USER_SPECIALITE_MEDECIN(QStringList &)
     {return   G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_QUALITE,
                                            G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY , G_mCDC->m_UserActuelPk);
     }
//-------------------------- USER_TITRE_PS -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::USER_TITRE_PS(QStringList &)
     {return G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_TITRE,
                                          G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY , G_mCDC->m_UserActuelPk);
     }
//-------------------------- USER_VILLE_MEDECIN -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::USER_VILLE_MEDECIN(QStringList &)
     {return G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_VILLE,
                                          G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY , G_mCDC->m_UserActuelPk);
     }
//-------------------------- USER_LOGIN_MEDECIN -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::USER_LOGIN_MEDECIN(QStringList &)
     {return G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_LOGIN,
                                          G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY , G_mCDC->m_UserActuelPk);
     }

//-------------------------- USER_IDENTIFICATION_MEDECIN -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::USER_IDENTIFICATION_MEDECIN(QStringList &)
    {return G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_NUM_ORDRE,
                                         G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY , G_mCDC->m_UserActuelPk);
    }
//-------------------------- USER_PRENOM_MEDECIN -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::USER_PRENOM_MEDECIN(QStringList &)
    {return G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_PRENOM,
                                         G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY , G_mCDC->m_UserActuelPk);
    }
//-------------------------- VILLE_PATIENT -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::VILLE_PATIENT(QStringList &)
    {return G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_DOSS_IDENT_TBL_NAME, G_mCDC->m_pMB->m_DOSS_IDENT_VILLE,
                                         G_mCDC->m_pMB->m_DOSS_IDENT_REF_PK ,  G_mCDC->m_IdentPrimKey);
    }
//-------------------------- VILLE_MEDECIN -------------------------------------------
/*! \brief non documenté */
QString C_TokenInterpret::VILLE_MEDECIN(QStringList &)
    {return G_mCDC->m_pMB->GetFieldValue(G_mCDC->m_pMB->m_USER_IDENT_TBL_NAME, G_mCDC->m_pMB->m_USER_IDENT_VILLE,
                                         G_mCDC->m_pMB->m_USER_IDENT_PRIMKEY , G_mCDC->m_UserDocPk);
    }


/////////////////////////////////// FONCTIONS DE SERVICE ////////////////////////////
//----------------------- Func_Extract_TTT ------------------------------------------
/*! \brief Retourne le traitement en cours du patient.
*/
QString C_TokenInterpret::Func_Extract_TTT(const QString &title, QString &linePatern, QString renouvInterc, QString &tableau, QString &poids_name, QString &taille_name)
{QString           resolvToken = "";
 QString           poids_var   = "";
 QString           taille_var  = "";

 QPL_CPosologie    ordoList;
 QStringList       lineList;
 //................ recuperer données du terrain .......................................
 QString  str_data = G_mCDC->m_pMB->GetDataFromRubList( GetIDCurrentDoc(TR("Terrain")) );       // recuperer données soit dans liste cache soit sur disque
 if (str_data.length()==0)              return resolvToken;
 char* pt          = (char*) (const char*) str_data;
 renouvInterc      = renouvInterc.stripWhiteSpace();

 //................ recuperer le poids et taille .................................................
 GetPoidsTaille(pt, tableau, poids_name, taille_name, poids_var, taille_var);
 //........... effacer les anciennes tables de variables ................
 //
 QString val1, val2, val3, val4, val5, val6, val7, val8, val9, val10;
 QString      section   = "";
 QString     var_name   = "";

 char     *prop_section = 0;       // permet de noter le pointeur sur la section propriete renouvelable/intercurent des produits

 while((pt = CGestIni::Param_GotoNextSection(pt, 0, &section)) && *pt)
  {if (section == TR("Propriété Ordonnance"))                  // à ce stade pt pointe au debut de la nouvelle ligne
        {prop_section = pt;                                // noter section des proprietes (à traiter apres liste med)
         section      = "";
        }
     //.................................. TTT ........................................................
     // IMPORTANT: cette section doit tjrs etre en dernier dans le fichier pour des raisons de fin !!!
     if (section==TR("Traitement"))                  // à ce stade pt pointe au debut de la nouvelle ligne
      {  QString stringStruct;
         CMedicaBase::Medica_DiskDataSplitIn_HtmlData_StructData(pt, 0, &stringStruct); // y isoler et recuperer les données calculables
         CMedicaBase::Medica_PosologieListDeserialize(stringStruct, ordoList);

         if (linePatern.contains("tableau", FALSE) != 0)
          {     QString tabTTT = "<table width=\"100%\" border=\"1\" cellpadding=\"2\" cellspacing=\"2\">";
                tabTTT += "<tr><td width=\"50%\">"+TR("Médicament")+"</td><td width = \"10%\">"+TR("Matin")+"</td>";
                tabTTT += "<td width = \"10%\">"+TR("Midi")+"</td><td width = \"10%\">"+TR("Soir")+"</td>";
                tabTTT += "<td width = \"10%\">"+TR("Coucher")+"</td></tr>";
                int nb = 0;
                QString libMed = "";
                for (QPL_CPosologie::iterator it = ordoList.begin(); it != ordoList.end(); ++it )
                  {  ++ nb; (*it).m_NumOrdre = nb;
                     libMed  = G_mCDC->m_pMD->Medica_GetMedicamentNameByCIP((*it).m_MEDICA_POSO_CIP);
                     libMed  = libMed.section (" ", 0, 1); // fait de la place dans le libellé du médicament...
                     if ((*it).m_ALD == 1) // en ALD
                        { libMed.append("<span style=\"font-weight:600\">*</span>"); }
                     tabTTT += "<tr><td width=\"50%\">"+libMed+"</td>";
                     QString tmpPoso = (*it).m_MEDICA_POSO_REPART_PRISES;
                     if (tmpPoso.contains("MA", FALSE) != 0)
                        { tabTTT += "<td width = \"10%\">&nbsp;X&nbsp;</td>";}
                     else
                        { tabTTT += "<td width = \"10%\">&nbsp;</td>";}
                     if (tmpPoso.contains("MI", FALSE) != 0)
                        { tabTTT += "<td width = \"10%\">&nbsp;X&nbsp;</td>";}
                     else
                        { tabTTT += "<td width = \"10%\">&nbsp;</td>";}
                     if (tmpPoso.contains("SO", FALSE) != 0)
                        { tabTTT += "<td width = \"10%\">&nbsp;X&nbsp;</td>";}
                     else
                        { tabTTT += "<td width = \"10%\">&nbsp;</td>";}
                     if (tmpPoso.contains("CO", FALSE) != 0)
                        { tabTTT += "<td width = \"10%\">&nbsp;X&nbsp;</td>";}
                     else
                        { tabTTT += "<td width = \"10%\">&nbsp;</td>";}
                  } // Fin for
             tabTTT += "</table><br />";
             return tabTTT;
          } // fin if tableau

         int nb = 0;
         //int medALD = 0;
         QString tmp;
         for (QPL_CPosologie::iterator it = ordoList.begin(); it != ordoList.end(); ++it )
             {++ nb; (*it).m_NumOrdre = nb;

              QString lineToInsert = linePatern;

              lineToInsert.replace("::NUM::", QString::number(nb));
              lineToInsert.replace("::LIBELLE::", G_mCDC->m_pMD->Medica_GetMedicamentNameByCIP((*it).m_MEDICA_POSO_CIP));
              lineToInsert.replace("::NB_PRISE::", (*it).m_MEDICA_POSO_NB_PRISES);
              lineToInsert.replace("::REPART_PRISES::", (*it).m_MEDICA_POSO_REPART_PRISES);
              if ((*it).m_ALD == 1)      { tmp = TR("En ALD");   }
              else if ((*it).m_ALD == 0) { tmp = TR("Hors ALD"); }
              lineToInsert.replace("::ALD::", tmp);
              lineToInsert.replace("::POSO_TEXTUELLE::", (*it).m_PosoTextuelle);
              lineToInsert.replace("::NOTE::", (*it).m_Note);
              lineToInsert.replace("::DUREE::", (*it).m_MEDICA_POSO_PENDANT);

              // m_pCMedicaBase->Medica_PosologieToSimpleText(*it, m_pCMDI_Terrain->GetPoids(), m_pCMDI_Terrain->GetTaille() );
              lineList.append(lineToInsert);
             } //end for

      break;
     } // end if section
  } // end while((pt=m_pMB->Param_GotoNextSection(pt, 0, &section)) && *pt)
 for ( QStringList::Iterator lt = lineList.begin(); lt != lineList.end(); ++lt )
     {resolvToken += *lt;
     }
 if (resolvToken.length()) resolvToken.prepend(title);

 return    resolvToken;
}

//---------------------- Func_Extract_Table ----------------------------------
/*! \brief Crée un tableau avec les variables du terrain en cours d'affichage.
 *  \todo Pour améliorer le débuggage utiliser Var_Code
 * {{:: Extract_VAR (VAR Constantes de Base , SAO2 , DATE VISITE ,   0  , TOUTES )}}
 * {{:: Extract_VAR (VAR Constantes de Base , SAO2 , DATE VISITE , -24  , PREMIERE )}}
 * {{:: Extract_VAR (VAR Constantes de Base , SAO2 , DATE VISITE , +24  , DERNIERE )}}
 * {{:: Extract_VAR (VAR Constantes de Base , SAO2 , DATE VISITE , +-24 , PLUS PROCHE )}}
 * {{:: Extract_Table (VAR Constantes de Base , Pouls L=50  & SAO2 L=80  & Temp L=100 ,DATE VISITE ,   0  , TOUTES , H=50 ,E=3)}}
*/
QString C_TokenInterpret::Func_Extract_Table(QString &section_VAR,
                                           QString &list_VAR,
                                           QString &date_deb,
                                           QString &date_end,
                                           QString &cell_W ,
                                           QString &cell_H,
                                           QString &border_W,
                                           QString &width,
                                           QString &dateTimeFormat,
                                           QString &dateTimeWidth)
{QString   resolvToken    = "";
 //.................. recuperer les données du terrain courant ..........................
 QString  str_data = G_mCDC->m_pMB->GetDataFromRubList( GetIDCurrentDoc(TR("Terrain")) );       // recuperer données soit dans liste cache soit sur disque
 if (str_data.length()==0)              return resolvToken;
 char* pt          = (char*) (const char*) str_data;

 //..................... menage dans les espaces............................................
 section_VAR    = section_VAR.stripWhiteSpace();
 list_VAR       = list_VAR.stripWhiteSpace();
 date_deb       = date_deb.stripWhiteSpace();
 date_end       = date_end.stripWhiteSpace();
 cell_W         = cell_W.stripWhiteSpace();
 cell_H         = cell_H.stripWhiteSpace();
 border_W       = border_W.stripWhiteSpace();
 width          = width.stripWhiteSpace();
 dateTimeFormat = dateTimeFormat.stripWhiteSpace();
 dateTimeWidth  = dateTimeWidth.stripWhiteSpace();
 //..................... recuperer les dates et determiner le filtrage ............................................
 int dateMustBeFiltred = 0;
 if ( ! (date_deb == "TOUTE DATE" && date_end == "TOUTE DATE"))
    {CRubRecord *pCRubRecord  = 0;
     //............. date de fin ...........................
     if (date_end == "DATE VISITE")
        {pCRubRecord = GetIDCurrentDoc(TR("Observation"));
         if (pCRubRecord)
            {date_end          = pCRubRecord->m_Date;
             date_end          = date_end.left(10) + "T23:59:59";           // DATE VISITE finit à 23h59 de la date
             dateMustBeFiltred = 1;
            }
        }
     else if (date_end == "TOUTE DATE")
        { date_end          = "3000-01-01T00:00:00";
          //date_end = QDateTime::currentDateTime().addYears(100).toString(Qt::ISODate);  //"dd-MM-yyyyThh:mm:ss"
          dateMustBeFiltred = 1;
        }
     else if ( date_end == "DATE ACTUELLE")
        {date_end = QDateTime::currentDateTime().toString(Qt::ISODate);  //"dd-MM-yyyyThh:mm:ss"
         dateMustBeFiltred = 1;
        }
     //............. date de debut ...........................
     if (date_deb== "DATE VISITE")
        {if (pCRubRecord==0) pCRubRecord = GetIDCurrentDoc(TR("Observation"));
         if (pCRubRecord)
            {date_deb          = pCRubRecord->m_Date;
             date_deb          = date_deb.left(10) + "T00:00:00";      // DATE VISITE commence à 00h00 de la date
             dateMustBeFiltred = 1;
            }
         }
     else if ( date_deb == "TOUTE DATE" )
        { date_deb          = "1900-01-01T00:00:00";
          //date_deb = QDateTime::currentDateTime().addYears(-100).toString(Qt::ISODate);  //"dd-MM-yyyyThh:mm:ss"
          dateMustBeFiltred = 1;
        }
     else if ( date_deb == "DATE ACTUELLE")
        {date_deb = QDateTime::currentDateTime().toString(Qt::ISODate);  //"dd-MM-yyyyThh:mm:ss"
         dateMustBeFiltred = 1;
        }
    }

 //........... noter les dimensions du tableau ................
 //
 QString val1, val2, val3, val4, val5, val6, val7, val8, val9, val10;
 QString       strTab[10];
 QString      section       = "";
 QString     var_name       = "";
 QStringList varNameList    = QStringList::split(';', list_VAR);
 QString            w_max   = cell_W;
 QStringList        var_w;
 //.................. epurer la liste du nom de variable des '= 80' et relever largeurs .......................
 for ( QStringList::Iterator it = varNameList.begin(); it != varNameList.end(); ++it )
     { QString v = *it;
       int a_pos = v.find('=');

       if (a_pos != -1)                         // si largeur indiquée s'en servir
          { var_w.append(v.mid(a_pos+1));
            *it = v.left(a_pos).stripWhiteSpace();
          }
       else                                     // si largeur non indiquée prendre celle par feaut
          { var_w.append(w_max);
            *it = v.stripWhiteSpace();
          }
     }

 QValueList<int> pos_tab;
 QString    head_table = "";
 QString    body_table = "";
 int     isOkToDisplay = 0;


 //......................... dates de debut et de fin ...................................
 QDateTime qdt_Deb;
 QDateTime qdt_End;

 if ( dateMustBeFiltred )
    {qdt_Deb = QDateTime::fromString ( date_deb, Qt::ISODate );
     if    (date_end == "0" || date_end.length() <= 0)  qdt_End = qdt_Deb;
     else                                               qdt_End = QDateTime::fromString ( date_end, Qt::ISODate );
     int nb_h = 0;
     if      (date_end == "0" || date_end.length() <= 0)   //YYYY-MM-DDTHH:MM:SS
             {qdt_Deb = QDateTime::fromString ( date_deb.left(10)+"T00:00:00", Qt::ISODate );
              qdt_End = qdt_Deb.addSecs (   24 * 3600 );
              dateMustBeFiltred = 1;
             }
     else if (date_end.left(2) == "+-" || date_end.left(2) == "-+")
             {nb_h = date_end.mid(2).toInt();
              qdt_Deb.addSecs ( - nb_h * 3600 );
              qdt_End.addSecs (   nb_h * 3600 );
              dateMustBeFiltred = 1;
             }
     else if (date_end.left(1) == "+" )
             {nb_h = date_end.mid(1).toInt();
              qdt_End.addSecs (   nb_h * 3600 );
              dateMustBeFiltred = 1;
             }
     else if (date_end.left(1) == "-" )
             {nb_h = date_end.mid(1).toInt();
              qdt_Deb.addSecs ( - nb_h * 3600 );
              dateMustBeFiltred = 1;
             }
    }

 head_table           += "<TABLE cellSpacing=\"" + QString("1")       + "\"" +
                         " cellpadding=\""       + border_W           + "\"" +
                         " width=\""             + width              + "\"" +
                         " border=\""            + border_W           + "\"><TBODY> <TR>";

 while((pt = CGestIni::Param_GotoNextSection(pt, 0, &section)) && *pt)
    {if ( section == section_VAR )                  // à ce stade pt pointe au debut de la nouvelle ligne
        {// QString name_section = section.mid(4);
         // [VAR Poids]     1      2       3       4    5   6        7                                      8
         //    Modèle  = Date, Valeur, 31536000, 100, 50, Kg(s), Attention à la surcharge pondérale, Attention à l'amaigrissement
         //    2004-03-15T17:14:48 =  68
         //                                   val1                             ,    val2               val3      val4 val5 val6  val7       val8
         int            i      =  0;
         int        n_var      =  0;

         if (dateTimeFormat.length())
            {//.......................... titre de la colonne Date ..................................
             QString dateTimeTitle = "Date";
             int p  = dateTimeFormat.find('=');
             if (p !=-1) {dateTimeTitle  = dateTimeFormat.mid(p+1);
                          dateTimeFormat = dateTimeFormat.left(p);
                         }
             head_table += "<TD width=" + dateTimeWidth + ">" + dateTimeTitle + "</TD>";   // titre colonne  date
            }
         while (*pt && *pt != '[')
               {var_name = "";
                pt   = CGestIni::Param_ExtraireNextValeurs(pt, var_name, &strTab[0], &strTab[1], &strTab[2], &strTab[3], &strTab[4], &strTab[5], &strTab[6], &strTab[7], &strTab[8]);
                //...................... definition des colonnes .....................................
                //
                if (var_name == TR("Modèle"))
                   {int ind  = varNameList.findIndex (  strTab[1] );                          // voir si ce nom de colonne est à afficher
                    if (ind != -1)
                       {pos_tab.append( n_var );                                              // noter la position de la colonne
                        head_table += "<TD width=" + var_w[ind] + QString(">") + strTab[1] + "</TD>";
                       }
                    else
                       { pos_tab.append( -1 );                                                // cette colonne n'est pas désirée à l'affichage
                       }
                    ++n_var;
                   } // endif (var_name=="Modèle")
                 //................ VALEURS DATEES DE VARIABLE ........................................
                 //                                             2004-03-15T17:14:48 =  68 , truc, 1000
                 else if ( n_var )                // NB :  var_name  reçoit la date
                   {int p_w      =  0;
                    int isDateOK =  1;

                    //................. filtrer selon les dates .......................................
                    QDateTime qdt = QDateTime::fromString ( var_name, Qt::ISODate );
                    if (dateMustBeFiltred)
                       {if (qdt>=qdt_Deb && qdt<=qdt_End) isDateOK = 1;
                        else                              isDateOK = 0;
                       }
                    if (isDateOK)
                       {body_table  += "<TR>\r\n";
                        if (dateTimeFormat.length() && qdt.isValid())  // afficher eventuellement la date
                            {var_name    = qdt.toString(dateTimeFormat);
                             body_table += "        <TD width=" + dateTimeWidth + ">" + var_name  + "</TD>\r\n";
                            }

                         for ( i = 0; i < n_var; ++i)     // parcourir toute les colonnes de variables
                             {if (pos_tab[i] != -1)       // cette colonne est elle à afficher si oui le faire
                                 {body_table += "        <TD width=" + var_w[p_w] + QString(">") + strTab[i] + "</TD>\r\n";
                                  ++p_w;
                                  ++isOkToDisplay;
                                 }
                             }
                         body_table += "</TR>\r\n";
                       } // end if (isDateOK)
                   } // end else if ( n_var )
               } // end while (*pt && *pt != '[')
         section="";
        } // endif (section.left(3)=="VAR" )
    }
 if (isOkToDisplay)
    {resolvToken = head_table + "</TR>\r\n" + body_table + "</TBODY></TABLE>\r\n";
    }
 return    resolvToken;
}



//---------------------- Func_Extract_ATCD ------------------------------------------
/*! \brief Fonction script de MédinTux qui permet d'accéder aux antécédents enregistrés des patients.
 * Plusieurs utilisations possibles de cette fonction : l'appel par "pattern" qui peut contenir
 * - ::LIBELLE::	Pour obtenir le libellé de l'antécédent
 * - ::MEDCHIR::	Pour le type d'antécédent (Médical, chirurgical, Facteur de risque, cardio-vasculaire...)
 * - ::ETAT::		Pour obtenir son état (guéri ou actif)
 * - ::CODE::		Pour obtenir le code CIM10 de l'antécédent
 * - ::NOTE::		Pour obtenir le commentaire de l'antécédent
 * - ::DATE::		Pour obtenir la date de l'antécédent.

 * L'appel du mode "linéaire" ou lisible permet d'obtenir une phrase digérée des antécédents. Pratique pour les courriers de correspondance.

 * Exemples d'utilisation dans les masques :
 *  \code   {{:: Extract_ATCD (lineaire) }}  \endcode
 *  \code   {{:: Extract_ATCD (Médicaux, Chirurgicaux, Allergies, Divers, ::LIBELLE:: (::NOTE::) en ::DATE::), en }}  \endcode
 *  \todo A CONNECTER AVEC G_pCApp->m_pAtcd_Code
*/
QString C_TokenInterpret::Func_Extract_ATCD(const QString &medPrefix,
                                          const QString &chirPrefix,
                                          const QString &allergPrefix,
                                          const QString &diversPrefix,
                                          const QString &linePatern,
                                          const QString &datePrefix)
{QString   resolvToken = "";
 QString   str_data    = G_mCDC->m_pMB->GetDataFromRubList( GetIDCurrentDoc(TR("Terrain")) );       // recuperer données soit dans liste cache soit sur disque
 if (str_data.length()==0)              return resolvToken;
 char *pt = (char*) (const char*)str_data;

 //........... effacer les anciennes tables de variables ................
 //
 QString val1, val2, val3, val4, val5;
 QString      section          = "";
 QString     var_name          = "";
 QString lineMedToInsert       = "";
 QString lineChirToInsert      = "";
 QString lineAllergToInsert    = "";
 QString lineDiversToInsert    = "";
 QString lineToInsert          = "";
 QStringList typesATCD;		// Reçoit la liste des types d'ATCD Médicaux reconnus par Medintux
 QStringList typesATCDChir;	// Reçoit la liste des types d'ATCD Chirurgicaux reconnus par Medintux
 QStringList linesATCD;  	// Liste mirroir qui contiendra les libellés d'ATCD Médicaux et leur date.
 QStringList linesATCDChir;  	// Liste mirroir qui contiendra les libellés d'ATCD Chirurgicaux et leur date.

 typesATCD.clear();
 typesATCDChir.clear();
 linesATCD.clear();
 typesATCD     = G_pCApp->m_pAtcd_Code->m_Rubriques_ATCD_Med;
 typesATCDChir = G_pCApp->m_pAtcd_Code->m_Rubriques_ATCD_Chir;
 uint i;
 for ( i = 0; i < typesATCD.count();++i)
 { linesATCD << " "; }
 for ( i = 0; i < typesATCDChir.count();++i)
 { linesATCDChir << " "; }
 bool trouve = FALSE;		// Au moment de la recherche du type d'ATCD TRUE = trouvé, FALSE cas contraire


 while((pt = CGestIni::Param_GotoNextSection(pt, 0, &section)) && *pt)
 { if (medPrefix.find(TR("lineaire")) >= 0)
   { //...................... Extract_ATCD (lineaire) ........................

//      if (!G_pCApp->m_pAtcd_Code) return "";
//      G_pCApp->m_pAtcd_Code->getAtcdToTxt(resolvToken);

     if (section==TR("Antécédents"))
     { while (*pt && *pt != '[')
       {var_name = "";
	pt = CGestIni::Param_ExtraireNextValeurs(pt, var_name, &val1, &val2, &val3, &val4, &val5);
	// Nettoie et prépare la lisibilité des items de l'antécédent
	var_name.replace("\\,",",");	var_name.replace("\\;",";");	var_name.replace("\\[","[");
	var_name.replace("\\]","]");	val4.replace("\\,",",");	val4.replace("\\;",";");
	val4.replace("\\[","[");	val4.replace("\\]","]");

	// ATCD codé CIM 10 ==> alléger le libellé
	if (val3.left(1) == "~" )
	{ // Enlève SAI, le texte après la virgule, le texte entre parenthèse
	  var_name = var_name.replace(" SAI", "");
	  int deb  = var_name.find(",");
	  int fin  = -1;
	  if (deb != -1) var_name = var_name.left(deb);
	  int i = 0;
	   while ((var_name.find("(") != -1) || (i != 10))
	   { ++i;
	     deb = var_name.find("(");
	     fin = var_name.find(")", deb);
	     if (fin != -1)
	     { var_name = var_name.left(deb-1) + var_name.right(var_name.length() - fin - 1);
	     }
	     else break;
	   }
	  var_name = var_name.stripWhiteSpace();
	} // Fin ATCD CIM 10

	// Construction des lignes
	lineToInsert = var_name;                                // Libellé
	if (val4 != "") lineToInsert += " (" + val4 + ")";      // Note
	if (val5 != "") lineToInsert += " en " + val5.right(4); // Date
	trouve = FALSE;						// Initialisation avant recherche

	// Affecter à la bonne ligne selon catégories (médical, chirurgical, allergie)
	if (val3.left(1)=="(")         lineAllergToInsert += lineToInsert + ", ";
	else
	{  // Gestion compatibilité avec ancienne version de gestion des ATCD (Méd ou Chir)
	   if (val1==TR("Méd")) { linesATCD[0] += lineToInsert + ", "; trouve = TRUE; }
	   if (val1==TR("Chir")) { linesATCDChir[0] += lineToInsert + ", "; trouve = TRUE; }
	   else if (val1=="") { lineDiversToInsert += lineToInsert + ", "; trouve = TRUE; }
	   { // Recherche parmis les ATCD Médicaux
	     QString isChir = val1.left(4);
	     if (isChir != "Chir")
 	     { for (uint i = 0; i < typesATCD.count();++i)
	       { if (val1 == typesATCD[i])
	         { linesATCD[i] += lineToInsert + ", ";
	  	   trouve = TRUE;
	           break;
	         }
	       } // Fin For
	     } // Fin if isChir
	     // Si pas trouvé ==> recherche parmis les ATCD chirurgicaux
	     if (!trouve)
	     { for (uint i = 0; i < typesATCDChir.count();++i)
	       { if (val1 == typesATCDChir[i])
	         { linesATCDChir[i] += lineToInsert + ", ";
		   trouve = TRUE;
	           break;
	         }
	       } // Fin For
	     }
	     // Si toujours pas trouvé ==> met en Divers
	     if (!trouve) lineDiversToInsert += lineToInsert + ", ";
	   }

	}

	// Manque les ATCD gynéco-obstétriques

       }  //  Fin while
       section="";
     }  // Fin if section == "Antécédents"

     // Construction des phrases à insérer
     lineToInsert = "";
     int i;
     for ( i = 0; i < (int)typesATCD.count();++i)
     { if (linesATCD[i] != " ")
	{ lineToInsert += "- " + typesATCD[i] + "&nbsp;: " + linesATCD[i].left(linesATCD[i].length()-2) +"&nbsp;; " + "<br />\n";
	}
     }
     if (lineDiversToInsert != "")
	{ lineToInsert += "- " + TR("Autres") + "&nbsp;: " + lineDiversToInsert.left(lineDiversToInsert.length()-2) +"&nbsp;; " + "<br />\n";
	}
     if (lineAllergToInsert != "")
	{ lineToInsert += "- " + TR("Allergies") + "&nbsp;: " + lineAllergToInsert.left(lineAllergToInsert.length()-2) +"&nbsp;; " + "<br />\n";
	}
     for ( i = 0; i < (int)typesATCDChir.count();++i)
     { if (linesATCDChir[i] != " ")
	{ lineToInsert += "- " + typesATCDChir[i] + "&nbsp;: " + linesATCDChir[i].left(linesATCDChir[i].length()-2) +"&nbsp;; " + "<br />\n";
	}
     }


//     lineToInsert = lineMedToInsert + lineChirToInsert + lineAllergToInsert + lineDiversToInsert;
     if (lineToInsert.length()<=0)
     { //  Le patient n'a pas d'ATCD ou ils ne sont pas renseignés....
       lineToInsert = TR("Sans antécédents connus.");
     }
     else
     {	// Prépare la ligne globale
	lineToInsert.prepend( TR("Ses antécédents sont marqués par : ") + "<br />\n" );

       // Mettre le point final à la phrase
       lineToInsert = lineToInsert.left(lineToInsert.length()-15) + ". <br />\n";
     }
     resolvToken = lineToInsert ;

   } // Fin if "lineaire"
   else
     {     //.................................. ATCD ........................................................;
           if (section==TR("Antécédents"))
             {
                while (*pt && *pt != '[')                      // libelle  med/chir    etat     code   commentaire date
                  {pt = CGestIni::Param_ExtraireNextValeurs(pt, var_name, &val1, &val2, &val3, &val4, &val5);
                   var_name.replace("\\,",",");  var_name.replace("\\;",";");   var_name.replace("\\[","["); var_name.replace("\\]","]");
                   val4.replace("\\,",",");      val4.replace("\\;",";");       val4.replace("\\[","[");     val4.replace("\\]","]");

                   //...................... remplacer les paterne ...................................
                   lineToInsert = linePatern;
                   if (var_name.lower().endsWith(" sai")) var_name.truncate(var_name.length()-4);
                   lineToInsert.replace("::LIBELLE::", var_name);
                   lineToInsert.replace("::MEDCHIR::", val1);
                   lineToInsert.replace("::ETAT::",    val2);
                   lineToInsert.replace("::CODE::",    val3);
                   lineToInsert.replace("::NOTE::",    val4);
                   if (val5.length())
                      {val5.prepend(datePrefix);
                       lineToInsert.replace("::DATE::",    val5);
                      }
                   else
                      {lineToInsert.replace("::DATE::",    "");
                      }
                   //...................... affecter selon catégories ................................
                   if (val3.left(1)=="(")                       lineAllergToInsert += lineToInsert + "<br />";
                   else if (val1.left(3).lower()== TR("Méd"))   lineMedToInsert    += lineToInsert + "<br />";
                   else if (val1.left(3).lower()== TR("Chir"))  lineChirToInsert   += lineToInsert + "<br />";
                   else                                         lineDiversToInsert += lineToInsert + "<br />";
                  }  // Fin while *pt
                section="";
             }  // Fin if section = antécédents
        } // Fin ......... Extract_ATCD (1,2,3,4,5) ...........
    } // Fin while section

 if (medPrefix.find(TR("lineaire")) == -1)
    {
        if (lineToInsert.length()<=0)    return QString("");
        if (lineMedToInsert.length())    lineMedToInsert.prepend(medPrefix+"<br />");
        if (lineChirToInsert.length())   lineChirToInsert.prepend(chirPrefix+"<br />");
        if (lineAllergToInsert.length()) lineAllergToInsert.prepend(allergPrefix+"<br />");
        if (lineDiversToInsert.length()) lineDiversToInsert.prepend(diversPrefix+"<br />");
        resolvToken = lineMedToInsert + lineChirToInsert + lineAllergToInsert + lineDiversToInsert;
    }
 return    resolvToken;
}
//------------------------ GetDateOfActiveRubrique -------------------------------------
/*! \brief Retourne la date du document en cours */
QString C_TokenInterpret::GetDateOfActiveRubrique()
{
  if (G_mCDC &&G_mCDC->m_pCRubCurrentRecord ) return G_mCDC->m_pCRubCurrentRecord->m_Date;
  else                               return QString(" ");
}


//-------------------- GetPoidsTaille --------------------------------------------
/*! \brief Retourne le poids et la taille.
 *  \todo pour faciliter débuggage utiliser Var_Code
*/
void C_TokenInterpret::GetPoidsTaille(const char* pt_doc, QString &tableau, QString &poids_name, QString &taille_name, QString &poids_var, QString &taille_var)
{poids_var      = "";
 taille_var     = "";
 if (pt_doc==0 || strlen(pt_doc)==0)    return;
 tableau        = tableau.stripWhiteSpace();
 poids_name     = poids_name.stripWhiteSpace();
 taille_name    = taille_name.stripWhiteSpace();
 //..................... recuperer la date ........................................
 char *pt = (char*) pt_doc;
 //........... effacer les anciennes tables de variables ................
 QString       strTab[10];
 QString      section   = "";
 QString     var_name   = "";

 while((pt = CGestIni::Param_GotoNextSection(pt, 0, &section)) && *pt)
    {if (section == tableau )                  // à ce stade pt pointe au debut de la nouvelle ligne
        {int               n_var   = 0;
         int    pos_poids_to_get   = -1;
         int   pos_taille_to_get   = -1;
         while (*pt && *pt != '[')
               {var_name = "";
                pt   = CGestIni::Param_ExtraireNextValeurs(pt, var_name, &strTab[0], &strTab[1], &strTab[2], &strTab[3], &strTab[4], &strTab[5], &strTab[6], &strTab[7], &strTab[8]);
                //...................... DEFINITION DE VARIABLE .....................................
                //                       contruire le dialogue des variables
                if (var_name== TR("Modèle") )
                   {if (pos_poids_to_get  == -1 && strTab[1] == poids_name)  pos_poids_to_get  = n_var;   // noter la position de la variable
                    if (pos_taille_to_get == -1 && strTab[1] == taille_name) pos_taille_to_get = n_var;   // noter la position de la variable
                    n_var++;
                   } // endif (var_name=="Modèle")
                 //................ VALEURS DATEES DE VARIABLE ........................................
                 else if (pos_poids_to_get!= -1 && var_name !="" ) // var_name  reçoit la date
                   {poids_var = strTab[pos_poids_to_get];
                   }
                 //................ VALEURS DATEES DE VARIABLE ........................................
                 else if (pos_taille_to_get!= -1 && var_name !="" ) // var_name  reçoit la date
                   {taille_var = strTab[pos_taille_to_get];
                   }
               } // end while (*pt && *pt != '[')
         section="";
        } // endif (section.left(3)=="VAR" )
    } // end while((pt=m_pMB->Param_GotoNextSection(pt, 0, &section)) && *pt)
}


//------------------------------------------ GetVarNeerer --------------------------------------------------------
/*! \brief Récupère toutes la valeurs de la variable la plus poche de la date passée en entrée
 * \param QString section         la section de la variable  (VAR Poids)
 * \param QString variable        la variable en question    (Poids)
 * \param QString dateSel         la date voulue en format String ISO
 * \return QString de la valeurs sans sa date
 * EXEMPLE :
 *      QString sect = "VAR Poids";
 *      QString varn = "Poids";
 *      QString datePlusProche = "2007-09-23T13:00:00"
 *      QString valeurPlusProche = GetVarNeerer ( sect, varn, datePlusProche);
 *  \todo Pour améliorer débuggage utiliser Var_Code
*/
//-----------------------------------------------------------------------------------------------------------------
QString C_TokenInterpret::GetVarNeerer (QString &section, QString &variable, QString &dateSel)
{  QStringList valeurs          = GetVar (section, variable);
   QString     valeurPlusProche = GetVarNeerer ( valeurs, dateSel);
   QStringList ret = QStringList::split( "/;/" , valeurPlusProche);
   if (ret.count()>=2) return ret[1];
   else                return QString::null;
}

//------------------------------------------ GetVarNeerer --------------------------------------------------------
/*! \brief Récupère toutes la valeurs de la variable la plus poche de la date passée en entrée
 * \param QStringList     les valeurs datées (renvoyées par GetVar)
 * \param QString         la date voulue en format String ISO
 * \return QString de la valeurs datée au format :   DATE/;/VALEUR
 * EXEMPLE :
 *      QString sect = "VAR Poids";
 *      QString varn = "Poids";
 *      QStringList valeurs = GetVar (sect, svarn);
 *      QString datePlusProche = "2007-09-23T13:00:00"
 *      QString valeurPlusProche = GetVarNeerer ( valeurs, datePlusProche);
 *  \todo Pour améliorer débuggage utiliser Var_Code
*/
//-----------------------------------------------------------------------------------
QString C_TokenInterpret::GetVarNeerer (QStringList &valuesList, QString &dateSel)
{if (valuesList.count() != 0 )
 {long          secondsToVar;
  long          secondsToRecent;
  QString       mostRecentVal = "";
  QString       sDate = dateSel.stripWhiteSpace();
  QDateTime     varQDate;
  QDateTime     dt = QDateTime::fromString( sDate , Qt::ISODate );   // DATE VISITE

  if (valuesList.count() == 1)
   {    //varDateVal = QStringList::split( "/;/", values[0]);
        //return varDateVal[1];
        return valuesList[0];
   }
  // trie de façon ascendante par la date (valeurVar[0] = la plus ancienne)
  valuesList.sort();

  // récupère dans varDate la première date comme référence la plus ancienne
  QStringList varDateValList    = QStringList::split( "/;/", valuesList[0]);
  QDateTime   varQDateRecent    = varQDateRecent.fromString(varDateValList[0] , Qt::ISODate);
  mostRecentVal                 = valuesList[0];        // au cas où il n'y aurait qu'une seule valeur...

  for (int i = 1; i < (int)valuesList.count(); ++i)
    {   varDateValList = QStringList::split( "/;/", valuesList[i] );
        varQDate       = varQDate.fromString(varDateValList[0], Qt::ISODate);

        // Compare le nombre de secondes entre DATE VISITE et les deux dates
        secondsToVar    = varQDate.secsTo(dt);
        secondsToRecent = varQDateRecent.secsTo(dt);
        if (secondsToVar < 0)         secondsToVar          = secondsToVar * (-1);
        if (secondsToRecent < 0)      secondsToRecent       = secondsToRecent * (-1);

    if (secondsToVar < secondsToRecent)
        { mostRecentVal  = valuesList[i];
          varQDateRecent = varQDate;
        }
     } // Fin  for

  return mostRecentVal;
 } // Fin if count > 0
 return "";
}


//------------------------------------------ GetVar ---------------------------------------------------------------
/*! \brief Récupère toutes les valeurs de la variable incluse dans section section_var de la rubrique Terrain
    \todo Utiliser Var_Code pour améliorer le débuggage
*/
// ENTREE :
//      section_var     : section
//      nalme_var       :le nom de la variable
// SORTIE :
//      QStringList des valeurs triés en ascendant des valeurs
// FORMAT DES DONNEES :
//      DATE/;/VALEUR
//
//  EXEMPLE :
//      QString sect = "VAR Poids";
//      QString varn = "Poids";
//      QStringList valeurs = GetVar (&sect, &varn);
//-----------------------------------------------------------------------------------------------------------------
QStringList C_TokenInterpret::GetVar (QString &section_var, QString &name_var)
{// recuperer données soit dans liste cache soit sur disque
 QString   str_data    = G_mCDC->m_pMB->GetDataFromRubList( GetIDCurrentDoc(TR("Terrain")) );
 if (str_data.length()==0)              return QString(" ");
 char *pt = (char*) (const char*) str_data;

 //........... effacer les anciennes tables de variables ................
 //
 QString       strTab[10];
 QString      section   = "";
 QString     var_name   = "";

 // char     *prop_section = 0;       // permet de noter le pointeur sur la section propriete renouvelable/intercurent des produits
 QStringList  valeurVar;        // récupère toutes les valeurs de VAR_name ainsi que leur date séparées par /;/

 while((pt = CGestIni::Param_GotoNextSection(pt, 0, &section)) && *pt)
    {//.................................. VAR ........................................................
     if (section == section_var )                  // à ce stade pt pointe au debut de la nouvelle ligne
        {int        n_var      = 0;
         int   pos_var_to_get  = -1;
         while (*pt && *pt != '[')
               {var_name = "";
                pt   = CGestIni::Param_ExtraireNextValeurs(pt, var_name, &strTab[0], &strTab[1], &strTab[2], &strTab[3], &strTab[4], &strTab[5], &strTab[6], &strTab[7], &strTab[8]);
                //...................... DEFINITION DE VARIABLE .....................................
                //                       contruire le dialogue des variables
                if (var_name==TR("Modèle"))
                   {if (pos_var_to_get == -1 && strTab[1] == name_var) pos_var_to_get = n_var;   // noter la position de la variable
                    n_var++;
                   } // fin Modèle
                 //................ VALEURS DATEES DE VARIABLE ........................................
                 else if (pos_var_to_get != -1 && var_name !="" &&  strTab[pos_var_to_get] != "") // var_name = la date
                   {// Récupère les valeurs et les dates de la variable demandée dans les listes
                    valeurVar.append(var_name+"/;/"+strTab[pos_var_to_get]);
                   }
               } // end while (*pt && *pt != '[')
         section="";
        } // end if section_VAR

    } // end while
 return valeurVar;
}

//----------------------------- Func_Extract_VAR --------------------------------------
/*! \brief Extrait les variables selon le modèle demandé.
 *  \todo Utiliser Var_Code pour améliorer débuggage.
*/
//   [VAR Constantes de Base]
//      Modèle = Date, Pouls, 31536000, 130, 40, pps, Tachycardie, Bradycardie
//      Modèle = Date, SAO2, 31536000, 0, 92, %, , Hypoxie
//      Modèle = Date, Temp, 31536000, 40.5, 35, ?, Hyporthermie, Hyperthermie
//   [VAR Poids]
//      Modèle = Date, Poids,  31536000, 100, 50, Kg(s), Obésité, Amaigrissement
//      Modèle = Date, Taille, 31536000, 0, 0, cm(s),,
//
//      {{:: Extract_VAR (VAR Constantes de Base , SAO2 , DATE VISITE ,   0  , TOUTES )}}
//      {{:: Extract_VAR (VAR Constantes de Base , SAO2 , DATE VISITE , -24  , PREMIERE )}}
//      {{:: Extract_VAR (VAR Constantes de Base , SAO2 , DATE VISITE , +24  , DERNIERE )}}
//      {{:: Extract_VAR (VAR Constantes de Base , SAO2 , DATE VISITE , +-24 , PLUS PROCHE )}}

QString C_TokenInterpret::Func_Extract_VAR(QString &section_VAR, QString &name_VAR, QString &date_deb, QString &date_end, QString &date_intervalle)
{QString   resolvToken = "";

 section_VAR = section_VAR.stripWhiteSpace();
 name_VAR    = name_VAR.stripWhiteSpace();
 date_deb    = date_deb.stripWhiteSpace();
 date_end    = date_end.stripWhiteSpace();
 date_intervalle = date_intervalle.stripWhiteSpace().lower();

 //..................... récupère les valeurs et leurs dates ......................................
 QStringList valeurVar = GetVar(section_VAR, name_VAR);

 //..................... recuperer la date du document ............................................
 QString str_date = GetDateOfActiveRubrique();

//      {{:: Extract_VAR (VAR Constantes de Base , SAO2 , DATE VISITE ,   0  , TOUTES )}}
//              Insère un tableau avec toutes les valeurs

//      {{:: Extract_VAR (VAR Constantes de Base , SAO2 , DATE VISITE , -24  , PREMIERE )}}
//              Insère la valeur chronologiquement la plus ancienne

//      {{:: Extract_VAR (VAR Constantes de Base , SAO2 , DATE VISITE , +24  , DERNIERE )}}
//              Insère la valeur chronologiquement la plus récente (voir futuriste...)

//      {{:: Extract_VAR (VAR Constantes de Base , SAO2 , DATE VISITE , +-24 , PLUS PROCHE )}}
//              Insère la valeur la plus proche (à la seconde près) de la date qu'elle soit antérieure ou postérieure à l'observation

  if (!valeurVar.isEmpty ())
   {
     QString            varDateStr;
     QDateTime          varDate;
     QDateTime          varDateMostRecent;
     QStringList        varDateVal;  // en  0 -> date ; en 1 -> valeur de la variable

     if (date_intervalle == "toutes")                                                           // Testé = OK
      { QString tableau;
        // tri les valeurs selon leur date  -- tri ascendant
        valeurVar.sort();

        // crée l'entete du tableau
        tableau =   "<table border=1 cellpadding=2 cellspacing=2>";
        tableau +=  "<tr><td><center><b>Date</b></center></td><td><center><b>";
        tableau +=  name_VAR + "</b></center></td></tr>";

        // insère les valeurs retrouvées
        for( int i = 0; i < (int)valeurVar.count() ; ++i)
         {
          varDateVal = QStringList::split( "/;/", valeurVar[i] );
          varDateVal[0].replace("T","&nbsp;&nbsp;");
          tableau += "<tr><td>"+varDateVal[0]+"</td><td>" +varDateVal[1] + "</td></tr>";
         }

        // Fin du tableau
        tableau += "</table><br /><br />";
        resolvToken = tableau;
      }
     else if (date_intervalle == TR("derniere"))                                                    // AMELIORABLE
      { valeurVar.sort();
        varDateVal = QStringList::split( "/;/", valeurVar.last () );
        resolvToken = varDateVal[1];
      }
     else if (date_intervalle == TR("premiere"))                                                   // AMELIORABLE
      { valeurVar.sort();
        varDateVal = QStringList::split( "/;/", valeurVar[0] );
        resolvToken = varDateVal[1];
      }
     else if (date_intervalle == TR("plus proche"))                                                 // Testé = OK
          { /*QString mostRecent = GetVarNeerer( valeurVar , str_date );
            varDateVal = QStringList::split( "/;/", mostRecent );
            resolvToken = varDateVal[1];*/
            resolvToken = GetVarNeerer ( section_VAR, name_VAR, str_date);
          }
  } // Fin si des valeurs ont été trouvées
  else
  { resolvToken = TR("Pas de valeur trouvée pour ") + name_VAR; }

  return    resolvToken;
}

//--------------------------- Func_Extract ---------------------------------------------------
/*! \brief Extrait une partie du texte du document selon le modèle demandé */
QString C_TokenInterpret::Func_Extract(QString &doc_type, QString &tag_deb, QString &tag_end, QString &find_to, QString &replace_by, const QString justNum)
{QString   resolvToken    = "";
 const char* pt_doc       = 0;
 char*       deb          = 0;
 char    *debEndMotif     = 0;
 QString     var_nameRech = "";
 QString     var_nameRepl = "";
 QString     str_data     = "";
 doc_type   = doc_type.stripWhiteSpace();
 tag_deb    = tag_deb.stripWhiteSpace();
 tag_end    = tag_end.stripWhiteSpace();
 find_to    = find_to.stripWhiteSpace();
 replace_by = replace_by.stripWhiteSpace();
 if (doc_type.length()>0)
    {str_data    = G_mCDC->m_pMB->GetDataFromRubList( GetIDCurrentDoc(doc_type) );       // recuperer données soit dans liste cache soit sur disque
     if (str_data.length()==0)              return resolvToken;
     pt_doc      = (char*) (const char*) str_data;
    }
 if (tag_deb.length()) deb = CHtmlTools::HtmlFind(pt_doc, tag_deb);
 if (deb && tag_end.length())
    {CHtmlTools::HtmlFind(deb, tag_end, &debEndMotif);
     if (debEndMotif)
        {resolvToken.setLatin1 (deb, debEndMotif - deb);
         CHtmlTools::HtmlToAscii(resolvToken);
         if ( find_to.length() )
            {if ( resolvToken.find(find_to,0,TRUE) != -1)
                {resolvToken = replace_by;
                }
             else                                         resolvToken = "";
            }
         resolvToken.replace("\n","<br />");       // Remplace les sauts de lignes ASCII par les sauts de ligne HTML
         resolvToken.replace("\r","");             // pour les puristes...resolvToken=resolvToken.stripWhiteSpace();
        }
     }
 if (justNum.length()) return  toNum(resolvToken);
 else                  return  resolvToken;
}

//--------------------------------- GetIDCurrentDoc -----------------------------------------------------
/*! \brief Retourne le CRubRecord correspondant au document actuellement affiché dans la CMDI gérant le doc_type.
*/
CRubRecord  *C_TokenInterpret::GetIDCurrentDoc(const QString &doc_type)
{CRubRecord  *pCRubRecordRet = 0;
 //................... si non précisé retourner la rubrique courante..............................
 if (doc_type.length()==0||doc_type==TR("*"))
    { CMDI_Generic *pCMDI_Generic   =  G_pCApp->GetCurrentRubrique();
      if (pCMDI_Generic)
         {RUBREC_LIST::iterator rit = pCMDI_Generic->Current_RubList_Iterator();
          if (rit != G_mCDC->m_pRubList->end())
             { pCRubRecordRet = &(*rit);
               return pCRubRecordRet;
             }
         }
    }
 //................... on cherche celui de la map (ceux en cours d'affichage)..............................
 DOCUMENT_DISPLAY_MAP::Iterator it = G_mCDC->m_pCurDisplayDocMap->find ( doc_type );
 if (! (it == G_mCDC->m_pCurDisplayDocMap->end()) ) return it.data();
 //...................................... si pas trouve on va rechercher le dernier .........................
 //                                       correspondant au type numerique dans la liste generale
 QString doc_type_num = doc_type;
 if ( ! (doc_type[0]>='0' && doc_type[0]<='9') ) // si pas exprime sous forme numerique alors on convertit
    {doc_type_num = G_pCApp->RubNameToStringType(doc_type);
    }
 //................... si pas trouve on cherche le dernier correspondant...................................
 CRubRecord  *pCRubRecord    = 0;
 RUBREC_LIST::Iterator ut ;

 for ( ut = G_mCDC->m_pRubList->begin(); ut != G_mCDC->m_pRubList->end(); ++ut )
     {pCRubRecord = &(*ut);
      if ( pCRubRecord->m_Type==doc_type_num) pCRubRecordRet = pCRubRecord;
     }
 return pCRubRecordRet;
}


//--------------------------- DocNameToDocNumType --------------------------------------------------
/*! \brief Transforme le nom de la rubrique en son équivalent numérique. Exemple : "Observation" -> "20030000"
*/
/*
QString C_TokenInterpret::DocNameToDocNumType(const QString &doc_name, int part / * = 8 * /)
{QString ret = "";

 const char *c = doc_name;
 switch (*c)
   {case 'U':                             ret = "20040000"; break;      //TYP_URG_OBSERV
    case 'O':                             ret = QString::number(CMDI_Observation::S_GetType()); break;
    case 'P':                             ret = "20020000"; break;
    case 'T':                             ret = "20060000"; break;
    case 'D':                             ret = "20080000"; break;
    case 'I':                             ret = "20080000"; break;
    case 'C':
         {if (doc_name== "Courrier")      ret = "20020500"; break;
          if (doc_name== "Certificat")    ret = "20020300"; break;
         }
   }
  return ret.left(part);
    m_ListRubName.append(CMDI_Observation::S_GetRubName());
    m_ListRubName.append(CMDI_Prescription::S_GetRubName());
    m_ListRubName.append(CMDI_Documents::S_GetRubName());
    m_ListRubName.append(CMDI_Terrain::S_GetRubName());
    m_ListRubName.append(CMDI_Ident::S_GetRubName());
    m_ListRubName.append(CMDI_ChoixPatient::S_GetRubName());

}
*/
//------------------------------ RelPathToAbsPath ---------------------------------------
QString & C_TokenInterpret::RelPathToAbsPath(QString &path)
{ int pos     = -1;
  int deb     = -1;
  QString tmp = "";
  if ((pos = path.findRev("$EndToAbsPath")) != -1)
     {do
       { if ( (deb = path.findRev("$ToAbsPath"),pos) != -1)
           { path = path.remove(pos,13);   // virer le $EndToAbsPath
             tmp  = QDir::cleanDirPath (G_pCApp->m_PathAppli + path.mid(deb+10, pos - deb -10).stripWhiteSpace());
             path = path.replace (deb, pos - deb, tmp );
             pos  = path.findRev("$EndToAbsPath", deb);
           }
        else
           { pos = -1;
           }
      } while (pos != -1);
       return path;
     }
   else if ( (pos = path.find("$ToAbsPath")) != -1)
     { path = path.left(pos) + QDir::cleanDirPath (G_pCApp->m_PathAppli + path.mid(pos+10).stripWhiteSpace());
       return path;
     }
 return path;
}

//-------------------------- extractArgList -------------------------------------------
/*! \brief non documenté */
long C_TokenInterpret::extractArgList(QStringList &arg_list, const QString &arg_str)
{char   *deb  = (char*)(const char*) arg_str;
 char   *pt   = deb;
 long    len  = 0;
 if (pt==0)                           return -1;
 while(pt && *pt)
    {if (pt[0] == '\\')
        {pt += 2;
        }
     else if (pt[0] == ',')
        {
         len =  pt-deb;
         ++pt;
         if (len==0) arg_list.append( "" );
         else
           {QString s = QString::fromAscii(deb, len );
                    s = s.replace("\\\\","!°!;:");
                    s = s.remove("\\");
                    s = s.replace("!°!;:","\\");
            arg_list.append( s);
           }
         deb = pt;
        }
     else
        {++pt;
        }
    }
 len =  pt-deb;
 if (len==0) arg_list.append( "" );
 else
    {QString s = QString::fromAscii(deb, len );
             s = s.replace("\\\\","!°!;:");
             s = s.remove("\\");
             s = s.replace("!°!;:","\\");
     arg_list.append( s);
    }
 return 1;
}
//--------------------=-------- findLastDelimiter -----------------------------------------------
/*! \brief Pour la récursivité. */
long C_TokenInterpret::findLastDelimiter(QString &str, char delimiter)
{char *deb = (char*)(const char*) str;
 char *pt  = deb;
 if (pt==0)                           return -1;
 while(pt && *pt)
    {if (pt[0] == '\\') pt += 2;
     else
        {if (pt[0] == delimiter)      return pt - deb;
         ++pt;
        }
    }
                                      return -1;
}

//------------------------------------------ GetDDR -----------------------------------------------------------------
/*! \brief Récupère dans le terrain la date des dernières règles en cas de grossesse. Retourne la date au format QT::ISODate ou QString(" ") si n'est pas trouvé.
 * \todo utiliser Atcd_Code
*/
QString C_TokenInterpret::GetDDR()
{ QString tmp1;
  // recuperer données soit dans liste cache soit sur disque
   QString   str_data    = G_mCDC->m_pMB->GetDataFromRubList( GetIDCurrentDoc(TR("Terrain")) );
   if (str_data.length()==0)              return QString(" ");
   char *pt = (char*) (const char*) str_data;

   //........... effacer les anciennes tables de variables ................
   QString   section   = "";
   QString   var_name   = "";

   //char     *prop_section = 0;       // permet de noter le pointeur sur la section propriete renouvelable/intercurent des produits

   while((pt = CGestIni::Param_GotoNextSection(pt, 0, &section)) && *pt)
    {//.................................. Obstétrique ........................................................;
     if (section == TR("Obstétrique"))// && m_IsFeminin == 1)                  // à ce stade pt pointe au debut de la nouvelle ligne
        {
         while (*pt && *pt != '[')
               {pt = CGestIni::Param_ExtraireNextValeurs(pt, var_name, &tmp1); // 18-03-2004
                if (var_name == TR("Grossesse") && tmp1 != TR("non"))   // val1 contient non ou ddr sauvegardée
                   {    tmp1 = tmp1.mid(6) + "-" + tmp1.mid(3,2) + "-" + tmp1.left(2);
                        return tmp1;
                   }
               }// Fin while [
         section="";
        } // Fin if section
    } // Fin while Section

  return QString(" ");

}

//------------------------------------------ Terme_Obst -------------------------------------------------------------
/*! \brief Calcul le terme de la grossesse à la date souhaitée.
 *  \param QDate DDR       Date des dernières règles
 *  \param QDate dt        Date pour le calcul
 *  \return Le terme au format string du style : " XX SA XX Jours "
 *  \todo à déplacer dans Atcd_Code.
*/
QString C_TokenInterpret::Terme_Obst(QDate DDR , QDate dt)
{ int nbDays = DDR.daysTo(dt);
  int nbDaysLeft = nbDays % 7;
  int nbWeeks = (nbDays - nbDaysLeft ) / 7;
  QString ret;

  if (dt < DDR) { ret = TR("Le terme n'est pas calculable (terme négatif). Vérifiez vos dates."); }
  else if (nbWeeks > 45) { ret = TR("Le terme n'est pas calculable (> 45 SA). Vérifiez vos dates."); }
  else { ret = QString::number(nbWeeks) + " SA "+ QString::number(nbDaysLeft) + TR(" Jours "); }

  return ret;
}


//------------------------------------------ Terme_Obst -----------------------------------------
/*! \brief Calcul le terme de la grossesse à la date souhaitée.
 *  \param QString DDR     Date des dernières règles format ISODate
 *  \param QDate dt        Date pour le calcul
 *  \return Le terme au format string du style : " XX SA XX Jours "
 */
QString C_TokenInterpret::Terme_Obst(QString DDR , QDate dt)
{ if (DDR == "" || DDR == " ") return " ";
  QDate DDR_dt = DDR_dt.fromString ( DDR , Qt::ISODate);

  return Terme_Obst(DDR_dt , dt)        ;
}

//------------------------------------------ toNum -----------------------------------------
/*! \brief ne retient d'une chaine de caracteres que les valeurs numeriques et le point (au passage les virgules seront transformees en point).
 *  \param text const char* DDR     Date des dernières règles format ISODate
 *  \return une QString resultat du traitement
 */
QString C_TokenInterpret::toNum(const char *text)
{QString str("");
 char* pt = (char*)text;
 if (pt==0) return str;
 while (*pt)
       {if (  (*pt>='0' && *pt<='9') || *pt=='.') str += *pt;
        else if ( *pt==',')                       str += '.';
        ++pt;
       }
 return str;
}

//-------------------------------------- FindToken ----------------------------------------------------------------
/*! \brief ne retient d'une chaine de caracteres que les valeurs numeriques et le point (au passage les virgules seront transformees en point).
 *  \param tokenToFind const QString &tokenToFind : token  a rechercher
 *  \param document const QString &document : document dans lequel rechercher le token
 *  \param fin int * : si different de zero il y sra retourne la fin du token dans le document
 *  \return un int si -1 pas trouve sinon position du token dans le documnt.
 */
int C_TokenInterpret::FindToken(const QString &tokenToFind, const QString &document, int *fin /* = 0*/)
{int deb = -1;
 FindToken(0, document.length(), tokenToFind, document, &deb, fin);
 return deb;
}

int C_TokenInterpret::FindToken(int pos_deb, int pos_max, const QString &tokenToFind, const QString &document, int *deb, int *fin /* = 0*/)
{int isWithToken   =  0;
 int pos_end       =  0;
     pos_deb       =  document.find("{{", pos_deb);
 while (pos_deb != -1 && pos_deb < pos_max)
       {pos_end        =  CGestIni::findFermant(&document, pos_deb+2, pos_max, "{{", "}}", isWithToken);
        if (isWithToken)
           { pos_max  = FindToken(pos_deb+2, pos_end, tokenToFind, document, deb,fin);
           }
        else
           {QString token     = document.mid(pos_deb+2, pos_end - pos_deb-2).upper();
            if (token.find(tokenToFind) != -1)
               {int pos;
                if (token.startsWith("::"))
                  { token = token.mid(2);
                    pos   =  token.find('(');
                    if (pos != -1) {token.truncate(pos);}
                    token = token.remove('#');
                  }
                else
                  {pos   =  token.find('=');
                   if (pos != -1) {token.truncate(pos);}
                  }
                token = token.stripWhiteSpace();
                if (token==tokenToFind)
                   {if (fin) *fin = pos_end;
                    *deb = pos_deb;
                    return 0;        // pos max devient Zero si recursivite engagee et donc fin de la boucl
                   }
               }
            pos_deb   =  document.find("{{", pos_deb+2);
           }
       }
  return pos_max;
}
