/*
 * Xailer source code:
 *
 * BrowseForFolder.prg
 * Dialogo BrowseForFolder
 *
 * Copyright 2003, 2007 Jose Lalin
 * Copyright 2003, 2007 Xailer.com
 * All rights reserved
 *
 */

#include "Xailer.ch"
#include "ShlObj.api"
#include "ShellApi.api"
#include "CommCtrl.api"


//--------------------------------------------------------------------------

CLASS XBrowseForFolderDlg FROM TComponent

PUBLISHED:
   PROPERTY nRoot       INIT ssfNONE ;
                        VALUES ssfNONE, ssfALTSTARTUP, ssfAPPDATA, ;
                               ssfBITBUCKET, ssfCOMMONALTSTARTUP, ;
                               ssfCOMMONAPPDATA, ssfCOMMONDESKTOPDIR, ;
                               ssfCOMMONFAVORITES, ssfCOMMONPROGRAMS, ;
                               ssfCOMMONSTARTMENU, ssfCOMMONSTARTUP, ;
                               ssfCONTROLS, ssfCOOKIES, ssfDESKTOP, ;
                               ssfDESKTOPDIRECTORY, ssfDRIVES, ;
                               ssfFAVORITES, ssfFONTS, ssfHISTORY, ;
                               ssfINTERNETCACHE, ssfLOCALAPPDATA, ;
                               ssfMYPICTURES, ssfNETHOOD, ssfNETWORK, ;
                               ssfPERSONAL, ssfPRINTERS, ssfPRINTHOOD, ;
                               ssfPROFILE, ssfPROGRAMFILES, ssfPROGRAMS, ;
                               ssfRECENT, ssfSENDTO, ssfSTARTMENU, ;
                               ssfSTARTUP, ssfSYSTEM, ssfTEMPLATES, ;
                               ssfWINDOWS

   PROPERTY cRoot             INIT "" EDITOR PE_BrowseFolder ;
                              WRITE INLINE ::FcRoot := ::SetRoot( Value )

   PROPERTY lForceCreate      INIT .F.

   PROPERTY cText             INIT ""
   PROPERTY cTitle            INIT ""
   PROPERTY cStatusText       INIT ""
   PROPERTY cOkBtnText        INIT ""

   PROPERTY lBrowseComputer      INIT .F. WRITE INLINE ::FlBrowseComputer := ::SetFlag( BIF_BROWSEFORCOMPUTER, Value )

   PROPERTY lEditBox             INIT .F. WRITE INLINE ::FlEditBox       := ::SetFlag( BIF_EDITBOX, Value )
   PROPERTY lExtendedUI          INIT .F. WRITE INLINE ::FlExtendedUI    := ::SetFlag( BIF_USENEWUI, Value )
   PROPERTY lDontGoBelowDomain   INIT .F. WRITE INLINE ::FlDontGoBelowDomain := ::SetFlag( BIF_DONTGOBELOWDOMAIN, Value )
   PROPERTY lIncludeFiles        INIT .F. WRITE INLINE ::FlIncludeFiles  := ::SetFlag( BIF_BROWSEINCLUDEFILES, Value )
   PROPERTY lIncludeURLS         INIT .F. WRITE INLINE ::FlIncludeURLS   := ::SetFlag( BIF_BROWSEINCLUDEURLS, Value )
   PROPERTY lNewDlgStyle         INIT .T. WRITE INLINE ::FlNewDlgStyle   := ::SetFlag( BIF_NEWDIALOGSTYLE, Value )
   PROPERTY lNoNewFolderButton   INIT .F. WRITE INLINE ::FlNoNewFolderButton := ::SetFlag( BIF_NONEWFOLDERBUTTON, Value )

   PROPERTY lReturnFSAncestors   INIT .F. WRITE INLINE ::FlReturnFSAncestors := ::SetFlag( BIF_RETURNFSANCESTORS, Value )
   PROPERTY lReturnFSDirs        INIT .F. WRITE INLINE ::FlReturnFSDirs  := ::SetFlag( BIF_RETURNONLYFSDIRS, Value )
   PROPERTY lValidate            INIT .F. WRITE INLINE ::FlValidate      := ::SetFlag( BIF_VALIDATE, Value )
   PROPERTY lShareable           INIT .F. WRITE INLINE ::FlShareable     := ::SetFlag( BIF_SHAREABLE, Value )
   PROPERTY lTooltips            INIT .F. WRITE INLINE ::FlTooltips      := ::SetFlag( BIF_UAHINT, Value )

   PROPERTY lCenter              INIT .F.

   EVENT OnChange( oSender, cFolder )     // --> lResult | Nil
   EVENT OnValidate( oSender, cText )     // --> nResult
   EVENT OnInitialized( oSender, hWnd )   // --> Nil

   EVENT OnShow( oSender )                // --> Nil
   EVENT OnClose( oSender )               // --> Nil

PROTECTED:
   DATA nFlags                INIT nOr( BIF_DEFAULT, BIF_NEWDIALOGSTYLE )

   METHOD SetFlag( nFlag, Value )
   METHOD SetRoot( cFolder )

