{Unidad con formulario de configuración para manejar las propiedades de una aplicación. Está pensado para usarse con frames de la clase Tframe, definida en la unidad "PropertyFrame". } unit FormConfig; {$mode objfpc}{$H+} interface uses SysUtils, Classes, Forms, Graphics, SynEdit, Buttons, ComCtrls, ExtCtrls, StdCtrls, EditBtn, Controls, MisUtils, FrameCfgSynEdit, Globales, MiConfigXML; type TEvCambiaProp = procedure of object; //evento para indicar que hay cambio { TConfig } TConfig = class(TForm) bitAceptar: TBitBtn; bitAplicar: TBitBtn; bitCancel: TBitBtn; chkListDet: TCheckBox; chkMarLin: TCheckBox; chkMosOcul: TCheckBox; chkMosRut: TCheckBox; chkOpenLast: TCheckBox; chkRefDesp: TCheckBox; DirectoryEdit1: TDirectoryEdit; DirectoryEdit2: TDirectoryEdit; DirectoryEdit3: TDirectoryEdit; edTpoMax: TEdit; edTpoMax1: TEdit; Label1: TLabel; Label2: TLabel; lblRutLeng: TLabel; lblRutMac: TLabel; lblRutScript: TLabel; PageControl1: TPageControl; Panel1: TPanel; TabGeneral: TTabSheet; TabFilePath: TTabSheet; TabMacSett: TTabSheet; TabMacEdit: TTabSheet; TabRemEdEdit: TTabSheet; TabRemExpl: TTabSheet; TreeView1: TTreeView; procedure bitAceptarClick(Sender: TObject); procedure bitAplicarClick(Sender: TObject); procedure bitCancelClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure FormShow(Sender: TObject); procedure TreeView1Click(Sender: TObject); private function GetTabFromId(id: string): TTabSheet; function ActivateControl(ctlRef: TComponent): boolean; procedure MostEnVentana; { private declarations } public //msjError: string; edMacr : TSynEdit; //Referencia al editor panel de comando edRemo : TSynEdit; //Referencia al editor remoto //Frames de configuración fcEdMacr : TfraCfgSynEdit; //Editor de macros fcEdRemo : TfraCfgSynEdit; //Editor remoto //Evento OnPropertiesChanged: procedure of object; //Evento de cambio de propiedades public //Propiedades generales VerPanCom : boolean; //Panel de comandos VerBHerPcom : boolean; //Barra de herramientas VerBHerTerm : boolean; //Barra de herramientas VerBarEst : boolean; //Barra de estado TipAlineam : integer; //Tipo de alineamiento de pantalla RecentFiles : TStringList; //Lista de archivos recientes AbrirUltScr : boolean; public //Propiedades de rutas de archivos UltScript : string; //Último script editado foldTemp : string; { TODO : ¿Realmente conviene personalizar estas rutas? ¿Por qué no las dejamos fijas en las rutas que se definen en la unidad "Globales"? } foldMacros : string; foldLenguajes : string; public //Configuraciones de Macros TpoMax : integer; marLin : boolean; public //Configuraciones del explorador remoto TpoMax2: integer; //Tiempo máximo de espera MosRut : boolean; //muestra la ruta actual ListDet: boolean; MosOcul: boolean; RefDesp: boolean; public procedure Iniciar(); procedure ReadFromFile(iniFile: string=''); procedure SaveToFile(iniFile: string=''); procedure Configurar(Id: string=''); end; var Config: TConfig; implementation {$R *.lfm} { TConfig } procedure TConfig.FormCreate(Sender: TObject); begin RecentFiles := TStringList.Create; //Crea frames de configuración de SynEdit fcEdMacr:= TfraCfgSynEdit.Create(Self); fcEdMacr.Name := 'emac'; //Para que no de error de nombre fcEdMacr.parent := TabMacEdit; fcEdRemo:= TfraCfgSynEdit.Create(Self); fcEdRemo.Name := 'erem'; //Para que no de error de nombre fcEdRemo.parent := TabRemEdEdit; //Prepara página y Selecciona primera opción PageControl1.ShowTabs := false; TreeView1.Items[0].Selected:=true; TreeView1Click(self); cfgFile.VerifyFile; end; procedure TConfig.FormDestroy(Sender: TObject); begin RecentFiles.Destroy end; procedure TConfig.FormShow(Sender: TObject); begin MostEnVentana; //carga las propiedades en el frame end; procedure TConfig.Iniciar(); //Inicia el formulario de configuración. Debe llamarse antes de usar el formulario y //después de haber cargado todos los frames. begin //Configuraciones generales cfgFile.Asoc_Bol('VerPanCom' , @VerPanCom , true); cfgFile.Asoc_Bol('VerBHerPcom', @VerBHerPcom, true); cfgFile.Asoc_Bol('VerBHerTerm', @VerBHerTerm, true); cfgFile.Asoc_Bol('VerBarEst' , @VerBarEst , true); cfgFile.Asoc_Int('TipAlineam' , @TipAlineam , 0); cfgFile.Asoc_StrList('Recents_ses', @RecentFiles); //Propiedades de rutas de archivos cfgFile.Asoc_Str('UltScript' , @UltScript ,''); cfgFile.Asoc_Bol('AbrirUltScr', @AbrirUltScr, chkOpenLast , true); cfgFile.Asoc_Str('foldTemp' , @foldTemp , DirectoryEdit1, patTemp); cfgFile.Asoc_Str('Macros' , @foldMacros , DirectoryEdit2, patMacros); cfgFile.Asoc_Str('Lenguajes' , @foldLenguajes , DirectoryEdit3, patSyntax); //Configuraciones de foldMacros cfgFile.Asoc_Int('TpoMax' , @TpoMax, edTpoMax , 10, 1, 180); cfgFile.Asoc_Bol('MarLin' , @marLin, chkMarLin, false); //Configuración de editor de foldMacros fcEdMacr.Iniciar('edMacros', cfgFile, $E8FFE8); //Configuración de editor remoto fcEdRemo.Iniciar('edRemoto', cfgFile); //Configuraciones del explorador remoto cfgFile.Asoc_Int('TpoMax2' , @TpoMax2, edTpoMax1 , 10, 1, 180); cfgFile.Asoc_Bol('MosRut' , @MosRut , chkMosRut , true); cfgFile.Asoc_Bol('ListDet' , @ListDet, chkListDet, true); cfgFile.Asoc_Bol('MosOcul' , @MosOcul, chkMosOcul, false); cfgFile.Asoc_Bol('RefDesp' , @RefDesp, chkRefDesp, true); //lee parámetros del archivo de configuración. ReadFromFile; end; function TConfig.GetTabFromId(id: string): TTabSheet; {Retorna una página del PageControl, de acuerdo al ID indicado.} begin case id of '1', '1.1' : exit(TabGeneral); '1.2' : exit(TabFilePath); '2', '2.1' : exit(TabMacSett); '2.2' : exit(TabMacEdit); '3', '3.1' : exit(TabRemEdEdit); '4' : exit(TabRemExpl); else exit(nil); end; end; procedure TConfig.TreeView1Click(Sender: TObject); var id: String; begin if TreeView1.Selected = nil then exit; //hay ítem seleccionado id := IdFromTTreeNode(TreeView1.Selected); if GetTabFromId(id) <> nil then GetTabFromId(id).Show; end; function TConfig.ActivateControl(ctlRef: TComponent): boolean; {Intenta seleccionar un control de la ventana de la configuración, a partir de una referencia "TComponente". Si logra la identifiación, devuelve en: "ctl" -> El control como un TWinControl. "tab" -> El contenedor como un TTabSheet. } var pag: TComponent; tab: TTabSheet; it: TTreeNode; id: String; ctl: TWinControl; begin if ctlRef=nil then exit(false); //Busca al contenedor pag := ctlRef.GetParentComponent; if pag.ClassName = 'TTabSheet' then begin //Lo contiene un TTabSheet. Lo activamos. tab := TTabSheet(pag); //tab.Show; Esto activaría la página, pero no actualizaría el TreeView1 //Busca el ítem del árbol que activa esa página for it in TreeView1.Items do begin id := IdFromTTreeNode(it); //Obtiene ID if GetTabFromId(id)=nil then continue; if GetTabFromId(id) = tab then begin //Encontramos el id que selecciona al "tab2. it.Selected := true; //Selecciona en el TreeView1 TreeView1Click(self); //Activa el "tab". //Intenta seleccionar al control if ctlRef is TWinControl then begin ctl := TWinControl(ctlRef); if (it.Visible=true) and (ctl.Visible = true) and ctl.CanFocus then begin ctl.SetFocus; end; end; exit(true); //Se ubicó end; end; //No se encontró al ítem que selecciona a este "tab". exit(false); end else begin //No se conoce al contenedor exit(false); end; end; procedure TConfig.bitAceptarClick(Sender: TObject); begin bitAplicarClick(Self); if cfgFile.MsjErr<>'' then exit; //hubo error self.Close; //porque es modal end; procedure TConfig.bitAplicarClick(Sender: TObject); begin if not cfgFile.WindowToProperties then begin //Se produjo un error //Trata de seleccionar al control con error. ActivateControl(cfgFile.ctlErr.ctlRef); MsgErr(cfgFile.MsjErr); exit; end; //Valida las rutas leidas if not DirectoryExists(foldTemp) then begin MsgExc('Folder not found: %s',[foldTemp]); foldTemp := patTemp; end; if not DirectoryExists(foldMacros) then begin MsgExc('Folder not found: %s', [foldMacros]); foldMacros := patMacros; end; if not DirectoryExists(foldLenguajes) then begin MsgExc('Folder not found: %s', [foldLenguajes]); foldLenguajes := patSyntax; end; if OnPropertiesChanged<>nil then OnPropertiesChanged(); SaveToFile; //Guarda propiedades en disco end; procedure TConfig.bitCancelClick(Sender: TObject); begin self.Hide; end; procedure TConfig.Configurar(Id: string=''); //Muestra el formulario, de modo que permita configurar la sesión actual var it: TTreeNode; begin if Id<> '' then begin /////se pide mostrar un Id en especial //oculta los demás it := TTreeNodeFromId(Id,TreeView1); if it <> nil then it.Selected:=true; TreeView1Click(self); end else begin ////////muestra todos for it in TreeView1.Items do begin it.Visible:=true; end; end; Showmodal; end; procedure TConfig.MostEnVentana; //Muestra las propiedades en la ventana de configuración. begin if not cfgFile.PropertiesToWindow then begin MsgErr(cfgFile.MsjErr); end; end; procedure TConfig.ReadFromFile(iniFile: string = ''); begin if not cfgFile.FileToProperties then begin MsgErr(cfgFile.MsjErr); end; if OnPropertiesChanged<>nil then OnPropertiesChanged(); end; procedure TConfig.SaveToFile(iniFile: string=''); //Escribe el archivo de configuración begin if not cfgFile.PropertiesToFile then begin MsgErr(cfgFile.MsjErr); end; end; end.