* Nom........: wNtkDict.PRG
* But........: Librairie des fonctions pour la gestion des dictionnaires
*              des données (Info-Base: .Dic) et d'index (Index-Base: .IDC)
*              d'une application.
*              Inclu: MakeSpecialButton() et IsSpecialBtnClicked() pour
*              l'arrêt des processus et traitements longs dont la gestion
*              des événements est assurée de façon asynchrone par NtkInkey(-1)
* Date.......: 01.04.2007 - 12.05.2007
* Auteur(s)..: Jn Dechereux


// Ntk Includes
#include "windows.ch"
#include "ntkcctrl.ch"
#include "ntkdll.ch"
#include "ntkgdi.ch"
#include "ntkmsg.ch"
**#include "ntkacc.ch"
#include "ntkdlg.ch"
*#include "ntkmenus.ch"
#include "ntkbtn.ch"
**#include "ntkedget.ch"
#include "ntkcmd.ch"
**#include "ntkcmdEx.ch"
#include "ntkdbdic.ch"
#include "wNtk.ch"
#include "wNtkKeys.ch"


#define	ID_BTNCANCEL    8599	   // unique id (used for the Special Push Button)


*************************************************************************************************
********
******** Examiner les tables d'une Info-Base (.DIC) selon le mode souhaité:
******** NTK_DBDIC_CREATE ou NTK_DBDIC_UPDATE.
********
******** Exemple: InfoBaseCheckUp( hWnd, "COMP.DIC", NTK_DBDIC_CREATE, P__FILES )
********
FUNCTION InfoBaseCheckUp( hWndP, cDicName, cCheckMode, cPathDest )
LOCAL nRet
LOCAL cGaugeText := "Contrôle des tables la Base de données - Patientez..."
PRIVATE oGauge

Default hWndP To NTK_SelectWindow()
NTK_EnableWindow( hWndP, .F. )

oGauge := TSGauge():Init(hWndP,;                   // Handle to parent window
                     WS_POPUP+WS_DLGFRAME,;        // Style of the window-box that will encapsulate the gauge
                     50,05,;                       // Width,Height of the gauge
                     WS_DLGFRAME+PBS_SMOOTH,;      // Gauge's style
                     cGaugeText ,;                 // Text string of the encapsultating box
                     {000,000,128},;               // Text string's rgb colors.
                     nil     ,;                    // Handle to the Bitmap used to paint the bkg of the encapsulting box
                     02.5,01,03.1,48 )             // Gauge rectangle coordinates inside the encapsulating box


// --  Remove the followings lines to allow end-user to Cancel current process
** // Syntaxe MakeSpecialButton( hWndP, nID, nTop, nLeft, nHeight, nSize, cBtnText, hFontBtn, nStyleBtn )
** aSpecBtnInfos := MakeSpecialButton( oGauge:gshWnd, ID_BTNCANCEL, 3.5, 17, 01, 15, "Ech=Abandon" )



oGauge:SetBarColor( NTK_RGB(255,000,000) )        // Set the the progress bar foreground color
// ---- Sets subtitle appearence
oGauge:SetSubTitle( cGaugeText )
oGauge:gsTextFgColor := NTK_RGB(255,000,000)
oGauge:gsTextBgColor := NTK_RGB(255,255,255)
oGauge:gssTitleFont  := NTK_GetStockObject( ANSI_VAR_FONT )



// ***** Syntaxe: NtkDBDIC_CheckUp( "mainapp.dic", nil, NTK_DBDIC_CREATE,  "c:\myapp\files\", {|cTableName,nPos,nMax,cMode| GaugeUpdate( hWnd,cTableName,nTablePos,nTableMax,cMode )} )
nRet := NtkDBDIC_CheckUp( cDicName ,;  // Info-Base (Data Dictionary, .DIC file) to examine...
                  nil,;                // Nil means: Probe all tables of the .DIC. Otherwise, you can specified the name of a particular DBF to checkup.
                  cCheckMode,;         // Probe Mode: Create or update tables (see \WNTK4HRB\INCLUDE\NTKDBDIC.CH)
                  cPathDest,;          // Path where tables are located and should be created or updated (depending on Probe Mode)
                  {|cTableName,nTablePos,nTableMax,cMode| InfoBaseCheckUpGauge(hWndP,cTableName,nTablePos,nTableMax,cMode, nil ) } ) // Code Block to be evaluated for each table of the Info-Base (.DIC) probed.
**                  {|cTableName,nTablePos,nTableMax,cMode| InfoBaseCheckUpGauge(hWndP,cTableName,nTablePos,nTableMax,cMode, aSpecBtnInfos ) } ) // Code Block to be evaluated for each table of the Info-Base (.DIC) probed.


