~ubuntu-branches/ubuntu/saucy/lazarus/saucy

« back to all changes in this revision

Viewing changes to packager/pkgmanager.pas

  • Committer: Package Import Robot
  • Author(s): Paul Gevers, Abou Al Montacir, Bart Martens, Paul Gevers
  • Date: 2013-06-08 14:12:17 UTC
  • mfrom: (1.1.9)
  • Revision ID: package-import@ubuntu.com-20130608141217-7k0cy9id8ifcnutc
Tags: 1.0.8+dfsg-1
[ Abou Al Montacir ]
* New upstream major release and multiple maintenace release offering many
  fixes and new features marking a new milestone for the Lazarus development
  and its stability level.
  - The detailed list of changes can be found here:
    http://wiki.lazarus.freepascal.org/Lazarus_1.0_release_notes
    http://wiki.lazarus.freepascal.org/Lazarus_1.0_fixes_branch
* LCL changes:
  - LCL is now a normal package.
      + Platform independent parts of the LCL are now in the package LCLBase
      + LCL is automatically recompiled when switching the target platform,
        unless pre-compiled binaries for this target are already installed.
      + No impact on existing projects.
      + Linker options needed by LCL are no more added to projects that do
        not use the LCL package.
  - Minor changes in LCL basic classes behaviour
      + TCustomForm.Create raises an exception if a form resource is not
        found.
      + TNotebook and TPage: a new implementation of these classes was added.
      + TDBNavigator: It is now possible to have focusable buttons by setting
        Options = [navFocusableButtons] and TabStop = True, useful for
        accessibility and for devices with neither mouse nor touch screen.
      + Names of TControlBorderSpacing.GetSideSpace and GetSpace were swapped
        and are now consistent. GetSideSpace = Around + GetSpace.
      + TForm.WindowState=wsFullscreen was added
      + TCanvas.TextFitInfo was added to calculate how many characters will
        fit into a specified Width. Useful for word-wrapping calculations.
      + TControl.GetColorResolvingParent and
        TControl.GetRGBColorResolvingParent were added, simplifying the work
        to obtain the final color of the control while resolving clDefault
        and the ParentColor.
      + LCLIntf.GetTextExtentExPoint now has a good default implementation
        which works in any platform not providing a specific implementation.
        However, Widgetset specific implementation is better, when available.
      + TTabControl was reorganized. Now it has the correct class hierarchy
        and inherits from TCustomTabControl as it should.
  - New unit in the LCL:
      + lazdialogs.pas: adds non-native versions of various native dialogs,
        for example TLazOpenDialog, TLazSaveDialog, TLazSelectDirectoryDialog.
        It is used by widgetsets which either do not have a native dialog, or
        do not wish to use it because it is limited. These dialogs can also be
        used by user applications directly.
      + lazdeviceapis.pas: offers an interface to more hardware devices such
        as the accelerometer, GPS, etc. See LazDeviceAPIs
      + lazcanvas.pas: provides a TFPImageCanvas descendent implementing
        drawing in a LCL-compatible way, but 100% in Pascal.
      + lazregions.pas. LazRegions is a wholly Pascal implementation of
        regions for canvas clipping, event clipping, finding in which control
        of a region tree one an event should reach, for drawing polygons, etc.
      + customdrawncontrols.pas, customdrawndrawers.pas,
        customdrawn_common.pas, customdrawn_android.pas and
        customdrawn_winxp.pas: are the Lazarus Custom Drawn Controls -controls
        which imitate the standard LCL ones, but with the difference that they
        are non-native and support skinning.
  - New APIs added to the LCL to improve support of accessibility software
    such as screen readers.
* IDE changes:
  - Many improvments.
  - The detailed list of changes can be found here:
    http://wiki.lazarus.freepascal.org/New_IDE_features_since#v1.0_.282012-08-29.29
    http://wiki.lazarus.freepascal.org/Lazarus_1.0_release_notes#IDE_Changes
* Debugger / Editor changes:
  - Added pascal sources and breakpoints to the disassembler
  - Added threads dialog.
