FrameTabSession.pas 67 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840
  1. unit FrameTabSession;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils, fgl, Forms, Controls, ExtCtrls, ComCtrls, Dialogs,
  6. Graphics, LCLType, LCLProc, ActnList, StdActns, Menus, StdCtrls,
  7. SynPluginMultiCaret, SynPluginSyncroEdit, SynFacilUtils, FormSelFuente,
  8. MisUtils, MiConfigXML, MiConfigBasic, UnTerminal, TermVT, SynEdit,
  9. SynEditMarkupHighAll, SynEditKeyCmds, SynEditMarkup, SynEditTypes,
  10. uResaltTerm, Globales, FormSesProperty, FormConfig, process,
  11. uPreProces, uPreBasicos;
  12. const
  13. FONT_TAB_SIZE = 9;
  14. MIN_WIDTH_TAB = 50; //Ancho por defecto de la lengueta
  15. MAX_LIN_TER = 32000;
  16. type
  17. TlogState = (logStopped, logRunning, logPaused);
  18. { TMarkup }
  19. {Marcador para resltar errores de sintaxis en SynEdit}
  20. TMarkup = class(TSynEditMarkupHighlightMatches)
  21. public
  22. procedure SetMark(p1, p2: TPoint);
  23. end;
  24. {Versión de "TConsoleProc" que permite acceder al campo "panel", donde se muestra el
  25. estado de la conexión}
  26. TConsoleProc2 = class(TConsoleProc)
  27. property panelState: TStatusPanel read panel write panel;
  28. end;
  29. {Parámetros de configuración de SynEdit}
  30. TEditCfg = record
  31. FontName : string; //Tipo de letra.
  32. FontSize : integer; //Tamaño de letra.
  33. MarLinAct : boolean; //Marcar línea actual.
  34. VerBarDesV : boolean; //Ver barras de desplazamiento.
  35. VerBarDesH : boolean; //Ver barras de desplazamiento.
  36. ResPalCur : boolean; //Resaltar palabra bajo el cursor.
  37. cTxtNor : TColor; //Color de texto normal.
  38. cFonEdi : TColor; //Color de fondo del control de edición.
  39. //cFonSel : TColor; //Color del fondo de la selección.
  40. //cTxtSel : TColor; //Color del texto de la selección.
  41. cLinAct : TColor; //Color de la línea actual.
  42. cResPal : TColor; //Color de la palabra actual.
  43. //Panel vertical
  44. VerPanVer : boolean; //Ver pánel vertical.
  45. VerNumLin : boolean; //Ver número de línea.
  46. VerMarPle : boolean; //Ver marcas de plegado.
  47. cFonPan : TColor; //Color de fondo del panel vertical.
  48. cTxtPan : TColor; //Color de texto del panel vertical.
  49. end;
  50. //Modos de la herramienta Explorador de archivos
  51. TexplorMode = (
  52. expBashComm, //Explorador manejado por comandos del bash de Linux.
  53. expExternal //Explorador externo.
  54. );
  55. //Modos de la herramienta Editor
  56. TeditMode = (
  57. edtLocal, //Editor local personalizado
  58. edtRemotSFTP, //Editor conexión remota SFTP
  59. edtBashComm //Editor por comandos de bash del linux.
  60. );
  61. { TfraTabSession }
  62. TfraTabSession = class(TFrame)
  63. published
  64. acEdCopy: TEditCopy;
  65. acEdCut: TEditCut;
  66. acEdPaste: TAction;
  67. acEdRedo: TAction;
  68. acEdSelecAll: TAction;
  69. acEdUndo: TAction;
  70. AcFilNewSes: TAction;
  71. AcFIlOpeSes: TAction;
  72. AcFilSavSes: TAction;
  73. AcFilSavSesAs: TAction;
  74. AcFilStarLog: TAction;
  75. AcFilStopLog: TAction;
  76. AcHerCfg: TAction;
  77. AcHerGraMac: TAction;
  78. AcPCmCamPos: TAction;
  79. acPCmEnvCtrC: TAction;
  80. AcPCmEnvLin: TAction;
  81. AcPCmEnvTod: TAction;
  82. AcPCmOcul: TAction;
  83. AcTerConec: TAction;
  84. AcTerCopNom: TAction;
  85. AcTerCopNomRut: TAction;
  86. AcTerCopPal: TAction;
  87. AcTerCopRut: TAction;
  88. AcTerDescon: TAction;
  89. AcTerDetPrm: TAction;
  90. AcTerEnvCR: TAction;
  91. AcTerEnvCRLF: TAction;
  92. AcTerEnvEnter: TAction;
  93. AcTerEnvLF: TAction;
  94. AcTerLimBuf: TAction;
  95. AcTerPrmAba: TAction;
  96. AcTerPrmArr: TAction;
  97. AcTerVerBHer: TAction;
  98. acFindFind: TAction;
  99. acFindNext: TAction;
  100. acFindPrev: TAction;
  101. acFindReplace: TAction;
  102. ActionList1: TActionList;
  103. FindDialog1: TFindDialog;
  104. ImageList1: TImageList;
  105. imgBookMarks: TImageList;
  106. MenuItem2: TMenuItem;
  107. MenuItem48: TMenuItem;
  108. MenuItem49: TMenuItem;
  109. MenuItem50: TMenuItem;
  110. MenuItem51: TMenuItem;
  111. MenuItem52: TMenuItem;
  112. MenuItem53: TMenuItem;
  113. MenuItem54: TMenuItem;
  114. MenuItem55: TMenuItem;
  115. MenuItem56: TMenuItem;
  116. MenuItem57: TMenuItem;
  117. MenuItem58: TMenuItem;
  118. MenuItem59: TMenuItem;
  119. MenuItem60: TMenuItem;
  120. MenuItem61: TMenuItem;
  121. MenuItem72: TMenuItem;
  122. MenuItem73: TMenuItem;
  123. MenuItem74: TMenuItem;
  124. MenuItem75: TMenuItem;
  125. MenuItem76: TMenuItem;
  126. MenuItem77: TMenuItem;
  127. MenuItem78: TMenuItem;
  128. MenuItem80: TMenuItem;
  129. MenuItem81: TMenuItem;
  130. MenuItem82: TMenuItem;
  131. MenuItem83: TMenuItem;
  132. MenuItem84: TMenuItem;
  133. MenuItem85: TMenuItem;
  134. MenuItem86: TMenuItem;
  135. mnPopComAlm: TMenuItem;
  136. mnPopLeng: TMenuItem;
  137. Panel1: TPanel;
  138. PopupMenu1: TPopupMenu;
  139. PopupMenu2: TPopupMenu;
  140. ReplaceDialog1: TReplaceDialog;
  141. SaveDialog1: TSaveDialog;
  142. SaveDialog2: TSaveDialog;
  143. Splitter1: TSplitter;
  144. edPCom: TSynEdit;
  145. edTerm: TSynEdit;
  146. Timer1: TTimer;
  147. ToolBar1: TToolBar;
  148. ToolButton1: TToolButton;
  149. ToolButton10: TToolButton;
  150. ToolButton11: TToolButton;
  151. ToolButton12: TToolButton;
  152. ToolButton13: TToolButton;
  153. ToolButton14: TToolButton;
  154. ToolButton15: TToolButton;
  155. ToolButton16: TToolButton;
  156. ToolButton17: TToolButton;
  157. ToolButton18: TToolButton;
  158. ToolButton19: TToolButton;
  159. ToolButton2: TToolButton;
  160. ToolButton20: TToolButton;
  161. ToolButton21: TToolButton;
  162. ToolButton22: TToolButton;
  163. ToolButton23: TToolButton;
  164. ToolButton24: TToolButton;
  165. ToolButton3: TToolButton;
  166. ToolButton4: TToolButton;
  167. ToolButton5: TToolButton;
  168. ToolButton6: TToolButton;
  169. ToolButton7: TToolButton;
  170. ToolButton8: TToolButton;
  171. ToolButton9: TToolButton;
  172. procedure acFindFindExecute(Sender: TObject);
  173. procedure AcFilSavSesAsExecute(Sender: TObject);
  174. procedure AcFilSavSesExecute(Sender: TObject);
  175. procedure AcFilStarLogExecute(Sender: TObject);
  176. procedure AcFilStopLogExecute(Sender: TObject);
  177. procedure acFindNextExecute(Sender: TObject);
  178. procedure acFindPrevExecute(Sender: TObject);
  179. procedure acFindReplaceExecute(Sender: TObject);
  180. procedure AcHerCfgExecute(Sender: TObject);
  181. procedure acPCmEnvCtrCExecute(Sender: TObject);
  182. procedure AcPCmEnvLinExecute(Sender: TObject);
  183. procedure AcPCmEnvTodExecute(Sender: TObject);
  184. procedure AcTerConecExecute(Sender: TObject);
  185. procedure AcTerCopNomExecute(Sender: TObject);
  186. procedure AcTerCopNomRutExecute(Sender: TObject);
  187. procedure AcTerCopPalExecute(Sender: TObject);
  188. procedure AcTerCopRutExecute(Sender: TObject);
  189. procedure AcTerDesconExecute(Sender: TObject);
  190. procedure AcTerDetPrmExecute(Sender: TObject);
  191. procedure AcTerEnvCRExecute(Sender: TObject);
  192. procedure AcTerEnvCRLFExecute(Sender: TObject);
  193. procedure AcTerEnvEnterExecute(Sender: TObject);
  194. procedure AcTerEnvLFExecute(Sender: TObject);
  195. procedure AcTerLimBufExecute(Sender: TObject);
  196. procedure AcTerPrmAbaExecute(Sender: TObject);
  197. procedure AcTerPrmArrExecute(Sender: TObject);
  198. procedure AcTerVerBHerExecute(Sender: TObject);
  199. procedure edPComEnter(Sender: TObject);
  200. procedure edTermEnter(Sender: TObject);
  201. procedure FindDialog1Find(Sender: TObject);
  202. procedure ReplaceDialog1Replace(Sender: TObject);
  203. procedure Splitter1Moved(Sender: TObject);
  204. procedure Timer1Timer(Sender: TObject);
  205. private
  206. ejecCom: boolean; //indica que está ejecutando un comando (editor remoto, exp. remoto ...)
  207. hlTerm : TResaltTerm;
  208. LlegoPrompt: boolean; //bandera
  209. parpadPan0: boolean; //para activar el parpadeo del panel0
  210. ticComRec : integer; //contador para comando recurrente
  211. edFocused : TSynEdit; //Editor con enfoque
  212. function BuscaPromptArr: integer;
  213. function BuscaPromptAba: integer;
  214. function BuscaUltPrompt: integer;
  215. function ConexDisponible: boolean;
  216. procedure ConfigEditor(ed: TSynEdit; cfgEdit: TEditCfg);
  217. procedure DistribuirPantalla;
  218. procedure UpdateActionsState(Sender: TObject);
  219. procedure edPComKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  220. procedure EnvioTemporizado;
  221. procedure ePComMenLangSelected(langName, xmlFile: string);
  222. procedure eScript_MouseDown(Sender: TObject; Button: TMouseButton;
  223. Shift: TShiftState; X, Y: Integer);
  224. procedure TestRecurringCommand;
  225. function InfoConnection: string;
  226. procedure edPComKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
  227. procedure proc_AddLine(HeightScr: integer);
  228. procedure proc_ChangeState(info: string; pIni: TPoint);
  229. procedure proc_InitScreen(const grilla: TtsGrid; fIni, fFin: integer);
  230. procedure proc_LineCompleted(const lin: string);
  231. procedure proc_LlegoPrompt(prmLine: string; pIni: TPoint; HeightScr: integer
  232. );
  233. procedure proc_RefreshLine(const grilla: TtsGrid; fIni, HeightScr: integer);
  234. procedure proc_RefreshLines(const grilla: TtsGrid; fIni, fFin,
  235. HeightScr: integer);
  236. procedure EnviarTxt(txt: string);
  237. public //Propiedades de lengueta
  238. { TODO : Para mejor separación de funciones, estos atributos no deberían estar aqui, sino en FrameTabSessions }
  239. x1 : integer; //Coordenada inicial de dibujo
  240. tabWidth: integer; //Ancho de lengueta
  241. public
  242. proc : TConsoleProc2; //Referencia al proceso actual
  243. ePCom : TSynFacilEditor;
  244. PanInfoConn: TStatusPanel; //Panel de información sobre la conexión
  245. procedure ConnectToGUI;
  246. procedure SetHide;
  247. procedure Activate; reintroduce;
  248. function getModified: boolean;
  249. procedure setModified(AValue: boolean);
  250. procedure PosicionarCursor(HeightScr: integer);
  251. function EnviarComando(com: string; var salida: TStringList): string;
  252. procedure UpdatePanInfoConn;
  253. procedure UpdatePanelState;
  254. procedure UpdatePanelLangName;
  255. procedure UpdateCommand;
  256. procedure PropertiesChanged;
  257. public //Parámetros de conexión
  258. Tipo : TTipCon; //Tipo de conexión
  259. IP : String; //Direción IP (solo válido con el tipo TCON_TELNET Y TCON_SSH)
  260. Port : String; //Puerto (solo válido con el tipo TCON_TELNET Y TCON_SSH)
  261. //nPort : integer; //Número de puerto serial. Solo válido para TCON_SERIAL. Falta implementar.
  262. //SerialPar : String; //Parámetros seriales FALTA IMPLEMENTAR
  263. Command : string; //comando a ejecutar en el proceso
  264. Other : String; //Ruta del aplicativo (solo válido con el tipo TCON_OTHER)
  265. LineDelimSend: TUtLineDelSend; //Tipo de delimitador de línea a enviar.
  266. LineDelimRecv: TUtLineDelRecv; //Tipo de delimitador de línea a recibir.
  267. ConRecientes : TStringList; //Lista de conexiones recientes
  268. public //Parámetros de detección de prompt
  269. detecPrompt: boolean;
  270. prIni : string;
  271. prFin : string;
  272. TipDetec : TPrompMatch;
  273. public //Parámetros de pantalla del Terminal
  274. maxLinTer : integer; //Máxima cantidad de líneas que se nantienen en el terminal
  275. maxColTer : integer; //Máxima cantidad de columnas que se muestran en el terminal
  276. interDirec : boolean; //Interceptar teclas direccionales
  277. curSigPrm : boolean; //cursor sigue a prompt
  278. public //Parámetros del editor del Terminal
  279. cfgEdTerm : TEditCfg;
  280. public //Parámetros de Comando recurrente
  281. Activar : boolean;
  282. Tempo : integer;
  283. tipEnvio: TTipEnvio;
  284. tipEnvio0: TTipEnvio; //temporal
  285. Comando : string;
  286. Comando0 : string;
  287. Archivo : string;
  288. Archivo0 : string;
  289. public //Parámetros del panel de comandos
  290. CompletCode: boolean; // Habilita el completado de código.
  291. CodFolding : boolean; // Habilita el plegado de código.
  292. SendLnEnter: boolean; // Enviar la línea actual con <Enter>.
  293. SendLnCtrEnter: boolean;// Enviar la línea actual con <Ctrl>+<Enter>.
  294. UsarPrep : boolean; // Usar preprocesador.
  295. public //Parámetros del editor del comandos
  296. cfgEdPCom : TEditCfg;
  297. public //Parámetros de la herramienta editor.
  298. commandEd : string; //Comando para lanzar al editor
  299. editMode : TeditMode; //Modo del editor
  300. exterEditor: string; //Ruta al editor externo, si no se selecciona interno.
  301. ftpEditUser: string; //Usuario SFTP para acceder a archivo a editar
  302. ftpEditPass: string; //Contraseña SFTP para acceder a archivo a editar
  303. public //Parámetros de la herramienta Explorador.
  304. commandEx : string; //Comando para lanzar al explorador.
  305. explorMode : TexplorMode; //Modo del explorador.
  306. exterExplor: string; //Ruta al explorador externo.
  307. commEx_bef : string; //Comandos antes de lanzar al editor.
  308. commEx_aft : string; //Comandos después de lanzar al editor.
  309. public //Parámetros adicionales
  310. langFile : string; //Archivo del lenguaje para el resaltador.
  311. textPCom : TStrings; //Texto del panel de comandos
  312. textTerm : TStrings; //Texto del terminal.
  313. pComWidth : integer; //Ancho de panel de comando.
  314. showPCom : boolean; //Visibilidad del panel de comandos
  315. showTerm : boolean; //Visibilidad del Terminal
  316. public //Detección de prompt
  317. procedure UpdatePromptProc;
  318. function ContienePrompt(const linAct: string): integer;
  319. function EsPrompt(const cad: string): boolean;
  320. private //Acceso a disco
  321. procedure UpdateCaption(filName: string);
  322. function getFileName: string;
  323. procedure setFileName(AValue: string);
  324. public //Acceso a disco
  325. property fileName: string read getFileName write setFileName;
  326. function IsTextFile: boolean;
  327. function WriteData: boolean;
  328. function SaveToFile: boolean;
  329. function SaveAsDialog: boolean;
  330. procedure LoadFromFile;
  331. public //Campos para manejo del registro
  332. logState: TlogState; //estado del registro
  333. logFile : text;
  334. logName : string; //archvio de registro
  335. function StartLog(logName0: string): boolean;
  336. procedure PauseLog;
  337. procedure StartLog;
  338. procedure EndLog;
  339. function WriteLog(txt: string): boolean;
  340. public //Manejadores de eventos
  341. function queryClose: boolean;
  342. public //Inicialización
  343. prop : TMiConfigXML;
  344. function ShowProperties: TModalResult;
  345. procedure InicConect;
  346. procedure InicConectTelnet(ip0: string);
  347. procedure InicConectSSH(ip0: string);
  348. constructor Create(AOwner: TComponent); override;
  349. procedure Init;
  350. procedure ExecSettings;
  351. destructor Destroy; override;
  352. end;
  353. TPages = specialize TFPGObjectList<TfraTabSession>;
  354. procedure InicTerminal(edTerm: TSynEdit; hlTerm: TResaltTerm);
  355. implementation
  356. uses FrameTabSessions, Comandos;
  357. {$R *.lfm}
  358. resourcestring
  359. MSG_MODIFSAV = 'File %s has been modified. Save?';
  360. function GetTabSessions(pag: TfraTabSession; out tabSessions: TfraTabSessions): boolean;
  361. {Devuelve la referencia al contenedor de páginas de este frame. Si no lo encuentra,
  362. devuelve FALSE.}
  363. var
  364. panContent: TWinControl;
  365. begin
  366. panContent := pag.Parent; //Panel contenedor.
  367. if panContent = nil then exit(false);
  368. tabSessions := TfraTabSessions(panContent.Parent); //Debe ser TFraTabSessions, sino fallará.
  369. //if tabSessions.ClassName<>'TFraTabSessions' then exit(false); //Verifica clase
  370. if tabSessions=nil then exit(false);
  371. exit(true);
  372. end;
  373. procedure InicTerminal(edTerm: TSynEdit; hlTerm: TResaltTerm);
  374. var
  375. SynMarkup: TSynEditMarkupHighlightAllCaret; //para resaltar palabras iguales
  376. begin
  377. edTerm.Highlighter := hlTerm; //asigna resaltador
  378. edTerm.Color := clBlack;
  379. edTerm.Gutter.Width := 37;
  380. edTerm.Gutter.Parts[0].Visible := false;
  381. edTerm.Gutter.Parts[2].Visible := false;
  382. //Inicia resaltado de palabras iguales
  383. SynMarkup := TSynEditMarkupHighlightAllCaret(edTerm.MarkupByClass[TSynEditMarkupHighlightAllCaret]);
  384. SynMarkup.MarkupInfo.FrameColor := clSilver;
  385. SynMarkup.MarkupInfo.Background := clBlack;
  386. SynMarkup.MarkupInfo.StoredName:='ResPalAct'; //para poder identificarlo
  387. SynMarkup.WaitTime := 250; // millisec
  388. SynMarkup.Trim := True; // no spaces, if using selection
  389. SynMarkup.FullWord := True; // only full words If "Foo" is under caret, do not mark it in "FooBar"
  390. SynMarkup.IgnoreKeywords := False;
  391. // edTerm.Font.Name:='Courier New';
  392. // edTerm.Font.Size:=10;
  393. //resalta
  394. edTerm.Options:=[eoBracketHighlight];
  395. //Limita posición X del cursor para que no escape de la línea
  396. edTerm.Options := edTerm.Options + [eoKeepCaretX];
  397. //permite indentar con <Tab>
  398. edTerm.Options := edTerm.Options + [eoTabIndent];
  399. //trata a las tabulaciones como un caracter
  400. edTerm.Options2 := edTerm.Options2 + [eoCaretSkipTab];
  401. end;
  402. { TMarkup }
  403. procedure TMarkup.SetMark(p1, p2: TPoint);
  404. begin
  405. Matches.StartPoint[0] := p1;
  406. Matches.EndPoint[0] := p2;
  407. InvalidateSynLines(p1.y, p2.y);
  408. end;
  409. { TfraTabSession }
  410. procedure TfraTabSession.edPComKeyUp(Sender: TObject; var Key: Word;
  411. Shift: TShiftState);
  412. procedure EnviarActual; //Envía la línea actual y controla el cursor
  413. begin
  414. AcPCmEnvLinExecute(self);
  415. if edPCom.SelAvail then begin //había selección
  416. //no se cambia la selección
  417. end else if edPCom.CaretY = edPCom.Lines.Count then begin
  418. //estamos en la última línea
  419. if edPCom.LineText = '' then exit; //no hay nada que enviar ni agregar
  420. edpCom.Lines.Add(''); //agrega una línea
  421. edPCom.ExecuteCommand(ecDown, '',nil); //baja cursor
  422. end else begin
  423. //es una línea normal
  424. edPCom.ExecuteCommand(ecDown, '',nil); //baja cursor
  425. end;
  426. end;
  427. var
  428. Enter: Boolean;
  429. begin
  430. Enter := (key = VK_RETURN);
  431. //Verificaciones
  432. if (Shift = []) and Enter and SendLnEnter then begin
  433. //Envía línea actual
  434. EnviarActual;
  435. Key := 0; //para que ya no lo procese
  436. end else if (Shift = [ssCtrl]) and Enter and SendLnCtrEnter then begin
  437. //Envía línea actual
  438. EnviarActual;
  439. Key := 0; //para que ya no lo procese
  440. end else if (Shift = [ssCtrl]) and Enter and not SendLnCtrEnter then begin
  441. //<Control>+<Enter>, pero no está configurado
  442. edPCom.ExecuteCommand(ecInsertLine, '',nil); //inserta salto
  443. edPCom.ExecuteCommand(ecDown, '',nil); //baja cursor
  444. Key := 0; //para que ya no lo procese
  445. end else if (Shift = [ssCtrl]) and (key = VK_UP) then begin
  446. AcTerPrmArrExecute(nil);
  447. end else if (Shift = [ssCtrl]) and (key = VK_DOWN) then begin
  448. AcTerPrmAbaExecute(nil);
  449. //end else if (Shift = [ssCtrl]) and (key = VK_C) then begin //Ctrl + C
  450. // AcTerEnvCtrlCExecute(nil) //envía Ctrl+C al terminal
  451. end;
  452. end;
  453. procedure TfraTabSession.proc_AddLine(HeightScr: integer);
  454. var
  455. i: Integer;
  456. begin
  457. // debugln('procAddLine: ');
  458. edTerm.BeginUpdate();
  459. if edTerm.Lines.Count>maxLinTer then begin
  460. //hace espacio
  461. for i:= 1 to 100 do
  462. edTerm.Lines.Delete(0); { TODO : Debe verificarse que no se deba eliminar tanto
  463. como para dejar menos líneas que la que tiene el VT100 }
  464. end;
  465. edTerm.Lines.Add('');
  466. // edTerm.ExecuteCommand(ecEditorBottom,'', nil); //mueve al final
  467. edTerm.EndUpdate;
  468. edTerm.ExecuteCommand(ecLineEnd,'', nil); //mueve al final
  469. end;
  470. procedure TfraTabSession.proc_ChangeState(info: string; pIni: TPoint);
  471. //Hubo un cambio de estado
  472. begin
  473. AcTerConec.Enabled := proc.state = ECO_STOPPED;
  474. AcTerDescon.Enabled := not (proc.state = ECO_STOPPED);
  475. end;
  476. procedure TfraTabSession.proc_InitScreen(const grilla: TtsGrid; fIni,
  477. fFin: integer);
  478. var
  479. i: Integer;
  480. begin
  481. // debugln('procAddLastLins: '+IntToStr(fIni)+','+IntToSTr(fFin));
  482. for i:=fIni to fFin do
  483. edTerm.Lines.Add(grilla[i]);
  484. end;
  485. procedure TfraTabSession.proc_LineCompleted(const lin: string);
  486. begin
  487. if logState = logRunning then begin
  488. writeln(logFile, lin);
  489. end;
  490. end;
  491. procedure TfraTabSession.proc_LlegoPrompt(prmLine: string; pIni: TPoint;
  492. HeightScr: integer);
  493. begin
  494. LlegoPrompt := true; //activa bandera
  495. // yvt := edTerm.Lines.Count-HeightScr-1; //calcula fila equivalente a inicio de VT100
  496. //debugln(' llegoPrompt en:'+IntToStr(yvt + pIni.y+1));
  497. end;
  498. procedure TfraTabSession.proc_RefreshLine(const grilla: TtsGrid; fIni,
  499. HeightScr: integer);
  500. var
  501. yvt: Integer;
  502. begin
  503. // debugln('procRefreshLine: '+IntToStr(fIni));
  504. yvt := edTerm.Lines.Count-HeightScr-1; //calcula fila equivalente a inicio de VT100
  505. edTerm.Lines[yvt+fIni] := grilla[fIni];
  506. PosicionarCursor(HeightScr);
  507. end;
  508. procedure TfraTabSession.proc_RefreshLines(const grilla: TtsGrid; fIni, fFin,
  509. HeightScr: integer);
  510. var
  511. yvt: Integer;
  512. f: Integer;
  513. begin
  514. // debugln('procRefreshLines: '+IntToStr(fIni)+','+IntToSTr(fFin));
  515. yvt := edTerm.Lines.Count-HeightScr-1; //calcula fila equivalente a inicio de VT100
  516. edTerm.BeginUpdate();
  517. for f:=fIni to fFin do
  518. edTerm.Lines[yvt+ f] := grilla[f];
  519. PosicionarCursor(HeightScr);
  520. edTerm.EndUpdate;
  521. edTerm.Refresh; //para mostrar el cambio
  522. end;
  523. procedure TfraTabSession.EnviarTxt(txt: string);
  524. //Envía un tetxo al terminal, aplicando el preprocesamiento si es necesario
  525. var
  526. usu: string;
  527. tabSessions: TfraTabSessions;
  528. begin
  529. if not GetTabSessions(self, tabSessions) then exit;
  530. if ProcessCommand(txt, self, tabSessions) then begin
  531. //Era un comando y lo procesó
  532. end else if UsarPrep then begin
  533. //se debe usar el preprocesador PreSQL
  534. PreProcesar('', txt, usu);
  535. if PErr.HayError Then begin
  536. msgerr(Perr.GenTxtError);
  537. exit; //verificación
  538. end;
  539. proc.SendLn(PPro.TextSalida);
  540. end else begin //envío común
  541. proc.SendLn(txt);
  542. end;
  543. end;
  544. function TfraTabSession.InfoConnection: string;
  545. //Actualiza el panel 0, con información de la conexión o de la ejecución de macros
  546. begin
  547. case Tipo of
  548. TCON_TELNET:
  549. Result :='Telnet: ' + IP;
  550. TCON_SSH:
  551. Result :='SSH: ' + IP;
  552. TCON_SERIAL:
  553. Result :='Serial: ' + frmSesProperty.cmbSerPort.Text;
  554. TCON_OTHER:
  555. Result :='Proc: ' + Other;
  556. end;
  557. end;
  558. procedure TfraTabSession.ConnectToGUI;
  559. var
  560. tabSessions: TfraTabSessions;
  561. res: string;
  562. begin
  563. if not GetTabSessions(self, tabSessions) then exit;
  564. tabSessions.PageEvent('req_conn_gui', self, res); //Requiere conexión a GUI
  565. end;
  566. procedure TfraTabSession.SetHide;
  567. begin
  568. self.Hide;
  569. end;
  570. procedure TfraTabSession.Activate;
  571. {Hace visible este frame. Se usa cuando se conmuta entre varias páginas.}
  572. begin
  573. Show; //Primero se hace visible.
  574. ConnectToGUI; //Pide configurar eventos.
  575. UpdatePanInfoConn; //Actualiza panel con información de la conexión.
  576. UpdatePanelState; //Actualiza panel de estado de la conexión
  577. ePCom.RefreshPanCursor; //Refresca el panel de posición del cursor.
  578. UpdatePanelLangName; //Actualiza nombre del lenguaje.
  579. end;
  580. procedure TfraTabSession.UpdatePanInfoConn;
  581. {Actualiza el panel de información de la conexión.}
  582. begin
  583. if PanInfoConn<>nil then PanInfoConn.Text := InfoConnection;
  584. end;
  585. procedure TfraTabSession.UpdatePanelState;
  586. {Actualiza el panel de estado de la conexión.}
  587. begin
  588. proc.RefPanelEstado;
  589. end;
  590. procedure TfraTabSession.UpdatePanelLangName;
  591. {Actualiza el panel del lenguaje del resaltador.}
  592. begin
  593. ePCom.PanLangName.Text := ePCom.hl.LangName;
  594. end;
  595. function TfraTabSession.getModified: boolean;
  596. begin
  597. Result := edPCom.Modified;
  598. end;
  599. procedure TfraTabSession.setModified(AValue: boolean);
  600. begin
  601. edPCom.Modified := AValue;
  602. end;
  603. procedure TfraTabSession.PosicionarCursor(HeightScr: integer);
  604. //Coloca el cursor del editor, en la misma posición que tiene el cursor del
  605. //terminal VT100 virtual.
  606. var
  607. yvt: Integer;
  608. begin
  609. if curSigPrm then begin
  610. yvt := edTerm.Lines.Count-HeightScr-1; //calcula fila equivalente a inicio de VT100
  611. edTErm.CaretXY := Point(proc.term.curX, yvt+proc.term.CurY+1);
  612. end;
  613. end;
  614. procedure TfraTabSession.PropertiesChanged;
  615. {Rutinas a ejecutar cuando han cambiado las propiedades de la sesión, como cuando se
  616. cargan de archivo o se cambian con la ventana de propiedades.}
  617. begin
  618. UpdatePromptProc; //Actualiza los parámetros de detección del "prompt" en "proc".
  619. UpdatePanInfoConn; //Actualiza información de la conexión
  620. UpdatePanelState; //Actualiza panel del estado de la conexión
  621. ePCom.RefreshPanCursor; //Refresca el panel de posición del cursor.
  622. if langFile<>'' then begin //Carga coloreado de sintaxis, actualiza menú y panel.
  623. ePCom.LoadSyntaxFromFile(patSyntax + DirectorySeparator + langFile);
  624. end;
  625. //Actualiza controles que dependen de las propiedades.
  626. ConfigEditor(edTerm, cfgEdTerm); //Configura editor.
  627. ConfigEditor(edPCom, cfgEdPCom); //Configura editor.
  628. edTerm.Invalidate; //Para que refresque los cambios.
  629. edPCom.Invalidate; //Para que refresque los cambios.
  630. edPCom.Width := pComWidth;
  631. //Visibilidad del panel de comando Y del terminal
  632. if showPCom and showTerm then begin //Mostrar ambos
  633. edPCom.Visible := true;
  634. edPCom.Align := alLeft;
  635. Splitter1.Visible := true;
  636. edTerm.Visible := true;
  637. edTerm.Align := alClient;
  638. end else if showPCom then begin //Solo panel de comandos
  639. edPCom.Visible := true;
  640. edPCom.Align := alClient; //Toda la pantalla
  641. Splitter1.Visible := false;
  642. edTerm.Visible := false;
  643. end else if showTerm then begin //Solo Terminal
  644. edPCom.Visible := false;
  645. Splitter1.Visible := false;
  646. edTerm.Visible := true;
  647. edTerm.Align := alClient; //Toda la pantalla
  648. end else begin
  649. edPCom.Visible := false;
  650. edTerm.Visible := false;
  651. end;
  652. end;
  653. //Acceso a disco
  654. procedure TfraTabSession.UpdateCaption(filName: string);
  655. {Actualiza el nombre del "Caption" del frame. Este nombre es el que se mostrará en la
  656. lengueta de esta página.}
  657. var
  658. tabSessions: TfraTabSessions;
  659. begin
  660. //La primera regla, es tomar solo el nombre del archivo.
  661. Caption := ExtractFileName(filName);
  662. if not GetTabSessions(self, tabSessions) then exit; //Acceso a "tabSessions"
  663. //Pero debemos validarla en el contenedor, si no queremos que se duplique.
  664. // tabSessions.ValidateCaption();
  665. {También deberíamos actualizar la geometría que maneja el contenedor, porque si
  666. cambia el "Caption", puede cambiar el ancho de la lengueta.}
  667. tabSessions.UpdateTabWidth(self); //Cambia el título Hay que actualizar ancho de lengueta.
  668. end;
  669. function TfraTabSession.getFileName: string;
  670. begin
  671. //Usamos en nombre del archivo del objeto "prop"
  672. Result := prop.GetFileName; //Usamos el "Caption como nombre de archivo".
  673. end;
  674. procedure TfraTabSession.setFileName(AValue: string);
  675. begin
  676. prop.SetFileName(AValue);
  677. end;
  678. //Acceso a disco
  679. function TfraTabSession.IsTextFile: boolean;
  680. begin
  681. Result := UpCase(ExtractFileExt(fileName)) = '.TXT';
  682. end;
  683. function TfraTabSession.WriteData: boolean;
  684. {Escribe el contenido del archivo actual en disco. Si se produce algún error,
  685. muestra un mensaje y devuelve FALSE.}
  686. begin
  687. if IsTextFile then begin
  688. //Se guarda como texto
  689. edPCom.Lines.SaveToFile(fileName); //Podría fallar.
  690. setModified(false);
  691. UpdateActionsState(nil);
  692. exit(true);
  693. end else begin
  694. //Se guarda como configuración
  695. if not prop.PropertiesToFile then begin
  696. MsgErr(prop.MsjErr);
  697. exit(false);
  698. end;
  699. //Todo salió bien.
  700. setModified(false);
  701. UpdateActionsState(nil);
  702. exit(true);
  703. end;
  704. end;
  705. function TfraTabSession.SaveToFile: boolean;
  706. {Guarda esta página en "fileName". Si se cancela el guardado o hay algún error, se
  707. devuelve FALSE.}
  708. begin
  709. if not FileExists(FileName) then begin
  710. //Es un archivo nuevo, que no se ha guardado.
  711. Result := SaveAsDialog();
  712. end else begin
  713. Result := WriteData;
  714. end;
  715. end;
  716. function TfraTabSession.SaveAsDialog: boolean;
  717. {Muestra la ventana para grabar esta sesión. Si se cancela, o no se puede grabar,
  718. devuelve FALSE.}
  719. var
  720. arc0, res, filter: String;
  721. resp: TModalResult;
  722. tabSessions: TfraTabSessions;
  723. begin
  724. //debugln(self.fileName);
  725. if not GetTabSessions(self, tabSessions) then exit;
  726. filter := 'Text files|*.txt|All files|*.*'; //Filtro por defecto
  727. //Pide filtro para el diálogo "Save As"
  728. tabSessions.PageEvent('req_filt_save', self, res);
  729. if res<>'' then filter := res;
  730. SaveDialog1.Filter := filter;
  731. //SaveDialog1.DefaultExt := MSG_FILE_EXT;
  732. SaveDialog1.FileName := fileName;
  733. if not SaveDialog1.Execute then begin //se canceló
  734. exit(false); //se canceló
  735. end;
  736. arc0 := SaveDialog1.FileName;
  737. if FileExists(arc0) then begin
  738. resp := MessageDlg('', Format('File %s already exists.',[arc0]) + LineEnding +
  739. '¿Overwrite?',
  740. mtConfirmation, [mbYes, mbNo, mbCancel], 0);
  741. if (resp = mrCancel) or (resp = mrNo) then exit(false);
  742. end;
  743. fileName := arc0; //asigna nuevo nombre
  744. if ExtractFileExt(fileName) = '' then begin
  745. tabSessions.PageEvent('reg_def_ext', self, res); //Pide extensión por defecto
  746. fileName := fileName + res; //Completa extensión
  747. end;
  748. //Puede haber cambiado el nombre del archivo. Actualiza texto de la lengueta.
  749. UpdateCaption(fileName);
  750. //Delegamos la función de guardar históricos a la IDE
  751. tabSessions.PageEvent('reg_reg_file', self, res);
  752. //Finalmente guarda.
  753. Result := WriteData;
  754. end;
  755. procedure TfraTabSession.LoadFromFile;
  756. {Actualiza el contenido de esta sesión a partir del archivo especificado en "fileName".}
  757. var
  758. tabSessions: TfraTabSessions;
  759. res: string;
  760. begin
  761. if not GetTabSessions(self, tabSessions) then exit;
  762. if IsTextFile then begin
  763. //Archivos de texto.
  764. UpdateCaption(fileName);
  765. //Carga contenido
  766. edPCom.Lines.LoadFromFile(fileName);
  767. //Muestra solo el panel de comandos
  768. showPCom := true;
  769. showTerm := false;
  770. PropertiesChanged;
  771. tabSessions.PageEvent('reg_reg_file', self, res);
  772. exit;
  773. end;
  774. prop.FileToProperties; //Accede a "fileName"
  775. if prop.MsjErr<>'' then begin //Accede a "fileName"
  776. MsgErr(prop.MsjErr);
  777. end;
  778. //Puede haber cambiado el nombre del archivo. Actualiza texto de la lengueta.
  779. UpdateCaption(fileName);
  780. PropertiesChanged; //Procesa el cambio de propiedades
  781. edTerm.CaretY := edTerm.Lines.Count; //Cursor en la línea final.
  782. edTerm.CaretX := length(edTerm.Lines[edTerm.Lines.Count-1])+1; //En la columna final.
  783. //Delegamos la función de guardar históricos a la IDE
  784. tabSessions.PageEvent('reg_reg_file', self, res);
  785. end;
  786. //Campos para manejo del registro
  787. function TfraTabSession.StartLog(logName0: string): boolean;
  788. {Inicia el registro de la salida.
  789. Si encuentra errorm devuelve FALSE.}
  790. begin
  791. if logState = logRunning then exit; //verifica
  792. logName := logName0; //actualiza nombre de archivo
  793. try
  794. AssignFile(logFile, logName);
  795. Rewrite(logFile);
  796. logState:=logRunning;
  797. exit(true);
  798. except
  799. logState:=logStopped;
  800. exit(false);
  801. end;
  802. end;
  803. procedure TfraTabSession.PauseLog;
  804. {Pausa el registro del terminal.}
  805. begin
  806. if logState = logRunning then
  807. logState := logPaused;
  808. end;
  809. procedure TfraTabSession.StartLog;
  810. {Reinicia el registro, después de haber sido pausado.}
  811. begin
  812. if logState = logPaused then
  813. logState := logRunning;
  814. end;
  815. procedure TfraTabSession.EndLog;
  816. begin
  817. if logState=logStopped then
  818. exit;
  819. //Está abierto. Se debe cerrar.
  820. if proc.LastLine<>'' then begin
  821. //La última línea, siempre debe escribirse
  822. WriteLog(proc.LastLine);
  823. end;
  824. CloseFile(logFile);
  825. logState := logStopped;
  826. end;
  827. function TfraTabSession.WriteLog(txt: string): boolean;
  828. {Escribe una línea de texto en el registro. SI se genera error devuelve FALSE.}
  829. begin
  830. if logState <> logRunning then exit(true);
  831. try
  832. write(logFile, txt);
  833. exit(true);
  834. except
  835. exit(false);
  836. end;
  837. end;
  838. function TfraTabSession.queryClose: boolean;
  839. {Consulta si se puede cerrar esta ventana. De ser así se devolverá TRUE.}
  840. var
  841. rpta: Byte;
  842. resp: TModalResult;
  843. begin
  844. //Verificación del estado del proceso.
  845. if proc.state <> ECO_STOPPED then begin
  846. rpta := MsgYesNoCancel('There is an opened connection. ¿Close?');
  847. if rpta in [2,3] then begin //cancelar
  848. exit(false); //sale
  849. end;
  850. if rpta = 1 then begin //detener primero
  851. AcTerDesconExecute(nil);
  852. end;
  853. end;
  854. //Verificación del texto grabado
  855. if edPCom.Modified then begin
  856. resp := MessageDlg('', Format(MSG_MODIFSAV, [ExtractFileName(fileName)]),
  857. mtConfirmation, [mbYes, mbNo, mbCancel],0);
  858. if resp = mrCancel then begin
  859. exit(false);
  860. end;
  861. if resp = mrYes then begin //guardar
  862. if not SaveToFile then exit(false);
  863. end;
  864. end;
  865. exit(true);
  866. end;
  867. procedure TfraTabSession.DistribuirPantalla;
  868. //Redistribuye los paneles de la pantalla
  869. begin
  870. // //primero quita alineamiento de componentes móviles
  871. // PAnel2.Align:=alNone;
  872. // Panel1.Align:=alNone;
  873. // Splitter1.Align:=alNone;
  874. // //alinea de acuerdo a TipAlineam
  875. // case Config.TipAlineam of
  876. // 0: begin //panel a la izquierda
  877. // Panel1.Align:=alLeft;
  878. // Splitter1.Align:=alLeft;
  879. // Panel2.Align:=alClient;
  880. // if Panel1.Width > Trunc(0.9*self.Width) then Panel1.Width := Trunc(0.5*self.Width);
  881. // end;
  882. // 1: begin //panel a la derecha
  883. // Panel1.Align:=alRight;
  884. // Splitter1.Align:=alRight;
  885. // PAnel2.Align:=alClient;
  886. // if Panel1.Width > Trunc(0.9*self.Width) then Panel1.Width := Trunc(0.5*self.Width);
  887. // end;
  888. // 2: begin //panel abajo
  889. // Panel1.Align:=alBottom;
  890. // Splitter1.Align:=alBottom;
  891. // PAnel2.Align:=alClient;
  892. // if Panel1.Height > Trunc(0.9*self.Height) then Panel1.Height := Trunc(0.5*self.Height);
  893. // end;
  894. // else //por defecto
  895. // Panel1.Align:=alLeft;
  896. // Splitter1.Align:=alLeft;
  897. // PAnel2.Align:=alClient;
  898. // end;
  899. end;
  900. procedure TfraTabSession.UpdateActionsState(Sender: TObject);
  901. begin
  902. if edPCom.Modified then begin
  903. AcFilSavSes.Enabled := true;
  904. end else begin
  905. AcFilSavSes.Enabled := false;
  906. end;
  907. end;
  908. function TfraTabSession.ShowProperties: TModalResult;
  909. begin
  910. prop.PropertiesToWindow; //Actualiza formulario
  911. //LLama a los métodos apropiados para actualizar estado de los controles.
  912. frmSesProperty.chkMarLinActChange(self);
  913. frmSesProperty.chkVerPanVerChange(self);
  914. frmSesProperty.chkSendRecComChange(self);
  915. frmSesProperty.chkDetecPromptChange(self);
  916. //Ejecuta ventana de propiedades.
  917. frmSesProperty.Exec(proc.State<>ECO_STOPPED);
  918. //Evalúa resultado
  919. case frmSesProperty.ModalResult of
  920. mrYes, mrOK: begin //Botones "Aceptar y Conectar" o "Aceptar".
  921. //Aplica cambios.
  922. prop.WindowToProperties;
  923. if prop.MsjErr<>'' then begin
  924. msgerr(prop.MsjErr);
  925. exit;
  926. end;
  927. //Guarda para tener actualizado los archivos de sintaxis.
  928. frmSesProperty.fraCfgSyntax.SaveChanges;
  929. PropertiesChanged; //Procesa el cambio de propiedades
  930. //fcConex.GrabarIP; //Debería grabar las últimas IP
  931. end;
  932. mrCancel: begin //Cancelar
  933. //MsgBox('mrCancel');
  934. end;
  935. else //No debería pasar.
  936. MsgBox('Unknown option');
  937. end;
  938. Result := frmSesProperty.ModalResult;
  939. end;
  940. function TfraTabSession.ConexDisponible: boolean;
  941. //Indica si la conexión está en estado ECO_READY, es decir, que puede
  942. //recibir un comando
  943. begin
  944. Result := (proc.state = ECO_READY);
  945. end;
  946. function TfraTabSession.BuscaUltPrompt: integer;
  947. //Busca el último prompt de todo el terminal
  948. //Si no lo encuentra devuelve -1
  949. var
  950. cy: Integer;
  951. begin
  952. cy := edterm.Lines.Count+1;
  953. repeat
  954. dec(cy)
  955. until (cy<1) or (ContienePrompt(edTerm.Lines[cy-1])>0);
  956. if cy<1 then exit(-1) else exit(cy);
  957. end;
  958. function TfraTabSession.EnviarComando(com: string; var salida: TStringList): string;
  959. {Función para enviar un comando por el Terminal. Espera hasta que aparezca de
  960. nuevo el "prompt" y devuelve el texto generado, por el comando, en "salida".
  961. Si hay error devuelve el mensaje de error.}
  962. var
  963. n: Integer;
  964. y1: Integer;
  965. y2: Integer;
  966. i: Integer;
  967. begin
  968. Result := '';
  969. if not ConexDisponible then begin
  970. Result := 'Not available connection.';
  971. MsgExc(Result);
  972. exit;
  973. end;
  974. // if config.fcDetPrompt then begin
  975. // msgExc('Para ejecutar comandos se debe tener la detección de prompt configurada');
  976. // end;
  977. ejecCom := true; //marca estado
  978. LlegoPrompt := False;
  979. salida.Clear; //por defecto limpia la lista
  980. //debugln('Inicio envío comando: '+ com);
  981. proc.SendLn(com);
  982. //debugln('Fin envío comando: '+ com);
  983. //Espera hasta la aparición del "prompt"
  984. n := 0;
  985. While Not LlegoPrompt And (n < Config.TpoMax2*10) do begin
  986. Sleep(100);
  987. Application.ProcessMessages;
  988. Inc(n);
  989. end;
  990. If n >= Config.TpoMax2*10 then begin //Hubo desborde
  991. Result := dic('Timeout');
  992. MsgExc(Result);
  993. exit;
  994. end else begin
  995. //llegó el promt (normalmente es por que hay datos)
  996. y2 := BuscaUltPrompt; //por si el cursor estaba fuera de foco
  997. //debugln('Fin comando con prompt en: '+ IntToStr(y2));
  998. //debugln('');
  999. edTerm.CaretY:=y2; //posiciona como ayuda para ver si lo hizo bien
  1000. y1 := BuscaPromptArr; //busca al prompt anterior
  1001. if y1 = -1 then begin
  1002. Result := 'Error detecting command prompt. ' +
  1003. 'Maybe you must increase the number of lines shown in the screen.';
  1004. MsgExc(Result);
  1005. exit;
  1006. end;
  1007. //copia la salida
  1008. for i:= y1+1 to y2-1 do //sin contar los prompt
  1009. salida.Add(edTerm.Lines[i-1]);
  1010. end;
  1011. ejecCom := false;
  1012. end;
  1013. function TfraTabSession.BuscaPromptArr: integer;
  1014. //Busca el primer prompt desde la posición actual hacia arriba
  1015. //Si no lo encuentra devuelve -1
  1016. var
  1017. cy: Integer;
  1018. begin
  1019. cy := edterm.CaretY;
  1020. repeat
  1021. dec(cy)
  1022. until (cy<1) or (ContienePrompt(edTerm.Lines[cy-1])>0);
  1023. if cy<1 then exit(-1) else exit(cy);
  1024. end;
  1025. function TfraTabSession.BuscaPromptAba: integer;
  1026. //Busca el primer prompt desde la posición actual hacia abajo
  1027. //Si no lo encuentra devuelve -1
  1028. var
  1029. cy: Integer;
  1030. begin
  1031. cy := edterm.CaretY;
  1032. repeat
  1033. inc(cy)
  1034. until (cy>edTerm.Lines.Count) or (ContienePrompt(edTerm.Lines[cy-1])>0);
  1035. if cy>edTerm.Lines.Count then exit(-1) else exit(cy);
  1036. end;
  1037. procedure TfraTabSession.edPComKeyDown(Sender: TObject; var Key: Word;
  1038. Shift: TShiftState);
  1039. var
  1040. Enter: Boolean;
  1041. begin
  1042. Enter := (key = VK_RETURN);
  1043. //Verificaciones
  1044. if (Shift = []) and Enter and SendLnEnter then begin
  1045. //Envíará línea actual
  1046. Key := 0;
  1047. end else if (Shift = [ssCtrl]) and Enter and SendLnCtrEnter then begin
  1048. //Envíará línea actual
  1049. Key := 0;
  1050. end else if (Shift = [ssCtrl]) and Enter and not SendLnCtrEnter then begin
  1051. Key := 0;
  1052. end;
  1053. end;
  1054. procedure TfraTabSession.ePComMenLangSelected(langName, xmlFile: string);
  1055. {Se ha seleccionado un lenguaje para el resaltador, usando el menú contextual.}
  1056. begin
  1057. langFile := ExtractFileName(xmlFile);
  1058. end;
  1059. procedure TfraTabSession.eScript_MouseDown(Sender: TObject;
  1060. Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  1061. var
  1062. caret: TPoint;
  1063. begin
  1064. //Obtiene coordenada donde cae el puntero del mouse.
  1065. if edPCom.SelAvail then begin
  1066. PopupMenu1.PopUp;
  1067. end else begin
  1068. if (Button = mbRight) then begin
  1069. caret := edPCom.PixelsToRowColumn(Point(X,Y));
  1070. edPCom.CaretY := caret.y;
  1071. //MsgBox('Eureka %d', [ caret.Y ] );
  1072. PopupMenu1.PopUp;
  1073. end;
  1074. end;
  1075. end;
  1076. procedure TfraTabSession.TestRecurringCommand;
  1077. begin
  1078. //guarda estado actual, para no perderlo
  1079. tipEnvio0 := tipEnvio;
  1080. Comando0 := Comando;
  1081. Archivo0 := Archivo;
  1082. prop.WindowToProperties; //mueve valores de controles a variables
  1083. //lama al evento para probar la temporización
  1084. EnvioTemporizado;
  1085. //Retorna valores
  1086. tipEnvio := tipEnvio0;
  1087. Comando := Comando0;
  1088. Archivo := Archivo0;
  1089. end;
  1090. procedure TfraTabSession.EnvioTemporizado;
  1091. //Envía el comando o archivo que se ha programado
  1092. begin
  1093. case tipEnvio of
  1094. teComando:
  1095. proc.SendLn(Comando);
  1096. teArchivo: begin
  1097. if not FileExists(archivo) then begin
  1098. MsgErr('File not found: %s', [archivo]);
  1099. exit;
  1100. end;
  1101. proc.SendLn(StringFromFile(archivo));
  1102. end;
  1103. end;
  1104. end;
  1105. procedure TfraTabSession.Timer1Timer(Sender: TObject);
  1106. {Temporizador cada de 0.5 segundos. Temporiza el envío de comandos recurrentes y
  1107. el parpadeo del Panel de Información de la conexión.}
  1108. begin
  1109. //Muestra mensaje de ejecución
  1110. // if ejecMac then begin
  1111. // //fuerza refresco del panel
  1112. // parpadPan0 := not parpadPan0; //para el parpadeo
  1113. // StatusBar1.InvalidatePanel(0,[ppText]);
  1114. // end;
  1115. if Activar then begin
  1116. inc(ticComRec);
  1117. if ticComRec mod (Tempo * 2 * 60) = 0 then begin
  1118. //hay envío recurrente de comando
  1119. EnvioTemporizado;
  1120. end;
  1121. end;
  1122. end;
  1123. procedure TfraTabSession.UpdateCommand;
  1124. //Configura el atributo "Command" de acuerdo a los parámetros de la conexión.
  1125. begin
  1126. case Tipo of
  1127. TCON_TELNET: begin
  1128. if Port='' then begin
  1129. Command:='plink -telnet ' + IP;
  1130. end else begin
  1131. Command:='plink -telnet ' + ' -P '+ Port + ' ' + IP;
  1132. end;
  1133. end;
  1134. TCON_SSH: begin
  1135. if Port='' then begin
  1136. Command:='plink -ssh ' + IP + ' ';
  1137. end else begin
  1138. Command:='plink -ssh -P '+ Port + ' ' + IP + ' ';
  1139. end;
  1140. end;
  1141. TCON_SERIAL: begin
  1142. Command:='plink -serial ' + frmSesProperty.cmbSerPort.Text + ' -sercfg '+frmSesProperty.txtSerCfg.Text;
  1143. end;
  1144. TCON_OTHER: begin
  1145. Command:=Other;
  1146. end;
  1147. end;
  1148. //Configura salto de línea
  1149. { TODO : ¿No se podría mejor eliminar LineDelimSend y LineDelimRecv; y usar "proc"? }
  1150. proc.LineDelimSend := LineDelimSend;
  1151. proc.LineDelimRecv := LineDelimRecv;
  1152. end;
  1153. procedure TfraTabSession.UpdatePromptProc;
  1154. {Configura al resaltador con la detección de prompt de la sesión. Se supone que se
  1155. debe llamar, cada vez que se cambia algún parámetro de la detección del prompt.}
  1156. begin
  1157. //Configura detección de prompt en proceso
  1158. if DetecPrompt then begin //hay detección
  1159. proc.detecPrompt:=true;
  1160. proc.promptIni:= prIni;
  1161. proc.promptFin:= prFin;
  1162. proc.promptMatch := TipDetec;
  1163. end else begin //sin detección
  1164. proc.detecPrompt:=false;
  1165. end;
  1166. {Actualizar terminal para redibujar contenido con el resaltador "hlTerm" que ahora
  1167. tiene sus parámetros cambiados (accesibles mediante hlTerm.curSesObj). }
  1168. edTerm.Invalidate;
  1169. end;
  1170. function TfraTabSession.ContienePrompt(const linAct: string): integer;
  1171. //Verifica si una cadena contiene al prompt, usando los valroes de cadena inicial (prIni)
  1172. //y cadena final (prFin). La veriifcaión se hace siempre desde el inicio de la cadena.
  1173. //Si la cadena contiene al prompt, devuelve la longitud del prompt hallado, de otra forma
  1174. //devuelve cero.
  1175. //Se usa para el resaltador de sintaxis y el manejo de pantalla. Debería ser similar a
  1176. //la detección de prompt usada en el proceso.
  1177. var
  1178. l: Integer;
  1179. p: SizeInt;
  1180. begin
  1181. Result := 0; //valor por defecto
  1182. l := length(prIni);
  1183. if (l>0) and (copy(linAct,1,l) = prIni) then begin
  1184. //puede ser
  1185. if prFin = '' then begin
  1186. //no hace falta validar más
  1187. Result := l; //el tamaño del prompt
  1188. exit; //no hace falta explorar más
  1189. end;
  1190. //hay que validar la existencia del fin del prompt
  1191. p :=pos(prFin,linAct);
  1192. if p>0 then begin //encontró
  1193. Result := p+length(prFin)-1; //el tamaño del prompt
  1194. exit;
  1195. end;
  1196. end;
  1197. end;
  1198. function TfraTabSession.EsPrompt(const cad: string): boolean;
  1199. //Indica si la línea dada, es el prompt, de acuerdo a los parámetros dados. Esta función
  1200. //se pone aquí, porque aquí se tiene fácil acceso a las configuraciones del prompt.
  1201. var
  1202. n: Integer;
  1203. begin
  1204. if DetecPrompt then begin //si hay detección activa
  1205. n := ContienePrompt(cad);
  1206. Result := (n>0) and (n = length(cad));
  1207. end else begin
  1208. Result := false;
  1209. end;
  1210. end;
  1211. //Inicialización
  1212. procedure TfraTabSession.InicConect;
  1213. begin
  1214. //Se supone que el proceso ya está configurado y listo para abrir
  1215. UpdateCommand; //Actualiza "Command".
  1216. UpdatePanInfoConn; //Actualiza información de la conexión.
  1217. //Inicia proceso
  1218. proc.Open(Command, '');
  1219. if msjError<>'' then begin
  1220. MsgErr(msjError);
  1221. end;
  1222. end;
  1223. constructor TfraTabSession.Create(AOwner: TComponent);
  1224. var
  1225. fSynchro: TSynPluginSyncroEdit;
  1226. fMultiCaret: TSynPluginMultiCaret;
  1227. begin
  1228. inherited Create(AOwner);
  1229. textPCom := edPCom.Lines; //Toma referencia al texto, para guardar.
  1230. textTerm := edTerm.Lines; //Toma referencia al texto, para guardar.
  1231. InicEditorC1(edPCom);
  1232. edPCom.Options := edPCom.Options + [eoRightMouseMovesCursor]; //Para fijar el cursor con click derecho
  1233. //Fija imágenes para marcadores
  1234. edPCom.BookMarkOptions.BookmarkImages := imgBookMarks;
  1235. //Crea un "plugin" de edición síncrona
  1236. fSynchro := TSynPluginSyncroEdit.Create(self);
  1237. fSynchro.Editor := edPCom;
  1238. //Configura múltiples cursores
  1239. fMultiCaret := TSynPluginMultiCaret.Create(self);
  1240. with fMultiCaret do begin
  1241. Editor := edPCom;
  1242. with KeyStrokes do begin
  1243. Add.Command := ecPluginMultiCaretSetCaret;
  1244. Add.Key := VK_INSERT;
  1245. Add.Shift := [ssShift, ssCtrl];
  1246. Add.ShiftMask := [ssShift,ssCtrl,ssAlt];
  1247. // Add.Command := ecPluginMultiCaretUnsetCaret;
  1248. // Add.Key := VK_DELETE;
  1249. // Add.Shift := [ssShift, ssCtrl];
  1250. // Add.ShiftMask := [ssShift,ssCtrl,ssAlt];
  1251. end;
  1252. end;
  1253. // edPCom.OnSpecialLineMarkup:=@edSpecialLineMarkup;
  1254. ePCom := TSynFacilEditor.Create(edPCom,'Noname','sh'); //Crea Editor
  1255. //ConnectToGUI; Won't work now
  1256. // ePCom.OnChangeEditorState := @ChangeEditorState; //Se debe hacer con ConnectToGUI()
  1257. ePCom.OnEditChange := @UpdateActionsState;
  1258. ePCom.OnKeyUp := @edPComKeyUp;
  1259. ePCom.OnKeyDown := @edPComKeyDown;
  1260. ePCom.OnMouseDown := @eScript_MouseDown;
  1261. ePCom.NewFile; //Pone en modo "NewFile", para actualizar estado inicial.
  1262. ePCom.InitMenuLanguages(mnPopLeng, patSyntax); //Inicia menú de lenguajes para el resaltador
  1263. ePCom.OnMenLangSelected := @ePComMenLangSelected; //Controla la selección del lenguaje.
  1264. //COnfiguración de pantalla de terminal
  1265. hlTerm := TResaltTerm.Create(nil); //Crea resaltador
  1266. hlTerm.curSesObj := self; //Fija referencia a esta sesión
  1267. InicTerminal(edTerm, hlTerm);
  1268. tabWidth := 30; //valor por defecto
  1269. //Inicia proceso
  1270. proc := TConsoleProc2.Create(nil); //El panel se fijará luego, cuando se conecte a la GUI.
  1271. proc.OnInitScreen := @proc_InitScreen;
  1272. proc.OnRefreshLine := @proc_RefreshLine;
  1273. proc.OnRefreshLines := @proc_RefreshLines;
  1274. proc.OnAddLine := @proc_AddLine;
  1275. proc.OnGetPrompt := @proc_LlegoPrompt;
  1276. proc.OnChangeState := @proc_ChangeState;
  1277. proc.OnLineCompleted:= @proc_LineCompleted;
  1278. //Usado para el registro
  1279. AcTerDescon.Enabled:=false; //Se supone que inicia siempre sin conectar.
  1280. end;
  1281. procedure TfraTabSession.ConfigEditor(ed: TSynEdit; cfgEdit: TEditCfg);
  1282. {Configura el editor con las propiedades almacenadas}
  1283. var
  1284. marc: TSynEditMarkup;
  1285. begin
  1286. if ed = nil then exit; //protección
  1287. //tipo de texto
  1288. if cfgEdit.FontName <> '' then ed.Font.Name := cfgEdit.FontName; //El texto sin atributo
  1289. if (cfgEdit.FontSize > 6) and (cfgEdit.FontSize < 32) then ed.Font.Size:=Round(cfgEdit.FontSize);
  1290. ed.Font.Color := cfgEdit.cTxtNor; //color de texto normal
  1291. ed.Color:= cfgEdit.cFonEdi; //color de fondo
  1292. if cfgEdit.MarLinAct then //resaltado de línea actual
  1293. ed.LineHighlightColor.Background:=cfgEdit.cLinAct
  1294. else
  1295. ed.LineHighlightColor.Background:=clNone;
  1296. //configura panel vertical
  1297. ed.Gutter.Visible:=cfgEdit.VerPanVer; //muestra panel vertical
  1298. ed.Gutter.Parts[1].Visible:=cfgEdit.VerNumLin; //Número de línea
  1299. if ed.Gutter.Parts.Count>4 then
  1300. ed.Gutter.Parts[4].Visible:=cfgEdit.VerMarPle; //marcas de plegado
  1301. ed.Gutter.Color:=cfgEdit.cFonPan; //color de fondo del panel
  1302. ed.Gutter.Parts[1].MarkupInfo.Background:=cfgEdit.cFonPan; //fondo del núemro de línea
  1303. ed.Gutter.Parts[1].MarkupInfo.Foreground:=cfgEdit.cTxtPan; //texto del núemro de línea
  1304. if cfgEdit.VerBarDesV and cfgEdit.VerBarDesH then //barras de desplazamiento
  1305. ed.ScrollBars:= ssBoth
  1306. else if cfgEdit.VerBarDesV and not cfgEdit.VerBarDesH then
  1307. ed.ScrollBars:= ssVertical
  1308. else if not cfgEdit.VerBarDesV and cfgEdit.VerBarDesH then
  1309. ed.ScrollBars:= ssHorizontal
  1310. else
  1311. ed.ScrollBars := ssNone;
  1312. ////////Configura el resaltado de la palabra actual //////////
  1313. marc := ed.MarkupByClass[TSynEditMarkupHighlightAllCaret];
  1314. if marc<>nil then begin //hay marcador
  1315. marc.Enabled := cfgEdit.ResPalCur; //configura
  1316. marc.MarkupInfo.Background := cfgEdit.cResPal;
  1317. end;
  1318. ///////fija color de delimitadores () {} [] ///////////
  1319. ed.BracketMatchColor.Foreground := clRed;
  1320. end;
  1321. procedure TfraTabSession.Init;
  1322. {Rutina que debe ser llamada para terminar la inicialización, después de la creación
  1323. del Frame. Debe llamarse solo una vez.
  1324. Se mantiene separada del constructor, porque depende de que el frame, tenga
  1325. un nombre ya asignado ("fileName" o "Caption" actualizado).}
  1326. var
  1327. f: TfrmSesProperty;
  1328. tmp: String;
  1329. begin
  1330. {Crea archivo XML de configuración aquí, porque recién aquí se tiene el nombre del
  1331. "Caption" (usado en la lengueta) y a partir de allí podemos generar un nombre del
  1332. archivo para este frame.}
  1333. prop := TMiConfigXML.Create(self.Caption); //"prop.GetFileName() será el nombre inicial del archivo.
  1334. f := frmSesProperty;
  1335. //Parámetros de conexión
  1336. prop.Asoc_Enum('tipo' , @Tipo , SizeOf(TTipCon), [f.optTelnet,f.optSSH,f.optSerial,f.optOtro], 1);
  1337. prop.Asoc_Str ('ip' , @IP , f.cmbIP , '127.0.0.1');
  1338. prop.Asoc_Str ('port' , @Port , f.txtPort , '22');
  1339. prop.Asoc_Str ('other' , @Other, f.txtOtro , '');
  1340. //prop.Asoc_StrList (@ConRecientes, 'Recient');
  1341. prop.Asoc_Enum('LineDelimSnd', @LineDelimSend, SizeOf(LineDelimSend), f.RadioGroup1, 2);
  1342. prop.Asoc_Enum('LineDelimRcv', @LineDelimRecv, SizeOf(LineDelimRecv), f.RadioGroup2, 2);
  1343. //Parámetros de detección de prompt.
  1344. prop.Asoc_Bol ('DetecPrompt' , @detecPrompt,f.chkDetecPrompt, false);
  1345. prop.Asoc_Str ('cadIni' , @prIni , f.txtCadIni, '');
  1346. prop.Asoc_Str ('cadFin' , @prFin , f.txtCadFin, '');
  1347. prop.Asoc_Enum('TipDetec' , @TipDetec , SizeOf(TipDetec),
  1348. [f.RadioButton1, f.RadioButton2 , f.RadioButton3, f.RadioButton4], 0);
  1349. //Parámetros de la pantalla del terminal.
  1350. prop.Asoc_Int ('maxLinTer' , @maxLinTer , f.txtMaxLinT, 5000, 200, MAX_LIN_TER); {menos de 200 líneas puede causar problemas con la rutina de limitación de tamaño}
  1351. prop.Asoc_Int ('maxColTer' , @maxColTer , f.txtMaxColT, 1000, 80,10000);
  1352. prop.Asoc_Bol ('interDirec' , @interDirec, f.chkInterDirec,true);
  1353. prop.Asoc_Bol ('curSigPrm' , @curSigPrm , f.chkCurSigPrmpt,true);
  1354. //Parámetros del editor del terminal
  1355. prop.Asoc_TCol('t_cTxtNor' , @cfgEdterm.cTxtNor , f.cbutTexto , clGray);
  1356. prop.Asoc_TCol('t_cFonEdi' , @cfgEdterm.cFonEdi , f.cbutBackCol , clBlack);
  1357. prop.Asoc_TCol('t_cLinAct' , @cfgEdterm.cLinAct , f.cbutLinAct , clYellow);
  1358. prop.Asoc_TCol('t_cResPal' , @cfgEdterm.cResPal , f.cbutResPal , clSkyBlue);
  1359. prop.Asoc_Bol ('t_VerBarDesV', @cfgEdterm.VerBarDesV, f.chkVerBarDesV, true);
  1360. prop.Asoc_Bol ('t_VerBarDesH', @cfgEdterm.VerBarDesH, f.chkVerBarDesH, false);
  1361. prop.Asoc_Bol ('t_ResPalCur' , @cfgEdterm.ResPalCur , f.chkHLCurWord, true);
  1362. prop.Asoc_Bol ('t_MarLinAct' , @cfgEdterm.MarLinAct , f.chkMarLinAct , false);
  1363. prop.Asoc_Bol ('t_VerPanVer' , @cfgEdterm.VerPanVer , f.chkVerPanVer , true);
  1364. prop.Asoc_Bol ('t_VerNumLin' , @cfgEdterm.VerNumLin , f.chkVerNumLin , false);
  1365. prop.Asoc_Bol ('t_VerMarPle' , @cfgEdterm.VerMarPle , f.chkVerMarPle , true);
  1366. prop.Asoc_TCol('t_cFonPan' , @cfgEdterm.cFonPan , f.cbutFonPan , clWhite);
  1367. prop.Asoc_TCol('t_cTxtPan' , @cfgEdterm.cTxtPan , f.cbutTxtPan , clBlack);
  1368. prop.Asoc_Int ('t_TamLet' , @cfgEdTerm.FontSize , f.spFontSize , 9);
  1369. prop.Asoc_Str ('t_TipLet' , @cfgEdTerm.FontName , f.cmbTipoLetra , 'Courier New');
  1370. //Parámetros de Comando recurrente
  1371. prop.Asoc_Bol ('Activar' , @Activar , f.chkSendRecCom , false);
  1372. prop.Asoc_Int ('Tempo' , @Tempo , f.speTempo , 5);
  1373. prop.Asoc_Enum('tipEnvio' , @tipEnvio , SizeOf(tipEnvio), [f.optComando, f.optScript], 0);
  1374. prop.Asoc_Str ('Comando' , @Comando , f.txtComando , '');
  1375. prop.Asoc_Str ('Archivo' , @Archivo , f.txtArchivo , '');
  1376. //Parámetros del editor de Comandos
  1377. prop.Asoc_TCol('c_cTxtNor' , @cfgEdPcom.cTxtNor , f.cbutTexto1 , clBlack);
  1378. prop.Asoc_TCol('c_cFonEdi' , @cfgEdPcom.cFonEdi , f.cbutBackCol1 , clWhite);
  1379. prop.Asoc_TCol('c_cLinAct' , @cfgEdPcom.cLinAct , f.cbutLinAct1 , clYellow);
  1380. prop.Asoc_TCol('c_cResPal' , @cfgEdPcom.cResPal , f.cbutResPal1 , clSkyBlue);
  1381. prop.Asoc_Bol ('c_VerBarDesV', @cfgEdPcom.VerBarDesV, f.chkVerBarDesV1, true);
  1382. prop.Asoc_Bol ('c_VerBarDesH', @cfgEdPcom.VerBarDesH, f.chkVerBarDesH1, false);
  1383. prop.Asoc_Bol ('c_ResPalCur' , @cfgEdPcom.ResPalCur , f.chkHLCurWord1 , true);
  1384. prop.Asoc_Bol ('c_MarLinAct' , @cfgEdPcom.MarLinAct , f.chkMarLinAct1 , true);
  1385. prop.Asoc_Bol ('c_VerPanVer' , @cfgEdPcom.VerPanVer , f.chkVerPanVer1 , true);
  1386. prop.Asoc_Bol ('c_VerNumLin' , @cfgEdPcom.VerNumLin , f.chkVerNumLin1 , false);
  1387. prop.Asoc_Bol ('c_VerMarPle' , @cfgEdPcom.VerMarPle , f.chkVerMarPle1 , true);
  1388. prop.Asoc_TCol('c_cFonPan' , @cfgEdPcom.cFonPan , f.cbutFonPan1 , clWhite);
  1389. prop.Asoc_TCol('c_cTxtPan' , @cfgEdPcom.cTxtPan , f.cbutTxtPan1 , clBlack);
  1390. prop.Asoc_Int ('c_TamLet' , @cfgEdPcom.FontSize , f.spFontSize1 , 10);
  1391. prop.Asoc_Str ('c_TipLet' , @cfgEdPcom.FontName , f.cmbTipoLetra1 , 'Courier New');
  1392. //Parámetros del panel de comandos.
  1393. prop.Asoc_Bol ('CompletCode' , @CompletCode , f.chkCompletCode , true);
  1394. prop.Asoc_Bol ('CodFolding' , @CodFolding , f.chkCodFolding , true);
  1395. prop.Asoc_Bol ('SendLnEnter' , @SendLnEnter , f.chkSendLnEnter , false);
  1396. prop.Asoc_Bol ('SendLnCtrEnter',@SendLnCtrEnter, f.chkSendLnCtrEnter, true);
  1397. prop.Asoc_Bol ('UsarPrep' , @UsarPrep , f.chkUsarPrep , false);
  1398. //Parámetros de la herramienta Editor
  1399. prop.Asoc_Str ('commandEd' , @commandEd , f.txtComLaunEdit , '$EDIT');
  1400. prop.Asoc_Enum('editMode' , @editMode , sizeOf(editMode) , f.radGroupEdtType, 0);
  1401. prop.Asoc_Str ('exterEditor' , @exterEditor , f.txtExternEdit , 'notepad');
  1402. prop.Asoc_Str ('ftpEditUser' , @ftpEditUser , f.txtEdiUser , '');
  1403. prop.Asoc_Str ('ftpEditPass' , @ftpEditPass , f.txtEdiPass , '');
  1404. //Parámetros de la herramienta Explorador
  1405. prop.Asoc_Str ('commandEx' , @commandEx , f.txtComLaunExpl , '$EXPLORER');
  1406. prop.Asoc_Enum('explorMode' , @explorMode , sizeOf(explorMode), f.radGroupExpType, 0);
  1407. prop.Asoc_Str ('exterExplor' , @exterExplor , f.txtExternExplor , 'explorer');
  1408. //Configuración del Editor-Sintaxis
  1409. f.fraCfgSyntax.LoadSyntaxFiles(patSyntax);
  1410. //Parámetros adicionales
  1411. prop.Asoc_Str ('langFile' , @langFile, '');
  1412. prop.Asoc_StrList('textPCom' , @textPCom);
  1413. // prop.Asoc_StrList('textTerm' , @textTerm);
  1414. prop.Asoc_Int('pComWidth' , @pComWidth, 300);
  1415. prop.Asoc_Bol('showPCom' , @showPCom, f.chkShowPCom, true);
  1416. prop.Asoc_Bol('showTerm' , @showTerm, f.chkShowTerm, true);
  1417. //Rutina para forzar la carga de valores por defecto de las propiedades.
  1418. tmp := fileName; //Guarda valor.
  1419. fileName := 'killme.tmp'; //Archivo temporal.
  1420. StringToFile('<?xml version="1.0" encoding="utf-8"?><CONFIG></CONFIG>', 'killme.tmp'); //Ceea archivo en blanco.
  1421. if not prop.FileToProperties then begin //FileToProperties() pondrá valores por defecto, si no encuentra la clave.
  1422. MsgErr(prop.MsjErr);
  1423. end;
  1424. fileName := tmp; //Restaura.
  1425. DeleteFile('killme.tmp'); //Limpia la casa
  1426. //Asigna evento a botón para probar comando recurrente
  1427. f.OnTest := @TestRecurringCommand;
  1428. end;
  1429. procedure TfraTabSession.Splitter1Moved(Sender: TObject);
  1430. {Se está dimensionando}
  1431. begin
  1432. pComWidth := edPCom.Width;
  1433. end;
  1434. procedure TfraTabSession.ExecSettings;
  1435. begin
  1436. //Muestra ventana de configuración de la conexión (y los demás parámetros.)
  1437. if ShowProperties = mrYes then begin
  1438. //Se dio "Aceptar y conectar". Ya tenemos los parámetros. Iniciamos la conexión.
  1439. if not (proc.state = ECO_STOPPED) then begin
  1440. MsgExc('You need to close the current connection.');
  1441. exit;
  1442. end;
  1443. InicConect;
  1444. //Marca como modificado
  1445. //setModified(true);
  1446. end;
  1447. end;
  1448. procedure TfraTabSession.InicConectTelnet(ip0: string);
  1449. begin
  1450. //configura conexión rápida Telnet
  1451. tipo := TCON_TELNET;
  1452. ip := ip0;
  1453. port := '23';
  1454. LineDelimSend := LDS_LF;
  1455. LineDelimRecv := LDR_LF;
  1456. InicConect;
  1457. //Marca como modificado
  1458. setModified(true);
  1459. end;
  1460. procedure TfraTabSession.InicConectSSH(ip0: string);
  1461. begin
  1462. //configura conexión rápida Telnet
  1463. tipo := TCON_SSH;
  1464. ip := ip0;
  1465. port := '22';
  1466. LineDelimSend := LDS_LF;
  1467. LineDelimRecv := LDR_LF;
  1468. InicConect;
  1469. //Marca como modificado
  1470. setModified(true);
  1471. end;
  1472. destructor TfraTabSession.Destroy;
  1473. begin
  1474. EndLog; //por si se estaba registrando
  1475. proc.Free;
  1476. // if prop<>nil then begin
  1477. // if FileExists(fileName) then begin
  1478. // prop.PropertiesToFile; //Save to disk
  1479. // end;
  1480. // end;
  1481. FreeAndNil(prop);
  1482. hlTerm.Destroy;
  1483. ePCom.Destroy;
  1484. inherited Destroy;
  1485. end;
  1486. procedure TfraTabSession.edPComEnter(Sender: TObject);
  1487. begin
  1488. edFocused := edPCom;
  1489. end;
  1490. procedure TfraTabSession.edTermEnter(Sender: TObject);
  1491. begin
  1492. edFocused := edTerm;
  1493. end;
  1494. procedure TfraTabSession.FindDialog1Find(Sender: TObject);
  1495. var
  1496. encon : integer;
  1497. buscado : string;
  1498. opciones: TSynSearchOptions;
  1499. curEdit: TSynEdit;
  1500. begin
  1501. //Busca el último editor que tuvo el enfoque.
  1502. if edFocused = nil then begin
  1503. exit;
  1504. end else begin
  1505. curEdit := edFocused;
  1506. end;
  1507. buscado := FindDialog1.FindText;
  1508. opciones := [];
  1509. if not(frDown in FindDialog1.Options) then opciones += [ssoBackwards];
  1510. if frMatchCase in FindDialog1.Options then opciones += [ssoMatchCase];
  1511. if frWholeWord in FindDialog1.Options then opciones += [ssoWholeWord];
  1512. if frEntireScope in FindDialog1.Options then opciones += [ssoEntireScope];
  1513. encon := curEdit.SearchReplace(buscado,'',opciones);
  1514. if encon = 0 then
  1515. MsgBox('Not found "%s"', [buscado]);
  1516. end;
  1517. procedure TfraTabSession.ReplaceDialog1Replace(Sender: TObject);
  1518. var
  1519. encon, r : integer;
  1520. buscado : string;
  1521. opciones: TSynSearchOptions;
  1522. curEdit: TSynEdit;
  1523. begin
  1524. //Busca el último editor que tuvo el enfoque.
  1525. if edFocused = nil then begin
  1526. exit;
  1527. end else begin
  1528. curEdit := edFocused;
  1529. end;
  1530. buscado := ReplaceDialog1.FindText;
  1531. opciones := [ssoFindContinue];
  1532. if not(frDown in ReplaceDialog1.Options) then opciones += [ssoBackwards];
  1533. if frMatchCase in ReplaceDialog1.Options then opciones += [ssoMatchCase];
  1534. if frWholeWord in ReplaceDialog1.Options then opciones += [ssoWholeWord];
  1535. if frEntireScope in ReplaceDialog1.Options then opciones += [ssoEntireScope];
  1536. if frReplaceAll in ReplaceDialog1.Options then begin
  1537. //se ha pedido reemplazar todo
  1538. encon := curEdit.SearchReplace(buscado,ReplaceDialog1.ReplaceText,
  1539. opciones+[ssoReplaceAll]); //reemplaza
  1540. MsgBox('%d words replaced', [IntToStr(encon)]);
  1541. exit;
  1542. end;
  1543. //reemplazo con confirmación
  1544. ReplaceDialog1.CloseDialog;
  1545. encon := curEdit.SearchReplace(buscado,'',opciones); //búsqueda
  1546. while encon <> 0 do begin
  1547. //pregunta
  1548. r := Application.MessageBox(pChar('Replace this?'), '', MB_YESNOCANCEL);
  1549. if r = IDCANCEL then exit;
  1550. if r = IDYES then begin
  1551. curEdit.TextBetweenPoints[curEdit.BlockBegin,curEdit.BlockEnd] := ReplaceDialog1.ReplaceText;
  1552. end;
  1553. //busca siguiente
  1554. encon := curEdit.SearchReplace(buscado,'',opciones); //búsca siguiente
  1555. end;
  1556. MsgBox('No found "%s"', [buscado]);
  1557. end;
  1558. //////////////// Acciones ///////////////////
  1559. //Acciones de archivo.
  1560. procedure TfraTabSession.AcFilStarLogExecute(Sender: TObject);
  1561. var
  1562. arc0: TComponentName;
  1563. begin
  1564. if logName='' then begin
  1565. SaveDialog2.Filter := dic('Log file|*.log|All files|*.*');
  1566. SaveDialog2.InitialDir:=patApp; //busca aquí por defecto
  1567. if not SaveDialog2.Execute then begin //se canceló
  1568. exit; //se canceló
  1569. end;
  1570. arc0:=SaveDialog2.FileName;
  1571. if FileExists(arc0) then begin
  1572. if MsgYesNoCancel('File %s already exists.' + LineEnding + '¿Overwrite?',
  1573. [arc0]) in [2,3] then exit;
  1574. end;
  1575. end;
  1576. logName := arc0;
  1577. if not StartLog(logName) then begin
  1578. MsgErr('Error opening log: ' + logName);
  1579. end;
  1580. end;
  1581. procedure TfraTabSession.AcFilSavSesExecute(Sender: TObject);
  1582. begin
  1583. SaveToFile;
  1584. end;
  1585. procedure TfraTabSession.AcFilSavSesAsExecute(Sender: TObject);
  1586. begin
  1587. SaveAsDialog;
  1588. end;
  1589. procedure TfraTabSession.AcFilStopLogExecute(Sender: TObject);
  1590. begin
  1591. EndLog;
  1592. end;
  1593. procedure TfraTabSession.acFindFindExecute(Sender: TObject);
  1594. begin
  1595. FindDialog1.Execute;
  1596. end;
  1597. procedure TfraTabSession.acFindNextExecute(Sender: TObject);
  1598. begin
  1599. FindDialog1Find(self);
  1600. end;
  1601. procedure TfraTabSession.acFindPrevExecute(Sender: TObject);
  1602. begin
  1603. if frDown in FindDialog1.Options then begin
  1604. FindDialog1.Options := FindDialog1.Options - [frDown]; //Quita
  1605. FindDialog1Find(self);
  1606. FindDialog1.Options := FindDialog1.Options + [frDown]; //Restaura
  1607. end else begin
  1608. FindDialog1Find(self);
  1609. end;
  1610. end;
  1611. procedure TfraTabSession.acFindReplaceExecute(Sender: TObject);
  1612. begin
  1613. ReplaceDialog1.Execute;
  1614. end;
  1615. //Acciones del Panel de comando.
  1616. procedure TfraTabSession.AcPCmEnvLinExecute(Sender: TObject);
  1617. var
  1618. lin: String;
  1619. begin
  1620. if proc = nil then exit;
  1621. if edPCom.SelAvail then begin //hay selección
  1622. //Envía texto seleccionado
  1623. EnviarTxt(edPCom.SelText);
  1624. end else begin //no hay selección, envía la línea actual
  1625. lin := edPCom.LineText; //línea actual
  1626. EnviarTxt(lin);
  1627. end;
  1628. end;
  1629. procedure TfraTabSession.AcPCmEnvTodExecute(Sender: TObject);
  1630. //Envía todo el texto.
  1631. begin
  1632. if proc = nil then exit ;
  1633. if edPCom.SelAvail then begin
  1634. //hay selección
  1635. frmSelFuente.optSel.Checked := true;
  1636. frmSelFuente.optLin.Enabled := false;
  1637. frmSelFuente.ShowModal;
  1638. If frmSelFuente.cancelado Then Exit; //cancelado
  1639. //se eligió
  1640. If frmSelFuente.optTod.Checked Then begin //todo
  1641. EnviarTxt(edPCom.Text);
  1642. end else if frmSelFuente.optSel.Checked Then begin //selección
  1643. EnviarTxt(edPCom.SelText);
  1644. end Else begin //solo la línea actual
  1645. EnviarTxt(edPCom.LineText);
  1646. End;
  1647. end else begin
  1648. //No hay selección, envía todo
  1649. if MsgYesNoCancel('Send all the content of the editor?')<>1 then begin
  1650. exit;
  1651. end;
  1652. EnviarTxt(edPCom.Text);
  1653. end;
  1654. end;
  1655. procedure TfraTabSession.acPCmEnvCtrCExecute(Sender: TObject);
  1656. begin
  1657. proc.Send(#3);
  1658. end;
  1659. procedure TfraTabSession.AcTerConecExecute(Sender: TObject);
  1660. begin
  1661. InicConect; //inicia conexión
  1662. end;
  1663. procedure TfraTabSession.AcTerDesconExecute(Sender: TObject); //desconectar
  1664. begin
  1665. if not proc.Close then
  1666. msgerr('Cannot clos the current process.');
  1667. end;
  1668. procedure TfraTabSession.AcTerCopPalExecute(Sender: TObject);
  1669. const CARS = ['a'..'z','A'..'Z','0'..'9','_','-'];
  1670. var
  1671. p, q: Integer;
  1672. linAct: String;
  1673. CurX: Integer;
  1674. begin
  1675. CurX := edTerm.CaretX;
  1676. linAct := edTerm.LineText;
  1677. p := CurX; if p>length(linact) then exit;
  1678. while (p>1) and (linAct[p] in CARS) do
  1679. dec(p);
  1680. if not (linAct[p] in CARS) then inc(p); //corrige
  1681. q := CurX;
  1682. while (q<=length(linAct)) and (linAct[q] in CARS) do
  1683. inc(q);
  1684. edTerm.BlockBegin:=Point(p,edTerm.CaretY);
  1685. edTerm.BlockEnd :=Point(q,edTerm.CaretY);
  1686. edTerm.CopyToClipboard;
  1687. end;
  1688. procedure TfraTabSession.AcTerCopNomExecute(Sender: TObject); //copia nombre
  1689. const CARS = ['a'..'z','A'..'Z','0'..'9','-','_','.'];
  1690. var
  1691. p, q: Integer;
  1692. linAct: String;
  1693. CurX: Integer;
  1694. begin
  1695. CurX := edTerm.CaretX;
  1696. linAct := edTerm.LineText;
  1697. p := CurX; if p>length(linact) then exit;
  1698. while (p>1) and (linAct[p] in CARS) do
  1699. dec(p);
  1700. if not (linAct[p] in CARS) then inc(p); //corrige
  1701. q := CurX;
  1702. while (q<=length(linAct)) and (linAct[q] in CARS) do
  1703. inc(q);
  1704. edTerm.BlockBegin:=Point(p,edTerm.CaretY);
  1705. edTerm.BlockEnd :=Point(q,edTerm.CaretY);
  1706. edTerm.CopyToClipboard;
  1707. end;
  1708. procedure TfraTabSession.AcTerCopRutExecute(Sender: TObject); //copia ruta
  1709. const CARS = ['a'..'z','A'..'Z','0'..'9','-','_','\','/','.'];
  1710. var
  1711. p, q: Integer;
  1712. linAct: String;
  1713. CurX: Integer;
  1714. begin
  1715. CurX := edTerm.CaretX;
  1716. linAct := edTerm.LineText;
  1717. p := CurX; if p>length(linact) then exit;
  1718. while (p>1) and (linAct[p] in CARS) do
  1719. dec(p);
  1720. if not (linAct[p] in CARS) then inc(p); //corrige
  1721. q := CurX;
  1722. while (q<=length(linAct)) and (linAct[q] in CARS) do
  1723. inc(q);
  1724. edTerm.BlockBegin:=Point(p,edTerm.CaretY);
  1725. edTerm.BlockEnd :=Point(q,edTerm.CaretY);
  1726. edTerm.CopyToClipboard;
  1727. end;
  1728. procedure TfraTabSession.AcTerCopNomRutExecute(Sender: TObject); //copia ruta y nombre
  1729. const CARS = ['a'..'z','A'..'Z','0'..'9','-','_','\','/','.'];
  1730. var
  1731. p, q: Integer;
  1732. linAct: String;
  1733. CurX: Integer;
  1734. begin
  1735. CurX := edTerm.CaretX;
  1736. linAct := edTerm.LineText;
  1737. p := CurX; if p>length(linact) then exit;
  1738. while (p>1) and (linAct[p] in CARS) do
  1739. dec(p);
  1740. if not (linAct[p] in CARS) then inc(p); //corrige
  1741. q := CurX;
  1742. while (q<=length(linAct)) and (linAct[q] in CARS) do
  1743. inc(q);
  1744. edTerm.BlockBegin:=Point(p,edTerm.CaretY);
  1745. edTerm.BlockEnd :=Point(q,edTerm.CaretY);
  1746. edTerm.CopyToClipboard;
  1747. end;
  1748. procedure TfraTabSession.AcTerDetPrmExecute(Sender: TObject); //Detecta prompt
  1749. begin
  1750. proc.AutoConfigPrompt; //auto-detección
  1751. DetecPrompt := proc.detecPrompt;
  1752. prIni := proc.promptIni;
  1753. prFin := proc.promptFin;
  1754. TipDetec := proc.promptMatch;
  1755. edTerm.Invalidate; //Colorea con nuevos parámetros de prompt
  1756. end;
  1757. procedure TfraTabSession.AcTerEnvEnterExecute(Sender: TObject); //Enter
  1758. begin
  1759. proc.SendLn('');
  1760. end;
  1761. procedure TfraTabSession.AcTerEnvCRExecute(Sender: TObject);
  1762. begin
  1763. proc.Send(#13);
  1764. end;
  1765. procedure TfraTabSession.AcTerEnvLFExecute(Sender: TObject);
  1766. begin
  1767. proc.Send(#10);
  1768. end;
  1769. procedure TfraTabSession.AcTerEnvCRLFExecute(Sender: TObject);
  1770. begin
  1771. proc.Send(#13#10);
  1772. end;
  1773. procedure TfraTabSession.AcTerLimBufExecute(Sender: TObject);
  1774. //limpia la salida
  1775. begin
  1776. edterm.ClearAll;
  1777. proc.ClearTerminal; //generará el evento OnInitLines()
  1778. end;
  1779. procedure TfraTabSession.AcTerPrmArrExecute(Sender: TObject);
  1780. //Mueve al prompt anterior
  1781. var
  1782. cy: Integer;
  1783. begin
  1784. cy := BuscaPromptArr;
  1785. if cy = -1 then begin
  1786. // msgexc('No se encuentra el prompt anterior');
  1787. end else begin
  1788. edTerm.CaretXY := point(1,cy);
  1789. edterm.SelectLine;
  1790. end;
  1791. end;
  1792. procedure TfraTabSession.AcTerPrmAbaExecute(Sender: TObject);
  1793. //Mueve al prompt siguiente
  1794. var
  1795. cy: Integer;
  1796. begin
  1797. cy := BuscaPromptAba;
  1798. if cy = -1 then begin
  1799. // msgexc('No se encuentra el prompt siguiente');
  1800. end else begin
  1801. edTerm.CaretXY := point(1,cy);
  1802. edterm.SelectLine;
  1803. end;
  1804. end;
  1805. procedure TfraTabSession.AcTerVerBHerExecute(Sender: TObject);
  1806. begin
  1807. end;
  1808. //Acciones de herramientas
  1809. procedure TfraTabSession.AcHerCfgExecute(Sender: TObject);
  1810. begin
  1811. ExecSettings;
  1812. end;
  1813. end.