* Program..: Relations.prg * Author...: Jeremy Suiter * Date.....: 26/03/2003 * * Notice...: Copyright (c) 2003, Jeremy Suiter, All Rights Reserved * Notes....: Visual DbEditor relations 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 oFieldList, oTables, oTags, oExpression, oRelations, nRelation:=1, oSelective ***************** Func SetRelations() ***************** Local nEvent:=Nil, mp1:=Nil, mp2:=Nil, aPos:={} Local oDlg:=Nil, oXbp:=Nil, drawingArea:=Nil, oGroup1:=Nil, x Begin Sequence If AreasInUse()<2 Errm(ERR_ERRM36) Break EndIf aPos:=CenterPos({558,362},AppDesktop():currentSize()) oDlg:=XbpDialog():new(AppDesktop(), MainWindow(), aPos, {558,362}, DEFAULT_PRESPARAM, .F.) oDlg:icon:=ICON_MAIN oDlg:taskList:=.F. oDlg:border:=XBPDLG_RAISEDBORDERTHIN_FIXED oDlg:title:="Add/Edit Relations" oDlg:close:={|mp1,mp2,obj| PostAppEvent(xbeP_Close+1000) } oDlg:create() oDlg:setModalState(XBP_DISP_APPMODAL) drawingArea:=oDlg:drawingArea drawingArea:setFont(oDlg:setFont()) // list of relations oGroup1:=XbpStatic():new(drawingArea, , {12,48}, {528,276}) oGroup1:caption:="Relations" oGroup1:clipSiblings:=.T. oGroup1:type:=XBPSTATIC_TYPE_GROUPBOX oGroup1:create() oRelations:=XbpListBox():new(oGroup1, , {12,12}, {504,240}, { { XBP_PP_BGCLR, XBPSYSCLR_ENTRYFIELD } }) oRelations:tabStop:=.T. oRelations:markMode:=XBPLISTBOX_MM_SINGLE oRelations:itemMarked:={|uNIL1, uNIL2, self| nRelation:=oRelations:getData()[1] } oRelations:create() For x:=1 To Len(aRelations) oRelations:addItem(aRelations[x,1]+", "+aRelations[x,2]+", "+aRelations[x,3]+", "+IIf(aRelations[x,5],"SELECTIVE","NON SELECTIVE")) Next oRelations:setData({1},.T.) // pushbuttons oXbp:=XbpPushButton():new(drawingArea, , {120,12}, {96,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } }) oXbp:caption:="Add" oXbp:tabStop:=.T. oXbp:create() oXbp:activate:={|| AddEditRelation(.T.) } oXbp:=XbpPushButton():new(drawingArea, , {228,12}, {96,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } }) oXbp:caption:="Edit" oXbp:tabStop:=.T. oXbp:create() oXbp:activate:={|| AddEditRelation(.F.) } oXbp:=XbpPushButton():new(drawingArea, , {336,12}, {96,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } }) oXbp:caption:=GEN_DELETE oXbp:tabStop:=.T. oXbp:create() oXbp:activate:={|| DeleteRelation() } oXbp:=XbpPushButton():new(drawingArea, , {444,12}, {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() SetAppFocus(oRelations) 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(oFocusBrowse) End Return Nil ******************** Func AddEditRelation(lAdd) ******************** * add new relation Local nEvent:=Nil, mp1:=Nil, mp2:=Nil, aPos:={}, oFocus:=SetAppFocus(), x, aAlias Local oDlg:=Nil, oXbp:=Nil, drawingArea:=Nil, oGroup1:=Nil, oGroup2:=Nil, oGroup3:=Nil Default(@lAdd,.T.) Begin Sequence aPos:=CenterPos({584,429},AppDesktop():currentSize()) oDlg:=XbpDialog():new(AppDesktop(), MainWindow(), aPos, {584,429}, DEFAULT_PRESPARAM, .F.) oDlg:icon:=ICON_MAIN oDlg:taskList:=.F. oDlg:border:=XBPDLG_RAISEDBORDERTHIN_FIXED oDlg:title:=IIf(lAdd,"Add","Edit")+" Relation" oDlg:close:={|mp1,mp2,obj| PostAppEvent(xbeP_Close+1000) } oDlg:create() oDlg:setModalState(XBP_DISP_APPMODAL) drawingArea:=oDlg:drawingArea drawingArea:setFont(oDlg:setFont()) // field list for link expression 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:create() AddFields(oFieldList) oFieldList:setData({1},.T.) // relation link expression oGroup2:=XbpStatic():new(drawingArea, , {228,192}, {336,204}) oGroup2:caption:="Link Expression" oGroup2:clipSiblings:=.T. oGroup2:type:=XBPSTATIC_TYPE_GROUPBOX oGroup2:create() oExpression:=XbpMle():new(oGroup2, , {12,12}, {312,168}, { { XBP_PP_BGCLR, XBPSYSCLR_ENTRYFIELD } }) oExpression:tabStop:=.T. oExpression:horizScroll:=.F. oExpression:create() If !lAdd oExpression:setData(aRelations[nRelation,2]) EndIf // relation options oGroup3:=XbpStatic():new(drawingArea, , {228,48}, {324,132}) oGroup3:caption:="Options" oGroup3:clipSiblings:=.T. oGroup3:type:=XBPSTATIC_TYPE_GROUPBOX oGroup3:create() // list of open tables (minus one that has focus) oXbp:=XbpStatic():new(oGroup3, , {12,84}, {60,24}) oXbp:caption:="Table" oXbp:clipSiblings:=.T. oXbp:options:=XBPSTATIC_TEXT_VCENTER oXbp:create() oTables:=XbpCombobox():new(oGroup3, , {12,12}, {184,72}, { { XBP_PP_BGCLR, XBPSYSCLR_ENTRYFIELD }, { XBP_PP_DISABLED_BGCLR, GRA_CLR_WHITE }}) oTables:tabstop:=.T. oTables:type:=XBPCOMBO_DROPDOWN oTables:itemSelected:={|| ListTags() } oTables:XbpSLE:editable:=.F. oTables:create() aAlias:=AliasNames() For x:=1 To Len(aAlias) If !Upper(aAlias[x])==Upper(Alias()) oTables:addItem(Upper(aAlias[x])+", "+(aAlias[x])->(DbInfo(DBO_FILENAME))) EndIf Next If !lAdd oTables:XbpSLE:setData(aRelations[nRelation,1]) EndIf // list of tags (populate when table selected) oXbp:=XbpStatic():new(oGroup3, , {204,84}, {48,24}) oXbp:caption:="Tag" oXbp:clipSiblings:=.T. oXbp:options:=XBPSTATIC_TEXT_VCENTER oXbp:create() oTags:=XbpCombobox():new(oGroup3, , {204,12}, {110,72}, { { XBP_PP_BGCLR, XBPSYSCLR_ENTRYFIELD }, { XBP_PP_DISABLED_BGCLR, GRA_CLR_WHITE }}) oTags:tabstop:=.T. oTags:XbpSLE:editable:=.F. oTags:type:=XBPCOMBO_DROPDOWN oTags:create() If !lAdd oTags:XbpSLE:setData(aRelations[nRelation,3]) EndIf oSelective:=XbpCheckbox():new(oGroup3, , {12,12}, {96,24}) oSelective:caption:="Selective" oSelective:tabStop:=.T. If !lAdd oSelective:selection:=aRelations[nRelation,5] EndIf oSelective:create() // pushbuttons oXbp:=XbpPushButton():new(drawingArea, , {360,12}, {96,24}, { { XBP_PP_BGCLR, XBPSYSCLR_BUTTONMIDDLE }, { XBP_PP_FGCLR, -58 } }) oXbp:caption:=IIf(lAdd,"Create","Modify") oXbp:tabStop:=.T. oXbp:create() oXbp:activate:={|| IIf(RelationCreate(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() 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 EndDo oDlg:destroy() SetAppFocus(oFocus) 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$oExpression:getData() oExpression:setData(oExpression:getData()+Iif(Empty(oExpression:getData()),"","+")+cTemp) EndIf End Return Nil ******************** Static Func ListTags() ******************** Local cArea:=Left(oTables:XbpSLE:GetData(),At(", ",oTables:XbpSLE:GetData())-1), x Begin Sequence oTags:clear() For x:=1 To Len((cArea)->(OrdList())) oTags:addItem(Iif(Empty((cArea)->(OrdName(x))),Ntrim(x),(cArea)->(OrdName(x)))) Next End Return Nil ******************* Func RelationCreate(lAdd) ******************* * create/modify relation Local lRetVal:=.T., cRelName:="", bRelation, x, cAlias:={} Begin Sequence If !TestCondition(oExpression:getData()) lRetVal:=.F. Break EndIf If Empty(oTables:XbpSLE:GetData()) Errm(ERR_ERRM37) lRetVal:=.F. Break EndIf If Empty(oTags:XbpSLE:GetData()) Errm(ERR_ERRM38) lRetVal:=.F. Break EndIf If lAdd cRelName:=Alias()+"_"+oTables:XbpSLE:GetData() x:=1 Do While .T. If Ascan(aRelations,{|aE| aE[1]==cRelName+Ntrim(x)})==0 cRelName:=cRelName+Ntrim(x) Exit EndIf x++ EndDo bRelation:=&("{|| "+oExpression:getData()+" }") cAlias:=Left(oTables:XbpSLE:GetData(),At(", ",oTables:XbpSLE:GetData())-1) DbSetRelation(cAlias,bRelation, oExpression:getData(), Iif(!"CDX"$(cAlias)->(DbInfo(DBO_DBENAME)),Nil,oTags:XbpSLE:GetData()), cRelName, oSelective:getData()) Aadd(aRelations,{cAlias, oExpression:getData(), oTags:XbpSLE:GetData(), cRelName, oSelective:getData()}) x:=Len(aRelations) oRelations:addItem(aRelations[x,1]+", "+aRelations[x,2]+", "+aRelations[x,3]+", "+IIf(aRelations[x,5],"SELECTIVE","NON SELECTIVE")) oFocusBrowse:setParent():setParent():relations:=aRelations nRelation:=Len(aRelations) oRelations:setData({nRelation},.T.) DbSkip(0) // force refresh Else aRelations[nRelation,1]:=oTables:XbpSLE:GetData() aRelations[nRelation,2]:=oExpression:getData() aRelations[nRelation,3]:=oTags:XbpSLE:GetData() aRelations[nRelation,5]:=oSelective:getData() oRelations:setItem(nRelation, aRelations[nRelation,1]+", "+aRelations[nRelation,2]+", "+aRelations[nRelation,3]+", "+ ; IIf(aRelations[nRelation,5],"SELECTIVE","NON SELECTIVE")) DbClearRelation() For x:=1 To Len(aRelations) bRelation:=&("{|| "+aRelations[x,2]+" }") DbSetRelation(aRelations[x,1], bRelation, aRelations[x,2], aRelations[x,3], aRelations[x,4], aRelations[x,5]) Next DbSkip(0) // force refresh EndIf End Return lRetVal ******************* Func DeleteRelation() ******************* * delete relation Local bRelation, x Begin Sequence If !YesNo("Delete this relation",GEN_DELETE) Break EndIf ARemove(aRelations,nRelation) oFocusBrowse:setParent():setParent():relations:=aRelations DbClearRelation() For x:=1 To Len(aRelations) bRelation:=&("{|| "+aRelations[x,2]+" }") DbSetRelation(aRelations[x,1], bRelation, aRelations[x,2], aRelations[x,3], aRelations[x,4], aRelations[x,5]) Next oRelations:delItem(nRelation) oRelations:setData({1},.T.) nRelation:=1 DbSkip(0) // force refresh End Return Nil