FrameTabSession.pas 68 KB

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