1 unit frmJCFNotepad; 2 3 {(*} 4 (*------------------------------------------------------------------------------ 5 Delphi Code formatter source code 6 7 The Original Code is frmJCFNotepad, released May 2003. 8 The Initial Developer of the Original Code is Anthony Steele. 9 Portions created by Anthony Steele are Copyright (C) 1999-2008 Anthony Steele. 10 All Rights Reserved. 11 Contributor(s): Anthony Steele. 12 13 The contents of this file are subject to the Mozilla Public License Version 1.1 14 (the "License"). you may not use this file except in compliance with the License. 15 You may obtain a copy of the License at http://www.mozilla.org/NPL/ 16 17 Software distributed under the License is distributed on an "AS IS" basis, 18 WITHOUT WARRANTY OF ANY KIND, either express or implied. 19 See the License for the specific language governing rights and limitations 20 under the License. 21 22 Alternatively, the contents of this file may be used under the terms of 23 the GNU General Public License Version 2 or later (the "GPL") 24 See http://www.gnu.org/licenses/gpl.html 25 ------------------------------------------------------------------------------*) 26 {*)} 27 28 {$I JcfGlobal.inc} 29 30 interface 31 32 uses 33 { delphi } 34 Windows, Messages, SysUtils, Classes, Controls, Forms, 35 Dialogs, StdCtrls, ComCtrls, ExtCtrls, ActnList, 36 Buttons, Menus, ShellAPI, 37 { JEDI } 38 JvMRUManager, JvMemo, JvComponent, JvExStdCtrls, JvFormPlacement, JvComponentBase, 39 { local } 40 JcfRegistrySettings, Converter, ConvertTypes, JcfUnicodeFiles; 41 42 { have to do file pos display *after* various processing } 43 const 44 WM_SHOWFILEPOS = WM_USER + 42; 45 46 type 47 TfmJCFNotepad = class(TForm) 48 sb1: TStatusBar; 49 pnlTop: TPanel; 50 pcPages: TPageControl; 51 tsInput: TTabSheet; 52 tsOutput: TTabSheet; 53 mInput: TJvMemo; 54 mOutput: TJvMemo; 55 mMessages: TJvMemo; 56 lblMessages: TLabel; 57 sbLoad: TSpeedButton; 58 sbSave: TSpeedButton; 59 sbGo: TSpeedButton; 60 ActionList1: TActionList; 61 actOpen: TAction; 62 actSave: TAction; 63 actGo: TAction; 64 OpenDialog1: TOpenDialog; 65 SaveDialog1: TSaveDialog; 66 actClear: TAction; 67 sbClear: TSpeedButton; 68 MainMenu1: TMainMenu; 69 mnuFile: TMenuItem; 70 mnuFileOpen: TMenuItem; 71 mnuFileSaveOut: TMenuItem; 72 mnuExit: TMenuItem; 73 mnuSettings: TMenuItem; 74 actCopy: TAction; 75 actPaste: TAction; 76 N1: TMenuItem; 77 mruFiles: TJvMRUManager; 78 mnuEdit: TMenuItem; 79 mnuEditPaste: TMenuItem; 80 mnuEditCopy: TMenuItem; 81 mnuEditGo: TMenuItem; 82 mnuEditClear: TMenuItem; 83 mnuEditCut: TMenuItem; 84 mnuEditCopyOutput: TMenuItem; 85 mnuEditSelectAll: TMenuItem; 86 mnuEditCopyMessages: TMenuItem; 87 mnuFormat: TMenuItem; 88 mnuFileSaveInAs: TMenuItem; 89 mnuHelp: TMenuItem; 90 mnuHelpAbout: TMenuItem; 91 mnuShowRegSetting: TMenuItem; 92 mnuFormatSettings: TMenuItem; 93 ActCut: TAction; 94 Contents1: TMenuItem; 95 JvFormStorage1: TJvFormStorage; 96 mnuFileSaveIn: TMenuItem; 97 procedure FormResize(Sender: TObject); 98 procedure pcPagesChange(Sender: TObject); 99 procedure actGoExecute(Sender: TObject); 100 procedure mInputKeyUp(Sender: TObject; var Key: word; Shift: TShiftState); 101 procedure FormShow(Sender: TObject); 102 procedure actOpenExecute(Sender: TObject); 103 procedure actClearExecute(Sender: TObject); 104 procedure actSaveExecute(Sender: TObject); 105 procedure mnuExitClick(Sender: TObject); 106 procedure FormCreate(Sender: TObject); 107 procedure FormDestroy(Sender: TObject); 108 procedure actCopyExecute(Sender: TObject); 109 procedure actPasteExecute(Sender: TObject); 110 procedure mruFilesClick(Sender: TObject; const RecentName, Caption: string; 111 UserData: integer); 112 procedure mnuEditCopyOutputClick(Sender: TObject); 113 procedure mnuEditSelectAllClick(Sender: TObject); 114 procedure mnuEditCopyMessagesClick(Sender: TObject); 115 procedure mnuFileSaveInAsClick(Sender: TObject); 116 procedure mnuHelpAboutClick(Sender: TObject); 117 procedure mnuShowRegSettingClick(Sender: TObject); 118 procedure mnuFormatSettingsClick(Sender: TObject); 119 procedure ActCutExecute(Sender: TObject); 120 procedure mInputMouseUp(Sender: TObject; Button: TMouseButton; 121 Shift: TShiftState; X, Y: integer); 122 procedure Contents1Click(Sender: TObject); 123 procedure FormKeyUp(Sender: TObject; var Key: word; Shift: TShiftState); 124 procedure mOutputKeyUp(Sender: TObject; var Key: word; Shift: TShiftState); 125 procedure mInputKeyDown(Sender: TObject; var Key: word; Shift: TShiftState); 126 procedure mInputEnter(Sender: TObject); 127 procedure mOutputEnter(Sender: TObject); 128 procedure mInputClick(Sender: TObject); 129 procedure mOutputClick(Sender: TObject); 130 procedure mInputKeyPress(Sender: TObject; var Key: char); 131 procedure mnuFileSaveInClick(Sender: TObject); 132 private 133 fcConvert: TConverter; 134 fsLastInputFileName: string; 135 feLastInputContentType: TFileContentType; 136 137 procedure OnConvertStatusMessage(const psUnit, psMessage: string; 138 const peMessageType: TStatusMessageType; 139 const piY, piX: integer); 140 141 procedure CheckInputState; 142 procedure CheckCutPasteState; 143 procedure DoFileOpen(const psFileName: string); 144 procedure SaveInputToFile(const psFileName: string); 145 146 procedure CheckSaveEnabled; 147 148 procedure AddCheckMRU(const psFile: string); 149 150 procedure ShowFilePos; 151 procedure SendShowFilePos; 152 153 procedure OnReceiveShowFilePos(var msg: TMessage); message WM_SHOWFILEPOS; 154 public 155 end; 156 157 var 158 fmJCFNotepad: TfmJCFNotepad; 159 160 implementation 161 162 uses 163 { delphi } 164 ClipBrd, 165 { local } 166 JcfStringUtils, 167 JcfHelp, fAbout, fRegistrySettings, fAllSettings, JcfFontSetFunctions; 168 169 {$ifdef FPC} 170 {$R *.lfm} 171 {$else} 172 {$R *.dfm} 173 {$endif} 174 175 procedure TfmJCFNotepad.CheckInputState; 176 begin 177 actGo.Enabled := (mInput.Text <> ''); 178 actClear.Enabled := (mInput.Text <> ''); 179 end; 180 181 procedure TfmJCFNotepad.CheckSaveEnabled; 182 begin 183 mnuFileSaveIn.Enabled := (fsLastInputFileName <> ''); 184 end; 185 186 procedure TfmJCFNotepad.CheckCutPasteState; 187 var 188 lbHasOutput: boolean; 189 begin 190 actPaste.Enabled := (pcPages.ActivePage = tsInput) and Clipboard.HasFormat(CF_TEXT); 191 actCut.Enabled := (pcPages.ActivePage = tsInput) and (mInput.SelLength > 0); 192 193 lbHasOutput := (pcPages.ActivePage = tsOutput) and (mOutput.Text <> ''); 194 actSave.Enabled := lbHasOutput; 195 196 if pcPages.ActivePage = tsOutput then 197 actCopy.Enabled := lbHasOutput 198 else 199 actCopy.Enabled := (mInput.Text <> ''); 200 201 end; 202 203 procedure TfmJCFNotepad.DoFileOpen(const psFileName: string); 204 var 205 lsFileContents: String; 206 begin 207 if psFileName = '' then 208 exit; 209 if not FileExists(psFileName) then 210 exit; 211 212 GetRegSettings.InputDir := ExtractFilePath(psFileName); 213 214 ReadTextFile(psFileName, lsFileContents, feLastInputContentType); 215 216 mInput.Text := lsFileContents; 217 sb1.Panels[1].Text := psFileName; 218 AddCheckMRU(psFileName); 219 fsLastInputFileName := psFileName; 220 221 CheckInputState; 222 SendShowFilePos; 223 CheckSaveEnabled; 224 end; 225 226 procedure TfmJCFNotepad.SaveInputToFile(const psFileName: string); 227 begin 228 if psFileName = '' then 229 exit; 230 231 // default the file type to utf-8 if it's not known 232 if feLastInputContentType = eUnknown then 233 begin 234 feLastInputContentType := eUtf8; 235 end; 236 237 WriteTextFile(psFileName, mInput.Text, feLastInputContentType); 238 239 240 sb1.Panels[1].Text := 'Saved input as ' + psFileName; 241 AddCheckMRU(psFileName); 242 243 fsLastInputFileName := psFileName; 244 CheckSaveEnabled; 245 end; 246 247 procedure TfmJCFNotepad.AddCheckMRU(const psFile: string); 248 var 249 liIndex: integer; 250 begin 251 liIndex := mruFiles.Strings.IndexOf(psFile); 252 253 if (liIndex < 0) then 254 begin 255 mruFiles.Add(psFile, 0); 256 liIndex := mruFiles.Strings.IndexOf(psFile); 257 end; 258 259 mruFiles.Strings.Move(liIndex, 0); 260 261 while mruFiles.Strings.Count > mruFiles.Capacity do 262 mruFiles.Strings.Delete(mruFiles.Strings.Count - 1); 263 end; 264 265 procedure TfmJCFNotepad.FormResize(Sender: TObject); 266 const 267 OUTPUT_PAD = 4; 268 begin 269 mOutput.Left := OUTPUT_PAD; 270 mOutput.Top := OUTPUT_PAD; 271 mOutput.Width := tsOutput.ClientWidth - (2 * OUTPUT_PAD); 272 273 // two thirds height 274 mOutput.Height := (tsOutput.Height * 2 div 3) - (2 * OUTPUT_PAD); 275 276 lblMessages.Left := 4; 277 lblMessages.Top := mOutput.Top + mOutput.Height + OUTPUT_PAD; 278 279 mMessages.Top := lblMessages.Top + lblMessages.Height + OUTPUT_PAD; 280 mMessages.Height := tsOutput.ClientHeight - (lblMessages.Top + 281 lblMessages.Height + (OUTPUT_PAD * 2)); 282 mMessages.Left := OUTPUT_PAD; 283 mMessages.Width := tsOutput.ClientWidth - (2 * OUTPUT_PAD); 284 end; 285 286 procedure TfmJCFNotepad.pcPagesChange(Sender: TObject); 287 begin 288 CheckCutPasteState; 289 SendShowFilePos; 290 end; 291 292 procedure TfmJCFNotepad.actGoExecute(Sender: TObject); 293 begin 294 actGo.Enabled := False; 295 296 mMessages.Clear; 297 fcConvert.OnStatusMessage := OnConvertStatusMessage; 298 299 fcConvert.InputCode := mInput.Lines.Text; 300 fcConvert.Convert; 301 mOutput.Lines.Text := fcConvert.OutputCode; 302 fcConvert.Clear; 303 304 pcPages.ActivePage := tsOutput; 305 pcPagesChange(nil); 306 307 CheckInputState; 308 end; 309 310 procedure TfmJCFNotepad.mInputKeyUp(Sender: TObject; var Key: word; Shift: TShiftState); 311 begin 312 CheckInputState; 313 CheckCutPasteState; 314 end; 315 316 317 procedure TfmJCFNotepad.FormShow(Sender: TObject); 318 begin 319 CheckInputState; 320 CheckCutPasteState; 321 end; 322 323 procedure TfmJCFNotepad.actOpenExecute(Sender: TObject); 324 begin 325 OpenDialog1.InitialDir := GetRegSettings.InputDir; 326 OpenDialog1.Filter := SOURCE_FILE_FILTERS; 327 328 if OpenDialog1.Execute then 329 begin 330 pcPages.ActivePage := tsInput; 331 DoFileOpen(OpenDialog1.FileName); 332 end; 333 end; 334 335 procedure TfmJCFNotepad.actClearExecute(Sender: TObject); 336 begin 337 mInput.Text := ''; 338 mOutput.Text := ''; 339 mMessages.Text := ''; 340 pcPages.ActivePage := tsInput; 341 342 CheckInputState; 343 CheckCutPasteState; 344 end; 345 346 procedure TfmJCFNotepad.actSaveExecute(Sender: TObject); 347 begin 348 SaveDialog1.InitialDir := GetRegSettings.OutputDir; 349 SaveDialog1.Title := 'Save output file'; 350 SaveDialog1.Filter := SOURCE_FILE_FILTERS; 351 352 353 if SaveDialog1.Execute then 354 begin 355 GetRegSettings.OutputDir := ExtractFilePath(SaveDialog1.FileName); 356 StringToFile(SaveDialog1.FileName, AnsiString(mOutput.Text)); 357 sb1.Panels[1].Text := 'Saved output: ' + SaveDialog1.FileName; 358 AddCheckMRU(SaveDialog1.FileName); 359 end; 360 end; 361 362 procedure TfmJCFNotepad.mnuExitClick(Sender: TObject); 363 begin 364 Close; 365 end; 366 367 procedure TfmJCFNotepad.FormCreate(Sender: TObject); 368 var 369 lsHelpFile: string; 370 begin 371 SetObjectFontToSystemFont(Self); 372 373 //lsHelpFile := IncludeTrailingPathDelimiter(ExtractFilePath(Application.ExeName)) + 'CodeFormat.chm'; 374 //lsHelpFile := IncludeTrailingPathDelimiter(ExtractFilePath(GetModuleName(GetModuleHandle('JCFIdeD11.bpl')))) + 'CodeFormat.chm'; 375 lsHelpFile := GetHelpFilePath; 376 377 if FileExists(lsHelpFile) then 378 Application.HelpFile := lsHelpFile; 379 380 fcConvert := TConverter.Create; 381 382 GetRegSettings.MRUFiles := mruFiles.Strings; 383 GetRegSettings.ReadAll; 384 385 mruFiles.RemoveInvalid; 386 387 pcPages.ActivePage := tsInput; 388 389 feLastInputContentType := eUnknown; 390 fsLastInputFileName := ''; 391 392 CheckSaveEnabled; 393 end; 394 395 procedure TfmJCFNotepad.FormDestroy(Sender: TObject); 396 begin 397 GetRegSettings.WriteAll; 398 GetRegSettings.MRUFiles := nil; 399 400 FreeAndNil(fcConvert); 401 end; 402 403 procedure TfmJCFNotepad.actCopyExecute(Sender: TObject); 404 begin 405 if pcPages.ActivePage = tsOutput then 406 mOutput.CopyToClipboard 407 else 408 mInput.CopyToClipboard; 409 end; 410 411 procedure TfmJCFNotepad.actPasteExecute(Sender: TObject); 412 begin 413 if (pcPages.ActivePage = tsInput) and Clipboard.HasFormat(CF_TEXT) then 414 begin 415 mInput.PasteFromClipboard; 416 CheckInputState; 417 end; 418 end; 419 420 procedure TfmJCFNotepad.mruFilesClick(Sender: TObject; 421 const RecentName, Caption: string; UserData: integer); 422 begin 423 DoFileOpen(RecentName); 424 end; 425 426 procedure TfmJCFNotepad.mnuEditCopyOutputClick(Sender: TObject); 427 begin 428 Clipboard.AsText := mOutput.Text; 429 end; 430 431 procedure TfmJCFNotepad.ActCutExecute(Sender: TObject); 432 begin 433 if (pcPages.ActivePage = tsInput) then 434 begin 435 mInput.CutToClipboard; 436 CheckInputState; 437 end; 438 end; 439 440 procedure TfmJCFNotepad.mnuEditSelectAllClick(Sender: TObject); 441 begin 442 if (pcPages.ActivePage = tsInput) then 443 begin 444 mInput.SetFocus; 445 mInput.SelectAll; 446 CheckCutPasteState; 447 end 448 else 449 begin 450 mOutput.SetFocus; 451 mOutput.SelectAll; 452 end; 453 end; 454 455 procedure TfmJCFNotepad.mnuEditCopyMessagesClick(Sender: TObject); 456 begin 457 Clipboard.AsText := mMessages.Text; 458 end; 459 460 procedure TfmJCFNotepad.mnuFileSaveInClick(Sender: TObject); 461 begin 462 if fsLastInputFileName <> '' then 463 begin 464 SaveInputToFile(fsLastInputFileName); 465 end; 466 467 end; 468 469 470 procedure TfmJCFNotepad.mnuFileSaveInAsClick(Sender: TObject); 471 begin 472 SaveDialog1.InitialDir := GetRegSettings.OutputDir; 473 SaveDialog1.Title := 'Save input file'; 474 SaveDialog1.Filter := SOURCE_FILE_FILTERS; 475 476 if SaveDialog1.Execute then 477 begin 478 GetRegSettings.OutputDir := ExtractFilePath(SaveDialog1.FileName); 479 480 SaveInputToFile(SaveDialog1.FileName); 481 end; 482 end; 483 484 procedure TfmJCFNotepad.mnuHelpAboutClick(Sender: TObject); 485 var 486 lfAbout: TfrmAboutBox; 487 begin 488 lfAbout := TfrmAboutBox.Create(self); 489 try 490 lfAbout.ShowModal; 491 finally 492 lfAbout.Release; 493 end; 494 end; 495 496 procedure TfmJCFNotepad.mnuShowRegSettingClick(Sender: TObject); 497 var 498 lfSettings: TfmRegistrySettings; 499 begin 500 lfSettings := TfmRegistrySettings.Create(self); 501 try 502 lfSettings.Execute; 503 finally 504 lfSettings.Release; 505 end; 506 end; 507 508 procedure TfmJCFNotepad.mnuFormatSettingsClick(Sender: TObject); 509 var 510 lfAllSettings: TFormAllSettings; 511 begin 512 lfAllSettings := TFormAllSettings.Create(self); 513 try 514 lfAllSettings.Execute; 515 finally 516 lfAllSettings.Release; 517 end; 518 end; 519 520 procedure TfmJCFNotepad.mInputMouseUp(Sender: TObject; Button: TMouseButton; 521 Shift: TShiftState; X, Y: integer); 522 begin 523 CheckCutPasteState; 524 end; 525 526 procedure TfmJCFNotepad.Contents1Click(Sender: TObject); 527 begin 528 try 529 Application.HelpContext(HELP_MAIN); 530 except 531 ShellExecute(Handle, 'open', PChar(Application.HelpFile), nil, nil, SW_SHOWNORMAL); 532 end; 533 end; 534 535 procedure TfmJCFNotepad.FormKeyUp(Sender: TObject; var Key: word; Shift: TShiftState); 536 begin 537 if Key = VK_F1 then 538 try 539 Application.HelpContext(HELP_MAIN); 540 except 541 ShellExecute(Handle, 'open', PChar(Application.HelpFile), nil, nil, SW_SHOWNORMAL); 542 end; 543 end; 544 545 procedure TfmJCFNotepad.ShowFilePos; 546 const 547 POS_NUM_LEN = 4; 548 var 549 liX, liY: integer; 550 lsPos: string; 551 lsX, lsY: string; 552 begin 553 if pcPages.ActivePage = tsInput then 554 begin 555 liX := mInput.CaretPos.X; 556 liY := mInput.CaretPos.Y; 557 end 558 else 559 begin 560 liX := mOutput.CaretPos.X; 561 liY := mOutput.CaretPos.Y; 562 end; 563 564 { index in delphi is 1-based not 0-based, 565 ie starts at line 1 char 1} 566 Inc(liX); 567 Inc(liY); 568 569 if liX > 0 then 570 lsX := StrPadLeft(IntToStr(liX), POS_NUM_LEN, ' ') 571 else 572 lsX := '?'; 573 574 if liY > 0 then 575 lsY := StrPadLeft(IntToStr(liY), POS_NUM_LEN, ' ') 576 else 577 lsY := '?'; 578 579 lsPos := lsY + ':' + lsX; 580 581 sb1.Panels[0].Text := lsPos; 582 end; 583 584 procedure TfmJCFNotepad.SendShowFilePos; 585 begin 586 { send a note to yourself to redisplay this 587 as soon as the current operation is finished } 588 PostMessage(Handle, WM_SHOWFILEPOS, 0, 0); 589 end; 590 591 { triggered by SendShowFilePos } 592 procedure TfmJCFNotepad.OnReceiveShowFilePos(var msg: TMessage); 593 begin 594 ShowFilePos; 595 end; 596 597 procedure TfmJCFNotepad.mOutputKeyUp(Sender: TObject; var Key: word; 598 Shift: TShiftState); 599 begin 600 SendShowFilePos; 601 end; 602 603 procedure TfmJCFNotepad.mInputKeyDown(Sender: TObject; var Key: word; 604 Shift: TShiftState); 605 begin 606 SendShowFilePos; 607 end; 608 609 procedure TfmJCFNotepad.mInputEnter(Sender: TObject); 610 begin 611 SendShowFilePos; 612 end; 613 614 procedure TfmJCFNotepad.mOutputEnter(Sender: TObject); 615 begin 616 SendShowFilePos; 617 end; 618 619 procedure TfmJCFNotepad.mInputClick(Sender: TObject); 620 begin 621 SendShowFilePos; 622 end; 623 624 procedure TfmJCFNotepad.mOutputClick(Sender: TObject); 625 begin 626 SendShowFilePos; 627 end; 628 629 procedure TfmJCFNotepad.mInputKeyPress(Sender: TObject; var Key: char); 630 begin 631 SendShowFilePos; 632 end; 633 634 procedure TfmJCFNotepad.OnConvertStatusMessage(const psUnit, psMessage: string; 635 const peMessageType: TStatusMessageType; 636 const piY, piX: integer); 637 var 638 lsWholeMessage: string; 639 begin 640 lsWholeMessage := psMessage; 641 if (piY >= 0) and (piX >= 0) then 642 lsWholeMessage := lsWholeMessage + ' at line ' + IntToStr(piY) + 643 ' col ' + IntToStr(piX); 644 645 mMessages.Lines.Add(lsWholeMessage); 646 647 { make it visible } 648 if pcPages.ActivePage <> tsOutput then 649 pcPages.ActivePage := tsOutput; 650 end; 651 652 end. 653