oGauge:Close()

NTK_EnableWindow( hWndP, .T. )
NTK_SelectWindow( hWndP )
NTK_SetFocus( hWndP )

IF nRet == -1
   NTK_MessageBox( hWndP, "Le chemin d'accès au serveur de fichiers n'est pas valide.", "Erreur! - Vérification B.D.D.", MB_OK+MB_ICONSTOP )
ELSEIF nRET == -2
   NTK_MessageBox( hWndP, "Impossible d'ouvrir l'Info-Base : "+AllTrim(cDicName), "Erreur! - Vérification B.D.D.", MB_OK+MB_ICONSTOP )
ELSEIF nRET == -3
   NTK_MessageBox( hWndP, "Certaines Tables de l'Info-Base n'ont pas pu être traitées.", "Alerte! - Vérification B.D.D.", MB_OK+MB_ICONEXCLAMATION )
ELSEIF nRET == -9
   NTK_MessageBox( hWndP, "Traitement interrompu par abandon délibéré de l'utilisateur.", "Alerte! - Vérification B.D.D.", MB_OK+MB_ICONEXCLAMATION )
ELSE
**   NTK_MessageBox( hWndP, "Toutes les Tables de " +AllTrim(cIdcName)+ " ont été vérifiées ou créées avec succès.", "information!", MB_OK+MB_ICONINFORMATION)
ENDIF

RETURN( nil  )
******
******
******
FUNCTION InfoBaseCheckUpGauge(hWndP,cTableName,nTablePos,nTableMax,cMode,aSpecBtnInfos)
LOCAL cMsg := ""
LOCAL nGaugePos

cMsg := "NE SURTOUT PAS INTERROMPRE. - PATIENTEZ..."+CHR(13)+;
        IIF( cMode==NTK_DBDIC_CREATE, "Création de ", "Mise à Jour de " ) +;
        cTableName + " - Table " + AllTrim(Str(nTablePos)) +"/"+ AllTrim(Str(nTableMax))


oGauge:SetSubTitle( cMsg )
oGauge:Repaint()
nGaugePos := IIF( nTableMax==0, 0,  (nTablePos*100)/nTableMax  )
oGauge:Update(nGaugePos)


NtkInkey(-1)  // Create a non standard wait-state, but an asynchronous one. Just
              // for detecting some Keyb+mouse events in Windows message queue
              // and then to tell him our process is always alive...

// --  Remove the following lines to allow end-user to Cancel current process
**IF NTK_Lastkey()==K_ESC  .OR. IsSpecialBtnClicked( aSpecBtnInfos )
**   nRet := NTK_MessageBox( hWndP,;
**                       "Voulez-vous vraiment interrompre ce processus?",;
**                       "Alerte - Vérification B.D.D.",;
**                       MB_YESNO+MB_ICONEXCLAMATION )
**   If nRet == IDYES
**      RETURN(.F.)  // Tells NtkDBDIC_CheckUp() we want to stop process right now!
**   EndIf
**
**ENDIF

RETURN(.T.)
******
******
******
******
******
******


*************************************************************************************************
********
******** Examiner les tables d'une Index-Base (.IDC) selon le mode souhaité:
********    NTK_DBIDC_CREATEINDEX
********    NTK_DBIDC_CLEANANDREBUILT
********    NTK_DBIDC_PACKANDINDEX
********    NTK_DBIDC_REINDEX
********
********
******** Exemple: IndexBaseCheckUp( hWnd, "COMP.IDC", NTK_DBIDC_PACKANDINDEX, P__FILES, .T., .F. )
********
FUNCTION IndexBaseCheckUp( hWndP, cIdcName, cCheckMode, cPathDest, lUserCancel, lDoInform )
LOCAL nRet
LOCAL cGaugeText := "Vérification des Index des tables la Base de données - Patientez..."
PRIVATE oGauge

Default lUserCancel To .T.
Default lDoInform   To .T.
Default hWndP       To NTK_SelectWindow()
NTK_EnableWindow( hWndP, .F. )

oGauge := TSGauge():Init(hWndP,;                   // Handle to parent window
                     WS_POPUP+WS_DLGFRAME,;        // Style of the window-box that will encapsulate the gauge
                     50,05,;                       // Width,Height of the gauge
                     WS_DLGFRAME+PBS_SMOOTH,;      // Gauge's style
                     cGaugeText ,;                 // Text string of the encapsultating box
                     {000,000,128},;               // Text string's rgb colors.
                     nil     ,;                    // Handle to the Bitmap used to paint the bkg of the encapsulting box
                     02.5,01,03.1,48 )             // Gauge rectangle coordinates inside the encapsulating box