* Components changes:
  - TAChart: many fixes and new features
  - CodeTool: support Delphi style generics and new syntax extensions.
  - AggPas: removed to honor free licencing. (Closes: Bug#708695)
[Bart Martens]
* New debian/watch file fixing issues with upstream RC release.
[Abou Al Montacir]
* Avoid changing files in .pc hidden directory, these are used by quilt for
  internal purpose and could lead to surprises during build.
[Paul Gevers]
* Updated get-orig-source target and it compinion script orig-tar.sh so that they
  repack the source file, allowing bug 708695 to be fixed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
45
45
  {$ENDIF}
46
46
  // FCL, LCL
47
47
  TypInfo, Classes, SysUtils, LCLProc, Forms, Controls, Dialogs, Menus,
48
 
  InterfaceBase, StringHashList, Translations, LResources,
 
48
  contnrs, StringHashList, Translations, LResources,
49
49
  // codetools
50
 
  CodeToolsCfgScript, CodeToolsConfig, CodeToolManager, CodeCache,
51
 
  BasicCodeTools, FileProcs, Laz_XMLCfg,
 
50
  CodeToolsConfig, CodeToolManager, CodeCache, CodeToolsStructs, BasicCodeTools,
 
51
  FileProcs, Laz2_XMLCfg, lazutf8classes,
52
52
  // IDE Interface
53
 
  SrcEditorIntf, NewItemIntf, ProjectIntf, PackageIntf,
 
53
  SrcEditorIntf, NewItemIntf, ProjectIntf, PackageIntf, CompOptsIntf,
54
54
  MenuIntf, IDEWindowIntf, PropEdits, MacroIntf, LazIDEIntf,
55
55
  // IDE
56
 
  LazConf, LazarusIDEStrConsts, IDEProcs, ObjectLists, DialogProcs, IDECommands,
 
56
  LazarusIDEStrConsts, IDEProcs, ObjectLists, DialogProcs, IDECommands,
57
57
  IDEOptionDefs, EnvironmentOpts, MiscOptions, InputHistory,
58
58
  Project, ComponentReg, UComponentManMain, PackageEditor, AddToPackageDlg,
59
59
  PackageDefs, PackageLinks, PackageSystem, OpenInstalledPkgDlg,
61
61
  IDETranslations, TransferMacros, BuildLazDialog, NewDialog,
62
62
  IDEDialogs, ProjectInspector, ComponentPalette, SourceEditor,
63
63
  AddFileToAPackageDlg, LazarusPackageIntf, PublishProjectDlg, PkgLinksDlg,
64
 
  InstallPkgSetDlg, ConfirmPkgListDlg,
 
64
  InstallPkgSetDlg, ConfirmPkgListDlg, NewPkgComponentDlg,
65
65
  // bosses
66
 
  BaseBuildManager, BasePkgManager,
67
 
  MainBar, MainIntf, MainBase;
 
66
  BaseBuildManager, BasePkgManager, MainBar, MainIntf, MainBase;
68
67
 
69
68
type
70
69
  { TPkgManager }
72
71
  TPkgManager = class(TBasePkgManager)
73
72
    // events - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
74
73
    // package editor
 
74
    function OnPackageEditorAddToProject(Sender: TObject; APackage: TLazPackage;
 
75
                                     OnlyTestIfPossible: boolean): TModalResult;
75
76
    function OnPackageEditorCompilePackage(Sender: TObject;
76
77
                          APackage: TLazPackage;
77
78
                          CompileClean, CompileRequired: boolean): TModalResult;
78
 
    function OnPackageEditorCreateMakefile(Sender: TObject;
79
 
                                           APackage: TLazPackage): TModalResult;
80
79
    function OnPackageEditorCreateFile(Sender: TObject;
81
80
                                       Params: TAddToPkgResult): TModalResult;
 
81
    function OnPackageEditorCreateMakefile(Sender: TObject;
 
82
                                           APackage: TLazPackage): TModalResult;
82
83
    function OnPackageEditorDeleteAmbiguousFiles(Sender: TObject;
83
84
      APackage: TLazPackage; const Filename: string): TModalResult;
84
 
    function OnPackageEditorAddToProject(Sender: TObject; APackage: TLazPackage;
85
 
                                     OnlyTestIfPossible: boolean): TModalResult;
86
85
    function OnPackageEditorInstallPackage(Sender: TObject;
87
86
                                           APackage: TLazPackage): TModalResult;
 
87
    function OnPackageEditorOpenPackage(Sender: TObject; APackage: TLazPackage
 
88
                                        ): TModalResult;
 
89
    function OnPackageEditorOpenPkgFile(Sender: TObject; PkgFile: TPkgFile
 
90
                                        ): TModalResult;
88
91
    function OnPackageEditorPublishPackage(Sender: TObject;
89
92
      APackage: TLazPackage): TModalResult;
90
93
    function OnPackageEditorRevertPackage(Sender: TObject; APackage: TLazPackage
91
94
      ): TModalResult;
92
 
    function OnPackageEditorUninstallPackage(Sender: TObject;
93
 
                                           APackage: TLazPackage): TModalResult;
94
 
    function OnPackageEditorOpenPkgFile(Sender: TObject; PkgFile: TPkgFile
95
 
                                        ): TModalResult;
96
 
    function OnPackageEditorOpenPackage(Sender: TObject; APackage: TLazPackage
97
 
                                        ): TModalResult;
98
95
    function OnPackageEditorSavePackage(Sender: TObject; APackage: TLazPackage;
99
96
                                        SaveAs: boolean): TModalResult;
 
97
    function OnPackageEditorUninstallPackage(Sender: TObject;
 
98
                                           APackage: TLazPackage): TModalResult;
100
99
    function OnPackageEditorViewPkgSource(Sender: TObject;
101
100
                                          APackage: TLazPackage): TModalResult;
 
101
    procedure OnAfterWritePackage(Sender: TObject; Restore: boolean);
 
102
    procedure OnBeforeReadPackage(Sender: TObject);
102
103
    procedure OnPackageEditorFreeEditor(APackage: TLazPackage);
103
104
    procedure OnPackageEditorGetUnitRegisterInfo(Sender: TObject;
104
105
                              const AFilename: string; var TheUnitName: string;
125
126
    procedure MainIDEitmPkgOpenPackageFileClick(Sender: TObject);
126
127
    procedure MainIDEitmPkgPkgGraphClick(Sender: TObject);
127
128
    procedure MainIDEitmPkgEditInstallPkgsClick(Sender: TObject);
128
 
    procedure MainIDEitmPkgAddCurUnitToPkgClick(Sender: TObject);
 
129
    procedure MainIDEitmPkgAddCurFileToPkgClick(Sender: TObject);
 
130
    procedure MainIDEitmPkgNewComponentClick(Sender: TObject);
129
131
    procedure MainIDEitmPkgOpenPackageOfCurUnitClicked(Sender: TObject);
130
132
    procedure MainIDEitmConfigCustomCompsClicked(Sender: TObject);
131
133
    procedure MainIDEitmOpenRecentPackageClicked(Sender: TObject);
154
156
                                            out Description: string);
155
157
    procedure GetDependencyOwnerDirectory(Dependency: TPkgDependency;
156
158
                                          out Directory: string);
157
 
    procedure GetWritablePkgOutputDirectory(APackage: TLazPackage;
158
 
                                            var AnOutDirectory: string);
159
159
    procedure PackageFileLoaded(Sender: TObject);
160
 
    procedure OnCheckInstallPackageList(PkgIDList: TFPList; out Ok: boolean);
161
 
    function LoadDependencyList(FirstDependency: TPkgDependency): TModalResult;
 
160
    procedure OnCheckInstallPackageList(PkgIDList: TObjectList;
 
161
                                     RemoveConflicts: boolean; out Ok: boolean);
 
162
    function LoadDependencyList(FirstDependency: TPkgDependency;
 
163
                                Quiet: boolean): TModalResult;
162
164
    procedure CreateIDEWindow(Sender: TObject; aFormName: string;
163
165
                          var AForm: TCustomForm; DoDisableAutoSizing: boolean);
164
166
  private
172
174
    function DoGetUnitRegisterInfo(const AFilename: string;
173
175
                          var TheUnitName: string; var HasRegisterProc: boolean;
174
176
                          IgnoreErrors: boolean): TModalResult;
175
 
    procedure SaveAutoInstallDependencies(SetWithStaticPcksFlagForIDE: boolean);
 
177
    procedure SaveAutoInstallDependencies;
176
178
    procedure LoadStaticCustomPackages;
177
179
    function LoadInstalledPackage(const PackageName: string;
178
180
                    AddToAutoInstall: boolean; var Quiet: boolean): TLazPackage;
213
215
    function GetSourceFilesOfOwners(OwnerList: TFPList): TStrings; override;
214
216
    function GetPossibleOwnersOfUnit(const UnitFilename: string;
215
217
                                     Flags: TPkgIntfOwnerSearchFlags): TFPList; override;
216
 
    function GetPackageOfCurrentSourceEditor: TPkgFile;
217
 
    function AddDependencyToOwners(OwnerList: TFPList; APackage: TLazPackage;
 
218
    function GetPackageOfCurrentSourceEditor(out APackage: TIDEPackage): TPkgFile;
 
219
    function GetPackageOfSourceEditor(out APackage: TIDEPackage; ASrcEdit: TObject): TLazPackageFile; override;
 
220
    function IsOwnerDependingOnPkg(AnOwner: TObject; const PkgName: string;
 
221
                                   out DependencyOwner: TObject): boolean; override;
 
222
    function AddDependencyToOwners(OwnerList: TFPList; APackage: TIDEPackage;
218
223
                   OnlyTestIfPossible: boolean = false): TModalResult; override;
219
224
    function DoOpenPkgFile(PkgFile: TPkgFile): TModalResult;
220
225
    function FindVirtualUnitSource(PkgFile: TPkgFile): string;
237
242
    procedure LazarusSrcDirChanged; override;
238
243
    function GetPackageCount: integer; override;
239
244
    function GetPackages(Index: integer): TIDEPackage; override;
240
 
    function FindPackageWithName(const PkgName: string): TIDEPackage; override;
241
 
 
 
245
    function FindPackageWithName(const PkgName: string; IgnorePackage: TIDEPackage = nil): TIDEPackage; override;
 
246
    function RedirectPackageDependency(APackage: TIDEPackage): TIDEPackage; override;
242
247
 
243
248
    // project
244
249
    function OpenProjectDependencies(AProject: TProject;
247
252
                                  Interactive: boolean): TModalResult; override;
248
253
    function CanOpenDesignerForm(AnUnitInfo: TUnitInfo; 
249
254
                                 Interactive: boolean): TModalResult; override;
250
 
    procedure AddDefaultDependencies(AProject: TProject); override;
251
255
    function AddProjectDependency(AProject: TProject; APackage: TLazPackage;
252
256
                                  OnlyTestIfPossible: boolean = false): TModalResult; override;
253
257
    function AddProjectDependency(AProject: TProject;
282
286
    function DoClosePackageEditor(APackage: TLazPackage): TModalResult; override;
283
287
    function DoCloseAllPackageEditors: TModalResult; override;
284
288
    function DoAddActiveUnitToAPackage: TModalResult;
 
289
    function DoNewPackageComponent: TModalResult;
 
290
    function SavePackageFiles(APackage: TLazPackage): TModalResult;
285
291
    function WarnAboutMissingPackageFiles(APackage: TLazPackage): TModalResult;
286
292
    function AddPackageDependency(APackage: TLazPackage; const ReqPackage: string;
287
293
                                  OnlyTestIfPossible: boolean = false): TModalResult; override;
288
294
    function GetPackageOfEditorItem(Sender: TObject): TIDEPackage; override;
289
295
 
290
 
 
291
296
    // package compilation
292
297
    function DoCompileProjectDependencies(AProject: TProject;
293
298
                               Flags: TPkgCompileFlags): TModalResult; override;
294
299
    function DoCompilePackage(APackage: TLazPackage; Flags: TPkgCompileFlags;
295
 
                              ShowAbort: boolean;
296
 
                              Globals: TGlobalCompilerOptions = nil): TModalResult; override;
 
300
                              ShowAbort: boolean): TModalResult; override;
297
301
    function DoCreatePackageMakefile(APackage: TLazPackage;
298
302
                                     ShowAbort: boolean): TModalResult;
299
303
 
304
308
    function DoInstallPackage(APackage: TLazPackage): TModalResult;
305
309
    function DoUninstallPackage(APackage: TLazPackage;
306
310
                   Flags: TPkgUninstallFlags; ShowAbort: boolean): TModalResult;
307
 
    function DoInstallPackages(PkgIdList: TFPList; AddExisting, RebuildIDE, Quiet: boolean;
308
 
                               CheckList: boolean = true): TModalResult;
 
311
    function CheckInstallPackageList(PkgIDList: TObjectList;
 
312
                          Flags: TPkgInstallInIDEFlags = []
 
313
                          ): boolean; override;
 
314
    function InstallPackages(PkgIdList: TObjectList;
 
315
                             Flags: TPkgInstallInIDEFlags = []): TModalResult; override;
309
316
    procedure DoTranslatePackage(APackage: TLazPackage);
310
317
    function DoOpenPackageSource(APackage: TLazPackage): TModalResult;
311
318
    function DoCompileAutoInstallPackages(Flags: TPkgCompileFlags;
406
413
procedure TPkgManager.MainIDEitmPkgEditInstallPkgsClick(Sender: TObject);
407
414
var
408
415
  RebuildIDE: Boolean;
409
 
  PkgIDList: TFPList;
 
416
  PkgIDList: TObjectList;
 
417
  Flags: TPkgInstallInIDEFlags;
410
418
begin
411
419
  RebuildIDE:=false;
412
420
  PkgIDList:=nil;
415
423
      @OnCheckInstallPackageList,PkgIDList,RebuildIDE)<>mrOk
416
424
    then exit;
417
425
 
418
 
    DoInstallPackages(PkgIDList,false,RebuildIDE,false,true);
 
426
    Flags:=[piiifSkipChecks,piiifClear];
 
427
    if RebuildIDE then Include(Flags,piiifRebuildIDE);
 
428
    InstallPackages(PkgIDList,Flags);
419
429
  finally
420
 
    if PkgIDList<>nil then FreeListObjects(PkgIDList,true);
 
430
    PkgIDList.Free;
421
431
  end;
422
432
end;
423
433
 
450
460
    if PkgFile.FileType=pftVirtualUnit then
451
461
      Filename:=FindVirtualUnitSource(PkgFile);
452
462
    if Filename='' then
453
 
      Filename:=PkgFile.Filename;
 
463
      Filename:=PkgFile.GetFullFilename;
454
464
    MainIDE.DoOpenFileAndJumpToIdentifier(
455
465
      Filename,PkgComponent.ComponentClass.ClassName,
456
466
      -1, -1, // open page somewhere
470
480
  GetDirectoryOfDependencyOwner(Dependency,Directory);
471
481
end;
472
482
 
473
 
procedure TPkgManager.GetWritablePkgOutputDirectory(APackage: TLazPackage;
474
 
  var AnOutDirectory: string);
475
 
var
476
 
  NewOutDir: String;
477
 
begin
478
 
  if DirectoryIsWritableCached(AnOutDirectory) then exit;
479
 
 
480
 
  ForceDirectory(AnOutDirectory);
481
 
  InvalidateFileStateCache;
482
 
  if DirectoryIsWritableCached(AnOutDirectory) then exit;
483
 
  //debugln('TPkgManager.GetWritablePkgOutputDirectory AnOutDirectory=',AnOutDirectory,' ',dbgs(DirectoryIsWritable(AnOutDirectory)));
484
 
  
485
 
  // output directory is not writable
486
 
  // -> redirect to config directory
487
 
  NewOutDir:=SetDirSeparators('/$(TargetCPU)-$(TargetOS)');
488
 
  IDEMacros.SubstituteMacros(NewOutDir);
489
 
  NewOutDir:=TrimFilename(GetPrimaryConfigPath+PathDelim+'lib'+PathDelim
490
 
                          +APackage.Name+NewOutDir);
491
 
  AnOutDirectory:=NewOutDir;
492
 
  debugln('TPkgManager.GetWritablePkgOutputDirectory APackage=',APackage.IDAsString,' AnOutDirectory="',AnOutDirectory,'"');
493
 
end;
494
 
 
495
483
procedure TPkgManager.PackageFileLoaded(Sender: TObject);
496
484
begin
497
485
  DoCallNotifyHandler(pihtPackageFileLoaded,Sender);
498
486
end;
499
487
 
500
 
procedure TPkgManager.OnCheckInstallPackageList(PkgIDList: TFPList;
501
 
  out Ok: boolean);
502
 
var
503
 
  NewFirstAutoInstallDependency: TPkgDependency;
504
 
  PkgList: TFPList;
505
 
  i: Integer;
506
 
  APackage: TLazPackage;
507
 
  CurResult: TModalResult;
 
488
procedure TPkgManager.OnCheckInstallPackageList(PkgIDList: TObjectList;
 
489
  RemoveConflicts: boolean; out Ok: boolean);
508
490
begin
509
 
  Ok:=false;
510
 
  PkgList:=nil;
511
 
  try
512
 
    // create new auto install dependency PkgIDList
513
 
    ListPkgIDToDependencyList(PkgIDList,NewFirstAutoInstallDependency,
514
 
                              pdlRequires,Self,true);
515
 
 
516
 
    // get all required packages
517
 
    if LoadDependencyList(NewFirstAutoInstallDependency)<>mrOk then exit;
518
 
    PackageGraph.GetAllRequiredPackages(NewFirstAutoInstallDependency,PkgList);
519
 
 
520
 
    // check if any package is a runtime package, that is not needed
521
 
    for i:=0 to PkgList.Count-1 do begin
522
 
      APackage:=TLazPackage(PkgList[i]);
523
 
      if (APackage.PackageType=lptRunTime)
524
 
      and (APackage.FirstUsedByDependency=nil) then begin
525
 
        // this is a runtime only package, not needed by any other package
526
 
        CurResult:=IDEQuestionDialog(lisPkgMangPackageIsNoDesigntimePackage,
527
 
          Format(lisPkgMangThePackageIsARuntimeOnlyPackageRuntimeOnlyPackages, [
528
 
            APackage.IDAsString, #13]),
529
 
          mtWarning, [mrIgnore, mrYesToAll, lisIgnoreAll, mrCancel]);
530
 
        case CurResult of
531
 
        mrIgnore: ;
532
 
        mrYesToAll: break;
533
 
        else exit;
534
 
        end;
535
 
      end;
536
 
    end;
537
 
 
538
 
    // try save all modified packages
539
 
    for i:=0 to PkgList.Count-1 do begin
540
 
      APackage:=TLazPackage(PkgList[i]);
541
 
      if (not APackage.AutoCreated)
542
 
      and (APackage.IsVirtual or APackage.Modified) then begin
543
 
        if DoSavePackage(APackage,[])<>mrOk then exit;
544
 
      end;
545
 
    end;
546
 
 
547
 
    Ok:=true;
548
 
  finally
549
 
    FreeDependencyList(NewFirstAutoInstallDependency,pdlRequires);
550
 
    PkgList.Free;
551
 
  end;
 
491
  Ok:=CheckInstallPackageList(PkgIDList);
552
492
end;
553
493
 
554
 
function TPkgManager.LoadDependencyList(FirstDependency: TPkgDependency
555
 
  ): TModalResult;
 
494
function TPkgManager.LoadDependencyList(FirstDependency: TPkgDependency;
 
495
  Quiet: boolean): TModalResult;
556
496
var
557
497
  CurDependency: TPkgDependency;
558
498
  OpenResult: TLoadPackageResult;
563
503
  while CurDependency<>nil do begin
564
504
    OpenResult:=PackageGraph.OpenDependency(CurDependency,false);
565
505
    if OpenResult<>lprSuccess then begin
566
 
      IDEMessageDialog(lisCCOErrorCaption,
567
 
        Format(lisUnableToLoadPackage, ['"', CurDependency.AsString, '"']),
568
 
        mtError,[mbCancel]);
 
506
      if not Quiet then
 
507
        IDEMessageDialog(lisCCOErrorCaption,
 
508
          Format(lisUnableToLoadPackage, ['"', CurDependency.AsString, '"']),
 
509
          mtError,[mbCancel]);
569
510
      exit;
570
511
    end;
571
512
    CurDependency:=CurDependency.NextRequiresDependency;
575
516
 
576
517
procedure TPkgManager.OnOpenPackageForCurrentSrcEditFile(Sender: TObject);
577
518
var
578
 
  PkgFile: TPkgFile;
 
519
  APackage: TIDEPackage;
579
520
begin
580
 
  PkgFile:=GetPackageOfCurrentSourceEditor;
581
 
  if PkgFile<>nil then
582
 
    DoOpenPackage(PkgFile.LazPackage,[],false);
 
521
  GetPackageOfCurrentSourceEditor(APackage);
 
522
  if APackage is TLazPackage then
 
523
    DoOpenPackage(TLazPackage(APackage),[],false);
583
524
end;
584
525
 
585
526
procedure TPkgManager.CreateIDEWindow(Sender: TObject; aFormName: string; var
601
542
    copy(aFormName,1,length(PackageEditorWindowPrefix)))=0
602
543
  then begin
603
544
    APackageName:=copy(aFormName,length(PackageEditorWindowPrefix)+1,length(aFormName));
604
 
    if (APackageName='') or not IsValidIdent(APackageName) then exit;
 
545
    if (APackageName='') or not IsValidUnitName(APackageName) then exit;
605
546
    NewDependency:=TPkgDependency.Create;
606
547
    try
607
548
      NewDependency.PackageName:=APackageName;
610
551
    finally
611
552
      NewDependency.Free;
612
553
    end;
613
 
    APackage:=PackageGraph.FindAPackageWithName(APackageName,nil);
 
554
    APackage:=PackageGraph.FindPackageWithName(APackageName,nil);
614
555
    if APackage=nil then exit;
615
556
    AForm:=PackageEditors.OpenEditor(APackage);
616
557
  end;
617
558
end;
618
559
 
619
 
procedure TPkgManager.MainIDEitmPkgAddCurUnitToPkgClick(Sender: TObject);
 
560
procedure TPkgManager.MainIDEitmPkgAddCurFileToPkgClick(Sender: TObject);
620
561
begin
621
562
  DoAddActiveUnitToAPackage;
622
563
end;
623
564
 
 
565
procedure TPkgManager.MainIDEitmPkgNewComponentClick(Sender: TObject);
 
566
begin
 
567
  DoNewPackageComponent;
 
568
end;
 
569
 
624
570
procedure TPkgManager.MainIDEitmPkgOpenPackageOfCurUnitClicked(Sender: TObject);
625
571
var
626
572
  ActiveSourceEditor: TSourceEditorInterface;
627
573
  ActiveUnitInfo: TUnitInfo;
628
574
  PkgFile: TPkgFile;
629
 
  Filename: String;
630
575
begin
631
576
  MainIDE.GetCurrentUnitInfo(ActiveSourceEditor,ActiveUnitInfo);
632
577
  if ActiveSourceEditor=nil then exit;
633
 
 
634
 
  Filename:=ActiveUnitInfo.Filename;
635
 
 
636
 
  PkgFile:=PackageGraph.FindFileInAllPackages(Filename,true,
 
578
  PkgFile:=PackageGraph.FindFileInAllPackages(ActiveUnitInfo.Filename,true,
637
579
                                            not ActiveUnitInfo.IsPartOfProject);
638
 
  if PkgFile=nil then begin
 
580
  if PkgFile=nil then
639
581
    IDEMessageDialog(lisProjAddPackageNotFound,
640
 
      lisPkgThisFileIsNotInAnyLoadedPackage, mtInformation,
641
 
      [mbCancel]);
642
 
    exit;
643
 
  end;
644
 
  DoOpenPackageFile(PkgFile.LazPackage.Filename,[pofAddToRecent],false)
 
582
        lisPkgThisFileIsNotInAnyLoadedPackage, mtInformation, [mbCancel])
 
583
  else
 
584
    DoOpenPackageFile(PkgFile.LazPackage.Filename,[pofAddToRecent],false);
 
585
end;
 
586
 
 
587
procedure TPkgManager.OnAfterWritePackage(Sender: TObject; Restore: boolean);
 
588
var
 
589
  APackage: TLazPackage absolute Sender;
 
590
begin
 
591
  //debugln(['TPkgManager.OnAfterWritePackage ',DbgSName(APackage),' Restore=',Restore]);
 
592
  if Restore then
 
593
    APackage.RestoreOptions;
 
594
end;
 
595
 
 
596
procedure TPkgManager.OnBeforeReadPackage(Sender: TObject);
 
597
var
 
598
  APackage: TLazPackage absolute Sender;
 
599
begin
 
600
  //debugln(['TPkgManager.OnBeforeReadPackage ',DbgSName(APackage)]);
 
601
  APackage.BackupOptions;
645
602
end;
646
603
 
647
604
function TPkgManager.OnPackageEditorCompilePackage(Sender: TObject;
648
605
  APackage: TLazPackage; CompileClean, CompileRequired: boolean): TModalResult;
649
606
var
650
607
  Flags: TPkgCompileFlags;
651
 
  Globals: TGlobalCompilerOptions;
652
608
begin
653
609
  Flags:=[];
654
610
  if CompileClean then Include(Flags,pcfCleanCompile);
655
611
  if CompileRequired then Include(Flags,pcfCompileDependenciesClean);
656
 
  if Project1<>nil then
657
 
    Globals:=Project1.CompilerOptions.Globals
658
 
  else
659
 
    Globals:=nil;
660
612
  //debugln('TPkgManager.OnPackageEditorCompilePackage OS=',Globals.TargetOS);
661
 
  Result:=DoCompilePackage(APackage,Flags,false,Globals);
 
613
  Result:=DoCompilePackage(APackage,Flags,false);
662
614
end;
663
615
 
664
616
function TPkgManager.OnPackageEditorCreateMakefile(Sender: TObject;
675
627
  NewSource: String;
676
628
  UnitDirectives: String;
677
629
  IconLRSFilename: String;
678
 
  BinFileStream: TFileStream;
 
630
  BinFileStream: TFileStreamUTF8;
679
631
  BinMemStream: TMemoryStream;
680
632
  BinExt: String;
681
 
  ResourceType: String;
682
 
  ResourceName: String;
 
633
  ResType: String;
 
634
  ResName: String;
683
635
  ResMemStream: TMemoryStream;
684
636
  CodeBuf: TCodeBuffer;
685
637
begin
695
647
      exit;
696
648
    end;
697
649
    try
698
 
      BinFileStream:=TFileStream.Create(UTF8ToSys(Params.IconFile),fmOpenRead);
 
650
      BinFileStream:=TFileStreamUTF8.Create(Params.IconFile,fmOpenRead);
699
651
      try
700
652
        BinMemStream:=TMemoryStream.Create;
701
653
        ResMemStream:=TMemoryStream.Create;
703
655
          BinMemStream.CopyFrom(BinFileStream,BinFileStream.Size);
704
656
          BinMemStream.Position:=0;
705
657
          BinExt:=uppercase(ExtractFileExt(Params.IconFile));
706
 
          ResourceType:=copy(BinExt,2,length(BinExt)-1);
707
 
          ResourceName:=ExtractFileNameOnly(Params.IconFile);
708
 
          BinaryToLazarusResourceCode(BinMemStream,ResMemStream
709
 
             ,ResourceName,ResourceType);
 
658
          ResType:=copy(BinExt,2,length(BinExt)-1);
 
659
          ResName:=ExtractFileNameOnly(Params.NewClassName);
 
660
          BinaryToLazarusResourceCode(BinMemStream,ResMemStream,ResName,ResType);
710
661
          ResMemStream.Position:=0;
711
662
          CodeBuf.LoadFromStream(ResMemStream);
712
663
          Result:=SaveCodeBuffer(CodeBuf);
729
680
 
730
681
  // create sourcecode
731
682
  LE:=LineEnding;
732
 
  UsesLine:='Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs';
 
683
  if PackageGraph.FindDependencyRecursively(Params.Pkg.FirstRequiredDependency,
 
684
    'LCL')<>nil
 
685
  then
 
686
    UsesLine:='Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs'
 
687
  else
 
688
    UsesLine:='Classes, SysUtils';
733
689
  if (System.Pos(Params.UsedUnitname,UsesLine)<1)
734
690
  and (Params.UsedUnitname<>'') then
735
691
    UsesLine:=UsesLine+', '+Params.UsedUnitname;
884
840
  end;
885
841
end;
886
842
 
887
 
procedure TPkgManager.PackageGraphDependencyModified(ADependency: TPkgDependency
888
 
  );
 
843
procedure TPkgManager.PackageGraphDependencyModified(ADependency: TPkgDependency);
889
844
var
890
845
  DepOwner: TObject;
891
846
begin
929
884
    if PackageEditors<>nil then
930
885
      PackageEditors.UpdateAllEditors(false);
931
886
    if ProjInspector<>nil then
932
 
      ProjInspector.UpdateItems;
 
887
      ProjInspector.UpdateItems(false);
933
888
    DoCallNotifyHandler(pihtGraphChanged,Self);
934
889
  end;
935
890
end;
996
951
    // open failed
997
952
    if not FileExistsUTF8(AFilename) then begin
998
953
      // file does not exist -> delete it from recent file list
999
 
      RemoveFromRecentList(AFilename,EnvironmentOptions.RecentPackageFiles);
 
954
      RemoveFromRecentList(AFilename,EnvironmentOptions.RecentPackageFiles,rltFile);
1000
955
      UpdateEnvironment;
1001
956
    end;
1002
957
  end;
1004
959
 
1005
960
procedure TPkgManager.OnApplicationIdle(Sender: TObject; var Done: Boolean);
1006
961
begin
 
962
  if PackageGraph = nil then Exit;
 
963
  if MainIDE.ToolStatus<>itNone then exit;
1007
964
  if (Screen.ActiveCustomForm<>nil)
1008
965
  and (fsModal in Screen.ActiveCustomForm.FormState) then exit;
1009
 
  if PackageGraph = nil then Exit;
1010
966
  PackageGraph.CloseUnneededPackages;
1011
967
end;
1012
968
 
1089
1045
      end;
1090
1046
 
1091
1047
      // check filename
1092
 
      if (NewPkgName='') or (not IsValidIdent(NewPkgName)) then begin
 
1048
      if (NewPkgName='') or (not IsValidUnitName(NewPkgName)) then begin
1093
1049
        Result:=IDEMessageDialog(lisPkgMangInvalidPackageName,
1094
1050
          Format(lisPkgMangThePackageNameIsNotAValidPackageNamePleaseChooseAn, [
1095
1051
            '"', NewPkgName, '"', #13]),
1132
1088
      end;
1133
1089
 
1134
1090
      // check package name conflict
1135
 
      ConflictPkg:=PackageGraph.FindAPackageWithName(NewPkgName,APackage);
 
1091
      ConflictPkg:=PackageGraph.FindPackageWithName(NewPkgName,APackage);
1136
1092
      if ConflictPkg<>nil then begin
1137
1093
        Result:=IDEMessageDialog(lisPkgMangPackageNameAlreadyExists,
1138
1094
          Format(lisPkgMangThereIsAlreadyAnotherPackageWithTheName, ['"',
1219
1175
  // rename package
1220
1176
  PackageGraph.ChangePackageID(APackage,NewPkgName,APackage.Version,
1221
1177
                               RenameDependencies,true);
1222
 
  SaveAutoInstallDependencies(false);
 
1178
  SaveAutoInstallDependencies;
1223
1179
  RenamePackageInProject;
1224
1180
 
1225
1181
  // clean up old package file to reduce ambiguousities
1231
1187
    then begin
1232
1188
      if DeleteFileUTF8(OldPkgFilename) then begin
1233
1189
        RemoveFromRecentList(OldPkgFilename,
1234
 
                             EnvironmentOptions.RecentPackageFiles);
 
1190
                             EnvironmentOptions.RecentPackageFiles,rltFile);
1235
1191
      end else begin
1236
1192
        IDEMessageDialog(lisPkgMangDeleteFailed,
1237
1193
          Format(lisPkgMangUnableToDeleteFile, ['"', OldPkgFilename, '"']),
1253
1209
  PkgFile1,PkgFile2: TPkgFile;
1254
1210
  ConflictPkg: TLazPackage;
1255
1211
  s: String;
 
1212
  Btns: TMsgDlgButtons;
1256
1213
begin
1257
1214
  {$IFDEF VerbosePkgCompile}
1258
1215
  debugln('TPkgManager.CheckPackageGraphForCompilation A');
1259
1216
  {$ENDIF}
1260
1217
  PathList:=nil;
 
1218
  if ShowAbort
 
1219
  then Btns := [mbCancel] // will be replaced to Ignore
 
1220
  else Btns := [mbOK];
1261
1221
  try
1262
1222
    // check for unsaved packages
1263
1223
    PathList:=PackageGraph.FindUnsavedDependencyPath(APackage,FirstDependency);
1281
1241
            Result:=IDEMessageDialogAb(lisPkgMangBrokenDependency,
1282
1242
              Format(lisPkgMangTheProjectRequiresThePackageButItWasNotFound, [
1283
1243
                '"', Dependency.AsString, '"', #13]),
1284
 
              mtError,[mbCancel],ShowAbort);
 
1244
              mtError,Btns,ShowAbort);
 
1245
            if not ShowAbort then
 
1246
              Result := mrCancel; // User confirmed error, implicitly cancel the action
1285
1247
            exit;
1286
1248
          end;
1287
1249
        end;
1288
1250
      end;
1289
1251
      DoShowPackageGraphPathList(PathList);
1290
1252
      Result:=IDEMessageDialogAb(lisPkgMangBrokenDependency,
1291
 
        lisPkgMangARequiredPackagesWasNotFound,
1292
 
        mtError,[mbCancel],ShowAbort);
1293
 
      exit;
1294
 
    end;
1295
 
 
1296
 
    // check for circle dependencies
1297
 
    PathList:=PackageGraph.FindCircleDependencyPath(APackage,FirstDependency);
1298
 
    if PathList<>nil then begin
1299
 
      DoShowPackageGraphPathList(PathList);
1300
 
      Result:=IDEMessageDialogAb(lisPkgMangCircleInPackageDependencies,
1301
 
        lisPkgMangThereIsACircleInTheRequiredPackages,
1302
 
        mtError,[mbCancel],ShowAbort);
 
1253
        lisPkgMangRequiredPackagesWereNotFound,
 
1254
        mtError,Btns,ShowAbort);
 
1255
      if not ShowAbort then
 
1256
        Result := mrCancel; // User confirmed error, implicitly cancel the action
 
1257
      exit;
 
1258
    end;
 
1259
 
 
1260
    // check for cycle dependencies
 
1261
    PathList:=PackageGraph.FindCycleDependencyPath(APackage,FirstDependency);
 
1262
    if PathList<>nil then begin
 
1263
      DoShowPackageGraphPathList(PathList);
 
1264
      Result:=IDEMessageDialogAb(lisPkgMangCircularDependencies,
 
1265
        lisPkgMangThereIsACircularDependency,
 
1266
        mtError,Btns,ShowAbort);
 
1267
      if not ShowAbort then
 
1268
        Result := mrCancel; // User confirmed error, implicitly cancel the action
 
1269
      exit;
 
1270
    end;
 
1271
 
 
1272
    // check for a package that compiles to the default FPC search path
 
1273
    PathList:=PackageGraph.FindPkgOutputInFPCSearchPath(APackage,FirstDependency);
 
1274
    if PathList<>nil then begin
 
1275
      ConflictPkg:=TObject(PathList[PathList.Count-1]) as TLazPackage;
 
1276
      DoShowPackageGraphPathList(PathList);
 
1277
      Result:=IDEMessageDialogAb(lisPkgMangCircularDependencies,
 
1278
        Format(lisPkgMangThePackageIsCompiledAutomaticallyAndItsOutputDirec, [
 
1279
          ConflictPkg.Name, ConflictPkg.GetOutputDirectory, #13#13, #13, #13,
 
1280
          #13]),
 
1281
        mtError,Btns,ShowAbort);
 
1282
      if not ShowAbort then
 
1283
        Result := mrCancel; // User confirmed error, implicitly cancel the action
1303
1284
      exit;
1304
1285
    end;
1305
1286
 
1321
1302
          +'Please report this bug and how you got here.'#13;
1322
1303
      Result:=IDEMessageDialogAb(lisPkgMangAmbiguousUnitsFound, Format(
1323
1304
        lisPkgMangBothPackagesAreConnectedThisMeansEitherOnePackageU, [s]),
1324
 
          mtError,[mbCancel],ShowAbort);
 
1305
          mtError,Btns,ShowAbort);
 
1306
      if not ShowAbort then
 
1307
        Result := mrCancel; // User confirmed error, implicitly cancel the action
1325
1308
      exit;
1326
1309
    end;
1327
1310
 
1339
1322
        s:='Internal inconsistency FindFPCConflictUnits: '
1340
1323
          +'Please report this bug and how you got here.'#13;
1341
1324
      Result:=IDEMessageDialogAb(lisPkgMangAmbiguousUnitsFound, s,
1342
 
          mtError,[mbCancel],ShowAbort);
 
1325
          mtError,Btns,ShowAbort);
 
1326
      if not ShowAbort then
 
1327
        Result := mrCancel; // User confirmed error, implicitly cancel the action
1343
1328
      exit;
1344
1329
    end;
1345
1330
 
1369
1354
  CodeBuffer: TCodeBuffer;
1370
1355
begin
1371
1356
  Result:=mrCancel;
1372
 
  ExpFilename:=CleanAndExpandFilename(AFilename);
 
1357
  ExpFilename:=TrimFilename(AFilename);
1373
1358
  // create default values
1374
1359
  TheUnitName:='';
1375
1360
  HasRegisterProc:=false;
1386
1371
  Result:=mrOk;
1387
1372
end;
1388
1373
 
1389
 
procedure TPkgManager.SaveAutoInstallDependencies(
1390
 
  SetWithStaticPcksFlagForIDE: boolean);
 
1374
procedure TPkgManager.SaveAutoInstallDependencies;
1391
1375
var
1392
1376
  Dependency: TPkgDependency;
1393
1377
  sl: TStringList;
1394
1378
begin
1395
 
  if SetWithStaticPcksFlagForIDE then begin
1396
 
    MiscellaneousOptions.BuildLazProfiles.Current.WithStaticPackages:=True;
1397
 
  end;
1398
 
 
1399
1379
  sl:=TStringList.Create;
1400
1380
  Dependency:=PackageGraph.FirstAutoInstallDependency;
1401
1381
  while Dependency<>nil do begin
1402
1382
    if (Dependency.LoadPackageResult=lprSuccess)
1403
1383
    and (not Dependency.RequiredPackage.AutoCreated)
1404
1384
    and (not PackageGraph.IsStaticBasePackage(Dependency.PackageName))
1405
 
    and (not Dependency.RequiredPackage.Missing) then begin
 
1385
    and (not Dependency.RequiredPackage.Missing)
 
1386
    and (not (Dependency.RequiredPackage.PackageType in [lptRunTime,lptRunTimeOnly]))
 
1387
    then begin
1406
1388
      if sl.IndexOf(Dependency.PackageName)<0 then begin
1407
1389
        sl.Add(Dependency.PackageName);
1408
 
        DebugLn('TPkgManager.SaveAutoInstallDependencies A ',Dependency.PackageName);
 
1390
        //DebugLn('TPkgManager.SaveAutoInstallDependencies A ',Dependency.PackageName);
1409
1391
      end;
1410
1392
    end;
1411
1393
    Dependency:=Dependency.NextRequiresDependency;
1428
1410
  Quiet:=false;
1429
1411
  for i:=0 to StaticPackages.Count-1 do begin
1430
1412
    StaticPackage:=PRegisteredPackage(StaticPackages[i]);
1431
 
    
 
1413
 
1432
1414
    // check package name
1433
 
    if (StaticPackage^.Name='') or (not IsValidIdent(StaticPackage^.Name))
 
1415
    if (StaticPackage^.Name='') or (not IsValidUnitName(StaticPackage^.Name))
1434
1416
    then begin
1435
1417
      DebugLn('TPkgManager.LoadStaticCustomPackages Invalid Package Name: "',
1436
1418
        BinaryStrToText(StaticPackage^.Name),'"');
1485
1467
 
1486
1468
procedure TPkgManager.LoadAutoInstallPackages;
1487
1469
begin
1488
 
  FLastLazarusSrcDir:=EnvironmentOptions.LazarusDirectory;
 
1470
  FLastLazarusSrcDir:=EnvironmentOptions.GetParsedLazarusDirectory;
1489
1471
  PackageGraph.LoadAutoInstallPackages(
1490
1472
    MiscellaneousOptions.BuildLazProfiles.StaticAutoInstallPackages);
1491
1473
end;
1499
1481
    //debugln('TPkgManager.AddUnitToProjectMainUsesSection B ',AnUnitName);
1500
1482
    if (AnUnitName<>'') then begin
1501
1483
      MainIDEInterface.SaveSourceEditorChangesToCodeCache(nil);
1502
 
      if CodeToolBoss.AddUnitToMainUsesSection(
 
1484
      if CodeToolBoss.AddUnitToMainUsesSectionIfNeeded(
1503
1485
        AProject.MainUnitInfo.Source,AnUnitName,AnUnitInFilename)
1504
1486
      then
1505
1487
        AProject.MainUnitInfo.Modified:=true;
1514
1496
  inherited Create(TheOwner);
1515
1497
  OnGetDependencyOwnerDescription:=@GetDependencyOwnerDescription;
1516
1498
  OnGetDependencyOwnerDirectory:=@GetDependencyOwnerDirectory;
1517
 
  OnGetWritablePkgOutputDirectory:=@GetWritablePkgOutputDirectory;
1518
1499
  OnPackageFileLoaded:=@PackageFileLoaded;
1519
1500
 
1520
1501
  // componentpalette
1556
1537
  PackageEditors.OnPublishPackage:=@OnPackageEditorPublishPackage;
1557
1538
  PackageEditors.OnCompilePackage:=@OnPackageEditorCompilePackage;
1558
1539
  PackageEditors.OnAddToProject:=@OnPackageEditorAddToProject;
 
1540
  PackageEditors.OnBeforeReadPackage:=@OnBeforeReadPackage;
 
1541
  PackageEditors.OnAfterWritePackage:=@OnAfterWritePackage;
1559
1542
  PackageEditors.OnInstallPackage:=@OnPackageEditorInstallPackage;
1560
1543
  PackageEditors.OnUninstallPackage:=@OnPackageEditorUninstallPackage;
1561
1544
  PackageEditors.OnViewPackageSource:=@OnPackageEditorViewPkgSource;
1571
1554
    'PKGUNITPATH',nil,@PackageGraph.MacroFunctionCTPkgUnitPath);
1572
1555
  CodeToolBoss.DefineTree.MacroFunctions.AddExtended(
1573
1556
    'PKGINCPATH',nil,@PackageGraph.MacroFunctionCTPkgIncPath);
1574
 
    
 
1557
  CodeToolBoss.DefineTree.MacroFunctions.AddExtended(
 
1558
    'PKGNAME',nil,@PackageGraph.MacroFunctionCTPkgName);
 
1559
 
1575
1560
  LazPackageDescriptors:=TLazPackageDescriptors.Create;
1576
1561
  LazPackageDescriptors.AddDefaultPackageDescriptors;
1577
1562
 
1601
1586
    itmPkgOpenPackage.OnClick :=@MainIDEitmPkgOpenPackageClicked;
1602
1587
    itmPkgOpenPackageFile.OnClick:=@MainIDEitmPkgOpenPackageFileClick;
1603
1588
    itmPkgOpenPackageOfCurUnit.OnClick :=@MainIDEitmPkgOpenPackageOfCurUnitClicked;
1604
 
    itmPkgAddCurUnitToPkg.OnClick:=@MainIDEitmPkgAddCurUnitToPkgClick;
 
1589
    itmPkgAddCurFileToPkg.OnClick:=@MainIDEitmPkgAddCurFileToPkgClick;
 
1590
    itmPkgAddNewComponentToPkg.OnClick:=@MainIDEitmPkgNewComponentClick;
1605
1591
    itmPkgPkgGraph.OnClick:=@MainIDEitmPkgPkgGraphClick;
1606
1592
    itmPkgEditInstallPkgs.OnClick:=@MainIDEitmPkgEditInstallPkgsClick;
1607
1593
    {$IFDEF CustomIDEComps}
1639
1625
procedure TPkgManager.AddFileToRecentPackages(const Filename: string);
1640
1626
begin
1641
1627
  AddToRecentList(Filename,EnvironmentOptions.RecentPackageFiles,
1642
 
                  EnvironmentOptions.MaxRecentPackageFiles);
 
1628
                  EnvironmentOptions.MaxRecentPackageFiles,rltFile);
1643
1629
  SetRecentPackagesMenu;
1644
1630
  MainIDE.SaveEnvironment;
1645
1631
end;
1656
1642
  PkgFile: TPkgFile;
1657
1643
begin
1658
1644
  Result:='';
 
1645
  if FilenameIsAbsolute(Filename) then begin
 
1646
    Result:=ExtractFilePath(Filename);
 
1647
    exit;
 
1648
  end;
1659
1649
  PkgFile:=PackageGraph.FindFileInAllPackages(Filename,true,true);
1660
1650
  if PkgFile=nil then exit;
1661
1651
  APackage:=PkgFile.LazPackage;
1693
1683
var
1694
1684
  Dependency: TPkgDependency;
1695
1685
begin
1696
 
  // break and free auto installed packages
 
1686
  // unbind and free auto installed packages
1697
1687
  while PackageGraph.FirstAutoInstallDependency<>nil do begin
1698
1688
    Dependency:=PackageGraph.FirstAutoInstallDependency;
1699
1689
    Dependency.RequiredPackage:=nil;
1715
1705
  ecOpenPackage: MainIDEitmPkgOpenPackageClicked(Self);
1716
1706
  ecOpenPackageFile: MainIDEitmPkgOpenPackageFileClick(Self);
1717
1707
  ecOpenPackageOfCurUnit: MainIDEitmPkgOpenPackageOfCurUnitClicked(Self);
1718
 
  ecAddCurUnitToPkg: MainIDEitmPkgAddCurUnitToPkgClick(Self);
 
1708
  ecAddCurFileToPkg: MainIDEitmPkgAddCurFileToPkgClick(Self);
1719
1709
  ecPackageGraph: MainIDEitmPkgPkgGraphClick(Self);
1720
1710
  ecEditInstallPkgs: MainIDEitmPkgEditInstallPkgsClick(Self);
1721
1711
  else
1726
1716
procedure TPkgManager.OnSourceEditorPopupMenu(
1727
1717
  const AddMenuItemProc: TAddMenuItemProc);
1728
1718
var
1729
 
  PkgFile: TPkgFile;
 
1719
  APackage: TIDEPackage;
1730
1720
begin
1731
 
  PkgFile:=GetPackageOfCurrentSourceEditor;
1732
 
  if PkgFile<>nil then
1733
 
    AddMenuItemProc(Format(lisOpenPackage2, [PkgFile.LazPackage.Name]), true,
 
1721
  GetPackageOfCurrentSourceEditor(APackage);
 
1722
  if APackage<>nil then
 
1723
    AddMenuItemProc(Format(lisOpenPackage2, [APackage.Name]), true,
1734
1724
                    @OnOpenPackageForCurrentSrcEditFile);
1735
1725
end;
1736
1726
 
1740
1730
  i: Integer;
1741
1731
begin
1742
1732
  PkgList:=nil;
1743
 
  OnGetAllRequiredPackages(PackageGraph.FirstAutoInstallDependency,PkgList);
 
1733
  PackageGraph.GetAllRequiredPackages(PackageGraph.FirstAutoInstallDependency,PkgList);
1744
1734
  if PkgList=nil then exit;
1745
1735
  for i:=0 to PkgList.Count-1 do
1746
1736
    if TObject(PkgList[i]) is TLazPackage then
1783
1773
    if LangEnd<>length(Filename)-2 then exit;
1784
1774
    AUnitName:=copy(Filename,1,UnitNameEnd-1);
1785
1775
    Language:=copy(Filename,UnitNameEnd+1,LangEnd-UnitNameEnd-1);
1786
 
    Result:=IsValidIdent(AUnitName) and (Language<>'');
 
1776
    Result:=IsValidUnitName(AUnitName) and (Language<>'');
1787
1777
    //DebugLn(['GetPOFilenameParts AUnitName=',AUnitName,' Language=',Language,' Result=',Result]);
1788
1778
  end;
1789
1779
  
1790
1780
  procedure TranslateWithFileMask(APackage: TLazPackage;
1791
1781
    const Directory, Language: string);
1792
1782
  var
1793
 
    FileInfo: TSearchRec;
1794
1783
    CurUnitName: string;
1795
1784
    CurLang: string;
1796
 
    FileMask: String;
 
1785
    Files: TStrings;
 
1786
    Filename: String;
1797
1787
  begin
1798
1788
    if Language='' then exit;
1799
 
    FileMask:=Directory+'*.'+Language+'.po';
1800
 
    //DebugLn(['TranslateWithFileMask APackage=',APackage.IDAsString,' FileMask="',FileMask,'"']);
1801
 
    if FindFirstUTF8(FileMask,faAnyFile,FileInfo)=0
1802
 
    then begin
1803
 
      repeat
1804
 
        // check if special file
1805
 
        if (FileInfo.Name='.') or (FileInfo.Name='..') or (FileInfo.Name='') then
1806
 
          continue;
1807
 
        if GetPOFilenameParts(FileInfo.Name,CurUnitName,CurLang)
 
1789
    Files:=nil;
 
1790
    try
 
1791
      CodeToolBoss.DirectoryCachePool.GetListing(Directory,Files,false);
 
1792
      for Filename in Files do begin
 
1793
        if CompareFileExt(Filename,'.po',false)<>0 then continue;
 
1794
        if GetPOFilenameParts(Filename,CurUnitName,CurLang)
1808
1795
        and (CurLang=Language)
1809
1796
        and (APackage.FindUnit(CurUnitName)<>nil)
1810
1797
        and not UnitTranslated(CurUnitName) then begin
1811
 
          TranslateUnit(Directory+FileInfo.Name,CurUnitName);
 
1798
          TranslateUnit(AppendPathDelim(Directory)+Filename,CurUnitName);
1812
1799
        end;
1813
 
      until FindNextUTF8(FileInfo)<>0;
 
1800
      end;
 
1801
    finally
 
1802
      Files.Free;
1814
1803
    end;
1815
 
    FindCloseUTF8(FileInfo);
1816
1804
  end;
1817
1805
 
1818
1806
var
1821
1809
  FallbackLang: String;
1822
1810
  Language: String;
1823
1811
begin
1824
 
  //DebugLn(['TPkgManager.DoTranslatePackage ', APackage.Name, 'from ', APackage.POOutputDirectory]);
 
1812
  //DebugLn(['TPkgManager.DoTranslatePackage ',APackage.Name,' from ', APackage.POOutputDirectory]);
1825
1813
  if (APackage.POOutputDirectory='') then exit;
1826
1814
  Directory:=AppendPathDelim(APackage.GetPOOutDirectory);
1827
1815
 
1834
1822
    FallbackLang:='';
1835
1823
  end;
1836
1824
  
 
1825
  //DebugLn(['TPkgManager.DoTranslatePackage ', APackage.Name,' from ', APackage.POOutputDirectory,', Translated=',APackage.Translated,' Lang=',Lang]);
1837
1826
  if APackage.Translated=Lang then exit;
1838
1827
  APackage.Translated:=Lang;
1839
1828
  
1841
1830
  try
1842
1831
    //DebugLn(['TPkgManager.DoTranslatePackage ',APackage.Name,' Directory=',Directory,' Lang=',Lang,' FallbackLang=',FallbackLang]);
1843
1832
    TranslateWithFileMask(APackage,Directory,Lang);
1844
 
    TranslateWithFileMask(APackage,Directory,FallbackLang);
 
1833
    if FallbackLang<>Lang then
 
1834
      TranslateWithFileMask(APackage,Directory,FallbackLang);
1845
1835
  finally
1846
1836
    TranslatedUnits.Free;
1847
1837
  end;
1853
1843
  ConflictPkg: TLazPackage;
1854
1844
begin
1855
1845
  // check Package Name
1856
 
  if (APackage.Name='') or (not IsValidIdent(APackage.Name)) then begin
 
1846
  if (APackage.Name='') or (not IsValidUnitName(APackage.Name)) then begin
1857
1847
    Result:=IDEMessageDialog(lisPkgMangInvalidPackageName2,
1858
1848
      Format(lisPkgMangThePackageNameOfTheFileIsInvalid, ['"', APackage.Name,
1859
1849
        '"', #13, '"', APackage.Filename, '"']),
1862
1852
  end;
1863
1853
 
1864
1854
  // check if Package with same name is already loaded
1865
 
  ConflictPkg:=PackageGraph.FindAPackageWithName(APackage.Name,nil);
 
1855
  ConflictPkg:=PackageGraph.FindPackageWithName(APackage.Name,nil);
1866
1856
  if ConflictPkg<>nil then begin
1867
1857
    if not PackageGraph.PackageCanBeReplaced(ConflictPkg,APackage) then begin
1868
1858
      Result:=IDEMessageDialog(lisPkgMangPackageConflicts,
1918
1908
  PkgLinks.SaveUserLinks;
1919
1909
end;
1920
1910
 
1921
 
procedure TPkgManager.AddDefaultDependencies(AProject: TProject);
1922
 
begin
1923
 
  OpenProjectDependencies(AProject,true);
1924
 
end;
1925
 
 
1926
1911
function TPkgManager.AddProjectDependency(AProject: TProject;
1927
1912
  APackage: TLazPackage; OnlyTestIfPossible: boolean): TModalResult;
1928
1913
var
1932
1917
begin
1933
1918
  Result:=mrCancel;
1934
1919
 
1935
 
  // check if there is dependency, that requires another version
 
1920
  // check if there is a dependency, that requires another version
1936
1921
  ConflictDependency:=PackageGraph.FindConflictRecursively(
1937
1922
    AProject.FirstRequiredDependency,APackage);
1938
1923
  if ConflictDependency<>nil then begin
1949
1934
    Result:=mrOk;
1950
1935
    exit;
1951
1936
  end;
 
1937
 
1952
1938
  ProvidingAPackage:=PackageGraph.FindPackageProvidingName(
1953
1939
    AProject.FirstRequiredDependency,APackage.Name);
1954
1940
  if ProvidingAPackage<>nil then
1955
1941
  begin
1956
1942
    // package is already provided by another package
1957
1943
    DebugLn(['TPkgManager.AddProjectDependency ',APackage.Name,' is already provided by ',ProvidingAPackage.IDAsString]);
1958
 
    Result:=mrCancel;
 
1944
    Result:=mrOk;
1959
1945
    exit;
1960
1946
  end;
1961
1947
 
1975
1961
  if (ADependency.RequiredPackage<>nil)
1976
1962
  and (not ADependency.RequiredPackage.AutoCreated)
1977
1963
  and ADependency.RequiredPackage.AddToProjectUsesSection
 
1964
  and ((ADependency.RequiredPackage.PackageType<>lptDesignTime)
 
1965
       or (pfUseDesignTimePackages in AProject.Flags))
1978
1966
  then begin
1979
1967
    AddUnitToProjectMainUsesSection(AProject,
1980
1968
      ExtractFileNameOnly(ADependency.RequiredPackage.GetCompileSourceFilename),'');
1985
1973
  ARegisteredComponent: TRegisteredComponent);
1986
1974
var
1987
1975
  PkgFile: TPkgFile;
 
1976
  APackage: TLazPackage;
1988
1977
begin
1989
1978
  if not (ARegisteredComponent is TPkgComponent) then exit;
1990
1979
  
1991
1980
  PkgFile:=TPkgComponent(ARegisteredComponent).PkgFile;
1992
 
  if (PkgFile=nil) or (PkgFile.LazPackage=nil) then exit;
1993
 
  AddProjectDependency(AProject,PkgFile.LazPackage);
 
1981
  if (PkgFile=nil) then exit;
 
1982
 
 
1983
  APackage:=PkgFile.LazPackage;
 
1984
  APackage:=TLazPackage(RedirectPackageDependency(APackage));
 
1985
 
 
1986
  AddProjectDependency(AProject,APackage);
1994
1987
end;
1995
1988
 
1996
1989
procedure TPkgManager.AddProjectLCLDependency(AProject: TProject);
2009
2002
  RequiredPackages:=SplitString(Packages,';');
2010
2003
  for i:=0 to RequiredPackages.Count-1 do begin
2011
2004
    PkgName:=Trim(RequiredPackages[i]);
2012
 
    if (PkgName='') or (not IsValidIdent(PkgName)) then continue;
2013
 
    APackage:=PackageGraph.FindAPackageWithName(PkgName,nil);
 
2005
    if (PkgName='') or (not IsValidUnitName(PkgName)) then continue;
 
2006
    APackage:=PackageGraph.FindPackageWithName(PkgName,nil);
2014
2007
    if APackage=nil then begin
2015
2008
      DebugLn(['TPkgManager.AddProjectDependencies package not found: ',PkgName]);
2016
2009
      continue;
2028
2021
  i: Integer;
2029
2022
  PkgFile: TPkgFile;
2030
2023
  Msg: String;
2031
 
  PkgList: TFPList;
 
2024
  PkgList: TObjectList;
2032
2025
begin
2033
2026
  Result:=mrOk;
2034
2027
  MissingUnits:=PackageGraph.FindNotInstalledRegisterUnits(nil,
2037
2030
    if Interactive then begin 
2038
2031
      Msg:=Format(lisProbablyYouNeedToInstallSomePackagesForBeforeConti, [#13,
2039
2032
        #13, #13, #13, #13, #13, #13, #13, #13]);
2040
 
      PkgList:=TFPList.Create;
 
2033
      PkgList:=TObjectList.Create(false);
2041
2034
      try
2042
2035
        for i:=0 to MissingUnits.Count-1 do begin
2043
2036
          PkgFile:=TPkgFile(MissingUnits[i]);
2054
2047
        begin
2055
2048
          // install
2056
2049
          AProject.AutoOpenDesignerFormsDisabled:=true;
2057
 
          DoInstallPackages(PkgList,true,true,false);
 
2050
          InstallPackages(PkgList,[piiifRebuildIDE]);
2058
2051
          Result:=mrAbort;
2059
2052
        end else begin
2060
2053
          // do not warn again
2071
2064
 
2072
2065
function TPkgManager.ShowConfigureCustomComponents: TModalResult;
2073
2066
begin
2074
 
  Result:=ShowConfigureCustomComponentDlg(EnvironmentOptions.LazarusDirectory);
 
2067
  Result:=ShowConfigureCustomComponentDlg(EnvironmentOptions.GetParsedLazarusDirectory);
2075
2068
end;
2076
2069
 
2077
2070
function TPkgManager.DoNewPackage: TModalResult;
2125
2118
    AFilename:=APackage.Filename;
2126
2119
    if FileExistsCached(AFilename) then begin
2127
2120
      AddToRecentList(AFilename,EnvironmentOptions.RecentPackageFiles,
2128
 
                      EnvironmentOptions.MaxRecentPackageFiles);
 
2121
                      EnvironmentOptions.MaxRecentPackageFiles,rltFile);
2129
2122
      SetRecentPackagesMenu;
2130
2123
    end;
2131
2124
  end;
2141
2134
  LoadResult: TLoadPackageResult;
2142
2135
begin
2143
2136
  Result:=mrCancel;
2144
 
  if (APackageName='') or not IsValidIdent(APackageName) then exit;
 
2137
  if (APackageName='') or not IsValidUnitName(APackageName) then exit;
2145
2138
  NewDependency:=TPkgDependency.Create;
2146
2139
  try
2147
2140
    NewDependency.PackageName:=APackageName;
2150
2143
  finally
2151
2144
    NewDependency.Free;
2152
2145
  end;
2153
 
  APackage:=PackageGraph.FindAPackageWithName(APackageName,nil);
 
2146
  APackage:=PackageGraph.FindPackageWithName(APackageName,nil);
2154
2147
  if APackage=nil then exit;
2155
2148
  Result:=DoOpenPackage(APackage,Flags,ShowAbort);
2156
2149
end;
2186
2179
  and (not (pofRevert in Flags)) then begin
2187
2180
    DoQuestionDlg(lisPkgMangInvalidFileExtension,
2188
2181
      Format(lisPkgMangTheFileIsNotALazarusPackage, ['"', AFilename, '"']));
2189
 
    RemoveFromRecentList(AFilename,EnvironmentOptions.RecentPackageFiles);
 
2182
    RemoveFromRecentList(AFilename,EnvironmentOptions.RecentPackageFiles,rltFile);
2190
2183
    SetRecentPackagesMenu;
2191
2184
    exit;
2192
2185
  end;
2194
2187
  // check filename
2195
2188
  AlternativePkgName:=ExtractFileNameOnly(AFilename);
2196
2189
  if (not (pofRevert in Flags))
2197
 
  and ((AlternativePkgName='') or (not IsValidIdent(AlternativePkgName)))
 
2190
  and ((AlternativePkgName='') or (not IsValidUnitName(AlternativePkgName)))
2198
2191
  then begin
2199
2192
    DoQuestionDlg(lisPkgMangInvalidPackageFilename,
2200
2193
      Format(lisPkgMangThePackageFileNameInIsNotAValidLazarusPackageName, ['"',
2201
2194
        AlternativePkgName, '"', #13, '"', AFilename, '"']));
2202
 
    RemoveFromRecentList(AFilename,EnvironmentOptions.RecentPackageFiles);
 
2195
    RemoveFromRecentList(AFilename,EnvironmentOptions.RecentPackageFiles,rltFile);
2203
2196
    SetRecentPackagesMenu;
2204
2197
    exit;
2205
2198
  end;
2207
2200
  // add to recent packages
2208
2201
  if pofAddToRecent in Flags then begin
2209
2202
    AddToRecentList(AFilename,EnvironmentOptions.RecentPackageFiles,
2210
 
                    EnvironmentOptions.MaxRecentPackageFiles);
 
2203
                    EnvironmentOptions.MaxRecentPackageFiles,rltFile);
2211
2204
    SetRecentPackagesMenu;
2212
2205
  end;
2213
2206
 
2226
2219
      IDEMessageDialog(lisFileNotFound,
2227
2220
        Format(lisPkgMangFileNotFound, ['"', AFilename, '"']),
2228
2221
        mtError,[mbCancel]);
2229
 
      RemoveFromRecentList(AFilename,EnvironmentOptions.RecentPackageFiles);
 
2222
      RemoveFromRecentList(AFilename,EnvironmentOptions.RecentPackageFiles,rltFile);
2230
2223
      SetRecentPackagesMenu;
2231
2224
      Result:=mrCancel;
2232
2225
      exit;
2322
2315
  
2323
2316
  if APackage.IsVirtual then Include(Flags,psfSaveAs);
2324
2317
 
2325
 
  // check if package needs saving
2326
 
  if (not (psfSaveAs in Flags))
2327
 
  and (not APackage.ReadOnly) and (not APackage.Modified)
2328
 
  and FileExistsCached(APackage.Filename) then begin
 
2318
  if not ( (psfSaveAs in Flags) or APackage.ReadOnly or APackage.Modified
 
2319
          or FileExistsCached(APackage.Filename)
 
2320
          or (APackage.UserIgnoreChangeStamp<>APackage.ChangeStamp )) then
 
2321
  begin
2329
2322
    Result:=mrOk;
2330
2323
    exit;
2331
2324
  end;
2332
2325
 
2333
 
  // ask user if package should be saved
2334
 
  if psfAskBeforeSaving in Flags then begin
2335
 
    Result:=IDEMessageDialog(lisPkgMangSavePackage2,
2336
 
               Format(lisPkgMangPackageChangedSave, ['"', APackage.IDAsString,
2337
 
                 '"']),
2338
 
               mtConfirmation,[mbYes,mbNo,mbAbort]);
2339
 
    if (Result=mrNo) then Result:=mrIgnore;
2340
 
    if Result<>mrYes then exit;
2341
 
  end;
2342
 
  
 
2326
  // save new or changed files
 
2327
  Result:=SavePackageFiles(APackage);
 
2328
  if Result<>mrOk then exit;
 
2329
 
2343
2330
  // warn about missing files
2344
2331
  Result:=WarnAboutMissingPackageFiles(APackage);
2345
2332
  if Result<>mrOk then exit;
2374
2361
      APackage.LPKSource:=Code;
2375
2362
      PkgLink:=PkgLinks.AddUserLink(APackage);
2376
2363
      if PkgLink<>nil then begin
2377
 
        PkgLink.FileDate:=FileDateToDateTime(FileAgeUTF8(APackage.Filename));
 
2364
        PkgLink.FileDate:=FileDateToDateTimeDef(FileAgeUTF8(APackage.Filename));
2378
2365
        PkgLink.FileDateValid:=true;
2379
2366
        PkgLinks.SaveUserLinks;
2380
2367
      end;
2399
2386
    AddFileToRecentPackages(APackage.Filename);
2400
2387
  end;
2401
2388
 
2402
 
  if APackage.Editor<>nil then APackage.Editor.UpdateAll(true);
 
2389
  if APackage.Editor<>nil then
 
2390
    APackage.Editor.UpdateAll(true);
2403
2391
  Result:=mrOk;
2404
2392
end;
2405
2393
 
2433
2421
  PackageGraphExplorer.ShowPath(PathList);
2434
2422
end;
2435
2423
 
2436
 
function TPkgManager.ShowBrokenDependenciesReport(Dependencies: TFPList
2437
 
  ): TModalResult;
 
2424
function TPkgManager.ShowBrokenDependenciesReport(Dependencies: TFPList): TModalResult;
2438
2425
var
2439
2426
  Msg: String;
2440
2427
  i: Integer;
2476
2463
var
2477
2464
  NewLazarusSrcDir: String;
2478
2465
  OldLazarusSrcDir: String;
2479
 
  APackage: TLazPackage;
 
2466
  VisitedPkgs: TStringToStringTree;
 
2467
  ReloadPkgs: TStringList;
 
2468
 
 
2469
  function PkgInOldLazarusDir(APackage: TLazPackage): boolean;
 
2470
  begin
 
2471
    Result:=FileIsInPath(APackage.Filename,OldLazarusSrcDir)
 
2472
      or PackageGraph.IsStaticBasePackage(APackage.Name)
 
2473
      or (SysUtils.CompareText(copy(APackage.Filename,1,length(LazDirMacro)),LazDirMacro)=0)
 
2474
  end;
 
2475
 
 
2476
  procedure GatherLazarusSrcPackages(APackage: TLazPackage);
 
2477
  var
 
2478
    ADependency: TPkgDependency;
 
2479
  begin
 
2480
    if APackage=nil then exit;
 
2481
    if VisitedPkgs.Contains(APackage.Name) then exit;
 
2482
    VisitedPkgs[APackage.Name]:='1';
 
2483
    // search the dependencies first
 
2484
    ADependency:=APackage.FirstRequiredDependency;
 
2485
    while ADependency<>nil do begin
 
2486
      GatherLazarusSrcPackages(ADependency.RequiredPackage);
 
2487
      ADependency:=ADependency.NextRequiresDependency;
 
2488
    end;
 
2489
    if PkgInOldLazarusDir(APackage) then begin
 
2490
      // this package was from the old lazarus source directory
 
2491
      ReloadPkgs.Add(APackage.Name);
 
2492
    end;
 
2493
  end;
 
2494
 
 
2495
  function ReloadPkg(APackage: TLazPackage): boolean;
 
2496
  var
 
2497
    Link: TPackageLink;
 
2498
    MsgResult: TModalResult;
 
2499
    Filename: String;
 
2500
  begin
 
2501
    Result:=true;
 
2502
    if APackage=nil then exit;
 
2503
    if not PkgInOldLazarusDir(APackage) then exit;
 
2504
    // this package was from the old lazarus source directory
 
2505
    // check if there is a package in the new version
 
2506
    Link:=PkgLinks.FindLinkWithPkgName(APackage.Name);
 
2507
    if Link<>nil then begin
 
2508
      Filename:=TrimFilename(Link.Filename);
 
2509
      if not FilenameIsAbsolute(Filename) then
 
2510
        Filename:=AppendPathDelim(NewLazarusSrcDir)+Filename;
 
2511
      if FileIsInPath(Filename,NewLazarusSrcDir)
 
2512
      and FileExistsUTF8(Filename) then
 
2513
      begin
 
2514
        DebugLn(['TPkgManager.LazarusSrcDirChanged load: ',Filename]);
 
2515
        // open package in new lazarus source directory
 
2516
        MsgResult:=DoOpenPackageFile(Filename,[pofDoNotOpenEditor,pofRevert],true);
 
2517
        if MsgResult=mrAbort then exit(false);
 
2518
      end;
 
2519
    end;
 
2520
  end;
 
2521
 
 
2522
var
2480
2523
  i: Integer;
2481
 
  Link: TPackageLink;
2482
 
  MsgResult: TModalResult;
2483
 
  Filename: String;
2484
2524
begin
2485
2525
  if PackageGraph=nil then exit;
2486
2526
  OldLazarusSrcDir:=FLastLazarusSrcDir;
2487
 
  NewLazarusSrcDir:=EnvironmentOptions.LazarusDirectory;
 
2527
  NewLazarusSrcDir:=EnvironmentOptions.GetParsedLazarusDirectory;
2488
2528
  FLastLazarusSrcDir:=NewLazarusSrcDir;
2489
2529
  if CompareFilenames(OldLazarusSrcDir,NewLazarusSrcDir)=0 then exit;
 
2530
  debugln(['TPkgManager.LazarusSrcDirChanged loading new lpl files from ',PkgLinks.GetGlobalLinkDirectory]);
 
2531
  if PkgLinks.IsUpdating then
 
2532
    debugln(['TPkgManager.LazarusSrcDirChanged inconsistency: pkglinks are locked']);
2490
2533
  PkgLinks.UpdateGlobalLinks;
2491
2534
 
2492
 
  i:=0;
2493
 
  while i<PackageGraph.Count do begin
2494
 
    APackage:=PackageGraph.Packages[i];
2495
 
    if (SysUtils.CompareText(copy(APackage.Filename,1,length(LazDirMacro)),LazDirMacro)=0)
2496
 
    or FileIsInPath(APackage.Filename,OldLazarusSrcDir)
2497
 
    or (PackageGraph.IsStaticBasePackage(APackage.Name) and (not APackage.AutoCreated))
2498
 
    then begin
2499
 
      // this package was from the old lazarus source directory
2500
 
      // check if there is a package in the new version
2501
 
      Link:=PkgLinks.FindLinkWithPkgName(APackage.Name);
2502
 
      if Link<>nil then begin
2503
 
        Filename:=TrimFilename(Link.Filename);
2504
 
        if not FilenameIsAbsolute(Filename) then
2505
 
          Filename:=AppendPathDelim(NewLazarusSrcDir)+Filename;
2506
 
        if FileIsInPath(Filename,NewLazarusSrcDir)
2507
 
        and FileExistsUTF8(Filename) then
2508
 
        begin
2509
 
          DebugLn(['TPkgManager.LazarusSrcDirChanged load: ',Filename]);
2510
 
          // open package in new lazarus source directory
2511
 
          MsgResult:=DoOpenPackageFile(Filename,[pofDoNotOpenEditor,pofRevert],true);
2512
 
          if MsgResult=mrAbort then break;
2513
 
        end;
2514
 
      end;
2515
 
    end;
2516
 
    inc(i);
 
2535
  VisitedPkgs:=TStringToStringTree.Create(false);
 
2536
  ReloadPkgs:=TStringList.Create;
 
2537
  try
 
2538
    // collect candidates
 
2539
    for i:=0 to PackageGraph.Count-1 do
 
2540
      GatherLazarusSrcPackages(PackageGraph.Packages[i]);
 
2541
    // reload
 
2542
    for i:=0 to ReloadPkgs.Count-1 do
 
2543
      ReloadPkg(PackageGraph.FindPackageWithName(ReloadPkgs[i],nil));
 
2544
  finally
 
2545
    ReloadPkgs.Free;
 
2546
    VisitedPkgs.Free;
2517
2547
  end;
2518
2548
end;
2519
2549
 
2527
2557
  Result:=PackageGraph.Packages[Index];
2528
2558
end;
2529
2559
 
2530
 
function TPkgManager.FindPackageWithName(const PkgName: string): TIDEPackage;
 
2560
function TPkgManager.FindPackageWithName(const PkgName: string;
 
2561
  IgnorePackage: TIDEPackage): TIDEPackage;
2531
2562
var
2532
 
  ID: TLazPackageID;
2533
 
begin
2534
 
  ID:=TLazPackageID.Create;
2535
 
  try
2536
 
    ID.Name:=PkgName;
2537
 
    Result:=PackageGraph.FindPackageWithID(ID);
2538
 
  finally
2539
 
    ID.Free;
 
2563
  Pkg: TLazPackage;
 
2564
begin
 
2565
  Pkg:=nil;
 
2566
  if (IgnorePackage<>nil) then
 
2567
    Pkg:=IgnorePackage as TLazPackage;
 
2568
  Result:=PackageGraph.FindPackageWithName(PkgName,Pkg);
 
2569
end;
 
2570
 
 
2571
function TPkgManager.RedirectPackageDependency(APackage: TIDEPackage): TIDEPackage;
 
2572
begin
 
2573
  Result:=APackage;
 
2574
  if Result=PackageGraph.LCLBasePackage then begin
 
2575
    // Older Lazarus does not have a LCLBase and a component does not work
 
2576
    // without an LCLBase implementation, so we have to use LCL instead.
 
2577
    Result:=PackageGraph.LCLPackage;
2540
2578
  end;
2541
2579
end;
2542
2580
 
2543
2581
function TPkgManager.DoCompileProjectDependencies(AProject: TProject;
2544
2582
  Flags: TPkgCompileFlags): TModalResult;
 
2583
var
 
2584
  CompilePolicy: TPackageUpdatePolicy;
2545
2585
begin
2546
2586
  // check graph for circles and broken dependencies
2547
2587
  if not (pcfDoNotCompileDependencies in Flags) then begin
2561
2601
  try
2562
2602
    // automatically compile required packages
2563
2603
    if not (pcfDoNotCompileDependencies in Flags) then begin
 
2604
      CompilePolicy:=pupAsNeeded;
 
2605
      if pcfCompileDependenciesClean in Flags then
 
2606
        CompilePolicy:=pupOnRebuildingAll;
2564
2607
      Result:=PackageGraph.CompileRequiredPackages(nil,
2565
 
                                      AProject.FirstRequiredDependency,
2566
 
                                      AProject.CompilerOptions.Globals,
2567
 
                                      [pupAsNeeded]);
 
2608
                                AProject.FirstRequiredDependency,
 
2609
                                not (pfUseDesignTimePackages in AProject.Flags),
 
2610
                                CompilePolicy);
2568
2611
      if Result<>mrOk then exit;
2569
2612
    end;
2570
2613
  finally
2575
2618
end;
2576
2619
 
2577
2620
function TPkgManager.DoCompilePackage(APackage: TLazPackage;
2578
 
  Flags: TPkgCompileFlags; ShowAbort: boolean; Globals: TGlobalCompilerOptions
2579
 
  ): TModalResult;
 
2621
  Flags: TPkgCompileFlags; ShowAbort: boolean): TModalResult;
2580
2622
begin
2581
2623
  Result:=mrCancel;
2582
2624
  
2602
2644
    if Result<>mrOk then exit;
2603
2645
  end;
2604
2646
  
2605
 
  Result:=WarnAboutMissingPackageFiles(APackage);
2606
 
  if Result<>mrOk then exit;
2607
 
 
2608
 
  Result:=PackageGraph.CompilePackage(APackage,Flags,false,Globals);
 
2647
  Result:=PackageGraph.CompilePackage(APackage,Flags,false);
2609
2648
end;
2610
2649
 
2611
2650
function TPkgManager.DoCreatePackageMakefile(APackage: TLazPackage;
2612
2651
  ShowAbort: boolean): TModalResult;
2613
2652
begin
2614
2653
  Result:=DoCompilePackage(APackage,[pcfDoNotCompileDependencies,
2615
 
                       pcfDoNotCompilePackage,pcfCreateMakefile],ShowAbort,nil);
 
2654
                       pcfDoNotCompilePackage,pcfCreateMakefile],ShowAbort);
2616
2655
end;
2617
2656
 
2618
2657
function TPkgManager.OnRenameFile(const OldFilename, NewFilename: string;
2626
2665
  if (OldFilename=NewFilename) then
2627
2666
    exit;
2628
2667
  //debugln('TPkgManager.OnRenameFile A OldFilename="',OldFilename,'" New="',NewFilename,'"');
2629
 
  OldPkgFile:=PackageGraph.FindFileInAllPackages(OldFilename,true,
2630
 
                                                 not IsPartOfProject);
 
2668
  OldPkgFile:=PackageGraph.FindFileInAllPackages(OldFilename,true,not IsPartOfProject);
2631
2669
  if (OldPkgFile=nil) or (OldPkgFile.LazPackage.ReadOnly) then
2632
2670
    exit;
2633
2671
  OldPackage:=OldPkgFile.LazPackage;
2635
2673
  NewPkgFile:=PackageGraph.FindFileInAllPackages(NewFilename,true,false);
2636
2674
  if (NewPkgFile<>nil) and (OldPackage<>NewPkgFile.LazPackage) then exit;
2637
2675
 
2638
 
  Result:=IDEMessageDialog(lisPkgMangRenameFileInPackage,
2639
 
    Format(lisPkgMangThePackageOwnsTheFileShouldTheFileBeRenamed, [
2640
 
      OldPackage.IDAsString, #13, '"', OldFilename, '"', #13]),
2641
 
    mtConfirmation,[mbYes,mbNo,mbAbort]);
2642
 
  if Result=mrNo then begin
2643
 
    Result:=mrOk;
2644
 
    exit;
2645
 
  end;
2646
 
  if Result<>mrYes then exit;
2647
 
  
2648
2676
  OldPkgFile.Filename:=NewFilename;
2649
 
  if OldPackage.Editor<>nil then OldPackage.Editor.UpdateAll(true);
 
2677
  if OldPackage.Editor<>nil then
 
2678
    OldPackage.Editor.UpdateAll(true);
2650
2679
  OldPackage.Modified:=true;
2651
 
 
2652
 
  Result:=mrOk;
2653
2680
end;
2654
2681
 
2655
2682
{------------------------------------------------------------------------------
2720
2747
    NewUnitName: String;
2721
2748
    PkgFile: TPkgFile;
2722
2749
    ClassUnitInfo: TUnitInfo;
 
2750
    APackage: TLazPackage;
2723
2751
  begin
2724
2752
    for i:=0 to ComponentClassnames.Count-1 do begin
2725
2753
      //DebugLn(['CollectNeededUnitnamesAndPackages ComponentClassnames[i]=',ComponentClassnames[i]]);
2728
2756
      if (RegComp<>nil) then begin
2729
2757
        if RegComp.ComponentClass<>nil then
2730
2758
          NewUnitName:=GetClassUnitName(RegComp.ComponentClass);
2731
 
        //DebugLn(['CollectNeededUnitnamesAndPackages AAA1 NewUnitName=',NewUnitName]);
 
2759
        //DebugLn(['CollectNeededUnitnamesAndPackages NewUnitName=',NewUnitName]);
2732
2760
        if NewUnitName='' then
2733
2761
          NewUnitName:=RegComp.GetUnitName;
2734
2762
      end else begin
2741
2769
        UnitNames.Add(NewUnitName);
2742
2770
        // find package
2743
2771
        PkgFile:=PackageGraph.FindUnitInAllPackages(NewUnitName,true);
2744
 
        //DebugLn(['CollectNeededUnitnamesAndPackages AAA2 PkgFile=',PkgFile<>nil]);
2745
 
        if (PkgFile=nil) and (RegComp is TPkgComponent) then begin
 
2772
        //DebugLn(['CollectNeededUnitnamesAndPackages PkgFile=',PkgFile<>nil]);
 
2773
        if (PkgFile=nil) and (RegComp is TPkgComponent) then
2746
2774
          PkgFile:=TPkgComponent(RegComp).PkgFile;
2747
 
          if (PkgFile<>nil) and (PkgFile.LazPackage<>nil)
2748
 
          and (Packages.IndexOf(PkgFile.LazPackage)<0) then
2749
 
            Packages.Add(PkgFile.LazPackage);
 
2775
        if (PkgFile<>nil) then begin
 
2776
          APackage:=PkgFile.LazPackage;
 
2777
          APackage:=TLazPackage(RedirectPackageDependency(APackage));
 
2778
          if (APackage<>nil) and (Packages.IndexOf(APackage)<0) then
 
2779
            Packages.Add(APackage);
2750
2780
        end;
2751
2781
      end;
2752
2782
    end;
2762
2792
  begin
2763
2793
    Result:=LoadAndParseUnitBuf;
2764
2794
    if Result<>mrOk then exit;
2765
 
    if not CodeToolBoss.FindUsedUnitNames(UnitBuf,MainUsesSection,
2766
 
      ImplementationUsesSection)
2767
 
    then begin
2768
 
      MainIDE.DoJumpToCodeToolBossError;
2769
 
      exit;
2770
 
    end;
2771
 
    for i:=0 to MainUsesSection.Count-1 do begin
2772
 
      j:=UnitNames.IndexOf(MainUsesSection[i]);
2773
 
      if j>=0 then UnitNames.Delete(j);
2774
 
    end;
2775
 
    MainUsesSection.Free;
2776
 
    ImplementationUsesSection.Free;
 
2795
    MainUsesSection:=nil;
 
2796
    ImplementationUsesSection:=nil;
 
2797
    try
 
2798
      if not CodeToolBoss.FindUsedUnitNames(UnitBuf,MainUsesSection,
 
2799
        ImplementationUsesSection)
 
2800
      then begin
 
2801
        MainIDE.DoJumpToCodeToolBossError;
 
2802
        exit;
 
2803
      end;
 
2804
      for i:=0 to MainUsesSection.Count-1 do begin
 
2805
        j:=UnitNames.IndexOf(MainUsesSection[i]);
 
2806
        if j>=0 then UnitNames.Delete(j);
 
2807
      end;
 
2808
    finally
 
2809
      MainUsesSection.Free;
 
2810
      ImplementationUsesSection.Free;
 
2811
    end;
2777
2812
    Result:=mrOk;
2778
2813
  end;
2779
2814
  
2797
2832
      for i:=0 to MissingDependencies.Count-1 do begin
2798
2833
        UnitOwner:=TObject(MissingDependencies[i]);
2799
2834
        RequiredPackage:=TLazPackage(MissingDependencies.Objects[i]);
 
2835
        RequiredPackage:=TLazPackage(RedirectPackageDependency(RequiredPackage));
2800
2836
        if UnitOwner is TProject then begin
2801
2837
          PackageAdditions:=Format(
2802
2838
            lisPkgMangAddingNewDependencyForProjectPackage, [PackageAdditions,
2803
 
            TProject(UnitOwner).Title, RequiredPackage.Name, #13#13]);
 
2839
            TProject(UnitOwner).GetTitle, RequiredPackage.Name, #13#13]);
2804
2840
        end else if UnitOwner is TLazPackage then begin
2805
2841
          PackageAdditions:=Format(
2806
2842
            lisPkgMangAddingNewDependencyForPackagePackage, [PackageAdditions,
2835
2871
      for i:=0 to MissingDependencies.Count-1 do begin
2836
2872
        UnitOwner:=TObject(MissingDependencies[i]);
2837
2873
        RequiredPackage:=TLazPackage(MissingDependencies.Objects[i]);
 
2874
        RequiredPackage:=TLazPackage(RedirectPackageDependency(RequiredPackage));
2838
2875
        if UnitOwner is TProject then begin
2839
 
          DebugLn('TPkgManager.AddUnitDependenciesForComponentClasses Adding Project Dependency ',TProject(UnitOwner).Title,' -> ',RequiredPackage.Name);
 
2876
          DebugLn('TPkgManager.AddUnitDependenciesForComponentClasses Adding Project Dependency ',TProject(UnitOwner).GetTitle,' -> ',RequiredPackage.Name);
2840
2877
          AddProjectDependency(TProject(UnitOwner),RequiredPackage);
2841
2878
        end else if UnitOwner is TLazPackage then begin
2842
2879
          DebugLn('TPkgManager.AddUnitDependenciesForComponentClasses Adding Package Dependency ',TLazPackage(UnitOwner).Name,' -> ',RequiredPackage.Name);
2843
 
          PackageGraph.AddDependencyToPackage(TLazPackage(UnitOwner),
2844
 
                                              RequiredPackage);
 
2880
          AddPackageDependency(TLazPackage(UnitOwner),RequiredPackage.Name);
2845
2881
        end;
2846
2882
      end;
2847
2883
    end;
2939
2975
          CurUnitName:='';
2940
2976
          if CurRegisteredComponent.ComponentClass<>nil then
2941
2977
            CurUnitName:=GetClassUnitName(CurRegisteredComponent.ComponentClass);
2942
 
          //DebugLn(['TPkgManager.GetMissingDependenciesForUnit AAA1 CurUnitName=',CurUnitName]);
 
2978
          //DebugLn(['TPkgManager.GetMissingDependenciesForUnit CurUnitName=',CurUnitName]);
2943
2979
          if CurUnitName='' then
2944
2980
            CurUnitName:=CurRegisteredComponent.GetUnitName;
2945
2981
          PkgFile:=PackageGraph.FindUnitInAllPackages(CurUnitName,true);
2946
 
          //DebugLn(['TPkgManager.GetMissingDependenciesForUnit AAA2 PkgFile=',PkgFile<>nil]);
 
2982
          //DebugLn(['TPkgManager.GetMissingDependenciesForUnit PkgFile=',PkgFile<>nil]);
2947
2983
          if PkgFile=nil then
2948
2984
            PkgFile:=TPkgComponent(CurRegisteredComponent).PkgFile;
2949
2985
          if PkgFile<>nil then begin
2950
2986
            RequiredPackage:=PkgFile.LazPackage;
 
2987
            RequiredPackage:=TLazPackage(RedirectPackageDependency(RequiredPackage));
2951
2988
            if (RequiredPackage<>nil)
2952
2989
            and (RequiredPackage<>UnitOwner)
2953
2990
            and (FindCompatibleDependencyInList(FirstDependency,pdlRequires,
3049
3086
      for j:=0 to CurPackage.FileCount-1 do begin
3050
3087
        CurPkgFile:=CurPackage.Files[j];
3051
3088
        if CurPkgFile.FileType in PkgFileUnitTypes then
3052
 
          AddFile(CurOwner,CurPkgFile.Filename);
 
3089
          AddFile(CurOwner,CurPkgFile.GetFullFilename);
3053
3090
      end;
3054
3091
    end else if CurOwner is TProject then begin
3055
3092
      CurProject:=TProject(CurOwner);
3101
3138
    and (BaseDir<>'') then begin
3102
3139
      // search in project source directories
3103
3140
      ProjectDirs:=AProject.LazCompilerOptions.OtherUnitFiles+';.';
3104
 
      if not IDEMacros.CreateAbsoluteSearchPath(ProjectDirs,BaseDir) then exit;
3105
 
      if FindPathInSearchPath(PChar(SrcDir),length(SrcDir),
3106
 
        PChar(ProjectDirs),length(ProjectDirs))<>nil
3107
 
      then
3108
 
        Add:=true;
 
3141
      if IDEMacros.CreateAbsoluteSearchPath(ProjectDirs,BaseDir) then begin
 
3142
        if FindPathInSearchPath(PChar(SrcDir),length(SrcDir),
 
3143
          PChar(ProjectDirs),length(ProjectDirs))<>nil
 
3144
        then
 
3145
          Add:=true;
 
3146
      end;
3109
3147
    end;
3110
3148
 
3111
3149
    if Add then
3131
3169
    PkgFile:=PackageGraph.FindFileInAllPackages(UnitFilename,true,true);
3132
3170
    if (PkgFile<>nil) and (PkgFile.LazPackage<>nil) then
3133
3171
      Result.Add(PkgFile.LazPackage);
 
3172
    //debugln(['TPkgManager.GetPossibleOwnersOfUnit ',UnitFilename,' ',PkgFile<>nil,' ',(PkgFile<>nil) and (PkgFile.LazPackage<>nil),' Result.Count=',Result.Count]);
3134
3173
    // check package source files (they usually do not have a TPkgFile)
3135
3174
    for i:=0 to PackageGraph.Count-1 do begin
3136
3175
      CurPackage:=PackageGraph.Packages[i];
3146
3185
    FreeThenNil(Result);
3147
3186
end;
3148
3187
 
3149
 
function TPkgManager.GetPackageOfCurrentSourceEditor: TPkgFile;
 
3188
function TPkgManager.GetPackageOfCurrentSourceEditor(out APackage: TIDEPackage
 
3189
  ): TPkgFile;
3150
3190
var
3151
3191
  SrcEdit: TSourceEditor;
3152
3192
begin
 
3193
  Result:=nil;
 
3194
  APackage:=nil;
3153
3195
  SrcEdit:=SourceEditorManager.GetActiveSE;
3154
 
  if SrcEdit<>nil then begin
3155
 
    Result:=SearchFile(SrcEdit.Filename,[],nil);
 
3196
  if SrcEdit=nil then exit;
 
3197
  Result := TPkgFile(GetPackageOfSourceEditor(APackage, SrcEdit));
 
3198
end;
 
3199
 
 
3200
function TPkgManager.GetPackageOfSourceEditor(out APackage: TIDEPackage;
 
3201
  ASrcEdit: TObject): TLazPackageFile;
 
3202
var
 
3203
  Filename: String;
 
3204
  i: Integer;
 
3205
begin
 
3206
  Result:=nil;
 
3207
  APackage:=nil;
 
3208
  if ASrcEdit=nil then exit;
 
3209
  Filename:=TSourceEditor(ASrcEdit).FileName;
 
3210
  Result:=SearchFile(Filename,[],nil);
 
3211
  if Result<>nil then begin
 
3212
    APackage:=Result.LazPackage;
 
3213
    exit;
 
3214
  end;
 
3215
  for i:=0 to PackageGraph.Count-1 do begin
 
3216
    APackage:=PackageGraph[i];
 
3217
    if CompareFilenames(TLazPackage(APackage).GetSrcFilename,FileName)=0 then
 
3218
      exit;
 
3219
  end;
 
3220
  APackage:=nil;
 
3221
end;
 
3222
 
 
3223
function TPkgManager.IsOwnerDependingOnPkg(AnOwner: TObject;
 
3224
  const PkgName: string; out DependencyOwner: TObject): boolean;
 
3225
var
 
3226
  FirstDep: TPkgDependency;
 
3227
  Dep: TPkgDependency;
 
3228
begin
 
3229
  Result:=false;
 
3230
  DependencyOwner:=nil;
 
3231
  if (AnOwner=nil) or (PkgName='') then exit;
 
3232
  if AnOwner is TProject then
 
3233
    FirstDep:=TProject(AnOwner).FirstRequiredDependency
 
3234
  else if AnOwner is TLazPackage then begin
 
3235
    if CompareDottedIdentifiers(PChar(TLazPackage(AnOwner).Name),
 
3236
      PChar(PkgName))=0
 
3237
    then begin
 
3238
      DependencyOwner:=AnOwner;
 
3239
      exit(true);
 
3240
    end;
 
3241
    FirstDep:=TLazPackage(AnOwner).FirstRequiredDependency;
3156
3242
  end else
3157
 
    SrcEdit:=nil;
 
3243
    exit(false);
 
3244
  if PackageGraph=nil then exit;
 
3245
  Dep:=PackageGraph.FindDependencyRecursively(FirstDep,PkgName);
 
3246
  if Dep=nil then exit;
 
3247
  DependencyOwner:=Dep.Owner;
 
3248
  Result:=true;
3158
3249
end;
3159
3250
 
3160
3251
function TPkgManager.AddDependencyToOwners(OwnerList: TFPList;
3161
 
  APackage: TLazPackage; OnlyTestIfPossible: boolean): TModalResult;
 
3252
  APackage: TIDEPackage; OnlyTestIfPossible: boolean): TModalResult;
3162
3253
var
3163
3254
  i: Integer;
3164
3255
  Item: TObject;
3165
3256
  NewDependency: TPkgDependency;
3166
3257
  ADependency: TPkgDependency;
 
3258
  r: TModalResult;
 
3259
  Pkg: TLazPackage;
3167
3260
begin
 
3261
  Pkg:=APackage as TLazPackage;
3168
3262
  if not OnlyTestIfPossible then begin
3169
3263
    Result:=AddDependencyToOwners(OwnerList,APackage,true);
3170
3264
    if Result<>mrOk then exit;
3175
3269
    Item:=TObject(OwnerList[i]);
3176
3270
    if Item=APackage then continue;
3177
3271
    if Item is TProject then begin
3178
 
      Result:=AddProjectDependency(TProject(Item),APackage,OnlyTestIfPossible);
 
3272
      Result:=AddProjectDependency(TProject(Item),Pkg,OnlyTestIfPossible);
3179
3273
      if Result<>mrOk then exit;
3180
3274
    end else if Item is TLazPackage then begin
3181
3275
      NewDependency:=TPkgDependency.Create;
3182
3276
      try
3183
3277
        NewDependency.PackageName:=APackage.Name;
3184
 
        if not CheckAddingDependency(TLazPackage(Item),NewDependency) then
3185
 
          exit;
3186
 
        if not OnlyTestIfPossible then begin
 
3278
        r:=CheckAddingDependency(TLazPackage(Item),NewDependency,false,false);
 
3279
        if r=mrCancel then exit;
 
3280
        if (not OnlyTestIfPossible) and (r<>mrIgnore) then begin
3187
3281
          ADependency:=NewDependency;
3188
3282
          NewDependency:=nil;
3189
3283
          PackageGraph.AddDependencyToPackage(TLazPackage(Item),ADependency);
3208
3302
      exit;
3209
3303
    end;
3210
3304
  end;
3211
 
  Result:=MainIDE.DoOpenMacroFile(Self,PkgFile.Filename);
 
3305
  Result:=MainIDE.DoOpenEditorFile(PkgFile.GetFullFilename,-1,-1,
 
3306
                                  [ofOnlyIfExists,ofAddToRecent,ofRegularFile]);
3212
3307
end;
3213
3308
 
3214
3309
function TPkgManager.FindVirtualUnitSource(PkgFile: TPkgFile): string;
3218
3313
  and (PkgFile.LazPackage<>nil)
3219
3314
  and (not FileExistsUTF8(PkgFile.Filename)) then begin
3220
3315
    Result:=MainIDE.FindSourceFile(PkgFile.GetShortFilename(false),
3221
 
                                     PkgFile.LazPackage.Directory,[]);
 
3316
                                   PkgFile.LazPackage.Directory,[]);
3222
3317
  end;
3223
3318
end;
3224
3319
 
3296
3391
    end;
3297
3392
    // add package dependency
3298
3393
    //DebugLn(['TPkgManager.AddDependencyToUnitOwners ',dbgsName(TObject(OwnersList[0])),' ',RequiredPkg.IDAsString]);
 
3394
    RequiredPkg:=TLazPackage(RedirectPackageDependency(RequiredPkg));
3299
3395
    Result:=AddDependencyToOwners(OwnersList,RequiredPkg,false);
3300
3396
  finally
3301
3397
    OwnersList.Free;
3338
3434
  if ActiveSourceEditor=nil then exit;
3339
3435
 
3340
3436
  Filename:=ActiveUnitInfo.Filename;
3341
 
  
 
3437
 
3342
3438
  // check if filename is absolute
3343
3439
  if ActiveUnitInfo.IsVirtual or (not FileExistsUTF8(Filename)) then begin
3344
3440
    Result:=IDEMessageDialog(lisPkgMangFileNotSaved,
3345
 
      lisPkgMangPleaseSaveTheFileBeforeAddingItToAPackage,
3346
 
      mtWarning,[mbCancel]);
 
3441
      lisPkgMangPleaseSaveTheFileBeforeAddingItToAPackage, mtWarning,[mbCancel]);
3347
3442
    exit;
3348
3443
  end;
3349
3444
  
3350
3445
  // check if file is part of project
3351
3446
  if ActiveUnitInfo.IsPartOfProject then begin
3352
3447
    Result:=IDEMessageDialog(lisPkgMangFileIsInProject,
3353
 
      Format(lisPkgMangWarningTheFileBelongsToTheCurrentProject, ['"',
3354
 
        Filename, '"', #13])
3355
 
      ,mtWarning,[mbIgnore,mbCancel,mbAbort]);
 
3448
      Format(lisPkgMangWarningTheFileBelongsToTheCurrentProject,
 
3449
             ['"', Filename, '"', #13])
 
3450
      ,mtWarning,[mbIgnore,mbCancel]);
3356
3451
    if Result<>mrIgnore then exit;
3357
3452
  end;
3358
 
  
 
3453
 
3359
3454
  // check if file is already in a package
3360
3455
  PkgFile:=PackageGraph.FindFileInAllPackages(Filename,true,true);
3361
3456
  if PkgFile<>nil then begin
3362
3457
    Result:=IDEMessageDialog(lisPkgMangFileIsAlreadyInPackage,
3363
 
      Format(lisPkgMangTheFileIsAlreadyInThePackage, ['"', Filename, '"', #13,
3364
 
        PkgFile.LazPackage.IDAsString]),
3365
 
      mtWarning,[mbIgnore,mbCancel,mbAbort]);
 
3458
      Format(lisPkgMangTheFileIsAlreadyInThePackage,
 
3459
             ['"', Filename, '"', #13, PkgFile.LazPackage.IDAsString]),
 
3460
      mtWarning,[mbIgnore,mbCancel]);
3366
3461
    if Result<>mrIgnore then exit;
3367
3462
  end;
3368
3463
  
3376
3471
    end;
3377
3472
  end;
3378
3473
  
3379
 
  Result:=ShowAddFileToAPackageDlg(Filename,TheUnitName,HasRegisterProc);
 
3474
  Result:=ShowAddFileToAPackageDlg(Filename,TheUnitName,HasRegisterProc,
 
3475
                                   @MainIDE.GetIDEFileState);
 
3476
end;
 
3477
 
 
3478
function TPkgManager.DoNewPackageComponent: TModalResult;
 
3479
var
 
3480
  APackage: TLazPackage;
 
3481
  CurEditor: TPackageEditorForm;
 
3482
  SaveFlags: TPkgSaveFlags;
 
3483
  Page: TAddToPkgType;
 
3484
begin
 
3485
  Result:=ShowNewPkgComponentDialog(APackage);
 
3486
  if Result<>mrOk then exit;
 
3487
  SaveFlags:=[];
 
3488
  if APackage=nil then begin
 
3489
    // create new package
 
3490
    // create a new package with standard dependencies
 
3491
    APackage:=PackageGraph.CreateNewPackage(NameToValidIdentifier(lisPkgMangNewPackage));
 
3492
    PackageGraph.AddDependencyToPackage(APackage,
 
3493
                  PackageGraph.IDEIntfPackage.CreateDependencyWithOwner(APackage));
 
3494
    APackage.Modified:=false;
 
3495
    Include(SaveFlags,psfSaveAs);
 
3496
  end;
 
3497
  // open a package editor
 
3498
  CurEditor:=PackageEditors.OpenEditor(APackage);
 
3499
  IDEWindowCreators.ShowForm(CurEditor,true);
 
3500
  // save
 
3501
  Result:=DoSavePackage(APackage,SaveFlags);
 
3502
  if Result<>mrOk then exit;
 
3503
  // show new component dialog
 
3504
  Page:=d2ptNewComponent;
 
3505
  Result:=CurEditor.ShowAddDialog(Page);
 
3506
end;
 
3507
 
 
3508
function TPkgManager.SavePackageFiles(APackage: TLazPackage): TModalResult;
 
3509
var
 
3510
  i: Integer;
 
3511
  AFile: TPkgFile;
 
3512
  AFilename: String;
 
3513
  SaveFlags: TSaveFlags;
 
3514
  SrcEdit: TSourceEditor;
 
3515
begin
 
3516
  Result:=mrOk;
 
3517
  for i:=0 to APackage.FileCount-1 do begin
 
3518
    AFile:=APackage.Files[i];
 
3519
    if AFile.FileType=pftVirtualUnit then continue;
 
3520
    AFilename:=AFile.Filename;
 
3521
    if System.Pos('$(',AFilename)>0 then begin
 
3522
      // filename contains macros -> skip
 
3523
      //debugln(['TPkgManager.SavePackageFiles macros ',AFilename]);
 
3524
      continue;
 
3525
    end;
 
3526
    // check if open in editor
 
3527
    SrcEdit:=SourceEditorManager.SourceEditorIntfWithFilename(AFilename);
 
3528
    if SrcEdit=nil then
 
3529
    begin
 
3530
      // not open in source editor => skip
 
3531
      //debugln(['TPkgManager.SavePackageFiles no src edit ',AFilename]);
 
3532
      continue;
 
3533
    end;
 
3534
    SaveFlags:=[sfCanAbort];
 
3535
    if not FilenameIsAbsolute(AFilename) then
 
3536
      SaveFlags:=[sfSaveAs];
 
3537
    debugln(['TPkgManager.SavePackageFiles saving ',AFilename]);
 
3538
    Result:=LazarusIDE.DoSaveEditorFile(SrcEdit,SaveFlags);
 
3539
    if Result=mrIgnore then Result:=mrOk;
 
3540
    if Result<>mrOk then exit;
 
3541
  end;
3380
3542
end;
3381
3543
 
3382
3544
function TPkgManager.WarnAboutMissingPackageFiles(APackage: TLazPackage
3390
3552
  for i:=0 to APackage.FileCount-1 do begin
3391
3553
    AFile:=APackage.Files[i];
3392
3554
    if AFile.FileType=pftVirtualUnit then continue;
3393
 
    AFilename:=AFile.Filename;
 
3555
    AFilename:=AFile.GetFullFilename;
3394
3556
    if System.Pos('$(',AFilename)>0 then begin
3395
3557
      // filename contains macros -> skip
3396
 
    end;
3397
 
    if (not APackage.IsVirtual) and FilenameIsAbsolute(AFilename) then
3398
 
      APackage.LongenFilename(AFilename);
3399
 
    if FilenameIsAbsolute(AFilename) then begin
3400
 
      if not FileExistsCached(AFilename) then begin
3401
 
        if not APackage.IsVirtual then
3402
 
          AFilename:=CreateRelativePath(AFilename,APackage.Directory);
3403
 
        Result:=IDEQuestionDialog(lisPkgMangPackageFileMissing,
3404
 
          Format(lisPkgMangTheFileOfPackageIsMissing, ['"', AFilename, '"',
3405
 
            #13, APackage.IDAsString]),
3406
 
          mtWarning,[mrIgnore,mrAbort]);
3407
 
        if Result<>mrAbort then
3408
 
          Result:=mrOk;
3409
 
        // one warning is enough
3410
 
        exit;
3411
 
      end;
3412
 
    end else begin
3413
 
      if not APackage.IsVirtual then begin
3414
 
        // an unsaved file
3415
 
        Result:=IDEQuestionDialog(lisPkgMangPackageFileNotSaved,
3416
 
          Format(lisPkgMangTheFileOfPackageNeedsToBeSavedFirst, ['"',
3417
 
            AFilename, '"', #13, APackage.IDAsString]),
3418
 
          mtWarning, [mrIgnore, lisPkgMangIgnoreAndSavePackageNow, mrAbort]);
3419
 
        if Result<>mrAbort then
3420
 
          Result:=mrOk;
3421
 
      end;
3422
 
    end;
 
3558
      continue;
 
3559
    end;
 
3560
    if FilenameIsAbsolute(AFilename) and FileExistsCached(AFilename) then
 
3561
      continue;
 
3562
    Result:=IDEQuestionDialog(lisPkgSysPackageFileNotFound,
 
3563
      Format(lisPkgMangTheFileOfPackageWasNotFound, [AFilename, APackage.
 
3564
        IDAsString]),
 
3565
      mtWarning,[mrIgnore,mrAbort]);
 
3566
    if Result<>mrAbort then
 
3567
      Result:=mrOk;
 
3568
    // one warning is enough
 
3569
    exit;
3423
3570
  end;
3424
3571
end;
3425
3572
 
3429
3576
  NewDependency: TPkgDependency;
3430
3577
  ADependency: TPkgDependency;
3431
3578
begin
3432
 
  Result:=mrCancel;
3433
3579
  NewDependency:=TPkgDependency.Create;
3434
3580
  try
3435
3581
    NewDependency.PackageName:=ReqPackage;
3436
 
    if not CheckAddingDependency(APackage,NewDependency) then
3437
 
      exit;
 
3582
    Result:=CheckAddingDependency(APackage,NewDependency,false,false);
 
3583
    if Result=mrIgnore then exit(mrOk);
 
3584
    if Result<>mrOk then exit;
3438
3585
    if not OnlyTestIfPossible then begin
3439
3586
      ADependency:=NewDependency;
3440
3587
      NewDependency:=nil;
3530
3677
  RequiredPackage: TLazPackage;
3531
3678
  BuildIDEFlags: TBuildLazarusFlags;
3532
3679
  Msg: string;
 
3680
  Btns: TMsgDlgButtons;
 
3681
  ConflictDep: TPkgDependency;
3533
3682
begin
3534
3683
  if not MainIDE.DoResetToolStatus([rfInteractive]) then exit(mrCancel);
3535
3684
 
3537
3686
  PkgList:=nil;
3538
3687
  try
3539
3688
    // check if package is designtime package
3540
 
    if APackage.PackageType=lptRunTime then begin
 
3689
    if APackage.PackageType in [lptRunTime,lptRunTimeOnly] then begin
 
3690
      Btns:=[mbAbort];
 
3691
      if APackage.PackageType=lptRunTime then
 
3692
        Include(Btns,mbIgnore);
3541
3693
      Result:=IDEMessageDialog(lisPkgMangPackageIsNoDesigntimePackage,
3542
 
        Format(lisPkgMangThePackageIsARuntimeOnlyPackageRuntimeOnlyPackages, [
3543
 
          APackage.IDAsString, #13]),
3544
 
        mtError,[mbIgnore,mbAbort]);
 
3694
        Format(lisPkgMangThePackageIsARuntimeOnlyPackageRuntimeOnlyPackages,
 
3695
               [APackage.IDAsString, #13]),
 
3696
        mtError,Btns);
3545
3697
      if Result<>mrIgnore then exit;
3546
3698
    end;
3547
 
  
 
3699
    // check if package requires a runtime only package
 
3700
    ConflictDep:=PackageGraph.FindRuntimePkgOnlyRecursively(
 
3701
      APackage.FirstRequiredDependency);
 
3702
    if ConflictDep<>nil then begin
 
3703
      IDEQuestionDialog(lisNotADesigntimePackage,
 
3704
        Format(lisThePackageCanNotBeInstalledBecauseItRequiresWhichI, [
 
3705
          APackage.Name, ConflictDep.AsString]),
 
3706
        mtError,
 
3707
        [mrCancel]
 
3708
        );
 
3709
      exit;
 
3710
    end;
 
3711
 
3548
3712
    // save package
3549
3713
    if APackage.IsVirtual or APackage.Modified then begin
3550
3714
      Result:=DoSavePackage(APackage,[]);
3553
3717
 
3554
3718
    // check consistency
3555
3719
    Result:=CheckPackageGraphForCompilation(APackage,nil,
3556
 
                                     EnvironmentOptions.LazarusDirectory,false);
 
3720
                            EnvironmentOptions.GetParsedLazarusDirectory,false);
3557
3721
    if Result<>mrOk then exit;
3558
3722
    
3559
3723
    // get all required packages, which will also be auto installed
3577
3741
        s:=s+RequiredPackage.IDAsString+#13;
3578
3742
      end;
3579
3743
      if PkgList.Count=0 then
3580
 
        Msg:=Format(
3581
 
          lisPkgMangInstallingThePackageWillAutomaticallyInstallThePac, [
3582
 
          APackage.IDAsString])
 
3744
        Msg:=Format(lisPkgMangInstallingThePackageWillAutomaticallyInstallThePac,
 
3745
                    [APackage.IDAsString])
3583
3746
      else
3584
 
        Msg:=Format(
3585
 
          lisPkgMangInstallingThePackageWillAutomaticallyInstallThePac2, [
3586
 
          APackage.IDAsString]);
 
3747
        Msg:=Format(lisPkgMangInstallingThePackageWillAutomaticallyInstallThePac2,
 
3748
                    [APackage.IDAsString]);
3587
3749
      Result:=IDEMessageDialog(lisPkgMangAutomaticallyInstalledPackages,
3588
3750
        Msg+#13+s,mtConfirmation,[mbOk,mbCancel]);
3589
3751
      if Result<>mrOk then exit;
3619
3781
 
3620
3782
  if NeedSaving then begin
3621
3783
    PackageGraph.SortAutoInstallDependencies;
3622
 
    SaveAutoInstallDependencies(true);
 
3784
    SaveAutoInstallDependencies;
3623
3785
  end;
3624
3786
 
3625
3787
  // save IDE build configs, so user can build IDE on command line
3626
 
  BuildIDEFlags:=[blfWithStaticPackages,blfDontClean,blfOnlyIDE];
 
3788
  BuildIDEFlags:=[blfDontClean,blfOnlyIDE];
3627
3789
  Result:=MainIDE.DoSaveBuildIDEConfigs(BuildIDEFlags);
3628
3790
  if Result<>mrOk then exit;
3629
3791
 
3630
3792
  // ask user to rebuild Lazarus now
3631
3793
  Result:=IDEMessageDialog(lisPkgMangRebuildLazarus,
3632
 
    Format(lisPkgMangThePackageWasMarkedForInstallationCurrentlyLazarus, [
3633
 
      '"', APackage.IDAsString, '"', #13, #13, #13]),
 
3794
    Format(lisPkgMangThePackageWasMarkedForInstallationCurrentlyLazarus,
 
3795
           ['"', APackage.IDAsString, '"', #13, #13, #13]),
3634
3796
    mtConfirmation,[mbYes,mbNo]);
3635
3797
  if Result<>mrYes then begin
3636
3798
    Result:=mrOk;
3660
3822
    DoShowPackageGraphPathList(DependencyPath);
3661
3823
    ParentPackage:=TLazPackage(DependencyPath[0]);
3662
3824
    Result:=IDEMessageDialogAb(lisPkgMangPackageIsRequired,
3663
 
      Format(lisPkgMangThePackageIsRequiredByWhichIsMarkedForInstallation, [
3664
 
        APackage.IDAsString, ParentPackage.IDAsString, #13]),
 
3825
      Format(lisPkgMangThePackageIsRequiredByWhichIsMarkedForInstallation,
 
3826
             [APackage.IDAsString, ParentPackage.IDAsString, #13]),
3665
3827
      mtError,[mbCancel],ShowAbort);
3666
3828
    exit;
3667
3829
  end;
3669
3831
  // check if package is a lazarus base package
3670
3832
  if PackageGraph.IsStaticBasePackage(APackage.Name) then begin
3671
3833
    Result:=IDEMessageDialogAb(lisUninstallImpossible,
3672
 
      Format(lisThePackageCanNotBeUninstalledBecauseItIsNeededByTh, [
3673
 
        APackage.Name]),
 
3834
      Format(lisThePackageCanNotBeUninstalledBecauseItIsNeededByTh,[APackage.Name]),
3674
3835
      mtError,[mbCancel],ShowAbort);
3675
3836
    exit;
3676
3837
  end;
3701
3862
        Dependency.Free;
3702
3863
        PackageGraph.SortAutoInstallDependencies;
3703
3864
      end;
3704
 
      SaveAutoInstallDependencies(true);
 
3865
      SaveAutoInstallDependencies;
3705
3866
    end;
3706
3867
 
3707
3868
    // save IDE build configs, so user can build IDE on command line
3708
 
    BuildIDEFlags:=[blfWithStaticPackages,blfDontClean,blfOnlyIDE];
 
3869
    BuildIDEFlags:=[blfDontClean,blfOnlyIDE];
3709
3870
    Result:=MainIDE.DoSaveBuildIDEConfigs(BuildIDEFlags);
3710
3871
    if Result<>mrOk then exit;
3711
3872
 
3712
3873
    if not (puifDoNotBuildIDE in Flags) then begin
3713
3874
      // ask user to rebuilt Lazarus now
3714
3875
      Result:=IDEMessageDialog(lisPkgMangRebuildLazarus,
3715
 
        Format(lisPkgMangThePackageWasMarkedCurrentlyLazarus, ['"',
3716
 
          APackage.IDAsString, '"', #13, #13, #13]),
 
3876
        Format(lisPkgMangThePackageWasMarkedCurrentlyLazarus,
 
3877
               ['"', APackage.IDAsString, '"', #13, #13, #13]),
3717
3878
        mtConfirmation,[mbYes,mbNo]);
3718
3879
      if Result=mrNo then begin
3719
3880
        Result:=mrOk;
3730
3891
  Result:=mrOk;
3731
3892
end;
3732
3893
 
3733
 
function TPkgManager.DoInstallPackages(PkgIdList: TFPList; AddExisting,
3734
 
  RebuildIDE, Quiet: boolean; CheckList: boolean): TModalResult;
 
3894
function TPkgManager.CheckInstallPackageList(PkgIDList: TObjectList;
 
3895
  Flags: TPkgInstallInIDEFlags): boolean;
 
3896
var
 
3897
  NewFirstAutoInstallDependency: TPkgDependency;
 
3898
 
 
3899
  procedure DeleteDependency(ADependency: TPkgDependency);
 
3900
  var
 
3901
    i: Integer;
 
3902
    PkgID: TLazPackageID;
 
3903
  begin
 
3904
    DeleteDependencyInList(ADependency,NewFirstAutoInstallDependency,pdlRequires);
 
3905
    if piiifRemoveConflicts in Flags then
 
3906
      for i:=PkgIDList.Count-1 downto 0 do begin
 
3907
        PkgID:=TLazPackageID(PkgIDList[i]);
 
3908
        if SysUtils.CompareText(PkgID.Name,ADependency.PackageName)=0 then begin
 
3909
          PkgIDList.Delete(i);
 
3910
          PkgID.Free;
 
3911
        end;
 
3912
      end;
 
3913
  end;
 
3914
 
 
3915
var
 
3916
  PkgList: TFPList;
 
3917
  i: Integer;
 
3918
  APackage: TLazPackage;
 
3919
  ADependency: TPkgDependency;
 
3920
  NextDependency: TPkgDependency;
 
3921
  SaveFlags: TPkgSaveFlags;
 
3922
  ConflictDep: TPkgDependency;
 
3923
begin
 
3924
  Result:=false;
 
3925
  PkgList:=nil;
 
3926
  try
 
3927
    // create new auto install dependency PkgIDList
 
3928
    ListPkgIDToDependencyList(PkgIDList,NewFirstAutoInstallDependency,
 
3929
                              pdlRequires,Self,true);
 
3930
 
 
3931
    // load all required packages
 
3932
    if LoadDependencyList(NewFirstAutoInstallDependency,piiifQuiet in Flags)<>mrOk then exit;
 
3933
 
 
3934
    // remove all top level runtime packages from the list
 
3935
    // Note: it's ok if a designtime package uses a runtime package
 
3936
    ADependency:=NewFirstAutoInstallDependency;
 
3937
    while ADependency<>nil do begin
 
3938
      NextDependency:=ADependency.NextRequiresDependency;
 
3939
      if (ADependency.RequiredPackage<>nil) then begin
 
3940
        if (ADependency.RequiredPackage.PackageType in [lptRunTime,lptRunTimeOnly])
 
3941
        then begin
 
3942
          // top level dependency on runtime package => delete
 
3943
          DeleteDependency(ADependency);
 
3944
        end else begin
 
3945
          ConflictDep:=PackageGraph.FindRuntimePkgOnlyRecursively(
 
3946
            ADependency.RequiredPackage.FirstRequiredDependency);
 
3947
          //debugln(['TPkgManager.CheckInstallPackageList ',ADependency.RequiredPackage.Name,' ',ConflictDep<>nil]);
 
3948
          if ConflictDep<>nil then begin
 
3949
            if piiifRemoveConflicts in Flags then begin
 
3950
              // can remove conflict
 
3951
              if not (piiifQuiet in Flags)
 
3952
              and (IDEQuestionDialog(lisNotADesigntimePackage,
 
3953
                Format(lisThePackageCanNotBeInstalledBecauseItRequiresWhichI, [
 
3954
                  ADependency.RequiredPackage.Name, ConflictDep.AsString]),
 
3955
                mtError,
 
3956
                [mrYes, Format(lisUninstall, [ADependency.RequiredPackage.Name]), mrCancel]
 
3957
                )<>mrYes)
 
3958
              then
 
3959
                exit;
 
3960
            end else begin
 
3961
              // can not remove conflict
 
3962
              if not (piiifQuiet in Flags) then
 
3963
                IDEQuestionDialog(lisNotADesigntimePackage,
 
3964
                  Format(lisThePackageCanNotBeInstalledBecauseItRequiresWhichI, [
 
3965
                    ADependency.RequiredPackage.Name, ConflictDep.AsString]),
 
3966
                  mtError,[mrCancel]);
 
3967
              exit;
 
3968
            end;
 
3969
            // dependency needs a runtime only package => delete
 
3970
            DeleteDependency(ADependency);
 
3971
          end;
 
3972
        end;
 
3973
      end;
 
3974
      ADependency:=NextDependency;
 
3975
    end;
 
3976
 
 
3977
    PackageGraph.GetAllRequiredPackages(NewFirstAutoInstallDependency,PkgList);
 
3978
 
 
3979
    // try save all modified packages
 
3980
    for i:=0 to PkgList.Count-1 do begin
 
3981
      APackage:=TLazPackage(PkgList[i]);
 
3982
      if (not APackage.AutoCreated)
 
3983
      and (APackage.IsVirtual or APackage.Modified) then begin
 
3984
        SaveFlags:=[];
 
3985
        if DoSavePackage(APackage,SaveFlags)<>mrOk then exit;
 
3986
      end;
 
3987
    end;
 
3988
 
 
3989
    Result:=true;
 
3990
  finally
 
3991
    FreeDependencyList(NewFirstAutoInstallDependency,pdlRequires);
 
3992
    PkgList.Free;
 
3993
  end;
 
3994
end;
 
3995
 
 
3996
function TPkgManager.InstallPackages(PkgIdList: TObjectList;
 
3997
  Flags: TPkgInstallInIDEFlags): TModalResult;
3735
3998
 
3736
3999
  procedure CreateChangeReport(
3737
4000
    OldDependencyList, NewDependencyList: TPkgDependency; Report: TStrings);
3749
4012
                                                CurDependency.PackageName);
3750
4013
      if OldDependency=nil then begin
3751
4014
        // newly installed
3752
 
        s:=s+'|'+lisNew;
 
4015
        s:=s+'|'+lisPkgMgrNew;
3753
4016
        Report.Add(s);
3754
4017
      end;
3755
4018
      CurDependency:=CurDependency.NextRequiresDependency;
3762
4025
                                                CurDependency.PackageName);
3763
4026
      if NewDependency=nil then
3764
4027
        // this package will be removed
3765
 
        Report.Add('|'+lisRemove+'|'+CurDependency.AsString);
 
4028
        Report.Add('|'+lisPkgMgrRemove+'|'+CurDependency.AsString);
3766
4029
      CurDependency:=CurDependency.NextRequiresDependency;
3767
4030
    end;
3768
4031
 
3775
4038
      if OldDependency<>nil then begin
3776
4039
        // stay installed
3777
4040
        if CurDependency.AsString<>OldDependency.AsString then
3778
 
          s:=s+'|'+lisKeep+'|'+OldDependency.AsString;
 
4041
          s:=s+'|'+lisPkgMgrKeep+'|'+OldDependency.AsString;
3779
4042
        Report.Add(s);
3780
4043
      end;
3781
4044
      CurDependency:=CurDependency.NextRequiresDependency;
3785
4048
var
3786
4049
  NewFirstAutoInstallDependency: TPkgDependency;
3787
4050
  BuildIDEFlags: TBuildLazarusFlags;
3788
 
  ok: boolean;
3789
4051
  Report: TStringList;
3790
4052
  PkgList: TFPList;
3791
4053
  RequiredPackage: TLazPackage;
3792
4054
  i: Integer;
3793
4055
  CurDependency: TPkgDependency;
 
4056
  OldID: TLazPackageID;
3794
4057
begin
3795
4058
  Result:=mrCancel;
3796
4059
  NewFirstAutoInstallDependency:=nil;
3797
4060
  PkgList:=nil;
3798
4061
  try
3799
 
    if AddExisting then
 
4062
    if not (piiifClear in Flags) then
3800
4063
    begin
3801
4064
      // add existing install packages to list
3802
4065
      NewFirstAutoInstallDependency:=PackageGraph.FirstAutoInstallDependency;
3803
4066
      while NewFirstAutoInstallDependency<>nil do begin
3804
 
        if NewFirstAutoInstallDependency.RequiredPackage<>nil then
3805
 
          PkgIdList.Add(NewFirstAutoInstallDependency.RequiredPackage);
 
4067
        if NewFirstAutoInstallDependency.RequiredPackage<>nil then begin
 
4068
          i:=PkgIdList.Count-1;
 
4069
          while (i>=0)
 
4070
          and (TLazPackageID(PkgIdList[i]).Compare(NewFirstAutoInstallDependency.RequiredPackage)<>0)
 
4071
          do dec(i);
 
4072
          if i<0 then begin
 
4073
            OldID:=TLazPackageID.Create;
 
4074
            OldID.AssignID(NewFirstAutoInstallDependency.RequiredPackage);
 
4075
            PkgIdList.Add(OldID);
 
4076
          end;
 
4077
        end;
3806
4078
        NewFirstAutoInstallDependency:=NewFirstAutoInstallDependency.NextRequiresDependency;
3807
4079
      end;
3808
4080
    end;
3809
4081
 
3810
 
    if CheckList then
 
4082
    if not (piiifSkipChecks in Flags) then
3811
4083
    begin
3812
 
      OnCheckInstallPackageList(PkgIDList,ok);
3813
 
      if not ok then exit(mrCancel);
 
4084
      if not CheckInstallPackageList(PkgIDList,Flags*[piiifQuiet,piiifRemoveConflicts]) then
 
4085
        exit(mrCancel);
3814
4086
    end;
3815
4087
 
3816
4088
    // create new auto install dependency PkgIDList
3820
4092
    PackageGraph.SortDependencyListTopologically(NewFirstAutoInstallDependency,
3821
4093
                                                 false);
3822
4094
 
3823
 
    if not Quiet then
 
4095
    if not (piiifQuiet in Flags) then
3824
4096
    begin
3825
4097
      // tell the user, which packages will stay, which will be removed and
3826
4098
      // which will be newly installed
3840
4112
    try
3841
4113
      // get all required packages
3842
4114
      //debugln('TPkgManager.MainIDEitmPkgEditInstallPkgsClick GetAllRequiredPackages for ',DependencyListAsString(NewFirstAutoInstallDependency,pdlRequires));
3843
 
      if LoadDependencyList(NewFirstAutoInstallDependency)<>mrOk then exit(mrCancel);
 
4115
      if LoadDependencyList(NewFirstAutoInstallDependency,false)<>mrOk then exit(mrCancel);
3844
4116
      PackageGraph.GetAllRequiredPackages(NewFirstAutoInstallDependency,PkgList);
3845
4117
 
3846
4118
      // mark packages for installation
3875
4147
    // save package list
3876
4148
    //debugln('TPkgManager.MainIDEitmPkgEditInstallPkgsClick save package list');
3877
4149
    PackageGraph.SortAutoInstallDependencies;
3878
 
    SaveAutoInstallDependencies(true);
 
4150
    SaveAutoInstallDependencies;
3879
4151
 
3880
4152
    // save IDE build configs, so user can build IDE on command line
3881
 
    BuildIDEFlags:=[blfWithStaticPackages,blfDontClean,blfOnlyIDE,
3882
 
                    blfWithoutCompilingIDE];
 
4153
    BuildIDEFlags:=[blfDontClean,blfOnlyIDE];
3883
4154
    if MainIDE.DoSaveBuildIDEConfigs(BuildIDEFlags)<>mrOk then exit(mrCancel);
3884
4155
 
3885
 
    if RebuildIDE then begin
 
4156
    if piiifRebuildIDE in Flags then
 
4157
    begin
3886
4158
      // rebuild Lazarus
3887
4159
      if MainIDE.DoBuildLazarus(BuildIDEFlags)<>mrOk then exit(mrCancel);
3888
4160
    end;
3906
4178
    exit;
3907
4179
  end;
3908
4180
  Filename:=APackage.GetSrcFilename;
3909
 
  if (not FilenameIsAbsolute(Filename)) or (not FileExistsUTF8(Filename)) then begin
3910
 
    IDEMessageDialog(lisCCOErrorCaption, lisPkgMangPleaseSaveThePackageFirst,
 
4181
  if (not FilenameIsAbsolute(Filename)) or (not FileExistsCached(Filename)) then begin
 
4182
    IDEMessageDialog(lisCCOErrorCaption, lisPkgMangPleaseCompileThePackageFirst,
3911
4183
      mtError,[mbCancel]);
3912
4184
    exit;
3913
4185
  end;
3921
4193
  OldDependency: TPkgDependency;
3922
4194
  Dependencies: TPkgDependency;
3923
4195
  AutoRemove: Boolean;
 
4196
  CompilePolicy: TPackageUpdatePolicy;
3924
4197
begin
3925
4198
  PackageGraph.BeginUpdate(false);
3926
4199
  Dependencies:=PackageGraph.FirstAutoInstallDependency;
3960
4233
          mrYes: ;
3961
4234
          mrYesToAll: AutoRemove:=true;
3962
4235
          else
3963
 
            SaveAutoInstallDependencies(true);
 
4236
            SaveAutoInstallDependencies;
3964
4237
            exit;
3965
4238
          end;
3966
4239
        end;
3968
4241
        OldDependency.Free;
3969
4242
      end;
3970
4243
    end;
3971
 
    SaveAutoInstallDependencies(true);
 
4244
    SaveAutoInstallDependencies;
3972
4245
 
3973
4246
    // check consistency
3974
4247
    Result:=CheckPackageGraphForCompilation(nil,Dependencies,
3975
 
                                EnvironmentOptions.LazarusDirectory,false);
 
4248
                            EnvironmentOptions.GetParsedLazarusDirectory,false);
3976
4249
    if Result<>mrOk then exit;
3977
4250
    //DebugLn(['TPkgManager.DoCompileAutoInstallPackages LCLUnitPath=',PackageGraph.LCLPackage.CompilerOptions.GetUnitPath(true)]);
3978
4251
 
3983
4256
    end;
3984
4257
    
3985
4258
    // compile all auto install dependencies
3986
 
    MiscellaneousOptions.BuildLazProfiles.UpdateGlobals;
3987
 
    Result:=PackageGraph.CompileRequiredPackages(nil,Dependencies,
3988
 
                   MiscellaneousOptions.BuildLazProfiles.Globals,[pupAsNeeded]);
 
4259
    CompilePolicy:=pupAsNeeded;
 
4260
    if pcfCompileDependenciesClean in Flags then
 
4261
      CompilePolicy:=pupOnRebuildingAll;
 
4262
    Result:=PackageGraph.CompileRequiredPackages(nil,Dependencies,false,
 
4263
                                                 CompilePolicy);
3989
4264
    if Result<>mrOk then exit;
3990
4265
    
3991
4266
  finally
4364
4639
 
4365
4640
function TPkgManager.DoClosePackageEditor(APackage: TLazPackage): TModalResult;
4366
4641
begin
4367
 
  if APackage.Editor<>nil then begin
 
4642
  if APackage.Editor<>nil then
4368
4643
    APackage.Editor.Free;
4369
 
  end;
4370
4644
  Result:=mrOk;
4371
4645
end;
4372
4646