FrameTabSession.pas 63 KB

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