PUBLIC:
   PROPERTY nIconIndex        INIT 0 READONLY

   METHOD Run()               // --> lSuccess
   METHOD Execute()           EXTERN XBrowseForFolderDlg_Run() // --> lSuccess

   METHOD BrowseComputers()   // --> lSuccess
   METHOD BrowsePrinters()    // --> lSuccess
   METHOD BrowseFolder()      // --> lSuccess
   METHOD BrowseFile()        // --> lSuccess

RESERVED:
   DATA cLastFolder           INIT ""
   METHOD MakeNewFolder()
   METHOD SetLastFolder( cFolder )  INLINE ::cLastFolder := cFolder

ENDCLASS

//--------------------------------------------------------------------------

METHOD SetFlag( nFlag, Value ) CLASS XBrowseForFolderDlg

   IF Value
      ::nFlags := nOr( ::nFlags, nFlag )
   ELSE
      ::nFlags := nExclude( ::nFlags, nFlag )
   ENDIF

RETURN Value

//--------------------------------------------------------------------------

METHOD SetRoot( cFolder ) CLASS XBrowseForFolderDlg

   cFolder := AllTrim( cFolder )

   IF Right( cFolder, 1 ) == "\"
      cFolder := Substr( cFolder, 1, Len( cFolder ) - 1 )
   ENDIF

RETURN cFolder

//--------------------------------------------------------------------------

METHOD BrowseComputers() CLASS XBrowseForFolderDlg

   LOCAL lSuccess := .F.

   ::lBrowseComputer := .T.
   ::nRoot := ssfNETWORK
   lSuccess := ::Run()
   ::nRoot := ssfNONE
   ::lBrowseComputer := .F.

RETURN lSuccess

//--------------------------------------------------------------------------

METHOD BrowsePrinters() CLASS XBrowseForFolderDlg

   LOCAL lSuccess := .F.

   ::lBrowseComputer := .F.
   ::lIncludeFiles := .T.
   ::nRoot := ssfPRINTERS
   lSuccess := ::Run()
   ::lIncludeFiles := .F.
   ::nRoot := ssfNONE

RETURN lSuccess

//--------------------------------------------------------------------------

METHOD BrowseFolder() CLASS XBrowseForFolderDlg

   LOCAL lSuccess := .F.

   ::lBrowseComputer := .F.
   ::lReturnFSDirs   := .T.
   lSuccess := ::Run()
   ::lReturnFSDirs   := .F.

RETURN lSuccess

//--------------------------------------------------------------------------

METHOD BrowseFile() CLASS XBrowseForFolderDlg

   LOCAL lSuccess := .F.

   ::lBrowseComputer := .F.
   ::lIncludeFiles   := .T.
   lSuccess := ::Run()
   ::lIncludeFiles   := .F.

RETURN lSuccess

//--------------------------------------------------------------------------

METHOD MakeNewFolder() CLASS XBrowseForFolderDlg

   LOCAL oForm
   LOCAL oEdit

   WITH OBJECT oForm := TForm():New( ::oParent )
      :cText := LT( XA_MSG_BROWSEFOLDER_MAKENEWFOLDER )
      :SetBounds( 20, 20, 346, 108)
      :lCentered := .T.
      :lParentIcon := .F.
      :nBorderStyle := bsDialog
      :lModal := .T.
      :Create()
   END

   WITH OBJECT oEdit := TEdit():New( oForm )
      :Value := ""
      :SetBounds( 12, 12, 314, 20 )
      :Create()
   END

   WITH OBJECT TButton():New( oForm )
      :cText := LT( XA_MSG_ACEPTAR )
      :SetBounds( 148, 44, 80, 25 )
      :nModalResult := mrOK
      :lDefault := .T.
      :Create()
   END

   WITH OBJECT TButton():New( oForm )
      :cText := LT( XA_MSG_CANCELAR )
      :SetBounds( 244, 44, 80, 25 )
      :nModalResult := mrCANCEL
      :Create()
   END

   oForm:ShowModal()

   IF oForm:nModalResult == mrOK .AND. ! Empty( oEdit:Value )
      MakeNestedDir( IIF( Empty( ::cLastFolder ), ::cRoot, ::cLastFolder + "\" ) + oEdit:Value )
   ENDIF

RETURN oForm:nModalResult == mrOK

//--------------------------------------------------------------------------

FUNCTION MakeNestedDir( cDirectory )      // --> nError

   LOCAL aDir
   LOCAL cDir
   LOCAL cStr := ""
   LOCAL nError := 0

   IF ! Empty( cDirectory )
      aDir := HB_ATokens( cDirectory, "\" )

      FOR EACH cDir IN aDir
         cStr += cDir + "\"
         IF ! ExistDir( cStr )
            nError := MakeDir( cStr )
            IF nError != 0
               EXIT
            ENDIF
         ENDIF
      NEXT
   ENDIF

RETURN nError

//--------------------------------------------------------------------------