// Syntaxe MakeSpecialButton( hWndP, nID, nTop, nLeft, nHeight, nSize, cBtnText, hFontBtn, nStyleBtn )
aSpecBtnInfos := MakeSpecialButton( oGauge:gshWnd, ID_BTNCANCEL, 3.5, 17, 01, 15, "Abandon (Ech)" )
IF !(lUserCancel)
   //NTK_EnableWindow( NTK_GetDlgItemText(oGauge:gshWnd,ID_BTNCANCEL), .F. )  // Disable Cancel Btn. So, User cannot stop the process...
   NTK_EnableWindow( aSpecBtnInfos[1], .F. )  // Disable Cancel Btn. So, User cannot stop the process...
ENDIF


oGauge:SetBarColor( NTK_RGB(255,000,000) )        // Set the the progress bar foreground color
// ---- Sets subtitle appearence
oGauge:SetSubTitle( cGaugeText )
oGauge:gsTextFgColor := NTK_RGB(000,000,255)
oGauge:gsTextBgColor := NTK_RGB(255,255,255)
oGauge:gssTitleFont  := NTK_GetStockObject( ANSI_VAR_FONT )



// ***** Syntaxe: NtkDBDIC_CheckUp( "mainapp.dic", nil, NTK_DBDIC_CREATE,  "c:\myapp\files\", {|cTableName,nPos,nMax,cMode| GaugeUpdate( hWnd,cTableName,nTablePos,nTableMax,cMode )} )
nRet := NtkDBIDC_CheckUp( cIdcName ,;  // Index-Base (Index Dictionary, .IDC file) to examine...
                  nil,;                // Nil means: Probe all tables of the .IDX. Otherwise, you can specified the name of a particular DBF to checkup.
                  cCheckMode,;         // Specify the way of how are built or rebuilt indexes (see \WNTK4HRB\INCLUDE\NTKDBDIC.CH)
                  cPathDest,;          // Path where Index are located and should be created or rebuilt
                  {|cDbfName,cIdxName,nIdxPos,nIdxMax,cMode,lUnique| IndexBaseCheckUpGauge(hWndP,cDbfName,cIdxName,nIdxPos,nIdxMax,cMode,lUnique, aSpecBtnInfos ) } ) // Code Block to be evaluated for each time the index of table declare within the Index-Base (.IDC) is probed.


oGauge:Close()

NTK_EnableWindow( hWndP, .T. )
NTK_SelectWindow( hWndP )
NTK_SetFocus( hWndP )

IF nRet == -1
   NTK_MessageBox( hWndP, "Le chemin d'accès au serveur de fichiers n'est pas valide.", "Erreur! - Vérification Index B.D.D.", MB_OK+MB_ICONSTOP )
ELSEIF nRET == -2
   NTK_MessageBox( hWndP, "Impossible d'ouvrir l'Index-Base : "+AllTrim(cIdcName), "Erreur! - Vérification Index B.D.D.", MB_OK+MB_ICONSTOP )
ELSEIF nRET == -3
   NTK_MessageBox( hWndP, "Certain Index des tables définies dans l'Index-Base n'ont pas pu être traitées.", "Alerte! - Vérification  Index B.D.D.", MB_OK+MB_ICONEXCLAMATION )
ELSEIF nRET == -9
   NTK_MessageBox( hWndP, "Traitement interrompu par abandon délibéré de l'utilisateur.", "Alerte! - Vérification  Index B.D.D.", MB_OK+MB_ICONEXCLAMATION )
ELSE
   If lDoInform
      NTK_MessageBox( hWndP, "Tous les index des tables definies dans " +AllTrim(cIdcName)+ " ont été vérifiés ou recréés avec succès.", "information!", MB_OK+MB_ICONINFORMATION)
   EndIf
ENDIF

RETURN( nil  )
******
******
******
FUNCTION IndexBaseCheckUpGauge(hWndP,cDbfName,cIdxName,nIdxPos,nIdxMax,cMode,lUnique,aSpecBtnInfos)
LOCAL cMsgAction := ""
LOCAL cMsg := ""
LOCAL nGaugePos

IF cMode==NTK_DBIDC_CREATEINDEX
   cMsgAction := "Création"
ELSEIF cMode==NTK_DBIDC_REINDEX
   cMsgAction := "Reclassement des données"
ELSEIF cMode==NTK_DBIDC_CLEANANDREBUILT .OR. cMode==NTK_DBIDC_PACKANDINDEX
   cMsgAction := "Nettoyage et Reclassement des données"
