* Program..: Dictionary.prg * Author...: Jeremy Suiter * Date.....: 07/05/2003 * * Notice...: Copyright (c) 2003, Jeremy Suiter, All Rights Reserved * Notes....: Visual DbEditor data dictionary functions #Include "Font.ch" #Include "Gra.ch" #Include "Xbp.ch" #Include "Appevent.ch" #Include "Common.ch" #Include "Dmlb.ch" #Include "Dbstruct.ch" #Include "Inkey.ch" #Include "DbEditor.ch" #Include "Resources.ch" Static oDictionary, oDetails, oDbe, oDirectory, oFiles, oStructure, oIndexes, oFieldList, oIndexKey, oForCond, oDescend, oUnique, oTagName, ; oPBCreate, oFileName ******************* Func DataDictionary() ******************* * main details for data dictionary Local nEvent, mp1:=Nil, mp2:=Nil, aPos, oFocus:=SetAppFocus(), nPos, cPath Local oDlg, oXbp, drawingArea, oGroup1 Begin Sequence Set Deleted On // temp set deleted status set back later cPath:=AppName(.T.) nPos:=Rat("\", cPath) If nPos > 0 cPath:=Substr(cPath,1,nPos) EndIf If !NetUse(cPath+"Dictionary",.T.,,,"FOXCDX") .Or. !NetUse(cPath+"Files",.T.,,,"FOXCDX") .Or. !NetUse(cPath+"Structure",.T.,,,"FOXCDX") ; .Or. !NetUse(cPath+"Indexes",.T.,"Indexes",,"FOXCDX") Break EndIf Select Files DbSetOrder(1) Select Structure DbSetOrder(1) Select Indexes DbSetOrder(1) Select Dictionary DbSetOrder(1) aPos:=CenterPos({548,272},AppDesktop():currentSize()) oDlg:=XbpDialog():new(AppDesktop(), SetAppWindow(), aPos, {548,272}, , .F.) oDlg:icon:=ICON_MAIN oDlg:taskList:=.F. oDlg:border:=XBPDLG_RAISEDBORDERTHIN_FIXED oDlg:close:={|mp1,mp2,obj| PostAppEvent(xbeP_Close+1000) } oDlg:title:="Data Dictionaries" oDlg:create() oDlg:setModalState(XBP_DISP_APPMODAL) oDlg:keyBoard:={| nKeyCode, uNIL, self | Iif(nKeyCode==xbeK_ESC,PostAppEvent(xbeP_Close+1000),Nil) } drawingArea:=oDlg:drawingArea drawingArea:setFontCompoundName("8.Helv") oGroup1:=XbpStatic():new(drawingArea, , {12,48}, {516,192}) oGroup1:caption:="Data Dictionaries" oGroup1:clipSiblings:=.T. oGroup1:type:=XBPSTATIC_TYPE_GROUPBOX oGroup1:create() oDictionary:=XbpListBox():new(oGroup1, , {12,12}, {156,156}, { { XBP_PP_BGCLR, XBPSYSCLR_ENTRYFIELD } }) oDictionary:tabStop:=.T. oDictionary:markMode:=XBPLISTBOX_MM_SINGLE oDictionary:setInputFocus:={| uNil1,uNil2,self | XbpBorder(self,GRA_CLR_BLUE) } oDictionary:killInputFocus:={| uNil1,uNil2,self | XbpBorder(self, GRA_CLR_BACKGROUND) } oDictionary:itemMarked:={|uNIL1, uNIL2, self| ShowDictInfo() } oDictionary:create() AddDictionaries() oDictionary:setData({1},.T.) oDetails:=XbpListBox():new(oGroup1, , {180,12}, {324,156}, { { XBP_PP_BGCLR, XBPSYSCLR_ENTRYFIELD } }) oDetails:markMode:=XBPLISTBOX_MM_SINGLE oDetails:horizScroll:=.T. oDetails:vertScroll:=.F. oDetails:tabStop:=.T. oDetails:setInputFocus:={| uNil1,uNil2,self | XbpBorder(self,GRA_CLR_BLUE) } oDetails:killInputFocus:={| uNil1,uNil2,self | XbpBorder(self, GRA_CLR_BACKGROUND) } oDetails:create() oXbp:=XbpPushButton():new(drawingArea, , {120,12}, {72,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } }) oXbp:caption:="New" oXbp:tabStop:=.T. oXbp:create() oXbp:activate:={|| AddEditDict(.T.), ShowDictInfo() } oXbp:=XbpPushButton():new(drawingArea, , {204,12}, {72,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } }) oXbp:caption:="Edit" oXbp:tabStop:=.T. oXbp:create() oXbp:activate:={|| AddEditDict(.F.), ShowDictInfo() } oXbp:=XbpPushButton():new(drawingArea, , {288,12}, {72,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } }) oXbp:caption:=GEN_DELETE oXbp:tabStop:=.T. oXbp:create() oXbp:activate:={|| DeleteDict(), AddDictionaries(), ShowDictInfo() } oXbp:=XbpPushButton():new(drawingArea, , {372,12}, {72,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } }) oXbp:caption:="Apply" oXbp:tabStop:=.T. oXbp:create() oXbp:activate:={|| ApplyDictionary() } oXbp:=XbpPushButton():new(drawingArea, , {456,12}, {72,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } }) oXbp:caption:=GEN_CLOSE oXbp:tabStop:=.T. oXbp:create() oXbp:activate:={|| PostAppEvent(xbeP_Close+1000) } oDlg:show() SetAppFocus(oDictionary) ShowDictInfo() nEvent:=xbe_None Do While nEvent<>xbeP_Close+1000 nEvent:=AppEvent(@mp1, @mp2, @oXbp) oXbp:handleEvent(nEvent, mp1, mp2) if nEvent == xbeP_Keyboard .and.; mp1 == xbeK_ESC exit endif EndDo oDlg:destroy() SetAppFocus(oFocus) If lShowDeleted Set Deleted Off Else Set Deleted On EndIf Dictionary->(DbCloseArea()) Files->(DbCloseArea()) Structure->(DbCloseArea()) Indexes->(DbCloseArea()) End Return Nil ******************** Func AddDictionaries() ******************** * add dictionaries Begin Sequence oDictionary:clear() Select Dictionary DbGoTop() Do While !Eof() oDictionary:addItem(Dictionary->id) DbSkip() EndDo oDictionary:setData({1},.T.) End Return Nil ****************** Func ShowDictInfo() ****************** * show dictionary info for selected Begin Sequence If Empty(oDictionary:getData()) Break EndIf Select Dictionary DbSetOrder(1) DbSeek(oDictionary:getItem(oDictionary:getData()[1])) If Found() oDetails:Clear() oDetails:addItem("DESCRIPTION:") oDetails:addItem(Dictionary->descriptn) oDetails:addItem("") oDetails:addItem("DIRECTORY:") oDetails:addItem(Dictionary->directory) oDetails:addItem("") oDetails:addItem("DBE: "+Dictionary->dbe) oDetails:addItem("NO FILES: "+Ntrim(Dictionary->no_files)) EndIf End Return Nil *************** Func DeleteDict(cFile) *************** * delete data dictionary Begin Sequence If cFile==Nil .And. !YesNo("Delete this data dictionary") Break EndIf Select Dictionary DbSetOrder(1) If RecLock() If cFile==Nil DbDelete() DbPack() EndIf CommitUnlock() Select Files DbGoTop() If cFile==Nil Delete All Else Delete For Files->file_name==cFile EndIf DbPack() Select Structure DbGoTop() If cFile==Nil Delete All Else Delete For Structure->file_name==cFile EndIf DbPack() Select Indexes DbGoTop() If cFile==Nil Delete All Else Delete For Indexes->file_name==cFile EndIf DbPack() EndIf DbGoTop() AddDictionaries() oDictionary:setData({1},.T.) ShowDictInfo() End Return Nil **************** Func AddEditDict(lAdd) **************** * add/edit dictionary main info Local nEvent, mp1:=Nil, mp2:=Nil, aEditControls:={} Local oDlg, oXbp, drawingArea, oGroup1, aPos:=Nil, oFocus:=SetAppFocus(), aDbe:={}, x Begin Sequence If lAdd .And. !Dictionary->(AddRec()) Break EndIf aPos:=CenterPos({581,319},AppDesktop():currentSize()) oDlg:=XbpDialog():new(AppDesktop(), SetAppWindow(), aPos, {581,319}, , .F.) oDlg:icon:=ICON_MAIN oDlg:taskList:=.F. oDlg:border:=XBPDLG_RAISEDBORDERTHIN_FIXED oDlg:close:={|mp1,mp2,obj| PostAppEvent(xbeP_Close+1000) } oDlg:title:="Dictionaries Info" oDlg:create() oDlg:setModalState(XBP_DISP_APPMODAL) oDlg:keyBoard:={| nKeyCode, uNIL, self | Iif(nKeyCode==xbeK_ESC,PostAppEvent(xbeP_Close+1000),Nil) } drawingArea:=oDlg:drawingArea drawingArea:setFontCompoundName("8.Helv") oGroup1:=XbpStatic():new(drawingArea, , {12,48}, {552,240}) oGroup1:caption:="Details" oGroup1:clipSiblings:=.T. oGroup1:type:=XBPSTATIC_TYPE_GROUPBOX oGroup1:create() oXbp:=XbpStatic():new(oGroup1, , {36,192}, {36,24}) oXbp:caption:="Id" oXbp:clipSiblings:=.T. oXbp:options:=XBPSTATIC_TEXT_VCENTER+XBPSTATIC_TEXT_RIGHT oXbp:create() oXbp:=XbpSLE():new(oGroup1, , {84,192}, {84,24}, { { XBP_PP_BGCLR, XBPSYSCLR_ENTRYFIELD } }) oXbp:bufferLength:=10 oXbp:tabStop:=.T. oXbp:dataLink:={|x| IIf(PCOUNT()==0, Trim(Dictionary->ID), Dictionary->ID:=x) } oXbp:create():setData() AAdd(aEditControls, oXbp) SetAppFocus(oXbp) oXbp:=XbpStatic():new(oGroup1, , {180,192}, {72,24}) oXbp:caption:="Description" oXbp:clipSiblings:=.T. oXbp:options:=XBPSTATIC_TEXT_VCENTER+XBPSTATIC_TEXT_RIGHT oXbp:create() oXbp:=XbpSLE():new(oGroup1, , {264,192}, {276,24}, { { XBP_PP_BGCLR, XBPSYSCLR_ENTRYFIELD } }) oXbp:bufferLength:=40 oXbp:tabStop:=.T. oXbp:dataLink:={|x| IIf(x==Nil, Trim(Dictionary->DESCRIPTN), Dictionary->DESCRIPTN:=x) } oXbp:create():setData() AAdd(aEditControls, oXbp) oXbp:=XbpStatic():new(oGroup1, , {12,156}, {60,24}) oXbp:caption:="Directory" oXbp:clipSiblings:=.T. oXbp:options:=XBPSTATIC_TEXT_VCENTER+XBPSTATIC_TEXT_RIGHT oXbp:create() oDirectory:=XbpSLE():new(oGroup1, , {84,156}, {432,24}, { { XBP_PP_BGCLR, XBPSYSCLR_ENTRYFIELD } }) oDirectory:bufferLength:=220 oDirectory:tabStop:=.T. oDirectory:dataLink:={|x| IIf(x==Nil, Trim(Dictionary->DIRECTORY), Dictionary->DIRECTORY:=x) } oDirectory:create():setData() AAdd(aEditControls, oDirectory) oXbp:=XbpPushButton():new(oGroup1, , {516,156}, {24,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } }) oXbp:caption:="..." oXbp:tabStop:=.T. oXbp:create() oXbp:activate:={|| Dictionary->directory:=SelectDirectory(), oDirectory:setData() } oXbp:=XbpStatic():new(oGroup1, , {12,120}, {60,24}) oXbp:caption:="Dbe" oXbp:clipSiblings:=.T. oXbp:options:=XBPSTATIC_TEXT_VCENTER+XBPSTATIC_TEXT_RIGHT oXbp:create() oDbe:=XbpCombobox():new(oGroup1, , {84,12}, {84,132}, { { XBP_PP_BGCLR, XBPSYSCLR_ENTRYFIELD }, { XBP_PP_DISABLED_BGCLR, GRA_CLR_WHITE }}) oDbe:tabstop:=.T. oDbe:type:=XBPCOMBO_DROPDOWN oDbe:XbpSLE:editable:=.F. oDbe:XbpSLE:dataLink:={|x| IIf(x==Nil, Trim(Dictionary->DBE), Dictionary->DBE:=x) } oDbe:setInputFocus:={| uNil1,uNil2,self | XbpBorder(self,GRA_CLR_BLUE) } oDbe:killInputFocus:={| uNil1,uNil2,self | XbpBorder(self, GRA_CLR_BACKGROUND) } oDbe:create() oDbe:XbpSLE:setData(Dictionary->DBE) aDbe:=DbeList() ASort(aDbe,,, {|aX,aY| aX[1] < aY[1] }) For x:=1 To Len(aDbe) If aDbe[x,2]==.F. oDbe:addItem(aDbe[x,1]) EndIf Next AAdd (aEditControls, oDbe:XbpSLE) oXbp:=XbpPushButton():new(drawingArea, , {252,12}, {96,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } }) oXbp:caption:="Edit Files" oXbp:tabStop:=.T. oXbp:create() oXbp:activate:={|| DictionaryFiles() } oXbp:=XbpPushButton():new(drawingArea, , {360,12}, {96,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } }) oXbp:caption:="Save" oXbp:tabStop:=.T. oXbp:create() oXbp:activate:={|| Gather(aEditControls) } oXbp:=XbpPushButton():new(drawingArea, , {468,12}, {96,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } }) oXbp:caption:=GEN_CLOSE oXbp:tabStop:=.T. oXbp:create() oXbp:activate:={|| Iif(lAdd .And. Empty(Dictionary->ID),Dictionary->(DbDelete()),Nil), PostAppEvent(xbeP_Close+1000) } oDlg:show() nEvent:=xbe_None Do While nEvent<>xbeP_Close+1000 nEvent:=AppEvent(@mp1, @mp2, @oXbp) oXbp:handleEvent(nEvent, mp1, mp2) if nEvent == xbeP_Keyboard .and.; mp1 == xbeK_ESC exit endif EndDo oDlg:destroy() SetAppFocus(oFocus) End Return Nil ******************** Func DictionaryFiles() ******************** * add/edit files Local nEvent, mp1:=Nil, mp2:=Nil Local oDlg, oXbp, drawingArea, oGroup1, aPos:=Nil, oFocus:=SetAppFocus() Local aPP, oColumn Begin Sequence // set scopes on files SetDictScopes() // dialog aPos:=CenterPos({725,446},AppDesktop():currentSize()) oDlg:=XbpDialog():new(AppDesktop(), SetAppWindow(), aPos, {725,446}, , .F.) oDlg:icon:=ICON_MAIN oDlg:taskList:=.F. oDlg:border:=XBPDLG_RAISEDBORDERTHIN_FIXED oDlg:close:={|mp1,mp2,obj| PostAppEvent(xbeP_Close+1000) } oDlg:title:="File Details" oDlg:create() oDlg:setModalState(XBP_DISP_APPMODAL) oDlg:keyBoard:={| nKeyCode, uNIL, self | Iif(nKeyCode==xbeK_ESC,PostAppEvent(xbeP_Close+1000),Nil) } drawingArea:=oDlg:drawingArea drawingArea:setFontCompoundName("8.Helv") oGroup1:=XbpStatic():new(drawingArea, , {16,48}, {688,360}) oGroup1:caption:="File Details" oGroup1:clipSiblings:=.T. oGroup1:type:=XBPSTATIC_TYPE_GROUPBOX oGroup1:create() // file details oXbp:=XbpStatic():new(oGroup1, , {8,312}, {80,24}) oXbp:caption:="Files" oXbp:clipSiblings:=.T. oXbp:options:=XBPSTATIC_TEXT_VCENTER oXbp:create() oFiles:=XbpListBox():new(oGroup1, , {8,72}, {144,240}, { { XBP_PP_BGCLR, XBPSYSCLR_ENTRYFIELD } }) oFiles:tabStop:=.T. oFiles:markMode:=XBPLISTBOX_MM_SINGLE oFiles:itemMarked:={|uNIL1, uNIL2, self| RefreshStructure(), ShowIndexes() } oFiles:setInputFocus:={| uNil1,uNil2,self | XbpBorder(self,GRA_CLR_BLUE) } oFiles:killInputFocus:={| uNil1,uNil2,self | XbpBorder(self, GRA_CLR_BACKGROUND) } oFiles:create() AddFiles() oXbp:=XbpPushButton():new(oGroup1, , {8,40}, {42,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } }) oXbp:caption:="Scan" oXbp:tabStop:=.T. oXbp:create() oXbp:activate:={|| ScanForFiles() } oXbp:=XbpPushButton():new(oGroup1, , {58,40}, {42,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } }) oXbp:caption:="Insert" oXbp:tabStop:=.T. oXbp:create() oXbp:activate:={|| InsertNewFile() } oXbp:=XbpPushButton():new(oGroup1, , {108,40}, {42,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } }) oXbp:caption:=GEN_DELETE oXbp:tabStop:=.T. oXbp:create() oXbp:activate:={|| DeleteFile() } // File structure oXbp:=XbpStatic():new(oGroup1, , {160,312}, {80,24}) oXbp:caption:="Structure" oXbp:clipSiblings:=.T. oXbp:options:=XBPSTATIC_TEXT_VCENTER oXbp:create() oStructure:=XbpBrowse():new(oGroup1, , {160,72}, {312,240}, PRESPARAM_FANCY,.F.):create() // Navigation code blocks for the browser oStructure:skipBlock :={|n| Structure->(DbSkipper(n)) } oStructure:goTopBlock :={| | Structure->(DbGoTop()) } oStructure:goBottomBlock:={| | Structure->(DbGoBottom()) } oStructure:phyPosBlock :={| | Structure->(Recno()) } // Navigation code blocks for the vertical scroll bar oStructure:posBlock :={| | Structure->(DbPosition()) } oStructure:goPosBlock :={|n| Structure->(DbGoPosition(n)) } oStructure:lastPosBlock :={| | 100 } oStructure:firstPosBlock:={| | 0 } oStructure:hScroll :=.F. oStructure:sizeCols :=.F. oStructure:softTrack :=.F. oStructure:setInputFocus:={| uNil1,uNil2,self | XbpBorder(self,GRA_CLR_BLUE) } oStructure:killInputFocus:={| uNil1,uNil2,self | XbpBorder(self, GRA_CLR_BACKGROUND) } // field name aPP:={{XBP_PP_COL_HA_CAPTION, "FIELD NAME " }, ; {XBP_PP_COL_FA_CAPTION, "FIELD NAME " }, ; {XBP_PP_COL_HA_BGCLR, GRA_CLR_DARKGRAY }, ; {XBP_PP_COL_HA_FGCLR, GRA_CLR_WHITE }, ; {XBP_PP_COL_FA_BGCLR, GRA_CLR_DARKGRAY }, ; {XBP_PP_COL_FA_FGCLR, GRA_CLR_WHITE }} oColumn :=XbpGetColumn():new(oStructure,,,, aPP) oColumn:dataLink :=EditBlock("Structure->field_name") oColumn:bufferLength:=10 oColumn:picture :="@!" oStructure:addColumn(oColumn) // field type aPP:={{XBP_PP_COL_HA_CAPTION, "FIELD TYPE" }, ; {XBP_PP_COL_FA_CAPTION, "FIELD TYPE" }, ; {XBP_PP_COL_HA_BGCLR, GRA_CLR_DARKGRAY }, ; {XBP_PP_COL_HA_FGCLR, GRA_CLR_WHITE }, ; {XBP_PP_COL_FA_BGCLR, GRA_CLR_DARKGRAY }, ; {XBP_PP_COL_FA_FGCLR, GRA_CLR_WHITE }} oColumn :=XbpGetColumn():new(oStructure,,,, aPP) oColumn:dataLink :=EditBlock("Structure->field_type") oColumn:bufferLength:=1 oColumn:picture :="@!" oStructure:addColumn(oColumn) // field length aPP:={{XBP_PP_COL_HA_CAPTION, "LENGTH" }, ; {XBP_PP_COL_FA_CAPTION, "LENGTH" }, ; {XBP_PP_COL_HA_BGCLR, GRA_CLR_DARKGRAY }, ; {XBP_PP_COL_HA_FGCLR, GRA_CLR_WHITE }, ; {XBP_PP_COL_FA_BGCLR, GRA_CLR_DARKGRAY }, ; {XBP_PP_COL_FA_FGCLR, GRA_CLR_WHITE }} oColumn :=XbpGetColumn():new(oStructure,,,, aPP) oColumn:dataLink :=EditBlock("Structure->field_len") oColumn:bufferLength:=4 oColumn:picture :="9999" oStructure:addColumn(oColumn) // field decimal aPP:={{XBP_PP_COL_HA_CAPTION, "DECIMAL" }, ; {XBP_PP_COL_FA_CAPTION, "DECIMAL" }, ; {XBP_PP_COL_HA_BGCLR, GRA_CLR_DARKGRAY }, ; {XBP_PP_COL_HA_FGCLR, GRA_CLR_WHITE }, ; {XBP_PP_COL_FA_BGCLR, GRA_CLR_DARKGRAY }, ; {XBP_PP_COL_FA_FGCLR, GRA_CLR_WHITE }} oColumn :=XbpGetColumn():new(oStructure,,,, aPP) oColumn:dataLink :=EditBlock("Structure->field_dec") oColumn:bufferLength:=4 oColumn:picture :="9999" oStructure:addColumn(oColumn) // Delegate keys for editing to the Xbp???Column object oStructure:keyBoard:={ |nKey, x, obj| StruBrowseKeys(nKey, obj, oStructure) } oStructure:show() oXbp:=XbpPushButton():new(oGroup1, , {160,40}, {42,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } }) oXbp:caption:="Insert" oXbp:tabStop:=.T. oXbp:create() oXbp:activate:={|| InsertStruct() } oXbp:=XbpPushButton():new(oGroup1, , {208,40}, {42,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } }) oXbp:caption:=GEN_DELETE oXbp:tabStop:=.T. oXbp:create() oXbp:activate:={|| DeleteStruct() } // index info oXbp:=XbpStatic():new(oGroup1, , {480,312}, {80,24}) oXbp:caption:="Indexes" oXbp:clipSiblings:=.T. oXbp:options:=XBPSTATIC_TEXT_VCENTER oXbp:create() oIndexes:=XbpListBox():new(oGroup1, , {480,72}, {200,240}, { { XBP_PP_BGCLR, XBPSYSCLR_ENTRYFIELD } }) oIndexes:tabStop:=.T. oIndexes:create() oXbp:=XbpPushButton():new(oGroup1, , {480,40}, {42,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } }) oXbp:caption:="Insert" oXbp:tabStop:=.T. oXbp:create() oXbp:activate:={|| InsertIndex(.T.) } oXbp:=XbpPushButton():new(oGroup1, , {530,40}, {42,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } }) oXbp:caption:=GEN_DELETE oXbp:tabStop:=.T. oXbp:create() oXbp:activate:={|| DeleteIndex() } oXbp:=XbpPushButton():new(oGroup1, , {580,40}, {42,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } }) oXbp:caption:="Edit" oXbp:tabStop:=.T. oXbp:create() oXbp:activate:={|| InsertIndex(.F.) } oXbp:=XbpStatic():new(oGroup1, , {8,8}, {672,24}) oXbp:clipSiblings:=.T. oXbp:type:=XBPSTATIC_TYPE_RECESSEDBOX oXbp:create() oXbp:=XbpStatic():new(oGroup1, , {9,9}, {670,22}) oXbp:clipSiblings:=.T. oXbp:type:=XBPSTATIC_TYPE_TEXT oXbp:options:=XBPSTATIC_TEXT_VCENTER oXbp:caption:=AllTrim(Dictionary->directory) oXbp:create() // close pushbutton oXbp:=XbpPushButton():new(drawingArea, , {608,8}, {96,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } }) oXbp:caption:=GEN_CLOSE oXbp:tabStop:=.T. oXbp:create() oXbp:activate:={|| PostAppEvent(xbeP_Close+1000) } oDlg:show() oFiles:setData({1}) ShowIndexes() RefreshStructure() SetAppFocus(oFiles) nEvent:=xbe_None Do While nEvent<>xbeP_Close+1000 nEvent:=AppEvent(@mp1, @mp2, @oXbp) oXbp:handleEvent(nEvent, mp1, mp2) if nEvent == xbeP_Keyboard .and.; mp1 == xbeK_ESC exit endif EndDo oDlg:destroy() SetAppFocus(oFocus) End Return Nil ***************** Func ScanForFiles() ***************** * scan for files Local aFiles, cFiles, aPos, x, y, oClose, aStruct Local nEvent, mp1:=Nil, mp2:=Nil Local oDlg, oXbp, drawingArea, oGroup1, oProgress1, oProgress2 Begin Sequence If YesNo("Scan file for information") InsertFile() Break EndIf If !YesNo("Scan directory for files") .Or. !YesNo("Existing information will be deleted! Are you sure") Break EndIf // delete old data Select Files DbGoTop() Delete For Files->id==Dictionary->id All DbPack() Select Structure DbGoTop() Delete For Structure->id==Dictionary->id All DbPack() Select Indexes DbGoTop() Delete For Indexes->id==Dictionary->id All DbPack() Do Case Case "DBF"$Dictionary->dbe .Or. "FOX"$Dictionary->dbe cFiles:="*.DBF" Case "SDF"$Dictionary->dbe cFiles:="*.SDF" Case "DEL"$Dictionary->dbe cFiles:="*.CSV" EndCase aFiles:=Directory(AllTrim(Dictionary->directory)+cFiles) If Len(aFiles)=0 Errm(ERR_ERRM9) Break EndIf Dictionary->no_files=Len(aFiles) aPos:=CenterPos({388,172},AppDesktop():currentSize()) oDlg:=XbpDialog():new(AppDesktop(), SetAppWindow(), aPos, {388,172}, , .F.) oDlg:icon:=ICON_MAIN oDlg:taskList:=.F. oDlg:border:=XBPDLG_RAISEDBORDERTHIN_FIXED oDlg:close:={|mp1,mp2,obj| PostAppEvent(xbeP_Close+1000) } oDlg:title:="Scan Progress" oDlg:create() oDlg:setModalState(XBP_DISP_APPMODAL) oDlg:keyBoard:={| nKeyCode, uNIL, self | Iif(nKeyCode==xbeK_ESC,PostAppEvent(xbeP_Close+1000),Nil) } drawingArea:=oDlg:drawingArea drawingArea:setFontCompoundName("8.Helv") oGroup1:=XbpStatic():new(drawingArea, , {8,40}, {360,96}) oGroup1:caption:="Progress" oGroup1:clipSiblings:=.T. oGroup1:type:=XBPSTATIC_TYPE_GROUPBOX oGroup1:create() oXbp:=XbpStatic():new(oGroup1, , {8,48}, {344,24}) oXbp:clipSiblings:=.T. oXbp:options:=6 oXbp:type:=XBPSTATIC_TYPE_RECESSEDBOX oXbp:create() oProgress1:=ProgressBar():new(oGroup1, , {8,48}, {344,24},,.F.) oProgress1:create() oXbp:=XbpStatic():new(oGroup1, , {8,8}, {344,24}) oXbp:clipSiblings:=.T. oXbp:options:=6 oXbp:type:=XBPSTATIC_TYPE_RECESSEDBOX oXbp:create() oProgress2:=ProgressBar():new(oGroup1, , {8,8}, {344,24},,.F.) oProgress2:create() oClose:=XbpPushButton():new(drawingArea, , {264,8}, {104,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } }) oClose:caption:=GEN_CLOSE oClose:tabStop:=.T. oClose:create() oClose:activate:={|| PostAppEvent(xbeP_Close+1000) } oClose:disable() oDlg:show() oProgress1:hide() oProgress2:hide() SetAppFocus(oDlg) AddFiles() // blanks the files listbox oProgress1:minimum:=1 oProgress1:maximum:=Len(aFiles)+1 oProgress1:current:=1 oProgress1:show() For x:=1 To Len(aFiles) If Files->(AddRec()) Files->id:=Dictionary->id Files->file_name:=AllTrim(aFiles[x,1]) Files->(CommitUnlock()) If NetUse(AllTrim(Dictionary->directory)+AllTrim(aFiles[x,1]),,,,AllTrim(Dictionary->dbe)) aStruct=DbStruct() oProgress2:minimum:=1 oProgress2:maximum:=Len(aStruct)+OrdCount() oProgress2:current:=1 oProgress2:show() For y:=1 To Len(aStruct) If Structure->(AddRec()) Structure->id :=Dictionary->id Structure->file_name :=AllTrim(aFiles[x,1]) Structure->field_name:=aStruct[y,1] Structure->field_type:=aStruct[y,2] Structure->field_len :=aStruct[y,3] Structure->field_dec :=aStruct[y,4] Structure->(CommitUnlock()) EndIf oProgress2:increment() Next If OrdCount()>0 For y:=1 To OrdCount() DbSetOrder(y) If Indexes->(AddRec()) Indexes->id :=Dictionary->id Indexes->file_name :=AllTrim(aFiles[x,1]) Indexes->index_name:=Upper(OrdBagName(y)) Indexes->tag_name :=OrdName(y) Indexes->index_key :=OrdKey(y) Indexes->descend :=OrdIsDescend() Indexes->unique :=OrdIsUnique() Indexes->for_cond :=OrdFor(y) EndIf oProgress2:increment() Next EndIf DbCloseArea() EndIf EndIf oProgress1:increment() Next oClose:enable() nEvent:=xbe_None Do While nEvent<>xbeP_Close+1000 nEvent:=AppEvent(@mp1, @mp2, @oXbp) oXbp:handleEvent(nEvent, mp1, mp2) if nEvent == xbeP_Keyboard .and.; mp1 == xbeK_ESC exit endif EndDo oDlg:destroy() SetAppFocus(oFiles) AddFiles() AddDictionaries() oDictionary:setData({1},.T.) ShowDictInfo() End Return Nil ************* Func AddFiles() ************* Begin Sequence oFiles:clear() Files->(DbGoTop()) Do While !Files->(Eof()) oFiles:addItem(Files->file_name) Files->(DbSkip()) EndDo oFiles:setData({1}) End Return Nil ****************** Func SetDictScopes(lGoTop) ****************** * set scopes for dictionary Default(@lGoTop,.T.) Begin Sequence If lGoTop Select Files DbSetScope(SCOPE_BOTH,Dictionary->id) DbGoTop() EndIf Select Structure DbSetScope(SCOPE_BOTH,Dictionary->id+Files->file_name) DbGoTop() Select Indexes DbSetScope(SCOPE_BOTH,Dictionary->id+Files->file_name) DbGoTop() End Return Nil ********************* Func RefreshStructure() ********************* Begin Sequence If Empty(oFiles:getData()) Break EndIf Files->(DbSeek(Dictionary->id+oFiles:getItem(oFiles:getData()[1]))) SetDictScopes(.F.) oStructure:refreshAll() oStructure:forceStable() End Return Nil **************** Func ShowIndexes() **************** * show indexes Begin Sequence oIndexes:clear() Do While !Indexes->(Eof()) If Empty(Indexes->tag_name) oIndexes:addItem(Indexes->index_name) Else oIndexes:addItem(Indexes->tag_name) EndIf Indexes->(DbSkip()) EndDo oIndexes:setData({1}) End Return Nil *************** Func DeleteFile() *************** * delete file from dictionary Local cFile:="" Begin Sequence If oFiles:numItems()==0 .Or. !YesNo("Delete this file") Break EndIf cFile:=oFiles:getItem(oFiles:getData()[1]) oFiles:delItem(oFiles:getData()[1]) DeleteDict(cFile) Dictionary->no_files-=1 oFiles:setData({1}) ShowIndexes() RefreshStructure() End Return Nil *************** Func InsertFile() *************** * insert file Local cFile:="", cPath:="", aStruct, y Begin Sequence cFile:=ReadFile(.F.) If Empty(cFile) Break EndIf cPath:=Upper(Left(cFile,Rat("\",cFile))) cFile:=Right(cFile,Len(cFile)-Rat("\",cFile)) Files->(DbSeek(Dictionary->id+cFile)) If !Upper(cPath)==Upper(AllTrim(Dictionary->directory)) Errm(ERR_ERRM10) Break EndIf If Files->(Found()) Errm(ERR_ERRM11) Break EndIf If Files->(AddRec()) Dictionary->no_files+=1 Files->id:=Dictionary->id Files->file_name:=AllTrim(cFile) Files->(CommitUnlock()) If NetUse(AllTrim(Dictionary->directory)+cFile,,,,AllTrim(Dictionary->dbe)) aStruct=DbStruct() For y:=1 To Len(aStruct) If Structure->(AddRec()) Structure->id :=Dictionary->id Structure->file_name :=AllTrim(cFile) Structure->field_name:=aStruct[y,1] Structure->field_type:=aStruct[y,2] Structure->field_len :=aStruct[y,3] Structure->field_dec :=aStruct[y,4] Structure->(CommitUnlock()) EndIf Next If OrdCount()>0 For y:=1 To OrdCount() DbSetOrder(y) If Indexes->(AddRec()) Indexes->id :=Dictionary->id Indexes->file_name :=AllTrim(cFile) Indexes->index_name:=Upper(OrdBagName(y)) Indexes->tag_name :=OrdName(y) Indexes->index_key :=OrdKey(y) Indexes->descend :=OrdIsDescend() Indexes->unique :=OrdIsUnique() Indexes->for_cond :=OrdFor(y) EndIf Next EndIf DbCloseArea() EndIf EndIf AddFiles() oFiles:setData({1}) ShowIndexes() RefreshStructure() End Return Nil ***************** Func InsertStruct() ***************** * insert record Begin Sequence If oFiles:numItems()>0 .And. YesNo("Insert record") .And. Structure->(AddRec()) Structure->id:=Dictionary->id Structure->file_name:=oFiles:getItem(oFiles:getData()[1]) oStructure:refreshAll() oStructure:forceStable() EndIf End Return Nil **************** Func DeleteStruct() **************** * delete record Begin Sequence If oFiles:numItems()>0 .And. YesNo("Delete record") .And. Structure->(RecLock()) Structure->(DbDelete()) DbPack() oStructure:refreshAll() oStructure:forceStable() EndIf End Return Nil **************** Func DeleteIndex() **************** * delete index from file Local cIndex Begin Sequence If oIndexes:numItems()==0 .Or. !YesNo("Delete this index") Break EndIf cIndex:=oIndexes:getItem(oIndexes:getData()[1]) Select Indexes Delete For Indexes->tag_name=cIndex Delete For Indexes->index_name=cIndex DbPack() oIndexes:delItem(oIndexes:getData()[1]) oIndexes:setData({1}) End Return Nil **************** Func InsertIndex(lAdd) **************** * insert new index Local cFile:=oFiles:getItem(oFiles:getData()[1]), lFound:=.F. Local nEvent:=Nil, mp1:=Nil, mp2:=Nil, aPos:={}, oFocus:=SetAppFocus() Local oDlg, oXbp, drawingArea, oGroup1, oGroup2, oGroup3 Default(@lAdd,.T.) Begin Sequence If !lAdd Indexes->(DbSeek(Dictionary->id+Files->file_name)) If !Indexes->(Found()) Break EndIf lFound:=.F. Do While AllTrim(Indexes->id)==AllTrim(Dictionary->id) .And. AllTrim(Indexes->file_name)==AllTrim(Files->file_name) .And. !Indexes->(Eof()) If Indexes->tag_name=oIndexes:getItem(oIndexes:getData()[1]) .Or. Indexes->index_name=oIndexes:getItem(oIndexes:getData()[1]) lFound:=.T. Exit EndIf Indexes->(DbSkip()) EndDo If !lFound Break EndIf EndIf If Empty(cFile) .Or. !NetUse(AllTrim(Dictionary->directory)+cFile,,,,AllTrim(Dictionary->dbe)) Break EndIf aPos:=CenterPos({584,429},AppDesktop():currentSize()) oDlg:=XbpDialog():new(AppDesktop(), SetAppFocus(), aPos, {584,429}, , .F.) oDlg:icon:=ICON_MAIN oDlg:taskList:=.F. oDlg:border:=XBPDLG_RAISEDBORDERTHIN_FIXED oDlg:title:="Create Index" oDlg:close:={|mp1,mp2,obj| PostAppEvent(xbeP_Close+1000) } oDlg:create() oDlg:setModalState(XBP_DISP_APPMODAL) oDlg:keyBoard:={| nKeyCode, uNIL, self | Iif(nKeyCode==xbeK_ESC,PostAppEvent(xbeP_Close+1000),Nil) } drawingArea:=oDlg:drawingArea drawingArea:setFontCompoundName("8.Helv") // display fields that can be indexed from oGroup1:=XbpStatic():new(drawingArea, , {12,48}, {204,348}) oGroup1:caption:="Fields" oGroup1:clipSiblings:=.T. oGroup1:type:=XBPSTATIC_TYPE_GROUPBOX oGroup1:create() oFieldList:=XbpListBox():new(oGroup1, , {12,12}, {180,312}, { { XBP_PP_BGCLR, XBPSYSCLR_ENTRYFIELD } }) oFieldList:tabStop:=.T. oFieldList:markMode:=XBPLISTBOX_MM_SINGLE oFieldlist:itemSelected:={|uNIL1, uNIL2, self| AddFieldToKey() } oFieldList:setInputFocus:={| uNil1,uNil2,self | XbpBorder(self,GRA_CLR_BLUE) } oFieldList:killInputFocus:={| uNil1,uNil2,self | XbpBorder(self, GRA_CLR_BACKGROUND) } oFieldList:create() AddFields(oFieldList) oFieldList:setData({1},.T.) // display and allow edit of index key oGroup2:=XbpStatic():new(drawingArea, , {228,232}, {336,164}) oGroup2:caption:="Index Key" oGroup2:clipSiblings:=.T. oGroup2:type:=XBPSTATIC_TYPE_GROUPBOX oGroup2:create() oIndexKey:=XbpMle():new(oGroup2, , {12,12}, {312,128}, { { XBP_PP_BGCLR, XBPSYSCLR_ENTRYFIELD } }) oIndexKey:tabStop:=.T. oIndexKey:horizScroll:=.F. oIndexKey:setInputFocus:={| uNil1,uNil2,self | XbpBorder(self,GRA_CLR_BLUE) } oIndexKey:killInputFocus:={| uNil1,uNil2,self | XbpBorder(self, GRA_CLR_BACKGROUND) } oIndexKey:create() // set index options oGroup3:=XbpStatic():new(drawingArea, , {228,88}, {336,132}) oGroup3:caption:="Index Options" oGroup3:clipSiblings:=.T. oGroup3:type:=XBPSTATIC_TYPE_GROUPBOX oGroup3:create() oXbp:=XbpStatic():new(oGroup3, , {12,84}, {24,24}) oXbp:caption:=GEN_FOR oXbp:clipSiblings:=.T. oXbp:options:=XBPSTATIC_TEXT_VCENTER oXbp:create() oForCond:=XbpSLE():new(oGroup3, , {36,84}, {288,24}, { { XBP_PP_BGCLR, XBPSYSCLR_ENTRYFIELD } }) oForCond:tabStop:=.T. oForCond:setInputFocus:={| uNil1,uNil2,self | XbpBorder(self,GRA_CLR_BLUE) } oForCond:killInputFocus:={| uNil1,uNil2,self | XbpBorder(self, GRA_CLR_BACKGROUND) } oForCond:create() oDescend:=XbpCheckbox():new(oGroup3, , {120,48}, {96,24}) oDescend:caption:="Descending" oDescend:tabStop:=.T. oDescend:setInputFocus:={| uNil1,uNil2,self | XbpBorder(self,GRA_CLR_BLUE) } oDescend:killInputFocus:={| uNil1,uNil2,self | XbpBorder(self, GRA_CLR_BACKGROUND) } oDescend:create() oUnique:=XbpCheckbox():new(oGroup3, , {36,48}, {72,24}) oUnique:caption:="Unique" oUnique:tabStop:=.T. oUnique:setInputFocus:={| uNil1,uNil2,self | XbpBorder(self,GRA_CLR_BLUE) } oUnique:killInputFocus:={| uNil1,uNil2,self | XbpBorder(self, GRA_CLR_BACKGROUND) } oUnique:create() oXbp:=XbpStatic():new(oGroup3, , {12,12}, {24,24}) oXbp:caption:="Tag" oXbp:clipSiblings:=.T. oXbp:options:=XBPSTATIC_TEXT_VCENTER oXbp:create() oTagName:=XbpSLE():new(oGroup3, , {36,12}, {288,24}, { { XBP_PP_BGCLR, XBPSYSCLR_ENTRYFIELD } }) oTagName:tabStop:=.T. oTagName:setInputFocus:={| uNil1,uNil2,self | XbpBorder(self,GRA_CLR_BLUE) } oTagName:killInputFocus:={| uNil1,uNil2,self | XbpBorder(self, GRA_CLR_BACKGROUND) } oTagName:create() If !"CDX"$DbInfo(DBO_DBENAME) oTagName:disable() EndIf // pushbuttons oPBCreate:=XbpPushButton():new(drawingArea, , {360,12}, {96,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } }) oPBCreate:caption:=IIf(lAdd,"Create","Save") oPBCreate:tabStop:=.T. oPBCreate:create() oPBCreate:activate:={|| IIf(AddEditIndex(lAdd), PostAppEvent(xbeP_Close+1000), Nil) } oXbp:=XbpPushButton():new(drawingArea, , {468,12}, {96,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } }) oXbp:caption:=GEN_CANCEL oXbp:tabStop:=.T. oXbp:create() oXbp:activate:={|| PostAppEvent(xbeP_Close+1000) } oDlg:show() If !lAdd oTagName:setData(AllTrim(Indexes->tag_name)) oIndexKey:setData(AllTrim(Indexes->index_key)) oDescend:setData(Indexes->descend) oUnique:setData(Indexes->unique) oForCond:setData(AllTrim(Indexes->for_cond)) EndIf SetAppFocus(oFieldList) nEvent:=xbe_None Do While nEvent<>xbeP_Close+1000 nEvent:=AppEvent(@mp1, @mp2, @oXbp) oXbp:handleEvent(nEvent, mp1, mp2) if nEvent == xbeP_Keyboard .and.; mp1 == xbeK_ESC exit endif If (!Empty(oIndexKey:getData()) .And. "CDX"$DbInfo(DBO_DBENAME) .And. !Empty(oTagName:getData())) .Or. ; (!Empty(oIndexKey:getData()) .And. "NTX"$DbInfo(DBO_DBENAME) .And. Empty(oTagName:getData())) oPBCreate:enable() Else oPBCreate:disable() EndIf EndDo oDlg:Destroy() SetAppFocus(oFocus) DbCloseArea() End Return Nil ************************* Static Func AddFieldToKey() ************************* * add field to key Local cTemp:="" Begin Sequence cTemp:=oFieldList:getItem(oFieldList:getData()[1]) cTemp:=Left(cTemp,At("[",cTemp)-2) If !cTemp$oIndexKey:getData() oIndexKey:setData(oIndexKey:getData()+Iif(Empty(oIndexKey:getData()),"","+")+cTemp) EndIf End Return Nil ***************** Func AddEditIndex(lAdd) ***************** * add index to file Local cFile:=AllTrim(oFiles:getItem(oFiles:getData()[1])) Local cNewFile:=Upper(Left(cFile,Len(cFile)-4)+OrdBagExt()), oDlg:=Nil, oFocus:=SetAppFocus(), lRetVal:=.T. Begin Sequence If "NTX"$DbInfo(DBO_DBENAME) oDlg:=XbpFileDialog():new() oDlg:fileFilters:={ {"NTX Index","NTX"} } oDlg:center:=.T. oDlg:create() Do While .T. cNewFile:=oDlg:saveAs(cDirectory+"*.NTX") If File(cNewFile) .And. !YesNo("File already exists, overwrite","Overwrite") Loop Else Exit EndIf EndDo oDlg:destroy() SetAppFocus(oFocus) EndIf If !TestCondition(oIndexKey:getData()) .Or. (!Empty(oForCond:getData()) .And. !TestCondition(oForCond:getData())) lRetVal:=.F. Break EndIf If lAdd If Indexes->(AddRec()) Indexes->id:=Dictionary->id Indexes->file_name :=Files->file_name Indexes->index_name:=cNewFile Indexes->tag_name :=Upper(oTagName:getData()) Indexes->index_key :=oIndexKey:getData() Indexes->descend :=oDescend:getData() Indexes->unique :=oUnique:getData() Indexes->for_cond :=oForCond:getData() EndIf If Empty(Indexes->tag_name) oIndexes:addItem(Indexes->index_name) Else oIndexes:addItem(Indexes->tag_name) EndIf Else If Indexes->(RecLock()) Indexes->tag_name :=Upper(oTagName:getData()) Indexes->index_key :=oIndexKey:getData() Indexes->descend :=oDescend:getData() Indexes->unique :=oUnique:getData() Indexes->for_cond :=oForCond:getData() EndIf EndIf End Return lRetVal ****************** Func InsertNewFile() ****************** Local oDlg, oXbp, drawingArea, oGroup1, aPos:={}, oController:=Nil, oFileName:=Nil, cFileName:=Space(100) Local nEvent, mp1:=Nil, mp2:=Nil, oFocus:=SetAppFocus() Begin Sequence aPos:=CenterPos({476,146},AppDesktop():currentSize()) oDlg:=XbpDialog():new(AppDesktop(), SetAppWindow(), aPos, {476,146}, , .F.) oDlg:icon:=ICON_MAIN oDlg:taskList:=.F. oDlg:border:=XBPDLG_RAISEDBORDERTHIN_FIXED oDlg:close:={|mp1,mp2,obj| PostAppEvent(xbeP_Close+1000) } oDlg:title:="Add New File" oDlg:create() oDlg:setModalState(XBP_DISP_APPMODAL) oDlg:keyBoard:={| nKeyCode, uNIL, self | Iif(nKeyCode==xbeK_ESC,PostAppEvent(xbeP_Close+1000),Nil) } drawingArea:=oDlg:drawingArea drawingArea:setFontCompoundName("8.Helv") oGroup1:=XbpStatic():new(drawingArea, , {16,48}, {440,56}) oGroup1:caption:="New File" oGroup1:clipSiblings:=.T. oGroup1:type:=XBPSTATIC_TYPE_GROUPBOX oGroup1:create() oXbp:=XbpStatic():new(oGroup1, , {8,8}, {64,24}) oXbp:caption:="Filename" oXbp:clipSiblings:=.T. oXbp:options:=XBPSTATIC_TEXT_VCENTER+XBPSTATIC_TEXT_RIGHT oXbp:create() oFileName:=XbpGet():new(oGroup1, , {80,8}, {352,24}) oFileName:tabStop:=.T. oFileName:bufferLength:=12 oFileName:picture:="@!" oFileName:dataLink:={|x| Iif(x==Nil, cFileName, cFileName:=x) } oFileName:create() oFileName:setInputFocus:={| uNil1,uNil2,self | XbpBorder(self,GRA_CLR_BLUE) } oFileName:killInputFocus:={| uNil1,uNil2,self | XbpBorder(self, GRA_CLR_BACKGROUND), cFileName:=AllTrim(self:getData()) } oXbp:=XbpPushButton():new(drawingArea, , {336,8}, {56,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } }) oXbp:caption:="Save" oXbp:tabStop:=.T. oXbp:create() oXbp:activate:={|| Iif(SaveNewFile(cFileName),PostAppEvent(xbeP_Close+1000),Nil) } oXbp:=XbpPushButton():new(drawingArea, , {400,8}, {56,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } }) oXbp:caption:=GEN_CANCEL oXbp:tabStop:=.T. oXbp:create() oXbp:activate:={|| PostAppEvent(xbeP_Close+1000) } oController:=XbpGetController():new(oDlg):create() oController:read(,.F.) oDlg:show() SetAppFocus(oFileName) nEvent:=xbe_None Do While nEvent<>xbeP_Close+1000 nEvent:=AppEvent(@mp1, @mp2, @oXbp) oXbp:handleEvent(nEvent, mp1, mp2) if nEvent == xbeP_Keyboard .and.; mp1 == xbeK_ESC exit endif EndDo oDlg:destroy() SetAppFocus(oFocus) End Return Nil **************** Func SaveNewFile(cFileName) **************** * save file info Local lRetVal:=.F. Begin Sequence If Empty(cFileName) .Or. Files->(DbSeek(Dictionary->id+AllTrim(cFileName))) .Or. !Files->(AddRec()) Errm(ERR_ERRM12) Break EndIf Files->id:=Dictionary->id Files->file_name:=cFileName Files->(CommitUnlock()) AddFiles() oFiles:setData({1}) ShowIndexes() RefreshStructure() lRetVal:=.T. End Return lRetVal ******************** Func ApplyDictionary() ******************** * apply dictionary to directory Local cApplyDir:=Space(100), oProgress1, oProgress2, oClose, aStru:={}, bTemp Local oDlg, oXbp, drawingArea, oGroup1, aPos:={}, cFile:="", cTempFile:="", bBlock, cOrigFile:="" Local nEvent, mp1:=Nil, mp2:=Nil, oFocus:=SetAppFocus(), lOk, x, aOrigStru Local oError, bSaveErrorBlock Begin Sequence If !YesNo("Apply dictionary structure") Break EndIf cApplyDir:=SelectDirectory() If Empty(cApplyDir) Break EndIf If !YesNo("Apply changes to "+cApplyDir+", Are you sure") Break EndIf aPos:=CenterPos({385,216},AppDesktop():currentSize()) oDlg:=XbpDialog():new(AppDesktop(), , aPos, {385,216}, , .F.) oDlg:icon:=ICON_MAIN oDlg:taskList:=.F. oDlg:border:=XBPDLG_RAISEDBORDERTHIN_FIXED oDlg:close:={|mp1,mp2,obj| PostAppEvent(xbeP_Close+1000) } oDlg:title:="Applying dictionary" oDlg:create() oDlg:setModalState(XBP_DISP_APPMODAL) oDlg:keyBoard:={| nKeyCode, uNIL, self | Iif(nKeyCode==xbeK_ESC,PostAppEvent(xbeP_Close+1000),Nil) } drawingArea:=oDlg:drawingArea drawingArea:setFontCompoundName("8.Helv") oGroup1:=XbpStatic():new(drawingArea, , {8,40}, {360,136}) oGroup1:caption:="Applying Changes" oGroup1:clipSiblings:=.T. oGroup1:type:=XBPSTATIC_TYPE_GROUPBOX oGroup1:create() oXbp:=XbpStatic():new(oGroup1, , {8,88}, {344,24}) oXbp:clipSiblings:=.T. oXbp:options:=6 oXbp:type:=XBPSTATIC_TYPE_RECESSEDBOX oXbp:create() oProgress1:=ProgressBar():new(oGroup1, , {8,88}, {344,24},,.F.) oProgress1:create() oXbp:=XbpStatic():new(oGroup1, , {8,48}, {344,24}) oXbp:caption:="Progress2" oXbp:clipSiblings:=.T. oXbp:options:=6 oXbp:type:=XBPSTATIC_TYPE_RECESSEDBOX oXbp:create() oProgress2:=ProgressBar():new(oGroup1, , {8,48}, {344,24},,.F.) oProgress2:create() oXbp:=XbpStatic():new(oGroup1, , {8,8}, {344,24}) oXbp:clipSiblings:=.T. oXbp:options:=6 oXbp:type:=XBPSTATIC_TYPE_RECESSEDBOX oXbp:create() oFileName:=XbpStatic():new(oGroup1, , {9,9}, {342,22}) oFileName:clipSiblings:=.T. oFileName:type:=XBPSTATIC_TYPE_TEXT oFileName:options:=XBPSTATIC_TEXT_VCENTER+XBPSTATIC_TEXT_LEFT oFileName:create() oClose:=XbpPushButton():new(drawingArea, , {264,8}, {104,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } }) oClose:caption:=GEN_CLOSE oClose:tabStop:=.T. oClose:create() oClose:activate:={|| PostAppEvent(xbeP_Close+1000) } oDlg:show() oProgress1:hide() oProgress2:hide() oClose:disable() SetAppFocus(oDlg) // apply dictionary info oProgress1:minimum:=1 oProgress1:maximum:=Dictionary->no_files+1 oProgress1:current:=1 oProgress1:show() // reset scopes for dictionary SetDictScopes(.T.) If !Files->(Eof()) Do While !Files->(Eof()) cOrigFile:=AllTrim(Dictionary->directory)+AllTrim(Files->file_name) cFile:=AllTrim(cApplyDir)+AllTrim(Files->file_name) oFileName:setCaption(cFile) SetDictScopes(.F.) // apply scopes to file lOk:=.T. // read structure into array Structure->(DbGoTop()) aStru:={} Do While !Structure->(Eof()) Aadd(aStru,{Structure->field_name, Structure->field_type, Structure->field_len, Structure->field_dec}) Structure->(DbSkip()) EndDo If File(cFile) // file exists, so check structure and mod if necessary cTempFile:=Left(cFile,At(".",cFile)-1)+"~."+Right(cFile,3) // check structure to see if any changes need to be made If NetUse(cFile,,,,AllTrim(Dictionary->dbe)) aOrigStru:=DbStruct() If Len(aStru)<>Len(aOrigStru) lOk:=.F. Else For x:=1 To Len(aStru) If !AllTrim(aStru[x,1])==AllTrim(aOrigStru[x,1]) .Or. !aStru[x,2]==aOrigStru[x,2] .Or. !aStru[x,3]==aOrigStru[x,3] .Or. ; !aStru[x,4]==aOrigStru[x,4] lOk:=.F. Exit EndIf Next EndIf DbCloseArea() EndIf If !lOk // create temp file If Len(aStru)>0 DbCreate(cTempFile, aStru, AllTrim(Dictionary->dbe)) Else Errm(ERR_ERRM13) EndIf oProgress2:minimum:=1 If NetUse(cOrigFile,,,,AllTrim(Dictionary->dbe)) oProgress2:maximum:=LastRec() DbCloseArea() Else oProgress2:maximum:=1 EndIf oProgress2:current:=1 DbCloseArea() If NetUse(cTempFile,,,,AllTrim(Dictionary->dbe)) bSaveErrorBlock:=ErrorBlock({|oError| Break(oError)}) Begin Sequence oProgress2:show() bBlock:={|| oProgress2:increment(), .T. } DbImport(cOrigFile, , bBlock, , , , , AllTrim(Dictionary->dbe)) DbCloseArea() If FErase(cFile)==-1 Errm(ERR_ERRM19) Break EndIf If File(Left(cFile,Len(cFile)-3)+"FPT") .And. FErase(Left(cFile,Len(cFile)-3)+"FPT")==-1 Errm(ERR_ERRM20) Break EndIf If File(Left(cFile,Len(cFile)-3)+"DBT") .And. FErase(Left(cFile,Len(cFile)-3)+"DBT")==-1 Errm(ERR_ERRM21) Break EndIf If Frename(cTempFile,cFile)==-1 Errm(ERR_ERRM14) Break Else If File(Left(cTempFile,Len(cTempFile)-3)+"FPT") .And. Frename(Left(cTempFile,Len(cTempFile)-3)+"FPT",Left(cFile,Len(cFile)-3)+"FPT")==-1 Errm(ERR_ERRM15) Break EndIf If File(Left(cTempFile,Len(cTempFile)-3)+"DBT") .And. Frename(Left(cTempFile,Len(cTempFile)-3)+"DBT",Left(cFile,Len(cFile)-3)+"DBT")==-1 Errm(ERR_ERRM15) Break EndIf EndIf Recover Using oError Errm(ERR_ERRM16) End // Restore prior error block ErrorBlock(bSaveErrorBlock) EndIf EndIf Else // file doesn't exist so create lOk:=.F. // create file If Len(aStru)>0 DbCreate(cFile, aStru, AllTrim(Dictionary->dbe)) Else Errm(ERR_ERRM17) EndIf EndIf // reindex file if necessary If (!lOk .Or. !File(AllTrim(cApplyDir)+AllTrim(Indexes->index_name))) .And. !Indexes->(Eof()) .And. NetUse(cFile,.T.,,,AllTrim(Dictionary->dbe)) Do While !Indexes->(Eof()) oProgress2:minimum:=1 oProgress2:maximum:=LastRec() oProgress2:current:=1 oProgress2:show() bTemp:=&("{|| "+AllTrim(Indexes->index_key)+" }") bBlock:={|| oProgress2:increment(), Eval(bTemp) } OrdCondSet(AllTrim(Indexes->for_cond), , , , , , , , , ,Indexes->descend) OrdCreate(AllTrim(cApplyDir)+AllTrim(Indexes->index_name), AllTrim(Indexes->tag_name), AllTrim(Indexes->index_key), bBlock, Indexes->unique) Indexes->(DbSkip()) EndDo DbCloseArea() EndIf oProgress1:increment() Files->(DbSkip()) EndDo Else Errm(ERR_ERRM19) oDlg:destroy() SetAppFocus(oFocus) Break EndIf oClose:enable() nEvent:=xbe_None Do While nEvent<>xbeP_Close+1000 nEvent:=AppEvent(@mp1, @mp2, @oXbp) oXbp:handleEvent(nEvent, mp1, mp2) if nEvent == xbeP_Keyboard .and.; mp1 == xbeK_ESC exit endif EndDo oDlg:destroy() SetAppFocus(oFocus) End Return Nil