PROGRAM Boilerplate2Prompt; {-- *************************************************************************** -- ** Descr. : Converts boilerplate texts to prompts. This script will convert -- ** all boilertexts to prompts that are left and within the same -- ** height or in case of multdisplay items it will check they are -- ** at the top. -- ** -- ** MinVers: Requires build 239 -- *************************************************************************** -- ** 30-Jan-02 1.001.00 Initial Creation, muellers@orcl-toolbox.com -- ** 02-Feb-02 1.002.00 fixed left label conversion & chek if multidisp item, muellers@orcl-toolbox.com -- ** 07-Apr-02 1.003.00 Forms50 compatibel, muellers@orcl-toolbox.com -- ***************************************************************************} //makes the acctuall conversion for the given item and boilerplate object PROCEDURE ConvertToPrompt(itm : number; blr : number; isleft : boolean); VAR fnt : number; //a font object to copy the font crd : number; //coordination info object frm : number; //forms module object lab_height : number; //labels position/height lab_width : number; lab_left : number; lab_top : number; itm_left : number; //items position/height itm_top : number; itm_height : number; itm_width : number; lab : varchar2; // text of the prompt; begin //get the forms coordinates metric info settings frm := Generic_GetObjProp(itm, D2FP_MODULE); crd := API_GetCoord(frm); //create a new font object fnt := Font_Create; //populate the font object with our boilers font - normaly you would use Font_Extract function //for doing this, but this function is not working with boilerplate fonts! Generic_SetTextProp(fnt,D2FP_FONT_NAM, Generic_GetTextProp(blr,D2FP_GRA_FONT_NAM)); Generic_SetNumProp(fnt,D2FP_FONT_SIZ, Generic_GetNumProp(blr,D2FP_GRA_FONT_SIZ)); Generic_SetNumProp(fnt,D2FP_FONT_STY, Generic_GetNumProp(blr,D2FP_GRA_FONT_STY)); Generic_SetNumProp(fnt,D2FP_FONT_WGHT, Generic_GetNumProp(blr,D2FP_GRA_FONT_WGHT)); Generic_SetNumProp(fnt,D2FP_FONT_SPCING, Generic_GetNumProp(blr,D2FP_GRA_FONT_SPCING)); //apply the font to the prompt font_apply(fnt,itm,D2FC_VATY_PROMPT); if api_Bigversion >= C_API_F60 then Generic_SetTextProp(itm,D2FP_PRMPT_FORE_COLOR, Generic_GetTextProp(blr,D2FP_GRA_FONT_COLOR)); // copy the text of the boiler to the prompt lab := Generic_GetTextProp(blr,D2FP_GRA_TEXT); Generic_SetTextProp(itm,D2FP_PRMPT,lab); //get the positions of the fields itm_left := Generic_GetValue(itm,D2FP_X_POS); itm_top := Generic_GetValue(itm,D2FP_Y_POS); itm_width := Generic_GetValue(itm,D2FP_WIDTH); itm_Height := Generic_GetValue(itm,D2FP_HEIGHT); lab_left := Generic_GetValue(blr,D2FP_X_POS); lab_top := Generic_GetValue(blr,D2FP_Y_POS); //get the labels height and width of the output string in the given coordinate metrics Font_StringSize(lab, fnt, crd, lab_width, lab_height); Generic_SetNumProp(itm, D2FP_PRMPT_DISP_STY, D2FC_PRDI_FIRST); //always only show on first record Generic_SetNumProp(itm, D2FP_PRMPT_ALIGN, D2FC_PRDI_FIRST); //always only show on first record Generic_SetNumProp(itm, D2FP_PRMPT_ALIGN, D2FC_ALIG_CENTER); // always align from y-center if isLeft then begin //if the label is show on the left Generic_SetNumProp(itm, D2FP_PRMPT_ALIGN_OFST, ((lab_top+(lab_height div 2)) - (itm_top+(itm_height div 2))) ); Generic_SetNumProp(itm, D2FP_PRMPT_ATT_OFST, (itm_left-(lab_left+lab_width))); Generic_SetNumProp(itm, D2FP_PRMPT_ATT_EDGE, D2FC_PRAT_START); end else begin //if the label is show on the top Generic_SetNumProp(itm, D2FP_PRMPT_ALIGN_OFST, ((lab_left+(lab_width div 2)) - (itm_left+(itm_width div 2))) ); Generic_SetNumProp(itm, D2FP_PRMPT_ATT_OFST, (itm_top-(lab_top+lab_height))); Generic_SetNumProp(itm, D2FP_PRMPT_ATT_EDGE, D2FC_PRAT_TOP); end; //free our temporary objects from memory generic_Destroy(fnt); generic_Destroy(crd); // logadd(' => '+ api_getobjectpath(itm) +' <> ' + api_getobjectpath(blr)); end; //checks if the item has a boiler to the left that qualifies as prompt //and replaces it ... returns false if nothing found FUNCTION CheckConvert_Left(itm : number; items : TStringList) : boolean; var i : number; left : number; //item left coords top : number; //item top coords bottom : number; //item bottom coords lableft : number; //boilerplate left labtop : number; //boilerplate top citm : number; //current item from list bpo : number; //boilerplater object maxdev : number; //max derivation from top/bottom that is allowed BEGIN result := false; //get positions of the item left := Generic_GetNumProp(itm,D2FP_X_POS); top := Generic_GetNumProp(itm,D2FP_Y_POS); bottom := Generic_GetNumProp(itm,D2FP_HEIGHT) + top; //get heights max derivation maxdev := (bottom-top) div 4; // initialize our boilerplate search variables lableft := -1000; labtop := -1000; bpo := 0; //loop through all items for i := 0 to items.count-1 do begin citm := items.objects[i]; //look if it is a graphics boilertext if Generic_QueryType(citm) = D2FFO_GRAPHIC then begin if Generic_GetNumProp(citm,D2FP_GRAPHICS_TYP) = D2FC_GRTY_TEXT then begin //look if it's a perfect match for a label if (Generic_GetNumProp(citm,D2FP_X_Pos) > lableft) and (Generic_GetNumProp(citm,D2FP_X_Pos) < left) and (Generic_GetNumProp(citm,D2FP_Y_Pos) > (top-maxdev)) and (Generic_GetNumProp(citm,D2FP_Y_Pos) < (bottom-maxdev)) then begin bpo := citm; lableft := Generic_GetNumProp(bpo,D2FP_X_POS); labtop := Generic_GetNumProp(bpo,D2FP_Y_POS); end; end; end; end; //only come in here if we have found a matching label if bpo <> 0 then begin //now doublecheck we don't have any items between! for i := 0 to items.count-1 do begin citm := items.objects[i]; if Generic_QueryType(citm) = D2FFO_ITEM then begin if (Generic_GetNumProp(citm,D2FP_X_Pos) > lableft) and (Generic_GetNumProp(citm,D2FP_X_Pos) < left) and (Generic_GetNumProp(citm,D2FP_Y_Pos) > (top-maxdev)) and (Generic_GetNumProp(citm,D2FP_Y_Pos) < (bottom-maxdev)) then begin //there is an item between, so set the boilerplate object to zero bpo := 0; end; end; end; if bpo <> 0 then begin //convert the boiler ConvertToPrompt(itm,bpo,true); //now mark the boiler for deletion, we can't delete now as this would make conversion //pretty difficult because we are using the list of items at differen places for i := 0 to items.count-1 do if bpo = items.objects[i] then items.strings[i] := '***'; //set return result to true result := true; end; end; END; //checks if the item has a boiler at the top that qualifies as prompt //and replaces it ... returns false if nothing found FUNCTION CheckConvert_Top(itm : number; items : TStringList) : boolean; var i : number; left : number; //item left coords top : number; //item top coords width : number; //item wudth coords height : number; //item height coords lableft : number; //boilerplate left labtop : number; //boilerplate top fnt : number; //a font object to copy the font crd : number; //coordination info object frm : number; //forms module object lab : varchar2;//the text of the label citm : number; //current item from list bpo : number; //boilerplater object labwidth : number; //boilerplate width labheight : number; //boilerplate height labfoundtop : number; //y coord of the label we have found BEGIN result := false; //get positions of the item left := Generic_GetNumProp(itm,D2FP_X_POS); top := Generic_GetNumProp(itm,D2FP_Y_POS); width := Generic_GetNumProp(itm,D2FP_WIDTH); // initialize our boilerplate variables labfoundtop := -1000; bpo := 0; //prepare the objects to get the labels width/height fnt := font_create; frm := Generic_GetObjProp(itm, D2FP_MODULE); crd := API_GetCoord(frm); //loop through all items and look for matching boiler texts for i := 0 to items.count-1 do begin citm := items.objects[i]; if Generic_QueryType(citm) = D2FFO_GRAPHIC then begin if Generic_GetNumProp(citm,D2FP_GRAPHICS_TYP) = D2FC_GRTY_TEXT then begin Generic_SetTextProp(fnt,D2FP_FONT_NAM, Generic_GetTextProp(citm,D2FP_GRA_FONT_NAM)); Generic_SetNumProp(fnt,D2FP_FONT_SIZ, Generic_GetNumProp(citm,D2FP_GRA_FONT_SIZ)); Generic_SetNumProp(fnt,D2FP_FONT_STY, Generic_GetNumProp(citm,D2FP_GRA_FONT_STY)); Generic_SetNumProp(fnt,D2FP_FONT_WGHT, Generic_GetNumProp(citm,D2FP_GRA_FONT_WGHT)); Generic_SetNumProp(fnt,D2FP_FONT_SPCING, Generic_GetNumProp(citm,D2FP_GRA_FONT_SPCING)); lab := Generic_GetTextProp(citm,D2FP_GRA_TEXT); lableft := Generic_GetNumProp(citm,D2FP_X_Pos); labtop := Generic_GetNumProp(citm,D2FP_Y_Pos); //get the labels height and width of the output string in the given coordinate metrics Font_StringSize(lab, fnt, crd, labwidth, labheight); if ((lableft+(labwidth div 2)) > left) and ((lableft+(labwidth div 2)) < (left+width)) and (labtop < top) and (labfoundtop < labtop) and (labtop > (top-(labheight * 2))) then //limit search to twice the height of the label from item begin //yep, we found a match! bpo := citm; labfoundtop := Generic_GetNumProp(citm,D2FP_Y_Pos); end; end; end; end; //if we have found a boiler then convert it if bpo <> 0 then begin ConvertToPrompt(itm,bpo,false); //mark the boiler for deletion for i := 0 to items.count-1 do if (bpo = items.objects[i]) then items.strings[i] := '***'; result := true; end; //destroy and free the temporary coordinate info and font object generic_destroy(crd); generic_destroy(fnt); END; //converts all the items for the given canvas PROCEDURE ConvertCanvas(canvobj : number); VAR cil : TStringList; //list of all canvas items l,k : number; typ : number; itm : number; //item srcx : varchar2; b2p_counter : number; //counter for number of converted boilers blk : number; //the current items block blkdipsrow : number; //display number of items setting from block itmdipsrow : number; //items real mutlidisplay count BEGIN //get a list of all items on the given canvas cil := API_GetCanvasItems(canvobj); //loop through this list for k := 0 to cil.count-1 do begin itm := cil.objects[k]; if (Generic_QueryType(itm) = D2FFO_ITEM) then begin //we only look for labels for textitems/displayiteems and listitems typ := Generic_GetNumProp(itm,D2FP_ITM_TYP); if (typ = D2FC_ITTY_TI) or (typ = D2FC_ITTY_DI) or (typ = D2FC_ITTY_LS) then begin //don't convert if already has a prompt or if not shown if (Generic_GetTextProp(itm,D2FP_PRMPT) = '') and (Generic_GetBoolProp(itm,D2FP_VISIBLE) = true) then begin blk := Generic_GetObjProp(itm,D2FP_OWNER); blkdipsrow := Generic_GetNumProp(blk,D2FP_RECS_DISP_COUNT); itmdipsrow := Generic_GetNumProp(itm,D2FP_ITMS_DISP); //how many items displayed? if ((itmdipsrow = 0) and (blkdipsrow = 1)) //if 0 then use blocks default! or ( itmdipsrow = 1 ) then begin //only one - then search left first! if CheckConvert_Left(itm,cil) = false then CheckConvert_Top(itm,cil); end else begin //multiple - then search top first! if CheckConvert_Top(itm,cil) = false then CheckConvert_Left(itm,cil); end; end; end; end; end; //delete and count converted boilerplates b2p_counter := 0; for k := 0 to cil.count-1 do if cil.strings[k] = '***' then begin generic_destroy(cil.objects[k]); inc(b2p_counter); end; //free the list of canvas items cil.free; //in case we made some conversion then log them if b2p_counter>0 then logadd(' => Converted '+to_char(b2p_counter)+' Boiler objects to prompts on Canvas '+API_GetObjectName(canvobj)); END; VAR frm : number; //currently processed forms object i,j : number; //standard loop variables ps : TParamScreen; //parameter screen pb : TParamBoard; //board on parameter screen cl : TStringList; //list of all canvas objects files : TStringList; //list of all files selected on parameterscreen {*Main Program Block*} BEGIN //create a nice parameterscreen ps := TParamScreen.create; pb := ps.AddBoard('Main Options',picOptions); pb.addparam(parLabel,'MYLABEL', 'This script will convert boilerplate texts into prompts when possible.','',''); pb.addparam(parFiles,'SRCFILES','Source Files','','Forms Modules (*.fmb)|*.fmb|All Files (*.*)|*.*'); pb.addparam(parPathname,'TRGPATH','Target Path','',''); pb.addparam(parDatabaseLogon,'MYDATABASE','DB Connection','scott/tiger',''); //show the screen and get the result if ps.ShowParamScreen('Boilerplatetext 2 Prompt Converter ...') then begin //sanity parameter check if ps.ParamValue('TRGPATH') ='' then raiseException('Missing Target Path!'); //try to connect to the database try api_Connect(ps.ParamValue('MYDATABASE')); except logadd('Connection ignored: '+GetError,logwarning); end; //create a new stringlist and get the selected files into the list files := tstringlist.create; files.text := ps.ParamValue('SRCFILES'); //loop through the files for j := 0 to files.count-1 do begin logadd('Converting '+to_char(j+1)+'/'+to_char(files.count)+' '+files.strings[j]); try frm := 0; frm := API_LoadModule(files.strings[j]); //get a list of all canvases and loop thourgh them cl := API_GetSubObjects(frm,D2FP_CANVAS); for i := 0 to cl.count-1 do begin //call our procedure to convert all the objects ConvertCanvas( cl.objects[i] ); end; //free the list of canvas from memory cl.free; //save the module to the new path and get rid of it api_SaveModule(frm,ps.ParamValue('TRGPATH')+'\'+extractFilename(files.strings[j])); except //error happened, just log it and go on ... logadd(' =>'+GetError,LogError); end; if frm <>0 then API_DestroyModule(frm); end; //free the list of files from memory files.free; end else begin logadd('Aborted on parameterscreen!'); end; ps.free; END.