/packager/addtopackagedlg.pas

http://github.com/graemeg/lazarus · Pascal · 1335 lines · 1125 code · 120 blank · 90 comment · 117 complexity · 470cf238b6155242726d60b28f023de7 MD5 · raw file

  1. {
  2. ***************************************************************************
  3. * *
  4. * This source is free software; you can redistribute it and/or modify *
  5. * it under the terms of the GNU General Public License as published by *
  6. * the Free Software Foundation; either version 2 of the License, or *
  7. * (at your option) any later version. *
  8. * *
  9. * This code is distributed in the hope that it will be useful, but *
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of *
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
  12. * General Public License for more details. *
  13. * *
  14. * A copy of the GNU General Public License is available on the World *
  15. * Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
  16. * obtain it by writing to the Free Software Foundation, *
  17. * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  18. * *
  19. ***************************************************************************
  20. Author: Mattias Gaertner
  21. Abstract:
  22. TAddToPackageDlg is the form for adding files to an open package.
  23. }
  24. unit AddToPackageDlg;
  25. {$mode objfpc}{$H+}
  26. interface
  27. uses
  28. Math, Classes, SysUtils, AVL_Tree,
  29. // LCL
  30. LCLProc, LCLType, Forms, Controls, Buttons, ExtDlgs, StdCtrls, ExtCtrls,
  31. Dialogs, ComCtrls, ButtonPanel,
  32. ListFilterEdit,
  33. // LazUtils
  34. FileUtil, LazFileUtils,
  35. // IDEIntf
  36. NewItemIntf, PackageIntf, FormEditingIntf, IDEWindowIntf, ComponentReg, IDEDialogs,
  37. // IDE
  38. LazarusIDEStrConsts, InputHistory, IDEDefs, EnvironmentOpts,
  39. PackageSystem, PackageDefs, AddDirToPkgDlg;
  40. type
  41. TAddToPkgType = (
  42. d2ptUnit,
  43. d2ptVirtualUnit,
  44. d2ptNewComponent,
  45. d2ptRequiredPkg,
  46. d2ptFile,
  47. d2ptFiles
  48. );
  49. { TAddToPkgResult }
  50. TAddToPkgResult = class
  51. public
  52. Pkg: TLazPackage;
  53. AddType: TAddToPkgType;
  54. Dependency: TPkgDependency;
  55. UnitFilename: string;
  56. Unit_Name: string;
  57. AncestorType: string;
  58. NewClassName: string;
  59. PageName: string;
  60. FileType: TPkgFileType;
  61. PkgFileFlags: TPkgFileFlags;
  62. UsedUnitname: string;
  63. IconFile: string;
  64. AutoAddLFMFile: boolean;
  65. AutoAddLRSFile: boolean;
  66. NewItem: TNewIDEItemTemplate;
  67. Next: TAddToPkgResult;
  68. procedure Clear;
  69. destructor Destroy; override;
  70. end;
  71. TOnGetUnitRegisterInfo = procedure(Sender: TObject; const AFilename: string;
  72. out TheUnitName: string; out HasRegisterProc: boolean) of object;
  73. { TAddToPackageDlg }
  74. TAddToPackageDlg = class(TForm)
  75. AddFilesBtnPanel: TPanel;
  76. AddFilesPage: TTabSheet;
  77. AncestorComboBox: TComboBox;
  78. AncestorShowAllCheckBox: TCheckBox;
  79. AncestorTypeLabel: TLabel;
  80. ButtonPanel1: TButtonPanel;
  81. ClassNameEdit: TEdit;
  82. ClassNameLabel: TLabel;
  83. ComponentIconLabel: TLabel;
  84. ComponentIconBitBtn: TBitBtn;
  85. ComponentUnitFileBrowseButton: TButton;
  86. ComponentUnitFileEdit: TEdit;
  87. ComponentUnitFileLabel: TLabel;
  88. ComponentUnitFileShortenButton: TButton;
  89. ComponentUnitNameEdit: TEdit;
  90. ComponentUnitNameLabel: TLabel;
  91. DependMaxVersionEdit: TEdit;
  92. DependMaxVersionLabel: TLabel;
  93. DependMinVersionEdit: TEdit;
  94. DependMinVersionLabel: TLabel;
  95. DependPkgNameLabel: TLabel;
  96. FilesDeleteButton: TBitBtn;
  97. FilesDirButton: TBitBtn;
  98. FilesListView: TListView;
  99. FilesShortenButton: TBitBtn;
  100. LabelIconInfo: TLabel;
  101. DependPkgNameListBox: TListBox;
  102. DependPkgNameFilter: TListFilterEdit;
  103. NewComponentPage: TTabSheet;
  104. NewDepPanel: TPanel;
  105. NewRequirementPage: TTabSheet;
  106. PageControl1: TPageControl;
  107. PalettePageCombobox: TComboBox;
  108. PalettePageLabel: TLabel;
  109. procedure AddToPackageDlgClose(Sender: TObject; var {%H-}CloseAction: TCloseAction);
  110. procedure AddToPackageDlgKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  111. procedure AncestorComboBoxChange(Sender: TObject);
  112. procedure AncestorComboBoxCloseUp(Sender: TObject);
  113. procedure AncestorShowAllCheckBoxClick(Sender: TObject);
  114. procedure CancelAddFileButtonClick(Sender: TObject);
  115. procedure CancelAddUnitButtonClick(Sender: TObject);
  116. procedure ClassNameEditChange(Sender: TObject);
  117. procedure ComponentIconBitBtnClick(Sender: TObject);
  118. procedure ComponentUnitFileBrowseButtonClick(Sender: TObject);
  119. procedure ComponentUnitFileShortenButtonClick(Sender: TObject);
  120. procedure ComponentUnitNameEditChange(Sender: TObject);
  121. procedure DependPkgNameListBoxSelectionChange(Sender: TObject; {%H-}User: boolean);
  122. procedure FilesAddButtonClick(Sender: TObject);
  123. procedure FilesDeleteButtonClick(Sender: TObject);
  124. procedure FilesDirButtonClick(Sender: TObject);
  125. procedure FilesListViewSelectItem(Sender: TObject; {%H-}Item: TListItem; {%H-}Selected: Boolean);
  126. procedure FilesShortenButtonClick(Sender: TObject);
  127. procedure FormCreate(Sender: TObject);
  128. procedure FormDestroy(Sender: TObject);
  129. procedure FormShow(Sender: TObject);
  130. procedure NewComponentButtonClick(Sender: TObject);
  131. procedure NewComponentPageResize(Sender: TObject);
  132. procedure NewDependButtonClick(Sender: TObject);
  133. procedure PageControl1Change(Sender: TObject);
  134. private
  135. fLastNewComponentAncestorType: string;
  136. fLastNewComponentClassName: string;
  137. FLazPackage: TLazPackage;
  138. FOnGetIDEFileInfo: TGetIDEFileStateEvent;
  139. FOnGetUnitRegisterInfo: TOnGetUnitRegisterInfo;
  140. fPkgComponents: TAVLTree;// tree of TPkgComponent
  141. fPackages: TAVLTree;// tree of TLazPackage or TPackageLink
  142. FComponentIconFilename: string;
  143. function GetActivatePage: TAddToPkgType;
  144. procedure SetActivatePage(AValue: TAddToPkgType);
  145. procedure SetLazPackage(const AValue: TLazPackage);
  146. procedure SetupComponents;
  147. procedure SetupNewComponentPage;
  148. procedure SetupAddDependencyPage;
  149. procedure SetupAddFilesPage;
  150. procedure OnIterateComponentClasses(PkgComponent: TPkgComponent);
  151. procedure OnIteratePackages(APackageID: TLazPackageID);
  152. function CheckNewCompOk: Boolean;
  153. function CheckNewReqOk: Boolean;
  154. function CheckFilesButtonsOk: Boolean;
  155. procedure AutoCompleteNewComponent;
  156. procedure AutoCompleteNewComponentUnitName;
  157. function SwitchRelativeAbsoluteFilename(const Filename: string): string;
  158. function FindFileInFilesList(AFilename: string): Integer;
  159. procedure LoadComponentIcon(AFilename: string);
  160. public
  161. Params: TAddToPkgResult;
  162. procedure UpdateAvailableAncestorTypes;
  163. procedure UpdateAvailablePageNames;
  164. procedure UpdateAvailableDependencyNames;
  165. public
  166. property LazPackage: TLazPackage read FLazPackage write SetLazPackage;
  167. property OnGetIDEFileInfo: TGetIDEFileStateEvent read FOnGetIDEFileInfo
  168. write FOnGetIDEFileInfo;
  169. property OnGetUnitRegisterInfo: TOnGetUnitRegisterInfo
  170. read FOnGetUnitRegisterInfo write FOnGetUnitRegisterInfo;
  171. property ActivatePage: TAddToPkgType read GetActivatePage write SetActivatePage;
  172. end;
  173. function ShowAddToPackageDlg(Pkg: TLazPackage; out Params: TAddToPkgResult;
  174. OnGetIDEFileInfo: TGetIDEFileStateEvent;
  175. OnGetUnitRegisterInfo: TOnGetUnitRegisterInfo;
  176. var Page: TAddToPkgType): TModalResult;
  177. function CheckAddingUnitFilename(LazPackage: TLazPackage;
  178. AddFileType: TAddToPkgType; OnGetIDEFileInfo: TGetIDEFileStateEvent;
  179. var AFilename: string): boolean;
  180. function CheckAddingDependency(LazPackage: TLazPackage;
  181. NewDependency: TPkgDependency; Quiet, WarnIfAlreadyThere: boolean
  182. ): TModalResult;// mrOk=can be added, mrCancel=do not add, mrIgnore=already there
  183. function CheckAddingPkgDependency(LazPackage: TLazPackage;
  184. RequiredPkg: TLazPackage; Quiet, WarnIfAlreadyThere: boolean): TModalResult;
  185. implementation
  186. {$R *.lfm}
  187. function ShowAddToPackageDlg(Pkg: TLazPackage; out Params: TAddToPkgResult;
  188. OnGetIDEFileInfo: TGetIDEFileStateEvent;
  189. OnGetUnitRegisterInfo: TOnGetUnitRegisterInfo; var Page: TAddToPkgType
  190. ): TModalResult;
  191. var
  192. AddDlg: TAddToPackageDlg;
  193. begin
  194. Params:=nil;
  195. AddDlg:=TAddToPackageDlg.Create(nil);
  196. AddDlg.OnGetIDEFileInfo:=OnGetIDEFileInfo;
  197. AddDlg.OnGetUnitRegisterInfo:=OnGetUnitRegisterInfo;
  198. AddDlg.LazPackage:=Pkg;
  199. AddDlg.ActivatePage:=Page;
  200. //auto press AddFiles if called with "Add files" page
  201. if Page=d2ptFiles then
  202. AddDlg.FilesDirButton.Click;
  203. //hide tabs for simpler use
  204. AddDlg.PageControl1.ShowTabs:=false;
  205. AddDlg.PageControl1.TabStop:=false;
  206. Result:=AddDlg.ShowModal;
  207. Page:=AddDlg.ActivatePage;
  208. if Result=mrOk then begin
  209. Params:=AddDlg.Params;
  210. AddDlg.Params:=nil;
  211. end;
  212. AddDlg.Free;
  213. end;
  214. function CheckAddingUnitFilename(LazPackage: TLazPackage;
  215. AddFileType: TAddToPkgType; OnGetIDEFileInfo: TGetIDEFileStateEvent;
  216. var AFilename: string): boolean;
  217. var
  218. AnUnitName: String;
  219. PkgFile: TPkgFile;
  220. Msg: String;
  221. IDEFileFlags: TIDEFileStateFlags;
  222. begin
  223. Result:=false;
  224. PkgFile:=Nil;
  225. // check if package is readonly
  226. if LazPackage.ReadOnly then begin
  227. IDEMessageDialog(lisAF2PPackageIsReadOnly,
  228. Format(lisAF2PThePackageIsReadOnly, [LazPackage.IDAsString]),
  229. mtError,[mbCancel]);
  230. exit;
  231. end;
  232. // normalize filename
  233. AFilename:=TrimFilename(AFilename);
  234. if (AddFileType<>d2ptVirtualUnit) and (not FilenameIsAbsolute(AFilename)) then
  235. begin
  236. if LazPackage.HasDirectory then
  237. AFilename:=LazPackage.Directory+AFilename
  238. else begin
  239. IDEMessageDialog(lisA2PInvalidFilename,
  240. Format(lisA2PTheFilenameIsAmbiguousPleaseSpecifiyAFilename,[AFilename,LineEnding]),
  241. mtError,[mbCancel]);
  242. exit;
  243. end;
  244. end;
  245. // check if file exists
  246. if (FilenameIsAbsolute(AFilename)) then begin
  247. if (not FileExistsUTF8(AFilename)) then begin
  248. if AddFileType=d2ptUnit then begin
  249. IDEMessageDialog(lisFileNotFound,
  250. Format(lisPkgMangFileNotFound, [AFilename]),
  251. mtError, [mbCancel]);
  252. exit;
  253. end;
  254. end;
  255. end;
  256. // check if file already exists in package
  257. if FilenameIsAbsolute(AFilename) then begin
  258. PkgFile:=LazPackage.FindPkgFile(AFilename,true,false);
  259. if PkgFile<>nil then begin
  260. Msg:=Format(lisA2PFileAlreadyExistsInThePackage, [AFilename]);
  261. if PkgFile.Filename<>AFilename then
  262. Msg:=Msg+LineEnding+Format(lisA2PExistingFile2, [PkgFile.Filename]);
  263. IDEMessageDialog(lisA2PFileAlreadyExists, Msg, mtError, [mbCancel]);
  264. exit;
  265. end;
  266. end;
  267. // check if file is part of project
  268. if FilenameIsAbsolute(AFilename) then begin
  269. if Assigned(OnGetIDEFileInfo) then begin
  270. IDEFileFlags:=[];
  271. OnGetIDEFileInfo(nil,AFilename,[ifsPartOfProject],IDEFileFlags);
  272. if (ifsPartOfProject in IDEFileFlags) then begin
  273. IDEMessageDialog(lisA2PFileIsUsed,
  274. Format(lisA2PTheFileIsPartOfTheCurrentProjectItIsABadIdea,[AFilename,LineEnding]),
  275. mtError,[mbCancel]);
  276. exit;
  277. end;
  278. end;
  279. end;
  280. // check file extension
  281. if AddFileType in [d2ptUnit,d2ptNewComponent,d2ptVirtualUnit] then begin
  282. if not FilenameIsPascalUnit(AFilename) then begin
  283. IDEMessageDialog(lisA2PFileNotUnit,
  284. lisA2PPascalUnitsMustHaveTheExtensionPPOrPas,
  285. mtWarning,[mbCancel]);
  286. exit;
  287. end;
  288. end;
  289. // check unitname
  290. if AddFileType in [d2ptUnit,d2ptNewComponent,d2ptVirtualUnit] then begin
  291. AnUnitName:=ExtractFileNameOnly(AFilename);
  292. if not IsValidUnitName(AnUnitName) then begin
  293. IDEMessageDialog(lisA2PFileNotUnit,
  294. Format(lisA2PisNotAValidUnitName, [AnUnitName]),
  295. mtWarning,[mbCancel]);
  296. exit;
  297. end;
  298. // check if unitname already exists in package
  299. PkgFile:=LazPackage.FindUnit(AnUnitName,true,PkgFile);
  300. if PkgFile<>nil then begin
  301. // a unit with this name already exists in this package => warn
  302. if IDEMessageDialog(lisA2PUnitnameAlreadyExists,
  303. Format(lisA2PTheUnitnameAlreadyExistsInThisPackage, [AnUnitName]),
  304. mtError,[mbCancel,mbIgnore])<>mrIgnore then exit;
  305. end else begin
  306. PkgFile:=PackageGraph.FindUnit(LazPackage,AnUnitName,true,true);
  307. if (PkgFile<>nil) and (PkgFile.LazPackage<>LazPackage) then begin
  308. // there is already a unit with this name in another package => warn
  309. if IDEMessageDialog(lisA2PUnitnameAlreadyExists,
  310. Format(lisA2PTheUnitnameAlreadyExistsInThePackage,
  311. [AnUnitName, LineEnding, PkgFile.LazPackage.IDAsString]),
  312. mtWarning,[mbCancel,mbIgnore])<>mrIgnore then exit;
  313. end;
  314. end;
  315. // check if unitname is a componentclass
  316. if IDEComponentPalette.FindComponent(AnUnitName)<>nil then begin
  317. if IDEMessageDialog(lisA2PAmbiguousUnitName,
  318. Format(lisA2PTheUnitNameIsTheSameAsAnRegisteredComponent,
  319. [AnUnitName, LineEnding]),
  320. mtWarning,[mbCancel,mbIgnore])<>mrIgnore
  321. then
  322. exit;
  323. end;
  324. end;
  325. // ok
  326. Result:=true;
  327. end;
  328. function CheckAddingDependency(LazPackage: TLazPackage;
  329. NewDependency: TPkgDependency; Quiet, WarnIfAlreadyThere: boolean): TModalResult;
  330. var
  331. NewPkgName: String;
  332. RequiredPackage: TLazPackage;
  333. ProvidingAPackage: TLazPackage;
  334. ConflictDependency: TPkgDependency;
  335. PathList: TFPList;
  336. s: String;
  337. begin
  338. Result:=mrCancel;
  339. NewPkgName:=NewDependency.PackageName;
  340. // check Max-Min version
  341. if (pdfMinVersion in NewDependency.Flags)
  342. and (pdfMaxVersion in NewDependency.Flags)
  343. and (NewDependency.MaxVersion.Compare(NewDependency.MinVersion)<0) then
  344. begin
  345. if not Quiet then
  346. IDEMessageDialog(lisProjAddInvalidMinMaxVersion,
  347. lisA2PTheMaximumVersionIsLowerThanTheMinimimVersion,
  348. mtError,[mbCancel]);
  349. exit(mrCancel);
  350. end;
  351. // check packagename
  352. if not IsValidPkgName(NewPkgName) then begin
  353. if not Quiet then
  354. IDEMessageDialog(lisProjAddInvalidPackagename,
  355. Format(lisA2PThePackageNameIsInvalidPleaseChooseAnExisting,[NewPkgName,LineEnding]),
  356. mtError,[mbCancel]);
  357. exit(mrCancel);
  358. end;
  359. // check if package is already required
  360. if (CompareText(NewPkgName,LazPackage.Name)=0)
  361. or (PackageGraph.FindDependencyRecursively(
  362. LazPackage.FirstRequiredDependency,NewPkgName)<>nil)
  363. then begin
  364. if WarnIfAlreadyThere then
  365. IDEMessageDialog(lisProjAddDependencyAlreadyExists,
  366. Format(lisA2PThePackageHasAlreadyADependencyForThe, [NewPkgName]),
  367. mtError,[mbCancel]);
  368. exit(mrIgnore);
  369. end;
  370. // check if required lpk exists
  371. if not PackageGraph.DependencyExists(NewDependency,fpfSearchAllExisting)
  372. then begin
  373. if not Quiet then
  374. IDEMessageDialog(lisProjAddPackageNotFound,
  375. Format(lisA2PNoPackageFoundForDependencyPleaseChooseAnExisting,
  376. [NewDependency.AsString, LineEnding]),
  377. mtError,[mbCancel]);
  378. exit(mrCancel);
  379. end;
  380. RequiredPackage:=PackageGraph.FindPackageWithName(NewPkgName,nil);
  381. if RequiredPackage<>nil then begin
  382. // check if there is a dependency, that requires another version
  383. ConflictDependency:=PackageGraph.FindConflictRecursively(
  384. LazPackage.FirstRequiredDependency,RequiredPackage);
  385. if ConflictDependency<>nil then begin
  386. DebugLn(['CheckAddingDependency ',LazPackage.Name,' requiring ',RequiredPackage.IDAsString,' conflicts with ',ConflictDependency.AsString]);
  387. if not Quiet then
  388. IDEMessageDialog(lisVersionMismatch,
  389. Format(lisUnableToAddTheDependencyBecauseThePackageHasAlread, [
  390. RequiredPackage.IDAsString, LazPackage.Name, ConflictDependency.
  391. AsString]),
  392. mtError,[mbCancel]);
  393. exit(mrCancel);
  394. end;
  395. // check if there is a cycle
  396. PathList:=PackageGraph.FindPath(RequiredPackage,nil,LazPackage.Name);
  397. if PathList<>nil then begin
  398. try
  399. s:=PackagePathToStr(PathList);
  400. DebugLn(['CheckAddingDependency ',LazPackage.Name,' requiring ',RequiredPackage.IDAsString,' creates cycles with ',s]);
  401. if not Quiet then
  402. IDEMessageDialog(lisCircularDependencyDetected,
  403. Format(lisUnableToAddTheDependencyBecauseThisWouldCreateA, [
  404. RequiredPackage.IDAsString, s]),
  405. mtError,[mbCancel]);
  406. exit(mrCancel);
  407. finally
  408. PathList.Free;
  409. end;
  410. end;
  411. end;
  412. ProvidingAPackage:=PackageGraph.FindPackageProvidingName(
  413. LazPackage.FirstRequiredDependency,NewPkgName);
  414. if ProvidingAPackage<>nil then
  415. begin
  416. // package is already provided by another package
  417. DebugLn(['CheckAddingDependency ',LazPackage.Name,' requiring ',NewPkgName,', but is already provided by ',ProvidingAPackage.IDAsString]);
  418. if WarnIfAlreadyThere then
  419. IDEMessageDialog(lisProjAddDependencyAlreadyExists,
  420. Format(lisUnableToAddTheDependencyBecauseThePackageHasAlread, [
  421. RequiredPackage.IDAsString, LazPackage.Name, ProvidingAPackage.Name]),
  422. mtError,[mbCancel]);
  423. exit(mrIgnore);
  424. end;
  425. Result:=mrOk;
  426. end;
  427. function CheckAddingPkgDependency(LazPackage: TLazPackage;
  428. RequiredPkg: TLazPackage; Quiet, WarnIfAlreadyThere: boolean): TModalResult;
  429. var
  430. NewDependency: TPkgDependency;
  431. begin
  432. NewDependency:=TPkgDependency.Create;
  433. try
  434. NewDependency.PackageName:=RequiredPkg.Name;
  435. Result:=CheckAddingDependency(LazPackage,NewDependency,Quiet,WarnIfAlreadyThere);
  436. finally
  437. NewDependency.Free;
  438. end;
  439. end;
  440. { TAddToPackageDlg }
  441. procedure TAddToPackageDlg.AddToPackageDlgClose(Sender: TObject;
  442. var CloseAction: TCloseAction);
  443. begin
  444. IDEDialogLayoutList.SaveLayout(Self);
  445. end;
  446. procedure TAddToPackageDlg.AddToPackageDlgKeyDown(Sender: TObject;
  447. var Key: Word; Shift: TShiftState);
  448. begin
  449. if (Key=VK_ESCAPE) and (Shift=[]) then
  450. ModalResult:=mrCancel;
  451. end;
  452. procedure TAddToPackageDlg.AncestorComboBoxChange(Sender: TObject);
  453. begin
  454. CheckNewCompOk;
  455. end;
  456. procedure TAddToPackageDlg.AncestorComboBoxCloseUp(Sender: TObject);
  457. begin
  458. if fLastNewComponentAncestorType<>AncestorComboBox.Text then
  459. AutoCompleteNewComponent;
  460. end;
  461. procedure TAddToPackageDlg.AncestorShowAllCheckBoxClick(Sender: TObject);
  462. begin
  463. UpdateAvailableAncestorTypes;
  464. end;
  465. procedure TAddToPackageDlg.CancelAddFileButtonClick(Sender: TObject);
  466. begin
  467. ModalResult:=mrCancel;
  468. end;
  469. procedure TAddToPackageDlg.CancelAddUnitButtonClick(Sender: TObject);
  470. begin
  471. ModalResult:=mrCancel;
  472. end;
  473. procedure TAddToPackageDlg.ClassNameEditChange(Sender: TObject);
  474. begin
  475. AutoCompleteNewComponentUnitName;
  476. CheckNewCompOk;
  477. end;
  478. procedure TAddToPackageDlg.ComponentIconBitBtnClick(Sender: TObject);
  479. var
  480. Dlg: TOpenPictureDialog;
  481. begin
  482. Dlg:=TOpenPictureDialog.Create(nil);
  483. try
  484. InputHistories.ApplyFileDialogSettings(Dlg);
  485. Dlg.InitialDir:=LazPackage.GetFileDialogInitialDir(ExtractFilePath(ComponentUnitFileEdit.Text));
  486. Dlg.Title:=lisTitleOpenComponentIcon24x24;
  487. Dlg.Options:=Dlg.Options+[ofPathMustExist];
  488. Dlg.Filter:=Format('%s|*.png|%s|*.bmp|%s|*.xpm|%s|%s',
  489. [dlgFilterImagesPng,
  490. dlgFilterImagesBitmap,
  491. dlgFilterImagesPixmap,
  492. dlgFilterAll, GetAllFilesMask]);
  493. if Dlg.Execute then begin
  494. LoadComponentIcon(Dlg.FileName);
  495. end;
  496. InputHistories.StoreFileDialogSettings(Dlg);
  497. finally
  498. Dlg.Free;
  499. end;
  500. end;
  501. procedure TAddToPackageDlg.ComponentUnitFileBrowseButtonClick(Sender: TObject);
  502. var
  503. SaveDialog: TSaveDialog;
  504. AFilename: string;
  505. begin
  506. SaveDialog:=TSaveDialog.Create(nil);
  507. try
  508. InputHistories.ApplyFileDialogSettings(SaveDialog);
  509. SaveDialog.InitialDir := LazPackage.GetFileDialogInitialDir(SaveDialog.InitialDir);
  510. SaveDialog.Title := lisSaveAs;
  511. SaveDialog.Options := SaveDialog.Options+[ofPathMustExist];
  512. SaveDialog.Filter := Format('%s|*.pas;*.pp', [dlgFilterPascalFile]);
  513. if SaveDialog.Execute then begin
  514. AFilename := CleanAndExpandFilename(SaveDialog.Filename);
  515. if FilenameIsPascalUnit(AFilename) then begin
  516. LazPackage.ShortenFilename(AFilename,true);
  517. ComponentUnitFileEdit.Text := AFilename;
  518. end else begin
  519. IDEMessageDialog(lisA2PInvalidFile,
  520. lisA2PAPascalUnitMustHaveTheExtensionPPOrPas,
  521. mtError,[mbCancel]);
  522. end;
  523. end;
  524. InputHistories.StoreFileDialogSettings(SaveDialog);
  525. finally
  526. SaveDialog.Free;
  527. end;
  528. end;
  529. procedure TAddToPackageDlg.ComponentUnitFileShortenButtonClick(Sender: TObject);
  530. begin
  531. if ''=ComponentUnitFileEdit.Text then exit;
  532. ComponentUnitFileEdit.Text:=SwitchRelativeAbsoluteFilename(ComponentUnitFileEdit.Text);
  533. end;
  534. procedure TAddToPackageDlg.ComponentUnitNameEditChange(Sender: TObject);
  535. begin
  536. CheckNewCompOk;
  537. end;
  538. procedure TAddToPackageDlg.DependPkgNameListBoxSelectionChange(Sender: TObject; User: boolean);
  539. begin
  540. CheckNewReqOk;
  541. end;
  542. procedure TAddToPackageDlg.FilesAddButtonClick(Sender: TObject);
  543. var
  544. i: Integer;
  545. Filename: String;
  546. NewFileType: TPkgFileType;
  547. HasRegisterProc: boolean;
  548. CurParams, LastParams: TAddToPkgResult;
  549. ok: Boolean;
  550. begin
  551. ok:=false;
  552. try
  553. LastParams:=nil;
  554. i:=0;
  555. while i<FilesListView.Items.Count do begin
  556. if not FilesListView.Items[i].Selected then begin
  557. Inc(i);
  558. Continue;
  559. end;
  560. Filename:=FilesListView.Items[i].Caption;
  561. LazPackage.LongenFilename(Filename);
  562. Assert(not DirPathExists(Filename));
  563. if LazPackage.FindPkgFile(Filename,true,false)<>nil then begin
  564. FilesListView.Items.Delete(i); // file already in package
  565. continue;
  566. end;
  567. if LastParams<>nil then begin
  568. LastParams.Next:=TAddToPkgResult.Create;
  569. CurParams:=LastParams.Next;
  570. end else
  571. CurParams:=Params;
  572. CurParams.Clear;
  573. CurParams.AddType:=d2ptFile;
  574. CurParams.UnitFilename:=Filename;
  575. NewFileType:=FileNameToPkgFileType(Filename);
  576. CurParams.FileType:=NewFileType;
  577. if NewFileType=pftUnit then begin
  578. CurParams.AddType:=d2ptUnit;
  579. Include(CurParams.PkgFileFlags,pffAddToPkgUsesSection);
  580. // check filename
  581. if not CheckAddingUnitFilename(LazPackage,CurParams.AddType,
  582. OnGetIDEFileInfo,CurParams.UnitFilename)
  583. then begin
  584. FilesListView.Items.Delete(i);
  585. exit;
  586. end;
  587. CurParams.AutoAddLFMFile:=true;
  588. CurParams.AutoAddLRSFile:=true;
  589. if Assigned(OnGetUnitRegisterInfo) then begin
  590. OnGetUnitRegisterInfo(Self,Filename,CurParams.Unit_Name,HasRegisterProc);
  591. if HasRegisterProc then
  592. Include(CurParams.PkgFileFlags,pffHasRegisterProc);
  593. end;
  594. // check unitname
  595. if CompareText(CurParams.Unit_Name,
  596. ExtractFileNameOnly(CurParams.UnitFilename))<>0
  597. then begin
  598. if IDEMessageDialog(lisA2PInvalidUnitName,
  599. Format(lisA2PTheUnitNameAndFilenameDiffer,
  600. [CurParams.Unit_Name, LineEnding, CurParams.UnitFilename]),
  601. mtError,[mbIgnore,mbCancel])<>mrIgnore
  602. then begin
  603. FilesListView.Items.Delete(i);
  604. exit;
  605. end;
  606. end;
  607. end;
  608. LastParams:=CurParams;
  609. inc(i);
  610. end;
  611. ButtonPanel1.OKButton.Enabled:=FilesListView.SelCount>0;
  612. ok:=LastParams<>nil;
  613. finally
  614. if not ok then Params.Clear;
  615. end;
  616. if LastParams=nil then begin
  617. exit;
  618. end;
  619. ModalResult:=mrOk;
  620. end;
  621. procedure TAddToPackageDlg.FilesDeleteButtonClick(Sender: TObject);
  622. var
  623. i: Integer;
  624. begin
  625. for i:=FilesListView.Items.Count-1 downto 0 do
  626. if FilesListView.Items[i].Selected then
  627. FilesListView.Items.Delete(i);
  628. CheckFilesButtonsOk;
  629. end;
  630. procedure TAddToPackageDlg.FilesDirButtonClick(Sender: TObject);
  631. var
  632. i: Integer;
  633. Files: TStrings;
  634. AFilename: string;
  635. NewListItem: TListItem;
  636. NewPgkFileType: TPkgFileType;
  637. begin
  638. Files:=nil;
  639. try
  640. if ShowAddDirToPkgDialog(LazPackage,Files)<>mrOk then exit;
  641. for i:=0 to Files.Count-1 do begin
  642. AFilename:=Files[i];
  643. if FindFileInFilesList(AFilename)<0 then begin
  644. LazPackage.ShortenFilename(AFilename,true);
  645. NewListItem:=FilesListView.Items.Add;
  646. NewListItem.Caption:=AFilename;
  647. NewPgkFileType:=FileNameToPkgFileType(AFilename);
  648. NewListItem.SubItems.Add(GetPkgFileTypeLocalizedName(NewPgkFileType));
  649. NewListItem.Selected:=True;
  650. end;
  651. end;
  652. CheckFilesButtonsOk;
  653. finally
  654. Files.Free;
  655. end;
  656. end;
  657. procedure TAddToPackageDlg.FilesListViewSelectItem(Sender: TObject;
  658. Item: TListItem; Selected: Boolean);
  659. begin
  660. CheckFilesButtonsOk;
  661. end;
  662. procedure TAddToPackageDlg.FilesShortenButtonClick(Sender: TObject);
  663. var
  664. SwitchToAbsolute: Boolean;
  665. i: Integer;
  666. Filename: String;
  667. begin
  668. if FilesListView.Items.Count=0 then exit;
  669. if (not LazPackage.HasDirectory)
  670. or (not FilenameIsAbsolute(LazPackage.Directory)) then exit;
  671. SwitchToAbsolute:=not FilenameIsAbsolute(FilesListView.Items[0].Caption);
  672. for i:=0 to FilesListView.Items.Count-1 do begin
  673. Filename:=FilesListView.Items[i].Caption;
  674. if SwitchToAbsolute then
  675. Filename:=CreateAbsolutePath(Filename,LazPackage.Directory)
  676. else
  677. Filename:=CreateRelativePath(Filename,LazPackage.Directory);
  678. FilesListView.Items[i].Caption:=Filename;
  679. end;
  680. end;
  681. function TAddToPackageDlg.CheckFilesButtonsOk: Boolean;
  682. begin
  683. FilesDeleteButton.Enabled:=FilesListView.SelCount>0;
  684. Result:=FilesListView.Items.Count>0;
  685. FilesShortenButton.Enabled:=Result;
  686. ButtonPanel1.OKButton.Enabled:=FilesListView.SelCount>0;
  687. end;
  688. procedure TAddToPackageDlg.FormCreate(Sender: TObject);
  689. begin
  690. Caption:=lisA2PAddToPackage;
  691. fPkgComponents:=TAVLTree.Create(@CompareIDEComponentByClassName);
  692. fPackages:=TAVLTree.Create(@CompareLazPackageID);
  693. Params:=TAddToPkgResult.Create;
  694. IDEDialogLayoutList.ApplyLayout(Self,500,300);
  695. SetupComponents;
  696. end;
  697. procedure TAddToPackageDlg.FormDestroy(Sender: TObject);
  698. begin
  699. FreeAndNil(fPkgComponents);
  700. FreeAndNil(fPackages);
  701. FreeAndNil(Params);
  702. end;
  703. procedure TAddToPackageDlg.FormShow(Sender: TObject);
  704. begin
  705. SelectNext(PageControl1.ActivePage, True, True);
  706. end;
  707. procedure TAddToPackageDlg.NewComponentButtonClick(Sender: TObject);
  708. var
  709. PkgFile: TPkgFile;
  710. PkgComponent: TPkgComponent;
  711. ARequiredPackage: TLazPackage;
  712. begin
  713. Params.Clear;
  714. Params.AddType:=d2ptNewComponent;
  715. Params.FileType:=pftUnit;
  716. Params.PkgFileFlags:=[pffHasRegisterProc,pffAddToPkgUsesSection];
  717. Params.AncestorType:=AncestorComboBox.Text;
  718. Params.NewClassName:=ClassNameEdit.Text;
  719. Params.PageName:=PalettePageCombobox.Text;
  720. Params.Unit_Name:=ComponentUnitNameEdit.Text;
  721. Params.UnitFilename:=ComponentUnitFileEdit.Text;
  722. Params.UsedUnitname:='';
  723. Params.IconFile:=FComponentIconFilename;
  724. // check Ancestor Type
  725. if not IsValidIdent(Params.AncestorType) then begin
  726. IDEMessageDialog(lisA2PInvalidAncestorType,
  727. Format(lisA2PTheAncestorTypeIsNotAValidPascalIdentifier, [Params.AncestorType]),
  728. mtError,[mbCancel]);
  729. exit;
  730. end;
  731. // check pagename
  732. if length(Params.PageName)>100 then begin
  733. IDEMessageDialog(lisA2PPageNameTooLong,
  734. Format(lisA2PThePageNameIsTooLongMax100Chars, [Params.PageName]),
  735. mtError,[mbCancel]);
  736. exit;
  737. end;
  738. // check unitname - filename redundancy
  739. if CompareText(Params.Unit_name,ExtractFileNameOnly(Params.UnitFilename))<>0
  740. then begin
  741. IDEMessageDialog(lisA2PUnitNameInvalid,
  742. Format(lisA2PTheUnitNameDoesNotCorrespondToTheFilename, [Params.Unit_Name]),
  743. mtError,[mbCancel]);
  744. exit;
  745. end;
  746. // check classname
  747. if not IsValidIdent(Params.NewClassName) then begin
  748. IDEMessageDialog(lisA2PInvalidClassName,
  749. Format(lisA2PTheClassNameIsNotAValidPascalIdentifier, [Params.NewClassName]),
  750. mtError,[mbCancel]);
  751. exit;
  752. end;
  753. // check classname<>ancestortype
  754. if CompareText(Params.NewClassName,Params.AncestorType)=0 then begin
  755. IDEMessageDialog(lisA2PInvalidCircularDependency,
  756. Format(lisA2PTheClassNameAndAncestorTypeAreTheSame,[Params.NewClassName,Params.AncestorType]),
  757. mtError,[mbCancel]);
  758. exit;
  759. end;
  760. // check ancestor type is not unitname
  761. PkgFile:=PackageGraph.FindUnit(LazPackage,Params.AncestorType,true,true);
  762. if PkgFile<>nil then begin
  763. if IDEMessageDialog(lisA2PAmbiguousAncestorType,
  764. Format(lisA2PTheAncestorTypeHasTheSameNameAsTheUnit,
  765. [Params.AncestorType, LineEnding, PkgFile.Filename]),
  766. mtError,[mbCancel,mbIgnore])<>mrIgnore
  767. then
  768. exit;
  769. end;
  770. // check classname does not interfere with an existing unitname
  771. PkgFile:=PackageGraph.FindUnit(LazPackage,Params.NewClassName,true,true);
  772. if PkgFile<>nil then begin
  773. if IDEMessageDialog(lisA2PAmbiguousClassName,
  774. Format(lisA2PTheClassNameHasTheSameNameAsTheUnit,
  775. [Params.AncestorType, LineEnding, PkgFile.Filename]),
  776. mtError,[mbCancel,mbIgnore])<>mrIgnore
  777. then
  778. exit;
  779. end;
  780. // check if classname already exists
  781. PkgComponent:=TPkgComponent(IDEComponentPalette.FindComponent(Params.NewClassname));
  782. if PkgComponent<>nil then begin
  783. if IDEMessageDialog(lisA2PClassNameAlreadyExists,
  784. Format(lisA2PTheClassNameExistsAlreadyInPackageFile, [Params.NewClassName, LineEnding,
  785. PkgComponent.PkgFile.LazPackage.IDAsString, LineEnding, PkgComponent.PkgFile.Filename]),
  786. mtError,[mbCancel,mbIgnore])<>mrIgnore
  787. then
  788. exit;
  789. end;
  790. // check filename
  791. if not CheckAddingUnitFilename(LazPackage,Params.AddType,
  792. OnGetIDEFileInfo,Params.UnitFilename) then exit;
  793. // create dependency if needed
  794. PkgComponent:=TPkgComponent(IDEComponentPalette.FindComponent(Params.AncestorType));
  795. if PkgComponent<>nil then begin
  796. Params.UsedUnitname:=PkgComponent.GetUnitName;
  797. ARequiredPackage:=PkgComponent.PkgFile.LazPackage;
  798. ARequiredPackage:=TLazPackage(PackageEditingInterface.RedirectPackageDependency(ARequiredPackage));
  799. if (LazPackage<>ARequiredPackage)
  800. and (not LazPackage.Requires(PkgComponent.PkgFile.LazPackage))
  801. then
  802. Params.Dependency:=ARequiredPackage.CreateDependencyWithOwner(nil);
  803. end;
  804. ModalResult:=mrOk;
  805. end;
  806. procedure TAddToPackageDlg.NewComponentPageResize(Sender: TObject);
  807. var
  808. x: Integer;
  809. begin
  810. x:=0;
  811. x:=Max(x,AncestorTypeLabel.Left+AncestorTypeLabel.Width);
  812. x:=Max(x,ClassNameLabel.Left+ClassNameLabel.Width);
  813. x:=Max(x,PalettePageLabel.Left+PalettePageLabel.Width);
  814. x:=Max(x,ComponentUnitFileLabel.Left+ComponentUnitFileLabel.Width);
  815. x:=Max(x,ComponentUnitNameLabel.Left+ComponentUnitNameLabel.Width);
  816. x:=Max(x,ComponentIconLabel.Left+ComponentIconLabel.Width);
  817. AncestorComboBox.Left:=x+6;
  818. end;
  819. procedure TAddToPackageDlg.NewDependButtonClick(Sender: TObject);
  820. var
  821. NewDependency: TPkgDependency;
  822. begin
  823. Params.Clear;
  824. Params.AddType:=d2ptRequiredPkg;
  825. NewDependency:=TPkgDependency.Create;
  826. try
  827. // check minimum version
  828. if DependMinVersionEdit.Text<>'' then begin
  829. if not NewDependency.MinVersion.ReadString(DependMinVersionEdit.Text) then
  830. begin
  831. IDEMessageDialog(lisProjAddInvalidVersion,
  832. Format(lisA2PTheMinimumVersionIsInvalidPleaseUseTheFormatMajor,
  833. [DependMinVersionEdit.Text, LineEnding, LineEnding]),
  834. mtError,[mbCancel]);
  835. exit;
  836. end;
  837. NewDependency.Flags:=NewDependency.Flags+[pdfMinVersion];
  838. end;
  839. // check maximum version
  840. if DependMaxVersionEdit.Text<>'' then begin
  841. if not NewDependency.MaxVersion.ReadString(DependMaxVersionEdit.Text) then
  842. begin
  843. IDEMessageDialog(lisProjAddInvalidVersion,
  844. Format(lisA2PTheMaximumVersionIsInvalidPleaseUseTheFormatMajor,
  845. [DependMaxVersionEdit.Text, LineEnding, LineEnding]),
  846. mtError,[mbCancel]);
  847. exit;
  848. end;
  849. NewDependency.Flags:=NewDependency.Flags+[pdfMaxVersion];
  850. end;
  851. NewDependency.PackageName:=DependPkgNameListBox.Items[DependPkgNameListBox.ItemIndex];
  852. ModalResult:=CheckAddingDependency(LazPackage,NewDependency,false,true);
  853. if ModalResult<>mrOk then exit;
  854. // ok
  855. Params.Dependency:=NewDependency;
  856. NewDependency:=nil;
  857. finally
  858. NewDependency.Free;
  859. end;
  860. end;
  861. procedure TAddToPackageDlg.SetLazPackage(const AValue: TLazPackage);
  862. begin
  863. if FLazPackage=AValue then exit;
  864. FLazPackage:=AValue;
  865. Params.Pkg:=FLazPackage;
  866. UpdateAvailableAncestorTypes;
  867. UpdateAvailablePageNames;
  868. UpdateAvailableDependencyNames;
  869. end;
  870. function TAddToPackageDlg.GetActivatePage: TAddToPkgType;
  871. begin
  872. if PageControl1.ActivePage=NewComponentPage then
  873. Result:=d2ptNewComponent
  874. else if PageControl1.ActivePage=NewRequirementPage then
  875. Result:=d2ptRequiredPkg
  876. else {if PageControl1.ActivePage=AddFilesPage then } begin
  877. Assert(PageControl1.ActivePage=AddFilesPage,
  878. 'TAddToPackageDlg.GetActivatePage: PageControl1.ActivePage <> AddFilesPage');
  879. Result:=d2ptFiles;
  880. end;
  881. //else
  882. // Result:=d2ptNewFile;
  883. end;
  884. procedure TAddToPackageDlg.SetActivatePage(AValue: TAddToPkgType);
  885. begin
  886. case AValue of
  887. d2ptNewComponent: PageControl1.ActivePage:=NewComponentPage;
  888. d2ptRequiredPkg: PageControl1.ActivePage:=NewRequirementPage;
  889. d2ptFiles: PageControl1.ActivePage:=AddFilesPage;
  890. else raise Exception.Create('TAddToPackageDlg.SetActivatePage: invalid value.');
  891. end;
  892. end;
  893. function TAddToPackageDlg.CheckNewCompOk: Boolean;
  894. begin
  895. Result:=(AncestorComboBox.Text<>'') and (ClassNameEdit.Text<>'') and (ComponentUnitNameEdit.Text<>'');
  896. ButtonPanel1.OKButton.Enabled:=Result;
  897. end;
  898. function TAddToPackageDlg.CheckNewReqOk: Boolean;
  899. begin
  900. Result:=DependPkgNameListBox.ItemIndex>-1;
  901. ButtonPanel1.OKButton.Enabled:=Result;
  902. end;
  903. procedure TAddToPackageDlg.PageControl1Change(Sender: TObject);
  904. begin
  905. case PageControl1.PageIndex of
  906. 0: begin // New Component
  907. ButtonPanel1.OkButton.Caption:=lisA2PCreateNewComp;
  908. ButtonPanel1.OkButton.OnClick:=@NewComponentButtonClick;
  909. CheckNewCompOk;
  910. end;
  911. 1: begin // New Requirement
  912. ButtonPanel1.OkButton.Caption:=lisA2PCreateNewReq;
  913. ButtonPanel1.OkButton.OnClick:=@NewDependButtonClick;
  914. CheckNewReqOk;
  915. end;
  916. 2: begin // Add Files
  917. ButtonPanel1.OkButton.Caption:=lisA2PAddFilesToPackage;
  918. ButtonPanel1.OkButton.OnClick:=@FilesAddButtonClick;
  919. CheckFilesButtonsOk;
  920. end;
  921. end;
  922. end;
  923. procedure TAddToPackageDlg.SetupComponents;
  924. begin
  925. //NewFilePage.Caption:=lisA2PNewFile;
  926. NewComponentPage.Caption:=lisA2PNewComponent;
  927. NewRequirementPage.Caption:=lisProjAddNewRequirement;
  928. AddFilesPage.Caption:=lisA2PAddFiles;
  929. ButtonPanel1.CancelButton.Caption:=lisCancel;
  930. PageControl1.PageIndex:=0;
  931. PageControl1Change(PageControl1);
  932. //SetupNewFilePage;
  933. SetupNewComponentPage;
  934. SetupAddDependencyPage;
  935. SetupAddFilesPage;
  936. end;
  937. procedure TAddToPackageDlg.SetupNewComponentPage;
  938. begin
  939. AncestorTypeLabel.Caption:=lisA2PAncestorType;
  940. AncestorComboBox.Text:='';
  941. AncestorShowAllCheckBox.Caption:=lisA2PShowAll;
  942. ClassNameLabel.Caption:=lisA2PNewClassName;
  943. ClassNameEdit.Text:='';
  944. PalettePageLabel.Caption:=lisA2PPalettePage;
  945. PalettePageCombobox.Text:='';
  946. ComponentUnitFileLabel.Caption:=lisA2PUnitFileName2;
  947. ComponentUnitFileEdit.Text:='';
  948. with ComponentUnitFileBrowseButton do begin
  949. Caption:='...';
  950. ShowHint:=true;
  951. Hint:=lisA2PSaveFileDialog;
  952. end;
  953. with ComponentUnitFileShortenButton do begin
  954. Caption:='<>';
  955. ShowHint:=true;
  956. Hint:=lisA2PShortenOrExpandFilename;
  957. end;
  958. ComponentUnitNameLabel.Caption:=lisA2PUnitName;
  959. ComponentUnitNameEdit.Text:='';
  960. ComponentIconLabel.Caption:=lisA2PIconAndSize;
  961. ComponentIconBitBtn.Width:=ComponentPaletteBtnWidth;
  962. ComponentIconBitBtn.Height:=ComponentPaletteBtnHeight;
  963. end;
  964. procedure TAddToPackageDlg.SetupAddDependencyPage;
  965. begin
  966. DependPkgNameLabel.Caption:=lisProjAddPackageName;
  967. DependMinVersionLabel.Caption:=lisProjAddMinimumVersionOptional;
  968. DependMinVersionEdit.Text:='';
  969. DependMaxVersionLabel.Caption:=lisProjAddMaximumVersionOptional;
  970. DependMaxVersionEdit.Text:='';
  971. end;
  972. procedure TAddToPackageDlg.SetupAddFilesPage;
  973. var
  974. CurColumn: TListColumn;
  975. begin
  976. with FilesListView do begin
  977. CurColumn:=Columns[0];
  978. CurColumn.Width:=200;
  979. CurColumn.Caption:=lisA2PFilename2;
  980. CurColumn:=Columns[1];
  981. CurColumn.Caption:=dlgEnvType;
  982. end;
  983. with FilesDirButton do begin
  984. Caption:=lisAddFilesInDirectory;
  985. LoadGlyphFromResourceName(HInstance, 'pkg_files');
  986. end;
  987. with FilesShortenButton do begin
  988. Caption:=lisA2PSwitchPaths;
  989. ShowHint:=true;
  990. Hint:=lisToggleShowingFilenamesWithFullPathOrWithRelativePa;
  991. end;
  992. with FilesDeleteButton do begin
  993. Caption:=lisDelete;
  994. ShowHint:=true;
  995. Hint:=lisDeleteSelectedFiles;
  996. LoadGlyphFromResourceName(HInstance, 'laz_delete');
  997. end;
  998. LabelIconInfo.Caption:=lisNoneClickToChooseOne;
  999. end;
  1000. procedure TAddToPackageDlg.OnIterateComponentClasses(PkgComponent: TPkgComponent);
  1001. begin
  1002. if fPkgComponents.Find(PkgComponent)=nil then
  1003. fPkgComponents.Add(PkgComponent);
  1004. end;
  1005. procedure TAddToPackageDlg.OnIteratePackages(APackageID: TLazPackageID);
  1006. begin
  1007. if (APackageID<>LazPackage) and (fPackages.Find(APackageID)=nil) then begin
  1008. //DebugLn(['TAddToPackageDlg.OnIteratePackages ',APackageID.IDAsString,' ',DbgSName(APackageID)]);
  1009. fPackages.Add(APackageID);
  1010. end;
  1011. end;
  1012. procedure TAddToPackageDlg.AutoCompleteNewComponent;
  1013. var
  1014. PkgComponent: TPkgComponent;
  1015. begin
  1016. fLastNewComponentAncestorType:=AncestorComboBox.Text;
  1017. if not IsValidIdent(fLastNewComponentAncestorType) then exit;
  1018. PkgComponent:=TPkgComponent(
  1019. IDEComponentPalette.FindComponent(fLastNewComponentAncestorType));
  1020. // create unique classname
  1021. if (not IsValidIdent(ClassNameEdit.Text)) or (ClassNameEdit.Text='') then
  1022. ClassNameEdit.Text:=IDEComponentPalette.CreateNewClassName(
  1023. fLastNewComponentAncestorType);
  1024. // choose the same page name
  1025. if (PalettePageCombobox.Text='')
  1026. and (PkgComponent<>nil) and (PkgComponent.RealPage<>nil) then
  1027. PalettePageCombobox.Text:=PkgComponent.RealPage.PageName;
  1028. // filename
  1029. AutoCompleteNewComponentUnitName;
  1030. ButtonPanel1.OkButton.Enabled:=True;
  1031. end;
  1032. procedure TAddToPackageDlg.AutoCompleteNewComponentUnitName;
  1033. var
  1034. CurClassName: String;
  1035. NewUnitName: String;
  1036. NewFileName: String;
  1037. begin
  1038. // check if update needed
  1039. CurClassName:=ClassNameEdit.Text;
  1040. if fLastNewComponentClassName=CurClassName then exit;
  1041. fLastNewComponentClassName:=CurClassName;
  1042. // check classname
  1043. if not IsValidIdent(CurClassName) then exit;
  1044. // create unitname
  1045. NewUnitName:=CurClassName;
  1046. if NewUnitName[1]='T' then
  1047. NewUnitName:=copy(NewUnitName,2,length(NewUnitName)-1);
  1048. NewUnitName:=PackageGraph.CreateUniqueUnitName(NewUnitName);
  1049. ComponentUnitNameEdit.Text:=NewUnitName;
  1050. // create filename
  1051. NewFileName:=NewUnitName;
  1052. if EnvironmentOptions.CharcaseFileAction in [ccfaAsk, ccfaAutoRename] then
  1053. NewFileName:=lowercase(NewFileName);
  1054. // append pascal file extension
  1055. NewFileName:=NewFileName
  1056. +EnvironmentOpts.PascalExtension[EnvironmentOptions.PascalFileExtension];
  1057. // prepend path
  1058. if LazPackage.HasDirectory then
  1059. NewFileName:=LazPackage.Directory+NewFileName;
  1060. ComponentUnitFileEdit.Text:=NewFileName;
  1061. end;
  1062. function TAddToPackageDlg.SwitchRelativeAbsoluteFilename(const Filename: string
  1063. ): string;
  1064. begin
  1065. Result:=Filename;
  1066. if (not LazPackage.HasDirectory)
  1067. or (not FilenameIsAbsolute(LazPackage.Directory)) then exit;
  1068. if FilenameIsAbsolute(Filename) then
  1069. Result:=TrimFilename(CreateRelativePath(Filename,LazPackage.Directory))
  1070. else
  1071. Result:=TrimFilename(CreateAbsoluteSearchPath(Filename,LazPackage.Directory));
  1072. end;
  1073. function TAddToPackageDlg.FindFileInFilesList(AFilename: string): Integer;
  1074. var
  1075. i: Integer;
  1076. Item: TListItem;
  1077. OtherFilename: String;
  1078. begin
  1079. if not FilenameIsAbsolute(AFilename) then
  1080. LazPackage.LongenFilename(AFilename);
  1081. for i:=0 to FilesListView.Items.Count-1 do begin
  1082. Item:=FilesListView.Items[i];
  1083. OtherFilename:=Item.Caption;
  1084. if not FilenameIsAbsolute(OtherFilename) then
  1085. LazPackage.LongenFilename(OtherFilename);
  1086. if CompareFilenames(AFilename,OtherFilename)=0 then begin
  1087. Result:=i;
  1088. exit;
  1089. end;
  1090. end;
  1091. Result:=-1;
  1092. end;
  1093. procedure TAddToPackageDlg.LoadComponentIcon(AFilename: string);
  1094. var
  1095. ShortFilename: String;
  1096. Image: TImage;
  1097. begin
  1098. try
  1099. Image:=TImage.Create(nil);
  1100. try
  1101. Image.Picture.LoadFromFile(AFilename);
  1102. ComponentIconBitBtn.Glyph.Assign(Image.Picture.Graphic);
  1103. ShortFilename:=AFilename;
  1104. LazPackage.ShortenFilename(ShortFilename,true);
  1105. LabelIconInfo.Caption:= Format('%s (%dx%d)',
  1106. [ShortFilename, ComponentIconBitBtn.Glyph.Width, ComponentIconBitBtn.Glyph.Height]);
  1107. FComponentIconFilename:=AFilename;
  1108. finally
  1109. Image.Free;
  1110. end;
  1111. except
  1112. on E: Exception do begin
  1113. IDEMessageDialog(lisCCOErrorCaption,
  1114. Format(lisErrorLoadingFile2,[AFilename]) + LineEnding + E.Message,
  1115. mtError, [mbCancel]);
  1116. ComponentIconBitBtn.Glyph.Clear;
  1117. FComponentIconFilename:='';
  1118. LabelIconInfo.Caption:=lisNoneClickToChooseOne;
  1119. end;
  1120. end;
  1121. end;
  1122. procedure TAddToPackageDlg.UpdateAvailableAncestorTypes;
  1123. var
  1124. ANode: TAVLTreeNode;
  1125. sl: TStringList;
  1126. OldAncestorType: String;
  1127. begin
  1128. // get all available registered components
  1129. fPkgComponents.Clear;
  1130. if AncestorShowAllCheckBox.Checked then begin
  1131. PackageGraph.IterateAllComponentClasses(@OnIterateComponentClasses);
  1132. end else begin
  1133. PackageGraph.IterateComponentClasses(LazPackage,@OnIterateComponentClasses,
  1134. true,true);
  1135. end;
  1136. // put them into a list
  1137. sl:=TStringList.Create;
  1138. ANode:=fPkgComponents.FindLowest;
  1139. while ANode<>nil do begin
  1140. sl.Add(TPkgComponent(ANode.Data).ComponentClass.ClassName);
  1141. ANode:=fPkgComponents.FindSuccessor(ANode);
  1142. end;
  1143. // add at least TComponent
  1144. sl.Add('TComponent');
  1145. sl.Sort;
  1146. // put them into the combobox
  1147. OldAncestorType:=AncestorComboBox.Text;
  1148. AncestorComboBox.Items.Assign(sl);
  1149. AncestorComboBox.Text:=OldAncestorType;
  1150. sl.Free;
  1151. end;
  1152. procedure TAddToPackageDlg.UpdateAvailablePageNames;
  1153. var
  1154. i: Integer;
  1155. APageName: String;
  1156. sl: TStringList;
  1157. begin
  1158. // get all current pagenames (excluding the hidden page)
  1159. sl:=TStringList.Create;
  1160. for i:=0 to IDEComponentPalette.Pages.Count-1 do begin
  1161. APageName:=IDEComponentPalette.Pages[i].PageName;
  1162. if APageName<>'' then
  1163. sl.Add(APageName);
  1164. end;
  1165. sl.Sort;
  1166. PalettePageCombobox.Items.Assign(sl);
  1167. sl.Free;
  1168. end;
  1169. procedure TAddToPackageDlg.UpdateAvailableDependencyNames;
  1170. var
  1171. ANode: TAVLTreeNode;
  1172. sl: TStringList;
  1173. PkgName: String;
  1174. Pkg: TLazPackage;
  1175. begin
  1176. fPackages.Clear;
  1177. PackageGraph.IteratePackages(fpfSearchAllExisting,@OnIteratePackages);
  1178. sl:=TStringList.Create;
  1179. ANode:=fPackages.FindLowest;
  1180. while ANode<>nil do begin
  1181. Pkg:=TLazPackage(ANode.Data);
  1182. PkgName:=Pkg.Name;
  1183. if (sl.IndexOf(PkgName)<0) then
  1184. sl.Add(PkgName);
  1185. ANode:=fPackages.FindSuccessor(ANode);
  1186. end;
  1187. DependPkgNameFilter.Items.Assign(sl);
  1188. DependPkgNameFilter.InvalidateFilter;
  1189. sl.Free;
  1190. end;
  1191. { TAddToPkgResult }
  1192. procedure TAddToPkgResult.Clear;
  1193. begin
  1194. AddType:=d2ptUnit;
  1195. Dependency:=nil;
  1196. UnitFilename:='';
  1197. Unit_Name:='';
  1198. AncestorType:='';
  1199. NewClassName:='';
  1200. PageName:='';
  1201. FileType:=pftUnit;
  1202. PkgFileFlags:=[];
  1203. UsedUnitname:='';
  1204. AutoAddLFMFile:=false;
  1205. AutoAddLRSFile:=false;
  1206. FreeThenNil(Next);
  1207. end;
  1208. destructor TAddToPkgResult.Destroy;
  1209. begin
  1210. FreeThenNil(Next);
  1211. inherited Destroy;
  1212. end;
  1213. end.