* Program..: Utilities.prg * Author...: Jeremy Suiter * Date.....: 19/03/2003 * * Notice...: Copyright (c) 2003, Jeremy Suiter, All Rights Reserved * Notes....: Visual DbEditor General 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 xBuffer:=Nil ************** Func CenterPos(aSize,aRefSize) ************** Return {Int((aRefSize[1] - aSize[1])/2), Int((aRefSize[2]-aSize[2])/2)} ************ Func Default(x,xval) ************ * Defaults variable x (passed by reference) to xval. Use as Default(@x,xval). If x==Nil x:=xval EndIf Return Nil ********* Func Errm(cMessage, cTitle, nIcon) ********* * error message box Local oFocus:=SetAppFocus() if nIcon == NIL nIcon := XBPMB_WARNING endif ConfirmBox(NIL, cMessage, Iif(cTitle=Nil,"Error!",cTitle), XBPMB_OK , nIcon+XBPMB_APPMODAL+XBPMB_MOVEABLE) SetAppFocus(oFocus) Return Nil ********** Func Ntrim(nVal) ********** * Handy VO function Return Ltrim(Str(nVal)) *************** Proc MenuCreate(oDlg, oMenuBar) *************** Local oMenu, oSubMenu oDlg:setDisplayFocus:={|mp1,mp2,obj| MainWindow(obj) } // First sub-menu oMenu:=SubMenuNew(oMenuBar, MENU_FILE) oMenu:setName(ID_UTILS_FILE) oMenu:addItem({ MENU_NEW, {|| Structure(.T.) }}) oMenu:addItem({ MENU_OPEN, {|| OpenFile(NIL, oDlg) }}) oMenu:addItem(MENUITEM_SEPARATOR) oMenu:addItem({ MENU_OPTIONS , {|| IIf(oFocusBrowse==Nil,SetOptions(),Nil) }}) oMenu:addItem({ MENU_PRINTER , {|| SetupPrinter() }}) oMenu:addItem(MENUITEM_SEPARATOR) oMenu:addItem({ MENU_EXIT , {|| PostAppEvent(xbeP_Close,,, oDlg) }}) oMenuBar:addItem({oMenu, Nil}) oMenu:=SubMenuNew(oMenuBar, MENU_UTILITIES) oMenu:setName(ID_UTILS_OPTIONS) oMenu:addItem({ MENU_CUT , {|| CutField() }}) oMenu:addItem({ MENU_COPY , {|| CopyField() }}) oMenu:addItem({ MENU_PASTE , {|| PasteField() }}) oMenu:addItem(MENUITEM_SEPARATOR) oSubMenu:=SubMenuNew(oMenuBar, MENU_FIND) oSubMenu:addItem({ MENU_SCOPE , {|| SetScope() }}) oSubMenu:addItem({ MENU_GOTO , {|| GotoRecord() }}) oSubMenu:addItem({ MENU_SEEK , {|| SeekRecord() }}) oSubMenu:addItem({ MENU_LOCATE , {|| LocateRecords() }}) oMenu:addItem({oSubMenu, Nil}) oMenu:addItem(MENUITEM_SEPARATOR) oSubMenu:=SubMenuNew(oMenuBar, MENU_RECORDS) oSubMenu:addItem({ MENU_INSERT , {|| InsertRec() }}) oSubMenu:addItem({ MENU_DUPLICATE , {|| DupRecord() }}) oSubMenu:addItem({ MENU_DELETE , {|| DelRecord() }}) oSubMenu:addItem({ MENU_RECALL , {|| RestRecord() }}) oMenu:addItem({oSubMenu, Nil}) oMenu:addItem(MENUITEM_SEPARATOR) oSubMenu:=SubMenuNew(oMenuBar, MENU_TABLE) oSubMenu:addItem({ MENU_INDEXES, {|| SetIndex() }}) oSubMenu:addItem({ MENU_STRUCTURE, {|| Structure(.F.) }}) oSubMenu:addItem(MENUITEM_SEPARATOR) oSubMenu:addItem({ MENU_RELATIONS , {|| SetRelations() }}) oSubMenu:addItem({ MENU_MATHFUNC , {|| MathFunc() }}) oSubMenu:addItem(MENUITEM_SEPARATOR) oSubMenu:addItem({ MENU_IMPORT , {|| ExportData() }}) oSubMenu:addItem(MENUITEM_SEPARATOR) oSubMenu:addItem({ MENU_PACK , {|| PackZapTable(.T.) }}) oSubMenu:addItem({ MENU_ZAP , {|| PackZapTable(.F.) }}) oMenu:addItem({oSubMenu, Nil}) oMenu:addItem(MENUITEM_SEPARATOR) oSubMenu:=SubMenuNew(oMenuBar, MENU_BULK) oSubMenu:addItem({ MENU_BULKREP , {|| BulkReplace() }}) oSubMenu:addItem({ MENU_BULKDEL , {|| BulkDeleteRecall(.T.) }}) oSubMenu:addItem({ MENU_BULKREC , {|| BulkDeleteRecall(.F.) }}) oMenu:addItem({oSubMenu, Nil}) oMenu:addItem(MENUITEM_SEPARATOR) oSubMenu:=SubMenuNew(oMenuBar, MENU_COLUMNS) oSubMenu:addItem({ MENU_FREEZE , {|| FreezeCol() }}) oSubMenu:addItem({ MENU_UNFREEZE , {|| DefrostCol() }}) oMenu:addItem({oSubMenu, Nil}) oMenu:addItem(MENUITEM_SEPARATOR) oMenu:addItem({ MENU_PREVIEW , {|| PreviewTable() }}) oMenu:disable() oMenuBar:addItem({oMenu, Nil}) oMenu:=SubMenuNew(oMenuBar, MENU_DATADICT) oMenu:addItem({ MENU_DDMAINT , {|| DataDictionary() }}) oMenu:disable() oMenuBar:addItem({oMenu, Nil}) /* * Create an instance of the WindowMenu class for managing child windows */ oMenu:=WindowMenu():new(oMenuBar) oMenu:menuPos:=4 oMenu:create() // Help menu oMenu:=SubMenuNew(oMenuBar, MENU_HELP) oMenu:addItem({ MENU_SHOWHELP, {|| HelpObject():showHelpContents() } }) oMenuBar:addItem({oMenu, Nil}) Return *************** Func SubMenuNew(oMenu,cTitle) *************** Local oSubMenu:=XbpMenu():new(oMenu) oSubMenu:title:=cTitle Return oSubMenu:create() *************** Func AddToolBar(oDlg, oToolBar) *************** * add toolbar items Local oTip, oTool, x x := 4 oTip := MainWindow():oShowTip oTool:=XbpPushButton():new() oTool:caption:=BITMAP_OPEN oTool:create(oToolBar, , {x,3}, {32,32}) oTool:activate := {|| OpenFile(NIL, oDlg)} oTool:motion := {|aPos, uNil, oXbp| oTip:showTip(aPos, oXbp,TT_OPENTABLE)} oTool:setPointer(,POINTER_HAND) x+=34 oTool:=XbpPushButton():new() oTool:caption:=BITMAP_CLOSE oTool:create(oToolBar, , {x,3}, {32,32}) oTool:activate := {|| CloseFile() } oTool:motion := {|aPos, uNil, oXbp| oTip:showTip(aPos, oXbp, TT_CLOSETABLE)} oTool:setPointer(,POINTER_HAND) x+=34 // separator oTool:=XbpStatic():new(oToolBar, , {x,3}, {4,32}) oTool:type:=XBPSTATIC_TYPE_RECESSEDRECT oTool:create() oTool:setPointer(,POINTER_HAND) x+=6 oTool:=XbpPushButton():new() oTool:caption:=BITMAP_DELETE oTool:create(oToolBar, , {x,3}, {32,32}) oTool:activate := {|| DelRecord() } oTool:motion := {|aPos, uNil, oXbp| oTip:showTip(aPos, oXbp,TT_DELETE)} oTool:setPointer(,POINTER_HAND) oTool:setName(ID_DELETE_BTN) x+=34 oTool:=XbpPushButton():new() oTool:caption:=BITMAP_UNDELETE oTool:create(oToolBar, , {x,3}, {32,32}) oTool:activate := {|| RestRecord() } oTool:motion := {|aPos, uNil, oXbp| oTip:showTip(aPos, oXbp,TT_RECALL)} oTool:setPointer(,POINTER_HAND) oTool:setName(ID_UNDELETE_BTN) x+=34 oTool:=XbpPushButton():new() oTool:caption:=BITMAP_INDEX oTool:create(oToolBar, , {x,3}, {32,32}) oTool:activate := {|| SetIndex() } oTool:motion := {|aPos, uNil, oXbp| oTip:showTip(aPos, oXbp,TT_INDEXOPT)} oTool:setPointer(,POINTER_HAND) oTool:setName(ID_INDEX_BTN) x+=34 oTool:=XbpPushButton():new() oTool:caption:=BITMAP_OPTIONS oTool:create(oToolBar, , {x,3}, {32,32}) oTool:activate := {|| SetScope() } oTool:motion := {|aPos, uNil, oXbp| oTip:showTip(aPos, oXbp,TT_SCOPE)} oTool:setPointer(,POINTER_HAND) oTool:setName(ID_SCOPE_BTN) x+=34 oTool:=XbpPushButton():new() oTool:caption:=BITMAP_STRUCT oTool:create(oToolBar, , {x,3}, {32,32}) oTool:activate := {|| Structure(.F.) } oTool:motion := {|aPos, uNil, oXbp| oTip:showTip(aPos, oXbp,TT_STRUCT)} oTool:setPointer(,POINTER_HAND) oTool:setName(ID_STRUCTURE_BTN) x+=34 oTool:=XbpPushButton():new() oTool:caption:=BITMAP_REPORTS oTool:create(oToolBar, , {x,3}, {32,32}) oTool:activate := {|| PreviewTable() } oTool:motion := {|aPos, uNil, oXbp| oTip:showTip(aPos, oXbp,TT_REPORTS)} oTool:setPointer(,POINTER_HAND) oTool:setName(ID_REPORTS_BTN) x+=34 // separator oTool:=XbpStatic():new(oToolBar, , {x,3}, {4,32}) oTool:type:=XBPSTATIC_TYPE_RECESSEDRECT oTool:create() oTool:setPointer(,POINTER_HAND) x+=6 oTool:=XbpPushButton():new() oTool:caption:=BITMAP_PRINTER oTool:create(oToolBar, , {x,3}, {32,32}) oTool:activate := {|| SetupPrinter() } oTool:motion := {|aPos, uNil, oXbp| oTip:showTip(aPos, oXbp,TT_PRINTER)} oTool:setPointer(,POINTER_HAND) x+=34 oTool:=XbpPushButton():new() oTool:caption:=BITMAP_CASCADE oTool:create(oToolBar, , {x,3}, {32,32}) oTool:activate := {|| MainWindow():cascade() } oTool:motion := {|aPos, uNil, oXbp| oTip:showTip(aPos, oXbp,TT_CASCADE)} oTool:setPointer(,POINTER_HAND) oTool:setName(ID_CASCADE_BTN) x+=34 oTool:=XbpPushButton():new() oTool:caption:=BITMAP_HELP oTool:create(oToolBar, , {x,3}, {32,32}) oTool:activate := {|| HelpObject():showHelpContents() } oTool:motion := {|aPos, uNil, oXbp| oTip:showTip(aPos, oXbp,TT_HELP)} oTool:setPointer(,POINTER_HAND) x+=34 oTool:=XbpPushButton():new() oTool:caption:=BITMAP_EXIT oTool:create(oToolBar, , {x,3}, {32,32}) oTool:activate := {|| AppQuit() } oTool:motion := {|aPos, uNil, oXbp| oTip:showTip(aPos, oXbp,TT_EXIT)} oTool:setPointer(,POINTER_HAND) Return Nil ************* Func ReadFile(lMultiple) ************* Local oDlg:=Nil, aFiles:={}, oFocus:=SetAppFocus() Local aFilters:={ {"DBF Files", "*.DBF"}, ; {"CSV Files", "*.CSV"}, ; {"SDF Files", "*.SDF"}, ; {"TXT Files", "*.TXT"} } Default(@lMultiple,.T.) oDlg:=XbpFileDialog():new() oDlg:fileFilters:=aFilters oDlg:center:=.T. oDlg:create() aFiles:=oDlg:open(cDirectory+"*."+cExtension,,lMultiple) //aFiles:=oDlg:open(cDirectory,,lMultiple) oDlg:destroy() SetAppFocus(oFocus) Return aFiles ************* Func OpenFile(cOpenFile, oDlg) ************* Local lRetVal := .F.,; cDefDbe := cDbe,; lExclusive := !lMultiUser,; lReadOnly := .F.,; nEvent := 0,; oController := Nil,; mp1 := Nil,; mp2 := Nil,; oDbe := Nil,; oGroup2 := Nil,; aDbe := {},; oFocus := SetAppFocus(),; nYBorderWidth := ((xbpGetSystemMetrics(SM_CYSIZEFRAME) * 2) + 8) Local aSize, cAliasSLE, oBrowseDialog, aFiles, oPS, oDbeDlg, oXbp, oGet, drawingArea, oGroup1, nInd, nLen MEMVAR cFile Default(@cOpenFile,"") do while .t. If Empty(cOpenFile) aFiles := ReadFile() If Empty(aFiles) exit EndIf else aFiles := {cOpenFile} endif cAliasSle := GetAlias(aFiles[01]) oPS := AppDesktop():lockPS() nLen := Len(aFiles) aSize := {340, 203} for nInd := 1 to nLen aSize[01] := Max(aSize[01], StringLength(aFiles[nInd], oPS)) next AppDesktop():unlockPS() aSize[01] += nYBorderWidth oDbeDlg := XbpDialog():new(AppDesktop(), oDlg, {0, 0}, aSize, DEFAULT_PRESPARAM, .F.) oDbeDlg:icon := ICON_MAIN oDbeDlg:taskList := .F. oDbeDlg:border:=XBPDLG_RAISEDBORDERTHIN_FIXED oDbeDlg:close:={|mp1,mp2,obj| PostAppEvent(xbeP_Close+1000) } oDbeDlg:create() oDbeDlg:setModalState(XBP_DISP_APPMODAL) oDbeDlg:keyBoard:={| nKeyCode, uNIL, self | Iif(nKeyCode==xbeK_ESC,PostAppEvent(xbeP_Close+1000),Nil) } drawingArea := oDbeDlg:drawingArea drawingArea:setFont(oDbeDlg:setFont()) oGroup1:=XbpStatic():new(drawingArea, , {12,48}, {132,128}) oGroup1:caption:="Select DBE" oGroup1:clipSiblings:=.T. oGroup1:type:=XBPSTATIC_TYPE_GROUPBOX oGroup1:create() oDbe:=XbpCombobox():new(oGroup1, , {12,12}, {108,96}, { { XBP_PP_BGCLR, XBPSYSCLR_ENTRYFIELD }, { XBP_PP_DISABLED_BGCLR, GRA_CLR_WHITE }}) oDbe:tabstop:=.T. oDbe:type:=XBPCOMBO_DROPDOWN oDbe:XbpSLE:editable:=.F. oDbe:ItemSelected:={|mp1, mp2, obj| cDefDbe:=obj:XbpSLE:getData() } oDbe:create() aDbe:=DbeList() ASort(aDbe,,, {|aX,aY| aX[1] < aY[1] }) nLen := Len(aDbe) For nInd := 1 To nLen If aDbe[nInd,2] == .F. oDbe:addItem(aDbe[nInd,1]) EndIf Next oDbe:XbpSLE:setData(cDefDbe) oGroup2:=XbpStatic():new(drawingArea, , {150,48}, {168,128}) oGroup2:caption:="Options" oGroup2:clipSiblings:=.T. oGroup2:type:=XBPSTATIC_TYPE_GROUPBOX oGroup2:create() oXbp:=XbpRadioButton():new(oGroup2, , {12,90}, {108,24}) oXbp:caption := "Shared" oXbp:tabStop := .T. oXbp:selection := !lExclusive oXbp:selected := {|| lExclusive := IIf(lExclusive,.T.,.F.), lReadOnly:=.F. } oXbp:create() oXbp:=XbpRadioButton():new(oGroup2, , {12,64}, {108,24}) oXbp:caption := "Exclusive" oXbp:tabStop := .T. oXbp:selection := lExclusive oXbp:selected := {|| lExclusive := IIf(lExclusive,.F.,.T.), lReadOnly:=.F. } oXbp:create() oXbp:=XbpRadioButton():new(oGroup2, , {12,38}, {108,24}) oXbp:caption := "Read Only" oXbp:tabStop := .T. oXbp:selection := lReadOnly oXbp:selected := {|| lReadOnly:=IIf(lReadOnly,.F.,.T.) } oXbp:create() // added by Chris van Reeven (ALIAS) oXbp:=XbpStatic():new(oGroup2, , {12,12}, {40,24}) oXbp:caption := "Alias" oXbp:clipSiblings := .T. oXbp:options:=XBPSTATIC_TEXT_VCENTER+XBPSTATIC_TEXT_LEFT oXbp:create() oGet:=XbpGet():new(oGroup2, , {47,12}, {110,24}) oGet:tabStop := .T. oGet:bufferLength := 12 oGet:picture := "@!" oGet:dataLink := {|x| Iif(x==Nil, cAliasSLE, cAliasSLE:=x) } oGet:create() oXbp:=XbpPushButton():new(drawingArea, , {12,12}, {60,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } }) oXbp:caption:=GEN_OPEN oXbp:tabStop:=.T. oXbp:create() oXbp:activate:={|| PostAppEvent(xbeP_Close+1000) } oXbp:=XbpPushButton():new(drawingArea, , {84,12}, {60,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } }) oXbp:caption:=GEN_CANCEL oXbp:tabStop:=.T. oXbp:create() oXbp:activate:={|| cFile:="", PostAppEvent(xbeP_Close+1001) } //(ak) CenterControl(oDbeDlg, MainWindow()) nLen := Len(aFiles) nInd := 1 For nInd := nInd To nLen cFile := aFiles[nInd] cAliasSle := GetAlias(cFile) oDbeDlg:setTitle(cFile) oDbeDlg:show() SetAppFocus(oDbe) oController := XbpGetController():new(oDbeDlg):create() oController:read(, .F.) EventLoop(@nEvent, @mp1, @mp2) oController:destroy() if (nEvent == (xbeP_Close + 1001) .or.; (nEvent == xbeP_Keyboard .and.; mp1 == xbeK_ESC)) loop endif If !NetUse(cFile, lExclusive, cAliasSLE, ,cDefDbe, lReadOnly) ConfirmBox(NIL, ('Could not to open the file:' + CRLF + cFile)) loop EndIf // create the XbpBrowseDialog window for each file aSize := oDlg:drawingArea:currentSize() aSize[01] *= .9 aSize[02] *= .9 oBrowseDialog := XbpBrowseDialog():new(oDlg:drawingArea, NIL, {0, 0}, aSize, BROWSE_PRESPARAM, .f.):create() oBrowseDialog:setTitle(cFile) oBrowseDialog:area := Select() oBrowseDialog:file := cFile oBrowseDialog:path := Left(cFile,Rat("\",cFile)) oBrowseDialog:relations := {} oBrowseDialog:read_only := lReadOnly oDbeDlg:Hide() EditBrowse(oBrowseDialog) lRetVal := .T. Next if lRetVal oDlg:cascade() else SetAppfocus(oFocus) endif oDbeDlg:destroy() exit Enddo Return lRetVal STATIC FUNCTION GetAlias(cFile) LOCAL nAt, cAliasSle cAliasSle := cFile nAt := RAt('\', cFile) if nAt > 0 cAliasSle := SubStr(cAliasSle, (nAt + 1)) endif if IsDigit(cAliasSle) cAliasSle := ('f' + cAliasSle) endif nAt := At('.', cAliasSle) if nAt > 0 cAliasSle := Left(cAliasSle, (nAt - 1)) endif RETURN cAliasSle //////////// // FUNCTION EventLoop(nEvent, mp1, mp2) // Controls Eventloop. // Parameters are @nEvent, @mp1, @mp2 // Returns NIL ///// LOCAL oXbp nEvent := xbe_None oXbp := NIL 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 RETURN NIL ************** Func CloseFile() ************** If oFocusBrowse <> NIL PostAppEvent(xbeP_Close, , , oFocusBrowse) endIf Return NIL *********** Func AddRec() *********** * attempt to append a record LOCAL mwait:=2,lRetVal:=.F. Begin Sequence DbAppend() If !NetErr() lRetVal:=.T. Break EndIf Do While mwait>=0 DbAppend() If !NetErr() lRetVal:=.T. Break EndIf Inkey(1) If (--mwait)=0 Break EndIf EndDo End Return lRetVal ***************** Func CommitUnlock() ***************** * commit and unlock DbCommit() DbUnlock() Return Nil *********** Func NetUse(cFile, lExcUse, cAlias, lNoIndex, cDBE, lReadOnly) *********** * Open file for use Local mwait:=2,cFname,x,y,lRetVal:=.F.//, cFilePath:="" Local oError, bSaveErrorBlock:=ErrorBlock({|oError| Break(oError)}) Default(@lExcUse,.F.) Default(@lNoIndex,.F.) If !"NTX"$cDBE .And. !"CDX"$cDBE lNoIndex:=.F. EndIf Begin Sequence If Empty(cAlias) If "\"$cFile .Or. "."$cFile .Or. ":"$cFile x=Max(At(":",cFile),Rat("\",cFile)) y=Rat(".",cFile) y=IIf(y=0,Len(cFile)+1,y) cAlias:=SubStr(cFile,x+1,y-x-1) //cFilePath:=Iif(x>0,Left(cFile,x),cFile) Else cAlias:=cFile EndIf if IsDigit(cAlias) cAlias := ('f' + cAlias) endif cAlias:=UniqueAlias(cAlias) EndIf If "."$cFile y=Rat(".",cFile) cFile:=Left(cFile,y-1) EndIf cFname:=cFile If FileInUse(cFile) Break EndIf Do While mwait>=0 If lExcUse Set Exclusive On EndIf DbUseArea(.T.,cDBE,cFname,cAlias, ,lReadOnly) If lExcUse Set Exclusive Off EndIf If !NetErr() .And. !Select(cAlias)=0 If !lNoIndex .And. ("NTX"$cDBE .Or. "CDX"$cDBE) .And. File(cFile+OrdBagExt()) OrdListAdd(cFile+OrdBagExt()) OrdSetFocus(1) EndIf lRetVal:=.T. Break EndIf Inkey(1) If (--mwait)=0 Break EndIf EndDo Recover Using oError If !lRetVal Errm(ERR_ERRM60) EndIf End // Restore prior error block ErrorBlock(bSaveErrorBlock) Return lRetVal ************ Func RecLock() ************ * attempt to lock a record Local mwait:=2,lRetVal:=.F. Begin Sequence DbRLock() If !NetErr() lRetVal:=.T. Break EndIf Do While mwait>=0 DbRLock() If !NetErr() lRetVal:=.T. Break EndIf Inkey(1) If (--mwait)=0 Break EndIf EndDo End Return lRetVal ************ Func CopyRec(cFileFrom,cFileTo,lAppend) ************ * Note that this version assumes cFileTo file or existing record already * locked and always leaves the cFileTo record locked Local nFields, x, nFieldPos, w1, w2, lRetVal:=.T., nRecFrom, nRecTo, oFrom Default(@lAppend,.F.) w1:=Iif(cFileFrom=Nil,Select(),Select(cFileFrom)) w2:=Iif(cFileTo=Nil,Select(),Select(cFileTo)) Begin Sequence If lAppend If w1==w2 nRecFrom:=RecNo() EndIf If !(w2)->(AddRec()) lRetVal:=.F. Break EndIf If w1==w2 nRecTo:=RecNo() EndIf EndIf nFields:=(w1)->(Fcount()) For x:=1 To nFields If w1==w2 DbGoto(nRecFrom) oFrom:=FieldGet(x) DbGoto(nRecTo) FieldPut(x,oFrom) Else If (nFieldPos:=(w2)->(FieldPos((w1)->(FieldName(x))))) > 0 (w2)->(FieldPut(nFieldpos,(w1)->(FieldGet(x)))) EndIf EndIf Next End Return lRetVal ********** Func YesNo(cMessage,cTitle) ********** Local nButton, oXbp:=SetAppFocus(), lRetVal:=.F. Begin Sequence nButton:=ConfirmBox(NIL, cMessage+"?", cTitle, ; XBPMB_YESNO , ; XBPMB_QUESTION+XBPMB_APPMODAL+XBPMB_MOVEABLE) If nButton==XBPMB_RET_YES lRetVal:=.T. EndIf SetAppFocus(oXbp) End Return lRetVal ************** Func EditBlock(cFieldName) ************** Local bBlock, cBlock Begin Sequence cBlock:="{|x| IIf(x==Nil,"+cFieldName+",WriteField('"+cFieldName+"',x)) }" bBlock:=&cBlock End Return bBlock *************** Func WriteField(cField, xValue) *************** Local cAlias:="" Begin Sequence If "->"$cField cAlias:=Left(cField,At("->",cField)-1) Else cAlias:=Alias() EndIf If (cAlias)->(RecLock()) &cField:=xValue (cAlias)->(CommitUnlock()) EndIf End Return xValue ************* Func NilValue(cType) ************* * Return blank value for data type Local xRetVal Begin Sequence Do Case Case cType=="N" xRetVal:=0 Case cType$"C,M" xRetVal:="" Case cType=="D" xRetVal:=Ctod(" / / ") Case cType=="L" xRetVal:=.F. EndCase End Return xRetVal ***************** Func StringLength(cString, oPS) ***************** Local aTextBox cString := Replicate("W",Len(cString)) aTextBox := GraQueryTextBox(oPS, cString) Return aTextBox[3,1]-aTextBox[2,1] // width of substring ********* Func XtoC(obj) ********* Local cRetVal Do Case Case ValType(obj)=="N" cRetVal:=Str(obj) Case ValType(obj)="C" cRetVal:=obj Case ValType(obj)=="D" cRetVal:=Dtos(obj) Case ValType(obj)=="L" cRetVal:=IIf(obj,"Y","N") Case ValType(obj)="M" cRetVal:=AllTrim(obj) EndCase Return cRetVal *************** Func AreasInUse() *************** * count number of areas in use Local nRetVal:=1 Begin Sequence Do While .T. If !(nRetVal)->(Used()) Exit EndIf nRetVal++ EndDo End Return nRetVal *************** Func AliasNames() *************** * Return array of alias names Local aRetVal:={}, x:=1 Begin Sequence Do While .T. If !(x)->(Used()) Exit EndIf Aadd(aRetVal,Alias(x)) x++ EndDo End Return aRetVal ****************** Func TestCondition(cCondition) ****************** Local oError, bSaveErrorBlock:=ErrorBlock({|oError| Break(oError)}) , lRetVal:=.T. Begin Sequence &(cCondition) // evaluate condition Recover Using oError Errm(ERR_ERRM61) lRetVal:=.F. End // Restore prior error block ErrorBlock(bSaveErrorBlock) Return lRetVal ************** Func AddFields(oFieldList, lNoConvert) ************** * add fields to listbox Local x, cDesc:="" Default(@lNoConvert,.F.) Begin Sequence For x:=1 To FCount() cDesc:=" ["+DbStruct()[x,DBS_TYPE]+","+Ntrim(DbStruct()[x,DBS_LEN])+","+Ntrim(DbStruct()[x,DBS_DEC])+"]" If lNoConvert oFieldList:addItem(FieldName(x)+cDesc) Else Do Case Case ValType(FieldGet(x))$"C" oFieldList:addItem(FieldName(x)+cDesc) Case ValType(FieldGet(x))="N" oFieldList:addItem("STR("+FieldName(x)+","+Ntrim(DbStruct()[x,DBS_LEN])+","+Ntrim(DbStruct()[x,DBS_DEC])+")"+cDesc) Case ValType(FieldGet(x))="D" oFieldList:addItem("DTOS("+FieldName(x)+")"+cDesc) Case ValType(FieldGet(x))$"L" oFieldList:addItem("IIF("+FieldName(x)+",'Y','N')"+cDesc) EndCase EndIf Next End Return Nil **************** Func UniqueAlias(cAlias) **************** Local x:=1 // cRetVal:="", // 04/29/03 by MMM Local n:=0 // 04/29/03 by MMM Begin Sequence n:=Select() If Select(cAlias)>=1 // 04/29/03 by MMM Do While .T. cAlias:=cAlias+Ntrim(x) // 04/29/03 by MMM If !Select(cAlias)>=1 // 04/29/03 by MMM Exit EndIf x++ EndDo EndIf // cRetVal:=Ntrim(x) // 04/29/03 by MMM Select(n) // 04/29/03 by MMM End Return cAlias // cRetVal // 04/29/03 by MMM ******************** Func CommitUnlockAll() ******************** * commit and unlock all DbCommitAll() DbUnlockAll() Return Nil ************** Func FileInUse(cFile) ************** Local lRetVal:=.F., x:=1 Begin Sequence Do While .T. If !(x)->(Used()) Exit EndIf If Upper((x)->(DbInfo(DBO_FILENAME)))==Upper(cFile) lRetVal:=.T. Exit EndIf x++ EndDo End Return lRetVal ************** Func DupRecord() ************** * duplicate current record Begin Sequence If YesNo("Duplicate this record","Duplicate") CopyRec(,,.T.) oFocusBrowse:refreshAll() oFocusBrowse:forceStable() EndIf End Return Nil ************** Func FreezeCol() ************** * freeze left columns Local aFrozen, x Begin Sequence aFrozen:=oFocusBrowse:setLeftFrozen() If Len(aFrozen)1 oFocusBrowse:GetColumn(Len(aFrozen)):colorblock:={|| { Nil, Nil } } ARemove(aFrozen,Len(aFrozen),1) oFocusBrowse:setLeftFrozen(aFrozen) oFocusBrowse:refreshAll() oFocusBrowse:forceStable() EndIf End Return Nil ************** Func InsertRec() ************** * insert record Begin Sequence If AddRec() oFocusBrowse:refreshAll() oFocusBrowse:forceStable() EndIf End Return Nil ************** Func CopyField() ************** * copy field data xBuffer:=Eval(FieldBlock(oFocusBrowse:getColumn(oFocusBrowse:colpos):cargo)) Return Nil *************** Func PasteField() *************** * paste field data Local bField Begin Sequence bField:=FieldBlock(oFocusBrowse:getColumn(oFocusBrowse:colpos):cargo) If Empty(xBuffer) .Or. !(ValType(xBuffer)+ValType(Eval(bField))$"CCMMC" .Or. ValType(xBuffer)=ValType(Eval(bField))) Tone(100,1) ElseIf RecLock() Eval(bField,xBuffer) oFocusBrowse:refreshcurrent() CommitUnlock() EndIf End Return Nil ************* Func CutField() ************* * cut field data Local bField Begin Sequence If RecLock() xBuffer:=Eval(FieldBlock(oFocusBrowse:getColumn(oFocusBrowse:colpos):cargo)) bField:=FieldBlock(oFocusBrowse:getColumn(oFocusBrowse:colpos):cargo) Eval(bField,NilValue(ValType(xBuffer))) oFocusBrowse:refreshcurrent() CommitUnlock() EndIf End Return Nil ************* Func RemoveFileExt( cFile ) ************* * Remove last file extension from a file name * LOCAL cRet, nPos DEFAULT cFile TO "" cRet := cFile IF ! EMPTY(cFile) IF ( nPos := RAT(".", cFile) ) > 0 cRet := SUBSTR(cFile, 1, nPos-1) ENDIF ENDIF RETURN cRet *************** Func IniFileLoc() *************** Local cAppPath:=AppName(.T.) cAppPath:=SubStr(cAppPath, 1, Rat("\", cAppPath)) /* If ini file exists in the current directory, use this one instead of the one from the exe directory. */ IF FEXISTS(".\DbEditor.ini") cAppPath := ".\" ENDIF Return (cAppPath+"DbEditor.ini") FUNCTION FixNames( cName ) LOCAL lUpper, nI, cRet cRet := cName cName := ALLTRIM(cName) IF ! EMPTY(cName) lUpper := .T. FOR nI := 1 TO LEN(cName) IF IsLower(cName[nI]) lUpper := .F. EXIT ENDIF NEXT IF lUpper IF AT(" ", cName) = 0 cRet := Proper(cName) ENDIF ENDIF ENDIF RETURN cRet FUNCTION PROPER( cString ) LOCAL cRet := LOWER(cString) RETURN UPPER(cRet[1]) + SUBSTR(cRet,2)