ENDIF

cIdxName := NtkExtractFName(cIdxName)
cDbfName := NtkExtractFName(cDbfName)
cMsg := "PATIENTEZ...  " +cMsgAction+ " de l'Index :"+CHR(13)+;
        cIdxName+ " de " +cDbfName+CHR(13)+;
        "#" + AllTrim(Str(nIdxPos)) +"/"+ AllTrim(Str(nIdxMax))


oGauge:SetSubTitle( cMsg )
oGauge:Repaint()

nGaugePos := IIF( nIdxMax==0, 0,  (nIdxPos*100)/nIdxMax  )
oGauge:Update(nGaugePos)


NtkInkey(-1)  // Create a non standard wait-state, but an asynchronous one. Just
              // for detecting some Keyb+mouse events in Windows message queue,
              // and then telling the OS, our process is always alive...

IF NTK_Lastkey()==K_ESC  .OR. IsSpecialBtnClicked( aSpecBtnInfos )
   nRet := NTK_MessageBox( hWndP,;
                       "Voulez-vous vraiment interrompre ce processus?",;
                       "Alerte - Vérification Index B.D.D.",;
                       MB_YESNO+MB_ICONEXCLAMATION )
   If nRet == IDYES
      RETURN(.F.)  // Tells NtkDBIDC_CheckUp() we want to stop process right now!
   EndIf

ENDIF

RETURN(.T.)
******
******
******
******
******
******



*********************************************************************************************************
*********************************************************************************************************
*********************************************************************************************************
*********************************************************************************************************
FUNCTION MakeSpecialButton( hWndP, nID, nTop, nLeft, nHeight, nSize, cBtnText, hFontBtn, nStyleBtn )
Local hWndBtn
Local nXLeft, nYTop, nXSize, nYHeight


Default nStyleBtn To WS_CHILD+BS_DEFPUSHBUTTON+WS_VISIBLE
Default hFontBtn  To NTK_GetStockObject( ANSI_VAR_FONT )

Default nTop      To 0
Default nLeft     To 0
Default nHeight   To NTK_StringHeight( cBtnText, hWndP, hFontBtn ) + 4
Default nSize     To Len(cBtnText) * NTK_StringWidth( cBtnText, hWndP, hFontBtn )

IF !( __NtkSetPixMode() )
   nXLeft   := nLeft   *  __NtkSetColRatio()
   nYTop    := nTop    *  __NtkSetRowRatio()
   nXSize   := nSize   *  __NtkSetColRatio()
   nYHeight := nHeight *  __NtkSetRowRatio()
ENDIF


//  Creates a DefPushBtn (default)
hWndBtn := NTK_CreateWindowEx( 0, "BUTTON"                    ,;
                               cBtnText                       ,;
                               nStyleBtn                      ,;
                               nXLeft,nYTop, nXSize, nYHeight ,;
                               hWndP,  nID ) //  hInst )

IF hWndBtn != 0
  NTK_SendMessage( hWndBtn, WM_SETFONT, hFontBtn, 0 )
  NTK_ShowWindow( hWndBtn, SW_NORMAL )   // make button visible within its parent container
  NTK_UpDateWindow( hWndP )   // make button visible within its parent container
  NTK_SelectWindow( hWndP )
  NTK_SetFocus( hWndP )
  NTK_InvalidateRect( hWndP )
ENDIF


RETURN(  { hWndBtn, nID, nTop, nLeft, nHeight, nSize }   )
******
******
******
FUNCTION IsSpecialBtnClicked( aBtnInfos )
LOCAL aPt0, aPt1
LOCAL hWndP   := NTK_GetParent(aBtnInfos[1])
LOCAL nTop    := aBtnInfos[3]
LOCAL nLeft   := aBtnInfos[4]
LOCAL nBottom := (aBtnInfos[3]+aBtnInfos[5])
LOCAL nRight  := (aBtnInfos[4]+aBtnInfos[6])


// ----- Converts button's coordinates into Absolute Screen Coordinates.
aPt0 := NtkC2S( nTop   , nLeft , hWndP )
aPt1 := NtkC2S( nBottom, nRight, hWndP )


// Syntaxe: NTK_OkMouse(X0,X1, Y0,Y1 ) -> lRet
IF NTK_OkMouse( aPt0[1], aPt0[2] , aPt1[1],aPt1[2] )
   NTK_MOUSESTATE := 0 // Tips: Force all the mouse's buttons to be released.
   RETURN .T.
ENDIF

RETURN .F.
******
******
******
