2
0

FrameTabSession.pas 69 KB

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