View Issue Details

IDProjectCategoryView StatusLast Update
0025903PatchesIDEpublic2018-07-17 00:12
ReporterdimprofiAssigned ToJuha Manninen 
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
Product Version1.3 (SVN)Product Build44492 
Target VersionFixed in Version 
Summary0025903: New Feature: import a path list to a units/includes (-Fu/-Fi) from text-file
DescriptionAdded a Button "Import Paths" to PathEditorDialog
Clicking on it, shows an OpenFileDialog to select a text-file to Import.
Importing is processed by TStringList.LoadFromFile();

The patch is usable on 1.2 and 1.3 Lazarus.
TagsFeature
Fixed in RevisionPartially r46035, r46200
LazTarget-
Widgetset
Attached Files
  • 2014-03-23 importpaths.patch (9,121 bytes)
    Index: ide/lazarusidestrconsts.pas
    ===================================================================
    --- ide/lazarusidestrconsts.pas	(revision 44492)
    +++ ide/lazarusidestrconsts.pas	(working copy)
    @@ -3412,6 +3412,7 @@
       lisPathEditBrowse = 'Browse';
       lisPathEditPathTemplates = 'Path templates';
       lisPathEditDeleteInvalidPaths = 'Delete Invalid Paths';
    +  lisPathEditImportPaths = 'Import Paths';
       
       // new dialog
       lisNewDlgNoItemSelected = 'No item selected';
    Index: ide/patheditordlg.lfm
    ===================================================================
    --- ide/patheditordlg.lfm	(revision 44492)
    +++ ide/patheditordlg.lfm	(working copy)
    @@ -2,30 +2,30 @@
       Left = 420
       Height = 446
       Top = 156
    -  Width = 553
    +  Width = 659
       AutoSize = True
       Caption = 'PathEditorDialog'
       ClientHeight = 446
    -  ClientWidth = 553
    +  ClientWidth = 659
       Constraints.MinHeight = 400
       Constraints.MinWidth = 500
       OnCreate = FormCreate
       OnResize = FormResize
       OnShow = FormShow
       Position = poScreenCenter
    -  LCLVersion = '1.1'
    +  LCLVersion = '1.3'
       object PathGroupBox: TGroupBox
         Left = 6
    -    Height = 216
    +    Height = 221
         Top = 6
    -    Width = 541
    +    Width = 647
         Align = alClient
         Anchors = [akTop, akLeft, akRight]
         AutoSize = True
         BorderSpacing.Around = 6
         Caption = 'PathGroupBox'
    -    ClientHeight = 195
    -    ClientWidth = 533
    +    ClientHeight = 203
    +    ClientWidth = 643
         Constraints.MinHeight = 194
         Constraints.MinWidth = 488
         TabOrder = 0
    @@ -35,9 +35,9 @@
           AnchorSideRight.Side = asrBottom
           AnchorSideBottom.Control = PathGroupBox
           AnchorSideBottom.Side = asrBottom
    -      Left = 502
    +      Left = 612
           Height = 25
    -      Top = 45
    +      Top = 47
           Width = 25
           Anchors = [akRight]
           BorderSpacing.Around = 6
    @@ -54,9 +54,9 @@
           AnchorSideTop.Side = asrBottom
           AnchorSideBottom.Control = PathGroupBox
           AnchorSideBottom.Side = asrBottom
    -      Left = 502
    +      Left = 612
           Height = 25
    -      Top = 84
    +      Top = 86
           Width = 25
           BorderSpacing.Around = 14
           GlyphShowMode = gsmAlways
    @@ -70,10 +70,10 @@
           AnchorSideLeft.Side = asrBottom
           AnchorSideBottom.Control = PathGroupBox
           AnchorSideBottom.Side = asrBottom
    -      Left = 206
    -      Height = 28
    -      Top = 161
    -      Width = 99
    +      Left = 205
    +      Height = 25
    +      Top = 172
    +      Width = 95
           Anchors = [akLeft, akBottom]
           AutoSize = True
           BorderSpacing.Around = 6
    @@ -89,9 +89,9 @@
           AnchorSideTop.Control = PathGroupBox
           AnchorSideRight.Control = MoveUpButton
           Left = 6
    -      Height = 127
    +      Height = 135
           Top = 6
    -      Width = 490
    +      Width = 600
           Anchors = [akTop, akLeft, akRight, akBottom]
           BorderSpacing.Around = 6
           ItemHeight = 0
    @@ -106,9 +106,9 @@
           AnchorSideBottom.Control = PathGroupBox
           AnchorSideBottom.Side = asrBottom
           Left = 6
    -      Height = 28
    -      Top = 161
    -      Width = 106
    +      Height = 25
    +      Top = 172
    +      Width = 103
           Anchors = [akLeft, akBottom]
           AutoSize = True
           BorderSpacing.Around = 6
    @@ -124,10 +124,10 @@
           AnchorSideLeft.Side = asrBottom
           AnchorSideBottom.Control = PathGroupBox
           AnchorSideBottom.Side = asrBottom
    -      Left = 118
    -      Height = 28
    -      Top = 161
    -      Width = 82
    +      Left = 115
    +      Height = 25
    +      Top = 172
    +      Width = 84
           Anchors = [akLeft, akBottom]
           AutoSize = True
           BorderSpacing.Around = 6
    @@ -143,10 +143,10 @@
           AnchorSideLeft.Side = asrBottom
           AnchorSideBottom.Control = PathGroupBox
           AnchorSideBottom.Side = asrBottom
    -      Left = 311
    -      Height = 28
    -      Top = 161
    -      Width = 174
    +      Left = 306
    +      Height = 25
    +      Top = 172
    +      Width = 159
           Anchors = [akLeft, akBottom]
           AutoSize = True
           BorderSpacing.Around = 6
    @@ -162,9 +162,9 @@
           AnchorSideRight.Side = asrBottom
           AnchorSideBottom.Control = ReplaceButton
           Left = 6
    -      Height = 25
    -      Top = 130
    -      Width = 490
    +      Height = 23
    +      Top = 143
    +      Width = 600
           OnAcceptDirectory = DirectoryEditAcceptDirectory
           ShowHidden = False
           ButtonWidth = 23
    @@ -174,19 +174,38 @@
           TabOrder = 3
           OnChange = DirectoryEditChange
         end
    +    object ImportPathsButton: TBitBtn
    +      AnchorSideLeft.Control = DeleteInvalidPathsButton
    +      AnchorSideLeft.Side = asrBottom
    +      AnchorSideBottom.Control = PathGroupBox
    +      AnchorSideBottom.Side = asrBottom
    +      Left = 471
    +      Height = 25
    +      Top = 172
    +      Width = 127
    +      Anchors = [akLeft, akBottom]
    +      AutoSize = True
    +      BorderSpacing.Around = 6
    +      Caption = 'ImportPathsButton'
    +      Enabled = False
    +      OnClick = ImportPathsButtonClick
    +      ParentShowHint = False
    +      ShowHint = True
    +      TabOrder = 8
    +    end
       end
       object TemplateGroupBox: TGroupBox
         AnchorSideTop.Side = asrBottom
         Left = 6
         Height = 164
    -    Top = 239
    -    Width = 541
    +    Top = 244
    +    Width = 647
         Align = alBottom
         Anchors = []
         BorderSpacing.Around = 6
         Caption = 'TemplateGroupBox'
    -    ClientHeight = 143
    -    ClientWidth = 533
    +    ClientHeight = 146
    +    ClientWidth = 643
         TabOrder = 1
         object TemplatesListBox: TListBox
           AnchorSideLeft.Control = TemplateGroupBox
    @@ -195,9 +214,9 @@
           AnchorSideRight.Side = asrBottom
           AnchorSideBottom.Control = AddTemplateButton
           Left = 6
    -      Height = 97
    +      Height = 103
           Top = 6
    -      Width = 521
    +      Width = 631
           Anchors = [akTop, akLeft, akRight, akBottom]
           BorderSpacing.Around = 6
           ItemHeight = 0
    @@ -211,9 +230,9 @@
           AnchorSideBottom.Control = TemplateGroupBox
           AnchorSideBottom.Side = asrBottom
           Left = 6
    -      Height = 28
    -      Top = 109
    -      Width = 140
    +      Height = 25
    +      Top = 115
    +      Width = 134
           Anchors = [akLeft, akBottom]
           AutoSize = True
           BorderSpacing.Around = 6
    @@ -226,9 +245,9 @@
       end
       object ButtonPanel1: TButtonPanel
         Left = 6
    -    Height = 31
    -    Top = 409
    -    Width = 541
    +    Height = 26
    +    Top = 414
    +    Width = 647
         OKButton.Name = 'OKButton'
         OKButton.DefaultCaption = True
         HelpButton.Name = 'HelpButton'
    @@ -245,8 +264,8 @@
         Cursor = crVSplit
         Left = 0
         Height = 5
    -    Top = 228
    -    Width = 553
    +    Top = 233
    +    Width = 659
         Align = alBottom
         ResizeAnchor = akBottom
       end
    @@ -255,4 +274,8 @@
         left = 504
         top = 32
       end
    +  object OpenDialogPathsImport: TOpenDialog
    +    left = 408
    +    top = 63
    +  end
     end
    Index: ide/patheditordlg.pas
    ===================================================================
    --- ide/patheditordlg.pas	(revision 44492)
    +++ ide/patheditordlg.pas	(working copy)
    @@ -32,6 +32,8 @@
       TPathEditorDialog = class(TForm)
         AddTemplateButton: TBitBtn;
         ButtonPanel1: TButtonPanel;
    +    ImportPathsButton: TBitBtn;
    +    OpenDialogPathsImport: TOpenDialog;
         ReplaceButton: TBitBtn;
         AddButton: TBitBtn;
         DeleteInvalidPathsButton: TBitBtn;
    @@ -54,6 +56,7 @@
         procedure FormCreate(Sender: TObject);
         procedure FormResize(Sender: TObject);
         procedure FormShow(Sender: TObject);
    +    procedure ImportPathsButtonClick(Sender: TObject);
         procedure MoveDownButtonClick(Sender: TObject);
         procedure MoveUpButtonClick(Sender: TObject);
         procedure PathListBoxDrawItem(Control: TWinControl; Index: Integer;
    @@ -259,6 +262,7 @@
       DeleteButton.Hint:=lisPathEditorDeleteHint;
       DeleteInvalidPathsButton.Caption:=lisPathEditDeleteInvalidPaths;
       DeleteInvalidPathsButton.Hint:=lisPathEditorDeleteInvalidHint;
    +  ImportPathsButton.Caption:=lisPathEditImportPaths;
     
       TemplateGroupBox.Caption:=lisPathEditPathTemplates;
       AddTemplateButton.Caption:=lisCodeTemplAdd;
    @@ -290,6 +294,46 @@
       UpdateButtons;
     end;
     
    +procedure TPathEditorDialog.ImportPathsButtonClick(Sender: TObject);
    +var paths:TStringList;
    +    y:integer;
    +    c:integer;
    +    RelPath:string;
    +begin
    +  if not OpenDialogPathsImport.Execute then exit;
    +
    +  paths:=TStringList.Create();
    +
    +  try
    +    paths.LoadFromFile(OpenDialogPathsImport.FileName);
    +
    +    with PathListBox do
    +    begin
    +      y:=ItemIndex+1;
    +
    +      if y=0 then
    +      begin
    +        y:=Count;
    +      end;
    +
    +      for c:=0 to paths.Count-1 do
    +      begin
    +        if Trim(paths[c])<>'' then
    +        begin
    +          RelPath:=BaseRelative(paths[c]);
    +          Items.InsertObject(y, RelPath, PathMayExist(paths[c]));
    +          ItemIndex:=y;
    +        end;
    +      end;
    +
    +      UpdateButtons;
    +    end;
    +
    +  finally
    +    FreeAndNil(paths);
    +  end;
    +end;
    +
     procedure TPathEditorDialog.MoveDownButtonClick(Sender: TObject);
     var
       y: integer;
    @@ -454,6 +498,7 @@
       i := PathListBox.ItemIndex;
       MoveUpButton.Enabled := i > 0;
       MoveDownButton.Enabled := (i > -1) and (i < PathListBox.Count-1);
    +  ImportPathsButton.Enabled:=true;
     end;
     
     procedure TPathEditorDialog.SetBaseDirectory(const AValue: string);
    
  • lazarus_patheditor.jpg (113,226 bytes)
    lazarus_patheditor.jpg (113,226 bytes)
  • 2014-03-29 paths import-export.patch (7,161 bytes)
    Index: ide/patheditordlg.lfm
    ===================================================================
    --- ide/patheditordlg.lfm	(revision 44550)
    +++ ide/patheditordlg.lfm	(working copy)
    
    +  object PathListBoxPopupMenu: TPopupMenu
    +    OnPopup = PathListBoxPopupMenuPopup
    +    left = 182
    +    top = 71
    +    object MultiselectPathListBoxMenuItem: TMenuItem
    +      AutoCheck = True
    +      Caption = 'Multiselect'
    +      OnClick = MultiselectPathListBoxMenuItemClick
    +    end
    +    object MenuItem2: TMenuItem
    +      Caption = '-'
    +    end
    +    object ExportPathsToClipboardMenuItem: TMenuItem
    +      Caption = 'Copy to Clipboard'
    +      OnClick = ExportPathsToClipboardMenuItemClick
    +    end
    +    object ExportPathsToFileMenuItem: TMenuItem
    +      Caption = 'Save to a Text-File'
    +      OnClick = ExportPathsToFileMenuItemClick
    +    end
    +    object MenuItem5: TMenuItem
    +      Caption = '-'
    +    end
    +    object ImportPathsFromClipboardMenuItem: TMenuItem
    +      Caption = 'Paste from Clipboard'
    +      OnClick = ImportPathsFromClipboardMenuItemClick
    +    end
    +    object ImportPathsFromFileMenuItem: TMenuItem
    +      Caption = 'Load from Text-File'
    +      OnClick = ImportPathsFromFileMenuItemClick
    +    end
    +  end
    +  object ImportPathsDialog: TOpenDialog
    +    left = 296
    +    top = 48
    +  end
    +  object ExportPathsDialog: TSaveDialog
    +    left = 299
    +    top = 107
    +  end
     end
    Index: ide/patheditordlg.pas
    ===================================================================
    --- ide/patheditordlg.pas	(revision 44550)
    +++ ide/patheditordlg.pas	(working copy)
    @@ -22,8 +22,8 @@
     
     uses
       Classes, SysUtils, Forms, Controls, Buttons, StdCtrls, Dialogs,
    -  FileUtil, ButtonPanel, ExtCtrls, EditBtn, MacroIntf, LCLType, Graphics,
    -  types, TransferMacros, LazarusIDEStrConsts, shortpathedit;
    +  FileUtil, ButtonPanel, ExtCtrls, EditBtn, MacroIntf, LCLType, Graphics, Menus,
    +  types, TransferMacros, LazarusIDEStrConsts, shortpathedit, Clipbrd;
     
     type
     
    @@ -32,10 +32,20 @@
       TPathEditorDialog = class(TForm)
         AddTemplateButton: TBitBtn;
         ButtonPanel1: TButtonPanel;
    +    MenuItem2: TMenuItem;
    +    ExportPathsToClipboardMenuItem: TMenuItem;
    +    ImportPathsFromClipboardMenuItem: TMenuItem;
    +    MenuItem5: TMenuItem;
    +    ExportPathsToFileMenuItem: TMenuItem;
    +    ImportPathsFromFileMenuItem: TMenuItem;
    +    MultiselectPathListBoxMenuItem: TMenuItem;
    +    ImportPathsDialog: TOpenDialog;
    +    PathListBoxPopupMenu: TPopupMenu;
         ReplaceButton: TBitBtn;
         AddButton: TBitBtn;
         DeleteInvalidPathsButton: TBitBtn;
         DirectoryEdit: TShortPathEdit;
    +    ExportPathsDialog: TSaveDialog;
         Splitter1: TSplitter;
         DeleteButton: TBitBtn;
         PathListBox: TListBox;
    @@ -51,15 +61,21 @@
         procedure DeleteButtonClick(Sender: TObject);
         procedure DirectoryEditAcceptDirectory(Sender: TObject; var Value: String);
         procedure DirectoryEditChange(Sender: TObject);
    +    procedure ExportPathsToClipboardMenuItemClick(Sender: TObject);
    +    procedure ExportPathsToFileMenuItemClick(Sender: TObject);
         procedure FormCreate(Sender: TObject);
         procedure FormResize(Sender: TObject);
         procedure FormShow(Sender: TObject);
    +    procedure ImportPathsFromClipboardMenuItemClick(Sender: TObject);
    +    procedure ImportPathsFromFileMenuItemClick(Sender: TObject);
    +    procedure MultiselectPathListBoxMenuItemClick(Sender: TObject);
         procedure MoveDownButtonClick(Sender: TObject);
         procedure MoveUpButtonClick(Sender: TObject);
         procedure PathListBoxDrawItem(Control: TWinControl; Index: Integer;
           ARect: TRect; State: TOwnerDrawState);
         procedure PathListBoxKeyDown(Sender: TObject; var Key: Word;
           Shift: TShiftState);
    +    procedure PathListBoxPopupMenuPopup(Sender: TObject);
         procedure PathListBoxSelectionChange(Sender: TObject; User: boolean);
         procedure ReplaceButtonClick(Sender: TObject);
         procedure TemplatesListBoxDblClick(Sender: TObject);
    @@ -219,6 +235,51 @@
       UpdateButtons;
     end;
     
    +procedure TPathEditorDialog.ExportPathsToClipboardMenuItemClick(Sender: TObject);
    +var paths:TStringList;
    +    c:integer;
    +begin
    +  paths:=TStringList.Create();
    +
    +  try
    +    for c:=0 to PathListBox.Count-1 do
    +    begin
    +      if PathListBox.selected[c] then
    +      begin
    +        paths.Add(PathAsAbsolute(PathListBox.Items[c]));
    +      end;
    +    end;
    +
    +    Clipboard.AsText:=paths.DelimitedText;
    +
    +  finally
    +    FreeAndNil(paths);
    +  end;
    +end;
    +
    +procedure TPathEditorDialog.ExportPathsToFileMenuItemClick(Sender: TObject);
    +var paths:TStringList;
    +    c:integer;
    +begin
    +  if not ExportPathsDialog.execute then exit;
    +
    +  paths:=TStringList.Create();
    +
    +  try
    +    for c:=0 to PathListBox.Count-1 do
    +    begin
    +      if PathListBox.selected[c] then
    +      begin
    +        paths.Add(PathAsAbsolute(PathListBox.Items[c]));
    +      end;
    +    end;
    +
    +    paths.SaveToFile(ExportPathsDialog.Filename);
    +  finally
    +    FreeAndNil(paths);
    +  end;
    +end;
    +
     procedure TPathEditorDialog.PathListBoxSelectionChange(Sender: TObject; User: boolean);
     Var
       FullPath : String;
    @@ -290,6 +351,92 @@
       UpdateButtons;
     end;
     
    +
    +procedure TPathEditorDialog.ImportPathsFromClipboardMenuItemClick(Sender: TObject);
    +var paths:TStringList;
    +    y:integer;
    +    c:integer;
    +    RelPath:string;
    +begin
    +  paths:=TStringList.Create();
    +
    +  try
    +    paths.DelimitedText:=Clipboard.AsText;
    +
    +    with PathListBox do
    +    begin
    +      y:=ItemIndex+1;
    +
    +      if y=0 then
    +      begin
    +        y:=Count;
    +      end;
    +
    +      for c:=0 to paths.Count-1 do
    +      begin
    +        if Trim(paths[c])<>'' then
    +        begin
    +          RelPath:=BaseRelative(paths[c]);
    +          Items.InsertObject(y, RelPath, PathMayExist(paths[c]));
    +          ItemIndex:=y;
    +        end;
    +      end;
    +
    +      UpdateButtons;
    +    end;
    +
    +  finally
    +      FreeAndNil(paths);
    +  end;
    +end;
    +
    +procedure TPathEditorDialog.ImportPathsFromFileMenuItemClick(Sender: TObject);
    +var paths:TStringList;
    +    y:integer;
    +    c:integer;
    +    RelPath:string;
    +begin
    +  if not ImportPathsDialog.Execute then exit;
    +
    +  paths:=TStringList.Create();
    +
    +  try
    +    paths.LoadFromFile(ImportPathsDialog.FileName);
    +
    +    with PathListBox do
    +    begin
    +      y:=ItemIndex+1;
    +
    +      if y=0 then
    +      begin
    +        y:=Count;
    +      end;
    +
    +      for c:=0 to paths.Count-1 do
    +      begin
    +
    +        if Trim(paths[c])<>'' then
    +        begin
    +          RelPath:=BaseRelative(paths[c]);
    +          Items.InsertObject(y, RelPath, PathMayExist(paths[c]));
    +          ItemIndex:=y;
    +        end;
    +      end;
    +
    +      UpdateButtons;
    +    end;
    +
    +  finally
    +    FreeAndNil(paths);
    +  end;
    +
    +end;
    +
    +procedure TPathEditorDialog.MultiselectPathListBoxMenuItemClick(Sender: TObject);
    +begin
    +  PathListBox.MultiSelect:=MultiSelectPathListBoxMenuItem.Checked;
    +end;
    +
     procedure TPathEditorDialog.MoveDownButtonClick(Sender: TObject);
     var
       y: integer;
    @@ -338,6 +485,11 @@
       end;
     end;
     
    +procedure TPathEditorDialog.PathListBoxPopupMenuPopup(Sender: TObject);
    +begin
    +  MultiSelectPathListBoxMenuItem.Checked:=PathListBox.MultiSelect;
    +end;
    +
     function TPathEditorDialog.GetPath: string;
     begin
       Result:=TextToPath(PathListBox.Items.Text);
    
  • 2014-04-02 paths import-export.patch (12,603 bytes)
    Index: ide/patheditordlg.lfm
    ===================================================================
    --- ide/patheditordlg.lfm	(revision 44550)
    +++ ide/patheditordlg.lfm	(working copy)
    @@ -1,7 +1,7 @@
     object PathEditorDialog: TPathEditorDialog
    -  Left = 420
    +  Left = 371
       Height = 446
    -  Top = 156
    +  Top = 278
       Width = 553
       AutoSize = True
       Caption = 'PathEditorDialog'
    @@ -13,10 +13,10 @@
       OnResize = FormResize
       OnShow = FormShow
       Position = poScreenCenter
    -  LCLVersion = '1.1'
    +  LCLVersion = '1.3'
       object PathGroupBox: TGroupBox
         Left = 6
    -    Height = 216
    +    Height = 221
         Top = 6
         Width = 541
         Align = alClient
    @@ -24,8 +24,8 @@
         AutoSize = True
         BorderSpacing.Around = 6
         Caption = 'PathGroupBox'
    -    ClientHeight = 195
    -    ClientWidth = 533
    +    ClientHeight = 203
    +    ClientWidth = 537
         Constraints.MinHeight = 194
         Constraints.MinWidth = 488
         TabOrder = 0
    @@ -35,9 +35,9 @@
           AnchorSideRight.Side = asrBottom
           AnchorSideBottom.Control = PathGroupBox
           AnchorSideBottom.Side = asrBottom
    -      Left = 502
    +      Left = 506
           Height = 25
    -      Top = 45
    +      Top = 47
           Width = 25
           Anchors = [akRight]
           BorderSpacing.Around = 6
    @@ -54,9 +54,9 @@
           AnchorSideTop.Side = asrBottom
           AnchorSideBottom.Control = PathGroupBox
           AnchorSideBottom.Side = asrBottom
    -      Left = 502
    +      Left = 506
           Height = 25
    -      Top = 84
    +      Top = 86
           Width = 25
           BorderSpacing.Around = 14
           GlyphShowMode = gsmAlways
    @@ -70,10 +70,10 @@
           AnchorSideLeft.Side = asrBottom
           AnchorSideBottom.Control = PathGroupBox
           AnchorSideBottom.Side = asrBottom
    -      Left = 206
    -      Height = 28
    -      Top = 161
    -      Width = 99
    +      Left = 205
    +      Height = 25
    +      Top = 172
    +      Width = 95
           Anchors = [akLeft, akBottom]
           AutoSize = True
           BorderSpacing.Around = 6
    @@ -89,15 +89,16 @@
           AnchorSideTop.Control = PathGroupBox
           AnchorSideRight.Control = MoveUpButton
           Left = 6
    -      Height = 127
    +      Height = 135
           Top = 6
    -      Width = 490
    +      Width = 494
           Anchors = [akTop, akLeft, akRight, akBottom]
           BorderSpacing.Around = 6
           ItemHeight = 0
           OnDrawItem = PathListBoxDrawItem
           OnKeyDown = PathListBoxKeyDown
           OnSelectionChange = PathListBoxSelectionChange
    +      PopupMenu = PathListBoxPopupMenu
           Style = lbOwnerDrawFixed
           TabOrder = 0
         end
    @@ -106,9 +107,9 @@
           AnchorSideBottom.Control = PathGroupBox
           AnchorSideBottom.Side = asrBottom
           Left = 6
    -      Height = 28
    -      Top = 161
    -      Width = 106
    +      Height = 25
    +      Top = 172
    +      Width = 103
           Anchors = [akLeft, akBottom]
           AutoSize = True
           BorderSpacing.Around = 6
    @@ -124,10 +125,10 @@
           AnchorSideLeft.Side = asrBottom
           AnchorSideBottom.Control = PathGroupBox
           AnchorSideBottom.Side = asrBottom
    -      Left = 118
    -      Height = 28
    -      Top = 161
    -      Width = 82
    +      Left = 115
    +      Height = 25
    +      Top = 172
    +      Width = 84
           Anchors = [akLeft, akBottom]
           AutoSize = True
           BorderSpacing.Around = 6
    @@ -143,10 +144,10 @@
           AnchorSideLeft.Side = asrBottom
           AnchorSideBottom.Control = PathGroupBox
           AnchorSideBottom.Side = asrBottom
    -      Left = 311
    -      Height = 28
    -      Top = 161
    -      Width = 174
    +      Left = 306
    +      Height = 25
    +      Top = 172
    +      Width = 159
           Anchors = [akLeft, akBottom]
           AutoSize = True
           BorderSpacing.Around = 6
    @@ -162,9 +163,9 @@
           AnchorSideRight.Side = asrBottom
           AnchorSideBottom.Control = ReplaceButton
           Left = 6
    -      Height = 25
    -      Top = 130
    -      Width = 490
    +      Height = 23
    +      Top = 143
    +      Width = 494
           OnAcceptDirectory = DirectoryEditAcceptDirectory
           ShowHidden = False
           ButtonWidth = 23
    @@ -179,14 +180,14 @@
         AnchorSideTop.Side = asrBottom
         Left = 6
         Height = 164
    -    Top = 239
    +    Top = 244
         Width = 541
         Align = alBottom
         Anchors = []
         BorderSpacing.Around = 6
         Caption = 'TemplateGroupBox'
    -    ClientHeight = 143
    -    ClientWidth = 533
    +    ClientHeight = 146
    +    ClientWidth = 537
         TabOrder = 1
         object TemplatesListBox: TListBox
           AnchorSideLeft.Control = TemplateGroupBox
    @@ -195,9 +196,9 @@
           AnchorSideRight.Side = asrBottom
           AnchorSideBottom.Control = AddTemplateButton
           Left = 6
    -      Height = 97
    +      Height = 103
           Top = 6
    -      Width = 521
    +      Width = 525
           Anchors = [akTop, akLeft, akRight, akBottom]
           BorderSpacing.Around = 6
           ItemHeight = 0
    @@ -211,9 +212,9 @@
           AnchorSideBottom.Control = TemplateGroupBox
           AnchorSideBottom.Side = asrBottom
           Left = 6
    -      Height = 28
    -      Top = 109
    -      Width = 140
    +      Height = 25
    +      Top = 115
    +      Width = 134
           Anchors = [akLeft, akBottom]
           AutoSize = True
           BorderSpacing.Around = 6
    @@ -226,8 +227,8 @@
       end
       object ButtonPanel1: TButtonPanel
         Left = 6
    -    Height = 31
    -    Top = 409
    +    Height = 26
    +    Top = 414
         Width = 541
         OKButton.Name = 'OKButton'
         OKButton.DefaultCaption = True
    @@ -245,14 +246,54 @@
         Cursor = crVSplit
         Left = 0
         Height = 5
    -    Top = 228
    +    Top = 233
         Width = 553
         Align = alBottom
         ResizeAnchor = akBottom
       end
       object BrowseDialog: TSelectDirectoryDialog
         Options = [ofFileMustExist, ofEnableSizing, ofViewDetail]
    -    left = 504
    -    top = 32
    +    left = 424
    +    top = 40
       end
    +  object PathListBoxPopupMenu: TPopupMenu
    +    OnPopup = PathListBoxPopupMenuPopup
    +    left = 182
    +    top = 71
    +    object MultiselectPathListBoxMenuItem: TMenuItem
    +      AutoCheck = True
    +      Caption = 'Multiselect'
    +      OnClick = MultiselectPathListBoxMenuItemClick
    +    end
    +    object MenuItem2: TMenuItem
    +      Caption = '-'
    +    end
    +    object ExportPathsToClipboardMenuItem: TMenuItem
    +      Caption = 'Copy to Clipboard'
    +      OnClick = ExportPathsToClipboardMenuItemClick
    +    end
    +    object ExportPathsToFileMenuItem: TMenuItem
    +      Caption = 'Save to a Text-File'
    +      OnClick = ExportPathsToFileMenuItemClick
    +    end
    +    object MenuItem5: TMenuItem
    +      Caption = '-'
    +    end
    +    object ImportPathsFromClipboardMenuItem: TMenuItem
    +      Caption = 'Paste from Clipboard'
    +      OnClick = ImportPathsFromClipboardMenuItemClick
    +    end
    +    object ImportPathsFromFileMenuItem: TMenuItem
    +      Caption = 'Load from Text-File'
    +      OnClick = ImportPathsFromFileMenuItemClick
    +    end
    +  end
    +  object ImportPathsDialog: TOpenDialog
    +    left = 296
    +    top = 48
    +  end
    +  object ExportPathsDialog: TSaveDialog
    +    left = 299
    +    top = 107
    +  end
     end
    Index: ide/patheditordlg.pas
    ===================================================================
    --- ide/patheditordlg.pas	(revision 44550)
    +++ ide/patheditordlg.pas	(working copy)
    @@ -22,8 +22,8 @@
     
     uses
       Classes, SysUtils, Forms, Controls, Buttons, StdCtrls, Dialogs,
    -  FileUtil, ButtonPanel, ExtCtrls, EditBtn, MacroIntf, LCLType, Graphics,
    -  types, TransferMacros, LazarusIDEStrConsts, shortpathedit;
    +  FileUtil, ButtonPanel, ExtCtrls, EditBtn, MacroIntf, LCLType, Graphics, Menus,
    +  types, TransferMacros, LazarusIDEStrConsts, shortpathedit, Clipbrd;
     
     type
     
    @@ -32,10 +32,20 @@
       TPathEditorDialog = class(TForm)
         AddTemplateButton: TBitBtn;
         ButtonPanel1: TButtonPanel;
    +    MenuItem2: TMenuItem;
    +    ExportPathsToClipboardMenuItem: TMenuItem;
    +    ImportPathsFromClipboardMenuItem: TMenuItem;
    +    MenuItem5: TMenuItem;
    +    ExportPathsToFileMenuItem: TMenuItem;
    +    ImportPathsFromFileMenuItem: TMenuItem;
    +    MultiselectPathListBoxMenuItem: TMenuItem;
    +    ImportPathsDialog: TOpenDialog;
    +    PathListBoxPopupMenu: TPopupMenu;
         ReplaceButton: TBitBtn;
         AddButton: TBitBtn;
         DeleteInvalidPathsButton: TBitBtn;
         DirectoryEdit: TShortPathEdit;
    +    ExportPathsDialog: TSaveDialog;
         Splitter1: TSplitter;
         DeleteButton: TBitBtn;
         PathListBox: TListBox;
    @@ -51,15 +61,21 @@
         procedure DeleteButtonClick(Sender: TObject);
         procedure DirectoryEditAcceptDirectory(Sender: TObject; var Value: String);
         procedure DirectoryEditChange(Sender: TObject);
    +    procedure ExportPathsToClipboardMenuItemClick(Sender: TObject);
    +    procedure ExportPathsToFileMenuItemClick(Sender: TObject);
         procedure FormCreate(Sender: TObject);
         procedure FormResize(Sender: TObject);
         procedure FormShow(Sender: TObject);
    +    procedure ImportPathsFromClipboardMenuItemClick(Sender: TObject);
    +    procedure ImportPathsFromFileMenuItemClick(Sender: TObject);
    +    procedure MultiselectPathListBoxMenuItemClick(Sender: TObject);
         procedure MoveDownButtonClick(Sender: TObject);
         procedure MoveUpButtonClick(Sender: TObject);
         procedure PathListBoxDrawItem(Control: TWinControl; Index: Integer;
           ARect: TRect; State: TOwnerDrawState);
         procedure PathListBoxKeyDown(Sender: TObject; var Key: Word;
           Shift: TShiftState);
    +    procedure PathListBoxPopupMenuPopup(Sender: TObject);
         procedure PathListBoxSelectionChange(Sender: TObject; User: boolean);
         procedure ReplaceButtonClick(Sender: TObject);
         procedure TemplatesListBoxDblClick(Sender: TObject);
    @@ -219,6 +235,51 @@
       UpdateButtons;
     end;
     
    +procedure TPathEditorDialog.ExportPathsToClipboardMenuItemClick(Sender: TObject);
    +var paths:TStringList;
    +    c:integer;
    +begin
    +  paths:=TStringList.Create();
    +
    +  try
    +    for c:=0 to PathListBox.Count-1 do
    +    begin
    +      if PathListBox.selected[c] then
    +      begin
    +        paths.Add(PathAsAbsolute(PathListBox.Items[c]));
    +      end;
    +    end;
    +
    +    Clipboard.AsText:=paths.DelimitedText;
    +
    +  finally
    +    FreeAndNil(paths);
    +  end;
    +end;
    +
    +procedure TPathEditorDialog.ExportPathsToFileMenuItemClick(Sender: TObject);
    +var paths:TStringList;
    +    c:integer;
    +begin
    +  if not ExportPathsDialog.execute then exit;
    +
    +  paths:=TStringList.Create();
    +
    +  try
    +    for c:=0 to PathListBox.Count-1 do
    +    begin
    +      if PathListBox.selected[c] then
    +      begin
    +        paths.Add(PathAsAbsolute(PathListBox.Items[c]));
    +      end;
    +    end;
    +
    +    paths.SaveToFile(ExportPathsDialog.Filename);
    +  finally
    +    FreeAndNil(paths);
    +  end;
    +end;
    +
     procedure TPathEditorDialog.PathListBoxSelectionChange(Sender: TObject; User: boolean);
     Var
       FullPath : String;
    @@ -290,6 +351,92 @@
       UpdateButtons;
     end;
     
    +
    +procedure TPathEditorDialog.ImportPathsFromClipboardMenuItemClick(Sender: TObject);
    +var paths:TStringList;
    +    y:integer;
    +    c:integer;
    +    RelPath:string;
    +begin
    +  paths:=TStringList.Create();
    +
    +  try
    +    paths.DelimitedText:=Clipboard.AsText;
    +
    +    with PathListBox do
    +    begin
    +      y:=ItemIndex+1;
    +
    +      if y=0 then
    +      begin
    +        y:=Count;
    +      end;
    +
    +      for c:=0 to paths.Count-1 do
    +      begin
    +        if Trim(paths[c])<>'' then
    +        begin
    +          RelPath:=BaseRelative(paths[c]);
    +          Items.InsertObject(y, RelPath, PathMayExist(paths[c]));
    +          ItemIndex:=y;
    +        end;
    +      end;
    +
    +      UpdateButtons;
    +    end;
    +
    +  finally
    +      FreeAndNil(paths);
    +  end;
    +end;
    +
    +procedure TPathEditorDialog.ImportPathsFromFileMenuItemClick(Sender: TObject);
    +var paths:TStringList;
    +    y:integer;
    +    c:integer;
    +    RelPath:string;
    +begin
    +  if not ImportPathsDialog.Execute then exit;
    +
    +  paths:=TStringList.Create();
    +
    +  try
    +    paths.LoadFromFile(ImportPathsDialog.FileName);
    +
    +    with PathListBox do
    +    begin
    +      y:=ItemIndex+1;
    +
    +      if y=0 then
    +      begin
    +        y:=Count;
    +      end;
    +
    +      for c:=0 to paths.Count-1 do
    +      begin
    +
    +        if Trim(paths[c])<>'' then
    +        begin
    +          RelPath:=BaseRelative(paths[c]);
    +          Items.InsertObject(y, RelPath, PathMayExist(paths[c]));
    +          ItemIndex:=y;
    +        end;
    +      end;
    +
    +      UpdateButtons;
    +    end;
    +
    +  finally
    +    FreeAndNil(paths);
    +  end;
    +
    +end;
    +
    +procedure TPathEditorDialog.MultiselectPathListBoxMenuItemClick(Sender: TObject);
    +begin
    +  PathListBox.MultiSelect:=MultiSelectPathListBoxMenuItem.Checked;
    +end;
    +
     procedure TPathEditorDialog.MoveDownButtonClick(Sender: TObject);
     var
       y: integer;
    @@ -338,6 +485,11 @@
       end;
     end;
     
    +procedure TPathEditorDialog.PathListBoxPopupMenuPopup(Sender: TObject);
    +begin
    +  MultiSelectPathListBoxMenuItem.Checked:=PathListBox.MultiSelect;
    +end;
    +
     function TPathEditorDialog.GetPath: string;
     begin
       Result:=TextToPath(PathListBox.Items.Text);
    
  • 2014-04-02 paths import-export for 44586.patch (12,603 bytes)
    Index: ide/patheditordlg.lfm
    ===================================================================
    --- ide/patheditordlg.lfm	(revision 44586)
    +++ ide/patheditordlg.lfm	(working copy)
    @@ -1,7 +1,7 @@
     object PathEditorDialog: TPathEditorDialog
    -  Left = 420
    +  Left = 371
       Height = 446
    -  Top = 156
    +  Top = 278
       Width = 553
       AutoSize = True
       Caption = 'PathEditorDialog'
    @@ -13,10 +13,10 @@
       OnResize = FormResize
       OnShow = FormShow
       Position = poScreenCenter
    -  LCLVersion = '1.1'
    +  LCLVersion = '1.3'
       object PathGroupBox: TGroupBox
         Left = 6
    -    Height = 216
    +    Height = 221
         Top = 6
         Width = 541
         Align = alClient
    @@ -24,8 +24,8 @@
         AutoSize = True
         BorderSpacing.Around = 6
         Caption = 'PathGroupBox'
    -    ClientHeight = 195
    -    ClientWidth = 533
    +    ClientHeight = 203
    +    ClientWidth = 537
         Constraints.MinHeight = 194
         Constraints.MinWidth = 488
         TabOrder = 0
    @@ -35,9 +35,9 @@
           AnchorSideRight.Side = asrBottom
           AnchorSideBottom.Control = PathGroupBox
           AnchorSideBottom.Side = asrBottom
    -      Left = 502
    +      Left = 506
           Height = 25
    -      Top = 45
    +      Top = 47
           Width = 25
           Anchors = [akRight]
           BorderSpacing.Around = 6
    @@ -54,9 +54,9 @@
           AnchorSideTop.Side = asrBottom
           AnchorSideBottom.Control = PathGroupBox
           AnchorSideBottom.Side = asrBottom
    -      Left = 502
    +      Left = 506
           Height = 25
    -      Top = 84
    +      Top = 86
           Width = 25
           BorderSpacing.Around = 14
           GlyphShowMode = gsmAlways
    @@ -70,10 +70,10 @@
           AnchorSideLeft.Side = asrBottom
           AnchorSideBottom.Control = PathGroupBox
           AnchorSideBottom.Side = asrBottom
    -      Left = 206
    -      Height = 28
    -      Top = 161
    -      Width = 99
    +      Left = 205
    +      Height = 25
    +      Top = 172
    +      Width = 95
           Anchors = [akLeft, akBottom]
           AutoSize = True
           BorderSpacing.Around = 6
    @@ -89,15 +89,16 @@
           AnchorSideTop.Control = PathGroupBox
           AnchorSideRight.Control = MoveUpButton
           Left = 6
    -      Height = 127
    +      Height = 135
           Top = 6
    -      Width = 490
    +      Width = 494
           Anchors = [akTop, akLeft, akRight, akBottom]
           BorderSpacing.Around = 6
           ItemHeight = 0
           OnDrawItem = PathListBoxDrawItem
           OnKeyDown = PathListBoxKeyDown
           OnSelectionChange = PathListBoxSelectionChange
    +      PopupMenu = PathListBoxPopupMenu
           Style = lbOwnerDrawFixed
           TabOrder = 0
         end
    @@ -106,9 +107,9 @@
           AnchorSideBottom.Control = PathGroupBox
           AnchorSideBottom.Side = asrBottom
           Left = 6
    -      Height = 28
    -      Top = 161
    -      Width = 106
    +      Height = 25
    +      Top = 172
    +      Width = 103
           Anchors = [akLeft, akBottom]
           AutoSize = True
           BorderSpacing.Around = 6
    @@ -124,10 +125,10 @@
           AnchorSideLeft.Side = asrBottom
           AnchorSideBottom.Control = PathGroupBox
           AnchorSideBottom.Side = asrBottom
    -      Left = 118
    -      Height = 28
    -      Top = 161
    -      Width = 82
    +      Left = 115
    +      Height = 25
    +      Top = 172
    +      Width = 84
           Anchors = [akLeft, akBottom]
           AutoSize = True
           BorderSpacing.Around = 6
    @@ -143,10 +144,10 @@
           AnchorSideLeft.Side = asrBottom
           AnchorSideBottom.Control = PathGroupBox
           AnchorSideBottom.Side = asrBottom
    -      Left = 311
    -      Height = 28
    -      Top = 161
    -      Width = 174
    +      Left = 306
    +      Height = 25
    +      Top = 172
    +      Width = 159
           Anchors = [akLeft, akBottom]
           AutoSize = True
           BorderSpacing.Around = 6
    @@ -162,9 +163,9 @@
           AnchorSideRight.Side = asrBottom
           AnchorSideBottom.Control = ReplaceButton
           Left = 6
    -      Height = 25
    -      Top = 130
    -      Width = 490
    +      Height = 23
    +      Top = 143
    +      Width = 494
           OnAcceptDirectory = DirectoryEditAcceptDirectory
           ShowHidden = False
           ButtonWidth = 23
    @@ -179,14 +180,14 @@
         AnchorSideTop.Side = asrBottom
         Left = 6
         Height = 164
    -    Top = 239
    +    Top = 244
         Width = 541
         Align = alBottom
         Anchors = []
         BorderSpacing.Around = 6
         Caption = 'TemplateGroupBox'
    -    ClientHeight = 143
    -    ClientWidth = 533
    +    ClientHeight = 146
    +    ClientWidth = 537
         TabOrder = 1
         object TemplatesListBox: TListBox
           AnchorSideLeft.Control = TemplateGroupBox
    @@ -195,9 +196,9 @@
           AnchorSideRight.Side = asrBottom
           AnchorSideBottom.Control = AddTemplateButton
           Left = 6
    -      Height = 97
    +      Height = 103
           Top = 6
    -      Width = 521
    +      Width = 525
           Anchors = [akTop, akLeft, akRight, akBottom]
           BorderSpacing.Around = 6
           ItemHeight = 0
    @@ -211,9 +212,9 @@
           AnchorSideBottom.Control = TemplateGroupBox
           AnchorSideBottom.Side = asrBottom
           Left = 6
    -      Height = 28
    -      Top = 109
    -      Width = 140
    +      Height = 25
    +      Top = 115
    +      Width = 134
           Anchors = [akLeft, akBottom]
           AutoSize = True
           BorderSpacing.Around = 6
    @@ -226,8 +227,8 @@
       end
       object ButtonPanel1: TButtonPanel
         Left = 6
    -    Height = 31
    -    Top = 409
    +    Height = 26
    +    Top = 414
         Width = 541
         OKButton.Name = 'OKButton'
         OKButton.DefaultCaption = True
    @@ -245,14 +246,54 @@
         Cursor = crVSplit
         Left = 0
         Height = 5
    -    Top = 228
    +    Top = 233
         Width = 553
         Align = alBottom
         ResizeAnchor = akBottom
       end
       object BrowseDialog: TSelectDirectoryDialog
         Options = [ofFileMustExist, ofEnableSizing, ofViewDetail]
    -    left = 504
    -    top = 32
    +    left = 424
    +    top = 40
       end
    +  object PathListBoxPopupMenu: TPopupMenu
    +    OnPopup = PathListBoxPopupMenuPopup
    +    left = 182
    +    top = 71
    +    object MultiselectPathListBoxMenuItem: TMenuItem
    +      AutoCheck = True
    +      Caption = 'Multiselect'
    +      OnClick = MultiselectPathListBoxMenuItemClick
    +    end
    +    object MenuItem2: TMenuItem
    +      Caption = '-'
    +    end
    +    object ExportPathsToClipboardMenuItem: TMenuItem
    +      Caption = 'Copy to Clipboard'
    +      OnClick = ExportPathsToClipboardMenuItemClick
    +    end
    +    object ExportPathsToFileMenuItem: TMenuItem
    +      Caption = 'Save to a Text-File'
    +      OnClick = ExportPathsToFileMenuItemClick
    +    end
    +    object MenuItem5: TMenuItem
    +      Caption = '-'
    +    end
    +    object ImportPathsFromClipboardMenuItem: TMenuItem
    +      Caption = 'Paste from Clipboard'
    +      OnClick = ImportPathsFromClipboardMenuItemClick
    +    end
    +    object ImportPathsFromFileMenuItem: TMenuItem
    +      Caption = 'Load from Text-File'
    +      OnClick = ImportPathsFromFileMenuItemClick
    +    end
    +  end
    +  object ImportPathsDialog: TOpenDialog
    +    left = 296
    +    top = 48
    +  end
    +  object ExportPathsDialog: TSaveDialog
    +    left = 299
    +    top = 107
    +  end
     end
    Index: ide/patheditordlg.pas
    ===================================================================
    --- ide/patheditordlg.pas	(revision 44586)
    +++ ide/patheditordlg.pas	(working copy)
    @@ -22,8 +22,8 @@
     
     uses
       Classes, SysUtils, Forms, Controls, Buttons, StdCtrls, Dialogs,
    -  FileUtil, ButtonPanel, ExtCtrls, EditBtn, MacroIntf, LCLType, Graphics,
    -  types, TransferMacros, LazarusIDEStrConsts, shortpathedit;
    +  FileUtil, ButtonPanel, ExtCtrls, EditBtn, MacroIntf, LCLType, Graphics, Menus,
    +  types, TransferMacros, LazarusIDEStrConsts, shortpathedit, Clipbrd;
     
     type
     
    @@ -32,10 +32,20 @@
       TPathEditorDialog = class(TForm)
         AddTemplateButton: TBitBtn;
         ButtonPanel1: TButtonPanel;
    +    MenuItem2: TMenuItem;
    +    ExportPathsToClipboardMenuItem: TMenuItem;
    +    ImportPathsFromClipboardMenuItem: TMenuItem;
    +    MenuItem5: TMenuItem;
    +    ExportPathsToFileMenuItem: TMenuItem;
    +    ImportPathsFromFileMenuItem: TMenuItem;
    +    MultiselectPathListBoxMenuItem: TMenuItem;
    +    ImportPathsDialog: TOpenDialog;
    +    PathListBoxPopupMenu: TPopupMenu;
         ReplaceButton: TBitBtn;
         AddButton: TBitBtn;
         DeleteInvalidPathsButton: TBitBtn;
         DirectoryEdit: TShortPathEdit;
    +    ExportPathsDialog: TSaveDialog;
         Splitter1: TSplitter;
         DeleteButton: TBitBtn;
         PathListBox: TListBox;
    @@ -51,15 +61,21 @@
         procedure DeleteButtonClick(Sender: TObject);
         procedure DirectoryEditAcceptDirectory(Sender: TObject; var Value: String);
         procedure DirectoryEditChange(Sender: TObject);
    +    procedure ExportPathsToClipboardMenuItemClick(Sender: TObject);
    +    procedure ExportPathsToFileMenuItemClick(Sender: TObject);
         procedure FormCreate(Sender: TObject);
         procedure FormResize(Sender: TObject);
         procedure FormShow(Sender: TObject);
    +    procedure ImportPathsFromClipboardMenuItemClick(Sender: TObject);
    +    procedure ImportPathsFromFileMenuItemClick(Sender: TObject);
    +    procedure MultiselectPathListBoxMenuItemClick(Sender: TObject);
         procedure MoveDownButtonClick(Sender: TObject);
         procedure MoveUpButtonClick(Sender: TObject);
         procedure PathListBoxDrawItem(Control: TWinControl; Index: Integer;
           ARect: TRect; State: TOwnerDrawState);
         procedure PathListBoxKeyDown(Sender: TObject; var Key: Word;
           Shift: TShiftState);
    +    procedure PathListBoxPopupMenuPopup(Sender: TObject);
         procedure PathListBoxSelectionChange(Sender: TObject; User: boolean);
         procedure ReplaceButtonClick(Sender: TObject);
         procedure TemplatesListBoxDblClick(Sender: TObject);
    @@ -219,6 +235,51 @@
       UpdateButtons;
     end;
     
    +procedure TPathEditorDialog.ExportPathsToClipboardMenuItemClick(Sender: TObject);
    +var paths:TStringList;
    +    c:integer;
    +begin
    +  paths:=TStringList.Create();
    +
    +  try
    +    for c:=0 to PathListBox.Count-1 do
    +    begin
    +      if PathListBox.selected[c] then
    +      begin
    +        paths.Add(PathAsAbsolute(PathListBox.Items[c]));
    +      end;
    +    end;
    +
    +    Clipboard.AsText:=paths.DelimitedText;
    +
    +  finally
    +    FreeAndNil(paths);
    +  end;
    +end;
    +
    +procedure TPathEditorDialog.ExportPathsToFileMenuItemClick(Sender: TObject);
    +var paths:TStringList;
    +    c:integer;
    +begin
    +  if not ExportPathsDialog.execute then exit;
    +
    +  paths:=TStringList.Create();
    +
    +  try
    +    for c:=0 to PathListBox.Count-1 do
    +    begin
    +      if PathListBox.selected[c] then
    +      begin
    +        paths.Add(PathAsAbsolute(PathListBox.Items[c]));
    +      end;
    +    end;
    +
    +    paths.SaveToFile(ExportPathsDialog.Filename);
    +  finally
    +    FreeAndNil(paths);
    +  end;
    +end;
    +
     procedure TPathEditorDialog.PathListBoxSelectionChange(Sender: TObject; User: boolean);
     Var
       FullPath : String;
    @@ -290,6 +351,92 @@
       UpdateButtons;
     end;
     
    +
    +procedure TPathEditorDialog.ImportPathsFromClipboardMenuItemClick(Sender: TObject);
    +var paths:TStringList;
    +    y:integer;
    +    c:integer;
    +    RelPath:string;
    +begin
    +  paths:=TStringList.Create();
    +
    +  try
    +    paths.DelimitedText:=Clipboard.AsText;
    +
    +    with PathListBox do
    +    begin
    +      y:=ItemIndex+1;
    +
    +      if y=0 then
    +      begin
    +        y:=Count;
    +      end;
    +
    +      for c:=0 to paths.Count-1 do
    +      begin
    +        if Trim(paths[c])<>'' then
    +        begin
    +          RelPath:=BaseRelative(paths[c]);
    +          Items.InsertObject(y, RelPath, PathMayExist(paths[c]));
    +          ItemIndex:=y;
    +        end;
    +      end;
    +
    +      UpdateButtons;
    +    end;
    +
    +  finally
    +      FreeAndNil(paths);
    +  end;
    +end;
    +
    +procedure TPathEditorDialog.ImportPathsFromFileMenuItemClick(Sender: TObject);
    +var paths:TStringList;
    +    y:integer;
    +    c:integer;
    +    RelPath:string;
    +begin
    +  if not ImportPathsDialog.Execute then exit;
    +
    +  paths:=TStringList.Create();
    +
    +  try
    +    paths.LoadFromFile(ImportPathsDialog.FileName);
    +
    +    with PathListBox do
    +    begin
    +      y:=ItemIndex+1;
    +
    +      if y=0 then
    +      begin
    +        y:=Count;
    +      end;
    +
    +      for c:=0 to paths.Count-1 do
    +      begin
    +
    +        if Trim(paths[c])<>'' then
    +        begin
    +          RelPath:=BaseRelative(paths[c]);
    +          Items.InsertObject(y, RelPath, PathMayExist(paths[c]));
    +          ItemIndex:=y;
    +        end;
    +      end;
    +
    +      UpdateButtons;
    +    end;
    +
    +  finally
    +    FreeAndNil(paths);
    +  end;
    +
    +end;
    +
    +procedure TPathEditorDialog.MultiselectPathListBoxMenuItemClick(Sender: TObject);
    +begin
    +  PathListBox.MultiSelect:=MultiSelectPathListBoxMenuItem.Checked;
    +end;
    +
     procedure TPathEditorDialog.MoveDownButtonClick(Sender: TObject);
     var
       y: integer;
    @@ -338,6 +485,11 @@
       end;
     end;
     
    +procedure TPathEditorDialog.PathListBoxPopupMenuPopup(Sender: TObject);
    +begin
    +  MultiSelectPathListBoxMenuItem.Checked:=PathListBox.MultiSelect;
    +end;
    +
     function TPathEditorDialog.GetPath: string;
     begin
       Result:=TextToPath(PathListBox.Items.Text);
    

Activities

dimprofi

2014-03-23 15:57

reporter  

2014-03-23 importpaths.patch (9,121 bytes)
Index: ide/lazarusidestrconsts.pas
===================================================================
--- ide/lazarusidestrconsts.pas	(revision 44492)
+++ ide/lazarusidestrconsts.pas	(working copy)
@@ -3412,6 +3412,7 @@
   lisPathEditBrowse = 'Browse';
   lisPathEditPathTemplates = 'Path templates';
   lisPathEditDeleteInvalidPaths = 'Delete Invalid Paths';
+  lisPathEditImportPaths = 'Import Paths';
   
   // new dialog
   lisNewDlgNoItemSelected = 'No item selected';
Index: ide/patheditordlg.lfm
===================================================================
--- ide/patheditordlg.lfm	(revision 44492)
+++ ide/patheditordlg.lfm	(working copy)
@@ -2,30 +2,30 @@
   Left = 420
   Height = 446
   Top = 156
-  Width = 553
+  Width = 659
   AutoSize = True
   Caption = 'PathEditorDialog'
   ClientHeight = 446
-  ClientWidth = 553
+  ClientWidth = 659
   Constraints.MinHeight = 400
   Constraints.MinWidth = 500
   OnCreate = FormCreate
   OnResize = FormResize
   OnShow = FormShow
   Position = poScreenCenter
-  LCLVersion = '1.1'
+  LCLVersion = '1.3'
   object PathGroupBox: TGroupBox
     Left = 6
-    Height = 216
+    Height = 221
     Top = 6
-    Width = 541
+    Width = 647
     Align = alClient
     Anchors = [akTop, akLeft, akRight]
     AutoSize = True
     BorderSpacing.Around = 6
     Caption = 'PathGroupBox'
-    ClientHeight = 195
-    ClientWidth = 533
+    ClientHeight = 203
+    ClientWidth = 643
     Constraints.MinHeight = 194
     Constraints.MinWidth = 488
     TabOrder = 0
@@ -35,9 +35,9 @@
       AnchorSideRight.Side = asrBottom
       AnchorSideBottom.Control = PathGroupBox
       AnchorSideBottom.Side = asrBottom
-      Left = 502
+      Left = 612
       Height = 25
-      Top = 45
+      Top = 47
       Width = 25
       Anchors = [akRight]
       BorderSpacing.Around = 6
@@ -54,9 +54,9 @@
       AnchorSideTop.Side = asrBottom
       AnchorSideBottom.Control = PathGroupBox
       AnchorSideBottom.Side = asrBottom
-      Left = 502
+      Left = 612
       Height = 25
-      Top = 84
+      Top = 86
       Width = 25
       BorderSpacing.Around = 14
       GlyphShowMode = gsmAlways
@@ -70,10 +70,10 @@
       AnchorSideLeft.Side = asrBottom
       AnchorSideBottom.Control = PathGroupBox
       AnchorSideBottom.Side = asrBottom
-      Left = 206
-      Height = 28
-      Top = 161
-      Width = 99
+      Left = 205
+      Height = 25
+      Top = 172
+      Width = 95
       Anchors = [akLeft, akBottom]
       AutoSize = True
       BorderSpacing.Around = 6
@@ -89,9 +89,9 @@
       AnchorSideTop.Control = PathGroupBox
       AnchorSideRight.Control = MoveUpButton
       Left = 6
-      Height = 127
+      Height = 135
       Top = 6
-      Width = 490
+      Width = 600
       Anchors = [akTop, akLeft, akRight, akBottom]
       BorderSpacing.Around = 6
       ItemHeight = 0
@@ -106,9 +106,9 @@
       AnchorSideBottom.Control = PathGroupBox
       AnchorSideBottom.Side = asrBottom
       Left = 6
-      Height = 28
-      Top = 161
-      Width = 106
+      Height = 25
+      Top = 172
+      Width = 103
       Anchors = [akLeft, akBottom]
       AutoSize = True
       BorderSpacing.Around = 6
@@ -124,10 +124,10 @@
       AnchorSideLeft.Side = asrBottom
       AnchorSideBottom.Control = PathGroupBox
       AnchorSideBottom.Side = asrBottom
-      Left = 118
-      Height = 28
-      Top = 161
-      Width = 82
+      Left = 115
+      Height = 25
+      Top = 172
+      Width = 84
       Anchors = [akLeft, akBottom]
       AutoSize = True
       BorderSpacing.Around = 6
@@ -143,10 +143,10 @@
       AnchorSideLeft.Side = asrBottom
       AnchorSideBottom.Control = PathGroupBox
       AnchorSideBottom.Side = asrBottom
-      Left = 311
-      Height = 28
-      Top = 161
-      Width = 174
+      Left = 306
+      Height = 25
+      Top = 172
+      Width = 159
       Anchors = [akLeft, akBottom]
       AutoSize = True
       BorderSpacing.Around = 6
@@ -162,9 +162,9 @@
       AnchorSideRight.Side = asrBottom
       AnchorSideBottom.Control = ReplaceButton
       Left = 6
-      Height = 25
-      Top = 130
-      Width = 490
+      Height = 23
+      Top = 143
+      Width = 600
       OnAcceptDirectory = DirectoryEditAcceptDirectory
       ShowHidden = False
       ButtonWidth = 23
@@ -174,19 +174,38 @@
       TabOrder = 3
       OnChange = DirectoryEditChange
     end
+    object ImportPathsButton: TBitBtn
+      AnchorSideLeft.Control = DeleteInvalidPathsButton
+      AnchorSideLeft.Side = asrBottom
+      AnchorSideBottom.Control = PathGroupBox
+      AnchorSideBottom.Side = asrBottom
+      Left = 471
+      Height = 25
+      Top = 172
+      Width = 127
+      Anchors = [akLeft, akBottom]
+      AutoSize = True
+      BorderSpacing.Around = 6
+      Caption = 'ImportPathsButton'
+      Enabled = False
+      OnClick = ImportPathsButtonClick
+      ParentShowHint = False
+      ShowHint = True
+      TabOrder = 8
+    end
   end
   object TemplateGroupBox: TGroupBox
     AnchorSideTop.Side = asrBottom
     Left = 6
     Height = 164
-    Top = 239
-    Width = 541
+    Top = 244
+    Width = 647
     Align = alBottom
     Anchors = []
     BorderSpacing.Around = 6
     Caption = 'TemplateGroupBox'
-    ClientHeight = 143
-    ClientWidth = 533
+    ClientHeight = 146
+    ClientWidth = 643
     TabOrder = 1
     object TemplatesListBox: TListBox
       AnchorSideLeft.Control = TemplateGroupBox
@@ -195,9 +214,9 @@
       AnchorSideRight.Side = asrBottom
       AnchorSideBottom.Control = AddTemplateButton
       Left = 6
-      Height = 97
+      Height = 103
       Top = 6
-      Width = 521
+      Width = 631
       Anchors = [akTop, akLeft, akRight, akBottom]
       BorderSpacing.Around = 6
       ItemHeight = 0
@@ -211,9 +230,9 @@
       AnchorSideBottom.Control = TemplateGroupBox
       AnchorSideBottom.Side = asrBottom
       Left = 6
-      Height = 28
-      Top = 109
-      Width = 140
+      Height = 25
+      Top = 115
+      Width = 134
       Anchors = [akLeft, akBottom]
       AutoSize = True
       BorderSpacing.Around = 6
@@ -226,9 +245,9 @@
   end
   object ButtonPanel1: TButtonPanel
     Left = 6
-    Height = 31
-    Top = 409
-    Width = 541
+    Height = 26
+    Top = 414
+    Width = 647
     OKButton.Name = 'OKButton'
     OKButton.DefaultCaption = True
     HelpButton.Name = 'HelpButton'
@@ -245,8 +264,8 @@
     Cursor = crVSplit
     Left = 0
     Height = 5
-    Top = 228
-    Width = 553
+    Top = 233
+    Width = 659
     Align = alBottom
     ResizeAnchor = akBottom
   end
@@ -255,4 +274,8 @@
     left = 504
     top = 32
   end
+  object OpenDialogPathsImport: TOpenDialog
+    left = 408
+    top = 63
+  end
 end
Index: ide/patheditordlg.pas
===================================================================
--- ide/patheditordlg.pas	(revision 44492)
+++ ide/patheditordlg.pas	(working copy)
@@ -32,6 +32,8 @@
   TPathEditorDialog = class(TForm)
     AddTemplateButton: TBitBtn;
     ButtonPanel1: TButtonPanel;
+    ImportPathsButton: TBitBtn;
+    OpenDialogPathsImport: TOpenDialog;
     ReplaceButton: TBitBtn;
     AddButton: TBitBtn;
     DeleteInvalidPathsButton: TBitBtn;
@@ -54,6 +56,7 @@
     procedure FormCreate(Sender: TObject);
     procedure FormResize(Sender: TObject);
     procedure FormShow(Sender: TObject);
+    procedure ImportPathsButtonClick(Sender: TObject);
     procedure MoveDownButtonClick(Sender: TObject);
     procedure MoveUpButtonClick(Sender: TObject);
     procedure PathListBoxDrawItem(Control: TWinControl; Index: Integer;
@@ -259,6 +262,7 @@
   DeleteButton.Hint:=lisPathEditorDeleteHint;
   DeleteInvalidPathsButton.Caption:=lisPathEditDeleteInvalidPaths;
   DeleteInvalidPathsButton.Hint:=lisPathEditorDeleteInvalidHint;
+  ImportPathsButton.Caption:=lisPathEditImportPaths;
 
   TemplateGroupBox.Caption:=lisPathEditPathTemplates;
   AddTemplateButton.Caption:=lisCodeTemplAdd;
@@ -290,6 +294,46 @@
   UpdateButtons;
 end;
 
+procedure TPathEditorDialog.ImportPathsButtonClick(Sender: TObject);
+var paths:TStringList;
+    y:integer;
+    c:integer;
+    RelPath:string;
+begin
+  if not OpenDialogPathsImport.Execute then exit;
+
+  paths:=TStringList.Create();
+
+  try
+    paths.LoadFromFile(OpenDialogPathsImport.FileName);
+
+    with PathListBox do
+    begin
+      y:=ItemIndex+1;
+
+      if y=0 then
+      begin
+        y:=Count;
+      end;
+
+      for c:=0 to paths.Count-1 do
+      begin
+        if Trim(paths[c])<>'' then
+        begin
+          RelPath:=BaseRelative(paths[c]);
+          Items.InsertObject(y, RelPath, PathMayExist(paths[c]));
+          ItemIndex:=y;
+        end;
+      end;
+
+      UpdateButtons;
+    end;
+
+  finally
+    FreeAndNil(paths);
+  end;
+end;
+
 procedure TPathEditorDialog.MoveDownButtonClick(Sender: TObject);
 var
   y: integer;
@@ -454,6 +498,7 @@
   i := PathListBox.ItemIndex;
   MoveUpButton.Enabled := i > 0;
   MoveDownButton.Enabled := (i > -1) and (i < PathListBox.Count-1);
+  ImportPathsButton.Enabled:=true;
 end;
 
 procedure TPathEditorDialog.SetBaseDirectory(const AValue: string);

dimprofi

2014-03-23 16:01

reporter  

lazarus_patheditor.jpg (113,226 bytes)
lazarus_patheditor.jpg (113,226 bytes)

Zeljan Rikalo

2014-03-23 16:29

developer   ~0073911

I would add Copy/Paste paths also (or better copy selected paths (allow multiselection in paths), and paste it to another paths or file (we have it before changing paths from synedit/memo to ttreeview or whatever control it is now).

Juha Manninen

2014-03-23 16:39

developer   ~0073912

Actually I have implemented the current path editor because I liked Delphi's path editor a lot, but I forgot about the copy/paste issue.

@dimprofi: would Copy/Paste instead of Import Paths solve your use case?

dimprofi

2014-03-23 16:42

reporter   ~0073913

Yeah, I agree!
I made this feature, because of the same paths for many and new projects.
If this patch will be accepted, gonna make a TreeView with a groups of paths - like a global pool for lazarus.
It's my first patch ever - need a motivation :)

Of course "Export Paths" (selected) to a text-file would be nice too.

dimprofi

2014-03-23 16:45

reporter   ~0073914

@Juha Manninen
Copy/Paste ist something different.
Now i made a pool of Include-Paths like a files, so on new Project I just nedd to import the needed group of paths :)

It's more about groupping a paths, than just transfering from project to project.

Martin Friebe

2014-03-23 16:49

manager   ~0073915

IMHO, I think, that instead of "load from textfile", the following 3 would be the better approach:

- Copy [selected/all] path (context menu)
- Paste path(s) from clipboard (context menu)
- drag'n'drop path(s) from text source (can be textfile in editor outside the IDE)

That way, you can copy the path, and paste to a textfile, and save. And you can drag'n'drop the path from your file to the IDE.

With the knowledge you already gathered, you should be able to change the patch, if you want?

dimprofi

2014-03-23 17:07

reporter   ~0073916

Last edited: 2014-03-23 17:10

View 3 revisions

@Martin Friebe
Drag'n'Drop is not faster, because I need to open explorer and then take a file and drag to a Lazarus :)

Copy/Paste is not the same - i would like to create ONCE groups of paths PERMANENTLY and import them to a projects.

For example "dcpcrypt.txt" including:
L:\libs\dcpcrypt
L:\libs\dcpcrypt\Hashes
L:\libs\dcpcrypt\Ciphers

Yes, i know that i can install *.lpk - but i'm transfering to much from Windows to Linux and compiling with Lazarus or just with FPC the same code.

Martin Friebe

2014-03-23 18:08

manager   ~0073917

Last edited: 2014-03-23 18:22

View 2 revisions

Btw, there already is a button "..." on the bottom row of the project options.

It opens a window, to load any set of compiler options from a file.

SO you save your defaults to an lpi (save a project with the defaults), then you should be able to import.

--
Not saying that your patch may not be an alternative. Just adding other possibilities.

dimprofi

2014-03-23 19:51

reporter   ~0073919

@Martin Friebe

"Btw, there already is a button "..." on the bottom row of the project options."

Hey! Never "saw" this button before! :)
May be, it should get better caption than "..." :)))

Nice function for some cases.

Juha Manninen

2014-03-24 17:31

developer   ~0073940

Last edited: 2014-03-24 17:40

View 2 revisions

Yes, the "..." caption should be "import/export".
About your patch: one button for importing paths may solve your use case but it is half-baked. There should be a complementing export function and then copy/paste.
That makes too many buttons so it must be in a pop-up menu.
Do you think you could make such a patch? Otherwise i will look at it later.
Drag'n'drop can be added later anyway. It does not need GUI controls.

dimprofi

2014-03-24 19:12

reporter   ~0073943

Last edited: 2014-03-24 19:17

View 2 revisions

@Juha Manninen

I planned first to use TPopupMenu, but I was afraid to add a new group of controls. I was not sure about how conservative the other developers are :)

So I should make TPopupMenu with a following Items/Functionality:
- Copy Paths
- Paste Paths
- Save Paths to a File
- Insert Paths from File

What about multiselect/operation on selected paths?
If yes, then I'm not sure to combine it with a right-click to pop up menu.

May be this four flat buttons at the right of the list and PathsList as CheckListBox on Demand?

Juha Manninen

2014-03-24 21:01

developer   ~0073944

Last edited: 2014-03-24 21:21

View 2 revisions

Multiselection affects the current operation, too. It must be well tested.
One choice is to keep the single selection but Copy and Export would work on all paths always.

Your plan for the buttons sounds OK although I did not understand how the CheckListBox would be used.
If you come up with a working solution I believe it can be applied.

dimprofi

2014-03-24 23:34

reporter   ~0073948

@Juha Manninen
OK,gonna prepare alpha patch first, so you can check the user-friendliness out :)

Juha Manninen

2014-03-27 23:04

developer   ~0074031

Last edited: 2014-03-29 10:36

View 4 revisions

@dimprofi: You have made a pull request for Graeme's Git mirror. Are those commits meant to be applied or are they practice?
In any case the pull request does not help because Graeme has no commit rights for Lazarus.
I would prefer a patch here. It can be git-formatted, no problem.
I have also promised to use a Git fork directly:
  http://wiki.freepascal.org/Creating_A_Patch#Using_a_forked_Git_repository_directly
Then I would pull your forked repo. It is up to you.

You could also subscribe to Lazarus mailing list:
  http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

dimprofi

2014-03-29 14:03

reporter   ~0074055

Last edited: 2014-03-29 14:13

View 2 revisions

Commit to GitHub was just a parallel request. Was not sure about positive reaction here :)

I'm not sure, which way is better. So let us start and continue here.

dimprofi

2014-03-29 14:37

reporter  

dimprofi

2014-03-29 14:39

reporter   ~0074056

@Juha Manninen

Check the new Screenshot out. Is it OK this way? TPopupMenu with five functionalities.

Juha Manninen

2014-03-29 15:49

developer   ~0074057

Last edited: 2014-03-29 15:50

View 2 revisions

> Commit to GitHub was just a parallel request.
Parallel to what? I did not see any new patch here.

Your popup menu looks good.
The problem is the existing functionality, namely what happens to the edited path value? Which row in the list is read / written?
The Multiselect menu option is interesting. It may solve the problem.
Send a patch and we can try.

dimprofi

2014-03-29 16:03

reporter   ~0074058

@Juha Manninen
>> Commit to GitHub was just a parallel request.
>Parallel to what? I did not see any new patch here.
That was not new - just the same like here "2014-03-23 importpaths.patch"

The problem is the existing functionality, namely what happens to the edited path value? Which row in the list is read / written?
---
Selected rows will be exported/imported directly to a Listbox and could be inserted after selected row on demand.
Or do you mean, it should import/export just to TEdit below? o_O

dimprofi

2014-03-29 16:42

reporter  

2014-03-29 paths import-export.patch (7,161 bytes)
Index: ide/patheditordlg.lfm
===================================================================
--- ide/patheditordlg.lfm	(revision 44550)
+++ ide/patheditordlg.lfm	(working copy)

+  object PathListBoxPopupMenu: TPopupMenu
+    OnPopup = PathListBoxPopupMenuPopup
+    left = 182
+    top = 71
+    object MultiselectPathListBoxMenuItem: TMenuItem
+      AutoCheck = True
+      Caption = 'Multiselect'
+      OnClick = MultiselectPathListBoxMenuItemClick
+    end
+    object MenuItem2: TMenuItem
+      Caption = '-'
+    end
+    object ExportPathsToClipboardMenuItem: TMenuItem
+      Caption = 'Copy to Clipboard'
+      OnClick = ExportPathsToClipboardMenuItemClick
+    end
+    object ExportPathsToFileMenuItem: TMenuItem
+      Caption = 'Save to a Text-File'
+      OnClick = ExportPathsToFileMenuItemClick
+    end
+    object MenuItem5: TMenuItem
+      Caption = '-'
+    end
+    object ImportPathsFromClipboardMenuItem: TMenuItem
+      Caption = 'Paste from Clipboard'
+      OnClick = ImportPathsFromClipboardMenuItemClick
+    end
+    object ImportPathsFromFileMenuItem: TMenuItem
+      Caption = 'Load from Text-File'
+      OnClick = ImportPathsFromFileMenuItemClick
+    end
+  end
+  object ImportPathsDialog: TOpenDialog
+    left = 296
+    top = 48
+  end
+  object ExportPathsDialog: TSaveDialog
+    left = 299
+    top = 107
+  end
 end
Index: ide/patheditordlg.pas
===================================================================
--- ide/patheditordlg.pas	(revision 44550)
+++ ide/patheditordlg.pas	(working copy)
@@ -22,8 +22,8 @@
 
 uses
   Classes, SysUtils, Forms, Controls, Buttons, StdCtrls, Dialogs,
-  FileUtil, ButtonPanel, ExtCtrls, EditBtn, MacroIntf, LCLType, Graphics,
-  types, TransferMacros, LazarusIDEStrConsts, shortpathedit;
+  FileUtil, ButtonPanel, ExtCtrls, EditBtn, MacroIntf, LCLType, Graphics, Menus,
+  types, TransferMacros, LazarusIDEStrConsts, shortpathedit, Clipbrd;
 
 type
 
@@ -32,10 +32,20 @@
   TPathEditorDialog = class(TForm)
     AddTemplateButton: TBitBtn;
     ButtonPanel1: TButtonPanel;
+    MenuItem2: TMenuItem;
+    ExportPathsToClipboardMenuItem: TMenuItem;
+    ImportPathsFromClipboardMenuItem: TMenuItem;
+    MenuItem5: TMenuItem;
+    ExportPathsToFileMenuItem: TMenuItem;
+    ImportPathsFromFileMenuItem: TMenuItem;
+    MultiselectPathListBoxMenuItem: TMenuItem;
+    ImportPathsDialog: TOpenDialog;
+    PathListBoxPopupMenu: TPopupMenu;
     ReplaceButton: TBitBtn;
     AddButton: TBitBtn;
     DeleteInvalidPathsButton: TBitBtn;
     DirectoryEdit: TShortPathEdit;
+    ExportPathsDialog: TSaveDialog;
     Splitter1: TSplitter;
     DeleteButton: TBitBtn;
     PathListBox: TListBox;
@@ -51,15 +61,21 @@
     procedure DeleteButtonClick(Sender: TObject);
     procedure DirectoryEditAcceptDirectory(Sender: TObject; var Value: String);
     procedure DirectoryEditChange(Sender: TObject);
+    procedure ExportPathsToClipboardMenuItemClick(Sender: TObject);
+    procedure ExportPathsToFileMenuItemClick(Sender: TObject);
     procedure FormCreate(Sender: TObject);
     procedure FormResize(Sender: TObject);
     procedure FormShow(Sender: TObject);
+    procedure ImportPathsFromClipboardMenuItemClick(Sender: TObject);
+    procedure ImportPathsFromFileMenuItemClick(Sender: TObject);
+    procedure MultiselectPathListBoxMenuItemClick(Sender: TObject);
     procedure MoveDownButtonClick(Sender: TObject);
     procedure MoveUpButtonClick(Sender: TObject);
     procedure PathListBoxDrawItem(Control: TWinControl; Index: Integer;
       ARect: TRect; State: TOwnerDrawState);
     procedure PathListBoxKeyDown(Sender: TObject; var Key: Word;
       Shift: TShiftState);
+    procedure PathListBoxPopupMenuPopup(Sender: TObject);
     procedure PathListBoxSelectionChange(Sender: TObject; User: boolean);
     procedure ReplaceButtonClick(Sender: TObject);
     procedure TemplatesListBoxDblClick(Sender: TObject);
@@ -219,6 +235,51 @@
   UpdateButtons;
 end;
 
+procedure TPathEditorDialog.ExportPathsToClipboardMenuItemClick(Sender: TObject);
+var paths:TStringList;
+    c:integer;
+begin
+  paths:=TStringList.Create();
+
+  try
+    for c:=0 to PathListBox.Count-1 do
+    begin
+      if PathListBox.selected[c] then
+      begin
+        paths.Add(PathAsAbsolute(PathListBox.Items[c]));
+      end;
+    end;
+
+    Clipboard.AsText:=paths.DelimitedText;
+
+  finally
+    FreeAndNil(paths);
+  end;
+end;
+
+procedure TPathEditorDialog.ExportPathsToFileMenuItemClick(Sender: TObject);
+var paths:TStringList;
+    c:integer;
+begin
+  if not ExportPathsDialog.execute then exit;
+
+  paths:=TStringList.Create();
+
+  try
+    for c:=0 to PathListBox.Count-1 do
+    begin
+      if PathListBox.selected[c] then
+      begin
+        paths.Add(PathAsAbsolute(PathListBox.Items[c]));
+      end;
+    end;
+
+    paths.SaveToFile(ExportPathsDialog.Filename);
+  finally
+    FreeAndNil(paths);
+  end;
+end;
+
 procedure TPathEditorDialog.PathListBoxSelectionChange(Sender: TObject; User: boolean);
 Var
   FullPath : String;
@@ -290,6 +351,92 @@
   UpdateButtons;
 end;
 
+
+procedure TPathEditorDialog.ImportPathsFromClipboardMenuItemClick(Sender: TObject);
+var paths:TStringList;
+    y:integer;
+    c:integer;
+    RelPath:string;
+begin
+  paths:=TStringList.Create();
+
+  try
+    paths.DelimitedText:=Clipboard.AsText;
+
+    with PathListBox do
+    begin
+      y:=ItemIndex+1;
+
+      if y=0 then
+      begin
+        y:=Count;
+      end;
+
+      for c:=0 to paths.Count-1 do
+      begin
+        if Trim(paths[c])<>'' then
+        begin
+          RelPath:=BaseRelative(paths[c]);
+          Items.InsertObject(y, RelPath, PathMayExist(paths[c]));
+          ItemIndex:=y;
+        end;
+      end;
+
+      UpdateButtons;
+    end;
+
+  finally
+      FreeAndNil(paths);
+  end;
+end;
+
+procedure TPathEditorDialog.ImportPathsFromFileMenuItemClick(Sender: TObject);
+var paths:TStringList;
+    y:integer;
+    c:integer;
+    RelPath:string;
+begin
+  if not ImportPathsDialog.Execute then exit;
+
+  paths:=TStringList.Create();
+
+  try
+    paths.LoadFromFile(ImportPathsDialog.FileName);
+
+    with PathListBox do
+    begin
+      y:=ItemIndex+1;
+
+      if y=0 then
+      begin
+        y:=Count;
+      end;
+
+      for c:=0 to paths.Count-1 do
+      begin
+
+        if Trim(paths[c])<>'' then
+        begin
+          RelPath:=BaseRelative(paths[c]);
+          Items.InsertObject(y, RelPath, PathMayExist(paths[c]));
+          ItemIndex:=y;
+        end;
+      end;
+
+      UpdateButtons;
+    end;
+
+  finally
+    FreeAndNil(paths);
+  end;
+
+end;
+
+procedure TPathEditorDialog.MultiselectPathListBoxMenuItemClick(Sender: TObject);
+begin
+  PathListBox.MultiSelect:=MultiSelectPathListBoxMenuItem.Checked;
+end;
+
 procedure TPathEditorDialog.MoveDownButtonClick(Sender: TObject);
 var
   y: integer;
@@ -338,6 +485,11 @@
   end;
 end;
 
+procedure TPathEditorDialog.PathListBoxPopupMenuPopup(Sender: TObject);
+begin
+  MultiSelectPathListBoxMenuItem.Checked:=PathListBox.MultiSelect;
+end;
+
 function TPathEditorDialog.GetPath: string;
 begin
   Result:=TextToPath(PathListBox.Items.Text);

dimprofi

2014-03-29 16:44

reporter   ~0074059

@Juha Manninen

2014-03-29 paths import-export.patch
Please check this patch out. Full functionality with a PopUp.

ToDo: localized captions for MenuItems.

Zeljan Rikalo

2014-03-29 16:46

developer   ~0074060

Do not forget that when you change paths (delete or add) laz should ask in which build modes do we want to commit change (except current one), like it asks when we add new unit into the project.

dimprofi

2014-03-29 22:44

reporter   ~0074070

Last edited: 2014-03-29 22:44

View 2 revisions

@Zeljan Rikalo

I saw nothing about this in the current implementation.
It's just an input dialog. That gives a paths back.
No modifications in "Project Setup" Dialog, that handles profiles, needed.

Juha Manninen

2014-03-30 21:06

developer   ~0074083

Patch command refuses to apply the .lfm file changes in "2014-03-29 paths import-export.patch". Indeed it looks a little odd. How did you make it?

Martin Friebe

2014-03-30 21:36

manager   ~0074084

The file has mixed line endings, some are windows, some are unix. converting them may help.

Juha Manninen

2014-03-31 22:45

developer   ~0074107

Last edited: 2014-03-31 23:36

View 2 revisions

It is not only about mixed line endings. There are clearly some lines missing.
@dimprofi, could you please make another patch. This command should work with svn:
 svn diff ide/patheditordlg.pas ide/patheditordlg.lfm > pathsimport-export.patch
and this with Git:
 git format-patch master
assuming you are in the feature branch with a commit.

dimprofi

2014-04-02 11:14

reporter  

2014-04-02 paths import-export.patch (12,603 bytes)
Index: ide/patheditordlg.lfm
===================================================================
--- ide/patheditordlg.lfm	(revision 44550)
+++ ide/patheditordlg.lfm	(working copy)
@@ -1,7 +1,7 @@
 object PathEditorDialog: TPathEditorDialog
-  Left = 420
+  Left = 371
   Height = 446
-  Top = 156
+  Top = 278
   Width = 553
   AutoSize = True
   Caption = 'PathEditorDialog'
@@ -13,10 +13,10 @@
   OnResize = FormResize
   OnShow = FormShow
   Position = poScreenCenter
-  LCLVersion = '1.1'
+  LCLVersion = '1.3'
   object PathGroupBox: TGroupBox
     Left = 6
-    Height = 216
+    Height = 221
     Top = 6
     Width = 541
     Align = alClient
@@ -24,8 +24,8 @@
     AutoSize = True
     BorderSpacing.Around = 6
     Caption = 'PathGroupBox'
-    ClientHeight = 195
-    ClientWidth = 533
+    ClientHeight = 203
+    ClientWidth = 537
     Constraints.MinHeight = 194
     Constraints.MinWidth = 488
     TabOrder = 0
@@ -35,9 +35,9 @@
       AnchorSideRight.Side = asrBottom
       AnchorSideBottom.Control = PathGroupBox
       AnchorSideBottom.Side = asrBottom
-      Left = 502
+      Left = 506
       Height = 25
-      Top = 45
+      Top = 47
       Width = 25
       Anchors = [akRight]
       BorderSpacing.Around = 6
@@ -54,9 +54,9 @@
       AnchorSideTop.Side = asrBottom
       AnchorSideBottom.Control = PathGroupBox
       AnchorSideBottom.Side = asrBottom
-      Left = 502
+      Left = 506
       Height = 25
-      Top = 84
+      Top = 86
       Width = 25
       BorderSpacing.Around = 14
       GlyphShowMode = gsmAlways
@@ -70,10 +70,10 @@
       AnchorSideLeft.Side = asrBottom
       AnchorSideBottom.Control = PathGroupBox
       AnchorSideBottom.Side = asrBottom
-      Left = 206
-      Height = 28
-      Top = 161
-      Width = 99
+      Left = 205
+      Height = 25
+      Top = 172
+      Width = 95
       Anchors = [akLeft, akBottom]
       AutoSize = True
       BorderSpacing.Around = 6
@@ -89,15 +89,16 @@
       AnchorSideTop.Control = PathGroupBox
       AnchorSideRight.Control = MoveUpButton
       Left = 6
-      Height = 127
+      Height = 135
       Top = 6
-      Width = 490
+      Width = 494
       Anchors = [akTop, akLeft, akRight, akBottom]
       BorderSpacing.Around = 6
       ItemHeight = 0
       OnDrawItem = PathListBoxDrawItem
       OnKeyDown = PathListBoxKeyDown
       OnSelectionChange = PathListBoxSelectionChange
+      PopupMenu = PathListBoxPopupMenu
       Style = lbOwnerDrawFixed
       TabOrder = 0
     end
@@ -106,9 +107,9 @@
       AnchorSideBottom.Control = PathGroupBox
       AnchorSideBottom.Side = asrBottom
       Left = 6
-      Height = 28
-      Top = 161
-      Width = 106
+      Height = 25
+      Top = 172
+      Width = 103
       Anchors = [akLeft, akBottom]
       AutoSize = True
       BorderSpacing.Around = 6
@@ -124,10 +125,10 @@
       AnchorSideLeft.Side = asrBottom
       AnchorSideBottom.Control = PathGroupBox
       AnchorSideBottom.Side = asrBottom
-      Left = 118
-      Height = 28
-      Top = 161
-      Width = 82
+      Left = 115
+      Height = 25
+      Top = 172
+      Width = 84
       Anchors = [akLeft, akBottom]
       AutoSize = True
       BorderSpacing.Around = 6
@@ -143,10 +144,10 @@
       AnchorSideLeft.Side = asrBottom
       AnchorSideBottom.Control = PathGroupBox
       AnchorSideBottom.Side = asrBottom
-      Left = 311
-      Height = 28
-      Top = 161
-      Width = 174
+      Left = 306
+      Height = 25
+      Top = 172
+      Width = 159
       Anchors = [akLeft, akBottom]
       AutoSize = True
       BorderSpacing.Around = 6
@@ -162,9 +163,9 @@
       AnchorSideRight.Side = asrBottom
       AnchorSideBottom.Control = ReplaceButton
       Left = 6
-      Height = 25
-      Top = 130
-      Width = 490
+      Height = 23
+      Top = 143
+      Width = 494
       OnAcceptDirectory = DirectoryEditAcceptDirectory
       ShowHidden = False
       ButtonWidth = 23
@@ -179,14 +180,14 @@
     AnchorSideTop.Side = asrBottom
     Left = 6
     Height = 164
-    Top = 239
+    Top = 244
     Width = 541
     Align = alBottom
     Anchors = []
     BorderSpacing.Around = 6
     Caption = 'TemplateGroupBox'
-    ClientHeight = 143
-    ClientWidth = 533
+    ClientHeight = 146
+    ClientWidth = 537
     TabOrder = 1
     object TemplatesListBox: TListBox
       AnchorSideLeft.Control = TemplateGroupBox
@@ -195,9 +196,9 @@
       AnchorSideRight.Side = asrBottom
       AnchorSideBottom.Control = AddTemplateButton
       Left = 6
-      Height = 97
+      Height = 103
       Top = 6
-      Width = 521
+      Width = 525
       Anchors = [akTop, akLeft, akRight, akBottom]
       BorderSpacing.Around = 6
       ItemHeight = 0
@@ -211,9 +212,9 @@
       AnchorSideBottom.Control = TemplateGroupBox
       AnchorSideBottom.Side = asrBottom
       Left = 6
-      Height = 28
-      Top = 109
-      Width = 140
+      Height = 25
+      Top = 115
+      Width = 134
       Anchors = [akLeft, akBottom]
       AutoSize = True
       BorderSpacing.Around = 6
@@ -226,8 +227,8 @@
   end
   object ButtonPanel1: TButtonPanel
     Left = 6
-    Height = 31
-    Top = 409
+    Height = 26
+    Top = 414
     Width = 541
     OKButton.Name = 'OKButton'
     OKButton.DefaultCaption = True
@@ -245,14 +246,54 @@
     Cursor = crVSplit
     Left = 0
     Height = 5
-    Top = 228
+    Top = 233
     Width = 553
     Align = alBottom
     ResizeAnchor = akBottom
   end
   object BrowseDialog: TSelectDirectoryDialog
     Options = [ofFileMustExist, ofEnableSizing, ofViewDetail]
-    left = 504
-    top = 32
+    left = 424
+    top = 40
   end
+  object PathListBoxPopupMenu: TPopupMenu
+    OnPopup = PathListBoxPopupMenuPopup
+    left = 182
+    top = 71
+    object MultiselectPathListBoxMenuItem: TMenuItem
+      AutoCheck = True
+      Caption = 'Multiselect'
+      OnClick = MultiselectPathListBoxMenuItemClick
+    end
+    object MenuItem2: TMenuItem
+      Caption = '-'
+    end
+    object ExportPathsToClipboardMenuItem: TMenuItem
+      Caption = 'Copy to Clipboard'
+      OnClick = ExportPathsToClipboardMenuItemClick
+    end
+    object ExportPathsToFileMenuItem: TMenuItem
+      Caption = 'Save to a Text-File'
+      OnClick = ExportPathsToFileMenuItemClick
+    end
+    object MenuItem5: TMenuItem
+      Caption = '-'
+    end
+    object ImportPathsFromClipboardMenuItem: TMenuItem
+      Caption = 'Paste from Clipboard'
+      OnClick = ImportPathsFromClipboardMenuItemClick
+    end
+    object ImportPathsFromFileMenuItem: TMenuItem
+      Caption = 'Load from Text-File'
+      OnClick = ImportPathsFromFileMenuItemClick
+    end
+  end
+  object ImportPathsDialog: TOpenDialog
+    left = 296
+    top = 48
+  end
+  object ExportPathsDialog: TSaveDialog
+    left = 299
+    top = 107
+  end
 end
Index: ide/patheditordlg.pas
===================================================================
--- ide/patheditordlg.pas	(revision 44550)
+++ ide/patheditordlg.pas	(working copy)
@@ -22,8 +22,8 @@
 
 uses
   Classes, SysUtils, Forms, Controls, Buttons, StdCtrls, Dialogs,
-  FileUtil, ButtonPanel, ExtCtrls, EditBtn, MacroIntf, LCLType, Graphics,
-  types, TransferMacros, LazarusIDEStrConsts, shortpathedit;
+  FileUtil, ButtonPanel, ExtCtrls, EditBtn, MacroIntf, LCLType, Graphics, Menus,
+  types, TransferMacros, LazarusIDEStrConsts, shortpathedit, Clipbrd;
 
 type
 
@@ -32,10 +32,20 @@
   TPathEditorDialog = class(TForm)
     AddTemplateButton: TBitBtn;
     ButtonPanel1: TButtonPanel;
+    MenuItem2: TMenuItem;
+    ExportPathsToClipboardMenuItem: TMenuItem;
+    ImportPathsFromClipboardMenuItem: TMenuItem;
+    MenuItem5: TMenuItem;
+    ExportPathsToFileMenuItem: TMenuItem;
+    ImportPathsFromFileMenuItem: TMenuItem;
+    MultiselectPathListBoxMenuItem: TMenuItem;
+    ImportPathsDialog: TOpenDialog;
+    PathListBoxPopupMenu: TPopupMenu;
     ReplaceButton: TBitBtn;
     AddButton: TBitBtn;
     DeleteInvalidPathsButton: TBitBtn;
     DirectoryEdit: TShortPathEdit;
+    ExportPathsDialog: TSaveDialog;
     Splitter1: TSplitter;
     DeleteButton: TBitBtn;
     PathListBox: TListBox;
@@ -51,15 +61,21 @@
     procedure DeleteButtonClick(Sender: TObject);
     procedure DirectoryEditAcceptDirectory(Sender: TObject; var Value: String);
     procedure DirectoryEditChange(Sender: TObject);
+    procedure ExportPathsToClipboardMenuItemClick(Sender: TObject);
+    procedure ExportPathsToFileMenuItemClick(Sender: TObject);
     procedure FormCreate(Sender: TObject);
     procedure FormResize(Sender: TObject);
     procedure FormShow(Sender: TObject);
+    procedure ImportPathsFromClipboardMenuItemClick(Sender: TObject);
+    procedure ImportPathsFromFileMenuItemClick(Sender: TObject);
+    procedure MultiselectPathListBoxMenuItemClick(Sender: TObject);
     procedure MoveDownButtonClick(Sender: TObject);
     procedure MoveUpButtonClick(Sender: TObject);
     procedure PathListBoxDrawItem(Control: TWinControl; Index: Integer;
       ARect: TRect; State: TOwnerDrawState);
     procedure PathListBoxKeyDown(Sender: TObject; var Key: Word;
       Shift: TShiftState);
+    procedure PathListBoxPopupMenuPopup(Sender: TObject);
     procedure PathListBoxSelectionChange(Sender: TObject; User: boolean);
     procedure ReplaceButtonClick(Sender: TObject);
     procedure TemplatesListBoxDblClick(Sender: TObject);
@@ -219,6 +235,51 @@
   UpdateButtons;
 end;
 
+procedure TPathEditorDialog.ExportPathsToClipboardMenuItemClick(Sender: TObject);
+var paths:TStringList;
+    c:integer;
+begin
+  paths:=TStringList.Create();
+
+  try
+    for c:=0 to PathListBox.Count-1 do
+    begin
+      if PathListBox.selected[c] then
+      begin
+        paths.Add(PathAsAbsolute(PathListBox.Items[c]));
+      end;
+    end;
+
+    Clipboard.AsText:=paths.DelimitedText;
+
+  finally
+    FreeAndNil(paths);
+  end;
+end;
+
+procedure TPathEditorDialog.ExportPathsToFileMenuItemClick(Sender: TObject);
+var paths:TStringList;
+    c:integer;
+begin
+  if not ExportPathsDialog.execute then exit;
+
+  paths:=TStringList.Create();
+
+  try
+    for c:=0 to PathListBox.Count-1 do
+    begin
+      if PathListBox.selected[c] then
+      begin
+        paths.Add(PathAsAbsolute(PathListBox.Items[c]));
+      end;
+    end;
+
+    paths.SaveToFile(ExportPathsDialog.Filename);
+  finally
+    FreeAndNil(paths);
+  end;
+end;
+
 procedure TPathEditorDialog.PathListBoxSelectionChange(Sender: TObject; User: boolean);
 Var
   FullPath : String;
@@ -290,6 +351,92 @@
   UpdateButtons;
 end;
 
+
+procedure TPathEditorDialog.ImportPathsFromClipboardMenuItemClick(Sender: TObject);
+var paths:TStringList;
+    y:integer;
+    c:integer;
+    RelPath:string;
+begin
+  paths:=TStringList.Create();
+
+  try
+    paths.DelimitedText:=Clipboard.AsText;
+
+    with PathListBox do
+    begin
+      y:=ItemIndex+1;
+
+      if y=0 then
+      begin
+        y:=Count;
+      end;
+
+      for c:=0 to paths.Count-1 do
+      begin
+        if Trim(paths[c])<>'' then
+        begin
+          RelPath:=BaseRelative(paths[c]);
+          Items.InsertObject(y, RelPath, PathMayExist(paths[c]));
+          ItemIndex:=y;
+        end;
+      end;
+
+      UpdateButtons;
+    end;
+
+  finally
+      FreeAndNil(paths);
+  end;
+end;
+
+procedure TPathEditorDialog.ImportPathsFromFileMenuItemClick(Sender: TObject);
+var paths:TStringList;
+    y:integer;
+    c:integer;
+    RelPath:string;
+begin
+  if not ImportPathsDialog.Execute then exit;
+
+  paths:=TStringList.Create();
+
+  try
+    paths.LoadFromFile(ImportPathsDialog.FileName);
+
+    with PathListBox do
+    begin
+      y:=ItemIndex+1;
+
+      if y=0 then
+      begin
+        y:=Count;
+      end;
+
+      for c:=0 to paths.Count-1 do
+      begin
+
+        if Trim(paths[c])<>'' then
+        begin
+          RelPath:=BaseRelative(paths[c]);
+          Items.InsertObject(y, RelPath, PathMayExist(paths[c]));
+          ItemIndex:=y;
+        end;
+      end;
+
+      UpdateButtons;
+    end;
+
+  finally
+    FreeAndNil(paths);
+  end;
+
+end;
+
+procedure TPathEditorDialog.MultiselectPathListBoxMenuItemClick(Sender: TObject);
+begin
+  PathListBox.MultiSelect:=MultiSelectPathListBoxMenuItem.Checked;
+end;
+
 procedure TPathEditorDialog.MoveDownButtonClick(Sender: TObject);
 var
   y: integer;
@@ -338,6 +485,11 @@
   end;
 end;
 
+procedure TPathEditorDialog.PathListBoxPopupMenuPopup(Sender: TObject);
+begin
+  MultiSelectPathListBoxMenuItem.Checked:=PathListBox.MultiSelect;
+end;
+
 function TPathEditorDialog.GetPath: string;
 begin
   Result:=TextToPath(PathListBox.Items.Text);

dimprofi

2014-04-02 11:15

reporter   ~0074114

OK! Just try this now: 2014-04-02 paths import-export.patch

P.S.: Sorry I'm new in publishing patches :)

dimprofi

2014-04-02 11:19

reporter  

2014-04-02 paths import-export for 44586.patch (12,603 bytes)
Index: ide/patheditordlg.lfm
===================================================================
--- ide/patheditordlg.lfm	(revision 44586)
+++ ide/patheditordlg.lfm	(working copy)
@@ -1,7 +1,7 @@
 object PathEditorDialog: TPathEditorDialog
-  Left = 420
+  Left = 371
   Height = 446
-  Top = 156
+  Top = 278
   Width = 553
   AutoSize = True
   Caption = 'PathEditorDialog'
@@ -13,10 +13,10 @@
   OnResize = FormResize
   OnShow = FormShow
   Position = poScreenCenter
-  LCLVersion = '1.1'
+  LCLVersion = '1.3'
   object PathGroupBox: TGroupBox
     Left = 6
-    Height = 216
+    Height = 221
     Top = 6
     Width = 541
     Align = alClient
@@ -24,8 +24,8 @@
     AutoSize = True
     BorderSpacing.Around = 6
     Caption = 'PathGroupBox'
-    ClientHeight = 195
-    ClientWidth = 533
+    ClientHeight = 203
+    ClientWidth = 537
     Constraints.MinHeight = 194
     Constraints.MinWidth = 488
     TabOrder = 0
@@ -35,9 +35,9 @@
       AnchorSideRight.Side = asrBottom
       AnchorSideBottom.Control = PathGroupBox
       AnchorSideBottom.Side = asrBottom
-      Left = 502
+      Left = 506
       Height = 25
-      Top = 45
+      Top = 47
       Width = 25
       Anchors = [akRight]
       BorderSpacing.Around = 6
@@ -54,9 +54,9 @@
       AnchorSideTop.Side = asrBottom
       AnchorSideBottom.Control = PathGroupBox
       AnchorSideBottom.Side = asrBottom
-      Left = 502
+      Left = 506
       Height = 25
-      Top = 84
+      Top = 86
       Width = 25
       BorderSpacing.Around = 14
       GlyphShowMode = gsmAlways
@@ -70,10 +70,10 @@
       AnchorSideLeft.Side = asrBottom
       AnchorSideBottom.Control = PathGroupBox
       AnchorSideBottom.Side = asrBottom
-      Left = 206
-      Height = 28
-      Top = 161
-      Width = 99
+      Left = 205
+      Height = 25
+      Top = 172
+      Width = 95
       Anchors = [akLeft, akBottom]
       AutoSize = True
       BorderSpacing.Around = 6
@@ -89,15 +89,16 @@
       AnchorSideTop.Control = PathGroupBox
       AnchorSideRight.Control = MoveUpButton
       Left = 6
-      Height = 127
+      Height = 135
       Top = 6
-      Width = 490
+      Width = 494
       Anchors = [akTop, akLeft, akRight, akBottom]
       BorderSpacing.Around = 6
       ItemHeight = 0
       OnDrawItem = PathListBoxDrawItem
       OnKeyDown = PathListBoxKeyDown
       OnSelectionChange = PathListBoxSelectionChange
+      PopupMenu = PathListBoxPopupMenu
       Style = lbOwnerDrawFixed
       TabOrder = 0
     end
@@ -106,9 +107,9 @@
       AnchorSideBottom.Control = PathGroupBox
       AnchorSideBottom.Side = asrBottom
       Left = 6
-      Height = 28
-      Top = 161
-      Width = 106
+      Height = 25
+      Top = 172
+      Width = 103
       Anchors = [akLeft, akBottom]
       AutoSize = True
       BorderSpacing.Around = 6
@@ -124,10 +125,10 @@
       AnchorSideLeft.Side = asrBottom
       AnchorSideBottom.Control = PathGroupBox
       AnchorSideBottom.Side = asrBottom
-      Left = 118
-      Height = 28
-      Top = 161
-      Width = 82
+      Left = 115
+      Height = 25
+      Top = 172
+      Width = 84
       Anchors = [akLeft, akBottom]
       AutoSize = True
       BorderSpacing.Around = 6
@@ -143,10 +144,10 @@
       AnchorSideLeft.Side = asrBottom
       AnchorSideBottom.Control = PathGroupBox
       AnchorSideBottom.Side = asrBottom
-      Left = 311
-      Height = 28
-      Top = 161
-      Width = 174
+      Left = 306
+      Height = 25
+      Top = 172
+      Width = 159
       Anchors = [akLeft, akBottom]
       AutoSize = True
       BorderSpacing.Around = 6
@@ -162,9 +163,9 @@
       AnchorSideRight.Side = asrBottom
       AnchorSideBottom.Control = ReplaceButton
       Left = 6
-      Height = 25
-      Top = 130
-      Width = 490
+      Height = 23
+      Top = 143
+      Width = 494
       OnAcceptDirectory = DirectoryEditAcceptDirectory
       ShowHidden = False
       ButtonWidth = 23
@@ -179,14 +180,14 @@
     AnchorSideTop.Side = asrBottom
     Left = 6
     Height = 164
-    Top = 239
+    Top = 244
     Width = 541
     Align = alBottom
     Anchors = []
     BorderSpacing.Around = 6
     Caption = 'TemplateGroupBox'
-    ClientHeight = 143
-    ClientWidth = 533
+    ClientHeight = 146
+    ClientWidth = 537
     TabOrder = 1
     object TemplatesListBox: TListBox
       AnchorSideLeft.Control = TemplateGroupBox
@@ -195,9 +196,9 @@
       AnchorSideRight.Side = asrBottom
       AnchorSideBottom.Control = AddTemplateButton
       Left = 6
-      Height = 97
+      Height = 103
       Top = 6
-      Width = 521
+      Width = 525
       Anchors = [akTop, akLeft, akRight, akBottom]
       BorderSpacing.Around = 6
       ItemHeight = 0
@@ -211,9 +212,9 @@
       AnchorSideBottom.Control = TemplateGroupBox
       AnchorSideBottom.Side = asrBottom
       Left = 6
-      Height = 28
-      Top = 109
-      Width = 140
+      Height = 25
+      Top = 115
+      Width = 134
       Anchors = [akLeft, akBottom]
       AutoSize = True
       BorderSpacing.Around = 6
@@ -226,8 +227,8 @@
   end
   object ButtonPanel1: TButtonPanel
     Left = 6
-    Height = 31
-    Top = 409
+    Height = 26
+    Top = 414
     Width = 541
     OKButton.Name = 'OKButton'
     OKButton.DefaultCaption = True
@@ -245,14 +246,54 @@
     Cursor = crVSplit
     Left = 0
     Height = 5
-    Top = 228
+    Top = 233
     Width = 553
     Align = alBottom
     ResizeAnchor = akBottom
   end
   object BrowseDialog: TSelectDirectoryDialog
     Options = [ofFileMustExist, ofEnableSizing, ofViewDetail]
-    left = 504
-    top = 32
+    left = 424
+    top = 40
   end
+  object PathListBoxPopupMenu: TPopupMenu
+    OnPopup = PathListBoxPopupMenuPopup
+    left = 182
+    top = 71
+    object MultiselectPathListBoxMenuItem: TMenuItem
+      AutoCheck = True
+      Caption = 'Multiselect'
+      OnClick = MultiselectPathListBoxMenuItemClick
+    end
+    object MenuItem2: TMenuItem
+      Caption = '-'
+    end
+    object ExportPathsToClipboardMenuItem: TMenuItem
+      Caption = 'Copy to Clipboard'
+      OnClick = ExportPathsToClipboardMenuItemClick
+    end
+    object ExportPathsToFileMenuItem: TMenuItem
+      Caption = 'Save to a Text-File'
+      OnClick = ExportPathsToFileMenuItemClick
+    end
+    object MenuItem5: TMenuItem
+      Caption = '-'
+    end
+    object ImportPathsFromClipboardMenuItem: TMenuItem
+      Caption = 'Paste from Clipboard'
+      OnClick = ImportPathsFromClipboardMenuItemClick
+    end
+    object ImportPathsFromFileMenuItem: TMenuItem
+      Caption = 'Load from Text-File'
+      OnClick = ImportPathsFromFileMenuItemClick
+    end
+  end
+  object ImportPathsDialog: TOpenDialog
+    left = 296
+    top = 48
+  end
+  object ExportPathsDialog: TSaveDialog
+    left = 299
+    top = 107
+  end
 end
Index: ide/patheditordlg.pas
===================================================================
--- ide/patheditordlg.pas	(revision 44586)
+++ ide/patheditordlg.pas	(working copy)
@@ -22,8 +22,8 @@
 
 uses
   Classes, SysUtils, Forms, Controls, Buttons, StdCtrls, Dialogs,
-  FileUtil, ButtonPanel, ExtCtrls, EditBtn, MacroIntf, LCLType, Graphics,
-  types, TransferMacros, LazarusIDEStrConsts, shortpathedit;
+  FileUtil, ButtonPanel, ExtCtrls, EditBtn, MacroIntf, LCLType, Graphics, Menus,
+  types, TransferMacros, LazarusIDEStrConsts, shortpathedit, Clipbrd;
 
 type
 
@@ -32,10 +32,20 @@
   TPathEditorDialog = class(TForm)
     AddTemplateButton: TBitBtn;
     ButtonPanel1: TButtonPanel;
+    MenuItem2: TMenuItem;
+    ExportPathsToClipboardMenuItem: TMenuItem;
+    ImportPathsFromClipboardMenuItem: TMenuItem;
+    MenuItem5: TMenuItem;
+    ExportPathsToFileMenuItem: TMenuItem;
+    ImportPathsFromFileMenuItem: TMenuItem;
+    MultiselectPathListBoxMenuItem: TMenuItem;
+    ImportPathsDialog: TOpenDialog;
+    PathListBoxPopupMenu: TPopupMenu;
     ReplaceButton: TBitBtn;
     AddButton: TBitBtn;
     DeleteInvalidPathsButton: TBitBtn;
     DirectoryEdit: TShortPathEdit;
+    ExportPathsDialog: TSaveDialog;
     Splitter1: TSplitter;
     DeleteButton: TBitBtn;
     PathListBox: TListBox;
@@ -51,15 +61,21 @@
     procedure DeleteButtonClick(Sender: TObject);
     procedure DirectoryEditAcceptDirectory(Sender: TObject; var Value: String);
     procedure DirectoryEditChange(Sender: TObject);
+    procedure ExportPathsToClipboardMenuItemClick(Sender: TObject);
+    procedure ExportPathsToFileMenuItemClick(Sender: TObject);
     procedure FormCreate(Sender: TObject);
     procedure FormResize(Sender: TObject);
     procedure FormShow(Sender: TObject);
+    procedure ImportPathsFromClipboardMenuItemClick(Sender: TObject);
+    procedure ImportPathsFromFileMenuItemClick(Sender: TObject);
+    procedure MultiselectPathListBoxMenuItemClick(Sender: TObject);
     procedure MoveDownButtonClick(Sender: TObject);
     procedure MoveUpButtonClick(Sender: TObject);
     procedure PathListBoxDrawItem(Control: TWinControl; Index: Integer;
       ARect: TRect; State: TOwnerDrawState);
     procedure PathListBoxKeyDown(Sender: TObject; var Key: Word;
       Shift: TShiftState);
+    procedure PathListBoxPopupMenuPopup(Sender: TObject);
     procedure PathListBoxSelectionChange(Sender: TObject; User: boolean);
     procedure ReplaceButtonClick(Sender: TObject);
     procedure TemplatesListBoxDblClick(Sender: TObject);
@@ -219,6 +235,51 @@
   UpdateButtons;
 end;
 
+procedure TPathEditorDialog.ExportPathsToClipboardMenuItemClick(Sender: TObject);
+var paths:TStringList;
+    c:integer;
+begin
+  paths:=TStringList.Create();
+
+  try
+    for c:=0 to PathListBox.Count-1 do
+    begin
+      if PathListBox.selected[c] then
+      begin
+        paths.Add(PathAsAbsolute(PathListBox.Items[c]));
+      end;
+    end;
+
+    Clipboard.AsText:=paths.DelimitedText;
+
+  finally
+    FreeAndNil(paths);
+  end;
+end;
+
+procedure TPathEditorDialog.ExportPathsToFileMenuItemClick(Sender: TObject);
+var paths:TStringList;
+    c:integer;
+begin
+  if not ExportPathsDialog.execute then exit;
+
+  paths:=TStringList.Create();
+
+  try
+    for c:=0 to PathListBox.Count-1 do
+    begin
+      if PathListBox.selected[c] then
+      begin
+        paths.Add(PathAsAbsolute(PathListBox.Items[c]));
+      end;
+    end;
+
+    paths.SaveToFile(ExportPathsDialog.Filename);
+  finally
+    FreeAndNil(paths);
+  end;
+end;
+
 procedure TPathEditorDialog.PathListBoxSelectionChange(Sender: TObject; User: boolean);
 Var
   FullPath : String;
@@ -290,6 +351,92 @@
   UpdateButtons;
 end;
 
+
+procedure TPathEditorDialog.ImportPathsFromClipboardMenuItemClick(Sender: TObject);
+var paths:TStringList;
+    y:integer;
+    c:integer;
+    RelPath:string;
+begin
+  paths:=TStringList.Create();
+
+  try
+    paths.DelimitedText:=Clipboard.AsText;
+
+    with PathListBox do
+    begin
+      y:=ItemIndex+1;
+
+      if y=0 then
+      begin
+        y:=Count;
+      end;
+
+      for c:=0 to paths.Count-1 do
+      begin
+        if Trim(paths[c])<>'' then
+        begin
+          RelPath:=BaseRelative(paths[c]);
+          Items.InsertObject(y, RelPath, PathMayExist(paths[c]));
+          ItemIndex:=y;
+        end;
+      end;
+
+      UpdateButtons;
+    end;
+
+  finally
+      FreeAndNil(paths);
+  end;
+end;
+
+procedure TPathEditorDialog.ImportPathsFromFileMenuItemClick(Sender: TObject);
+var paths:TStringList;
+    y:integer;
+    c:integer;
+    RelPath:string;
+begin
+  if not ImportPathsDialog.Execute then exit;
+
+  paths:=TStringList.Create();
+
+  try
+    paths.LoadFromFile(ImportPathsDialog.FileName);
+
+    with PathListBox do
+    begin
+      y:=ItemIndex+1;
+
+      if y=0 then
+      begin
+        y:=Count;
+      end;
+
+      for c:=0 to paths.Count-1 do
+      begin
+
+        if Trim(paths[c])<>'' then
+        begin
+          RelPath:=BaseRelative(paths[c]);
+          Items.InsertObject(y, RelPath, PathMayExist(paths[c]));
+          ItemIndex:=y;
+        end;
+      end;
+
+      UpdateButtons;
+    end;
+
+  finally
+    FreeAndNil(paths);
+  end;
+
+end;
+
+procedure TPathEditorDialog.MultiselectPathListBoxMenuItemClick(Sender: TObject);
+begin
+  PathListBox.MultiSelect:=MultiSelectPathListBoxMenuItem.Checked;
+end;
+
 procedure TPathEditorDialog.MoveDownButtonClick(Sender: TObject);
 var
   y: integer;
@@ -338,6 +485,11 @@
   end;
 end;
 
+procedure TPathEditorDialog.PathListBoxPopupMenuPopup(Sender: TObject);
+begin
+  MultiSelectPathListBoxMenuItem.Checked:=PathListBox.MultiSelect;
+end;
+
 function TPathEditorDialog.GetPath: string;
 begin
   Result:=TextToPath(PathListBox.Items.Text);

Juha Manninen

2014-04-02 14:03

developer   ~0074116

Last edited: 2014-04-02 14:08

View 2 revisions

Thanks, now it applies.
I tested with GTK2 bindings on Linux and found some GUI issues :

With single selection, when you right-click on an item which is not already selected, the pop-up operation works on a previously selected item.
The newly clicked item gets selected _after_ the operation is done.
It is counter-intuitive, the clicked item should be selected first.

With multiselection the pop-up operation works on selected items (correct) but then the clicked item gets selected again.

The move up/down arrows are enabled also with multiselect but they work wrong. Only the first/last selected item is affected.

I also noticed that the text formats for clipboard and file are different. Maybe it is intentional and needed, I don't know.
Clipboard gets a comma-separated list, file gets a newline-separated list.

First I thought the multiselect setting should be stored environment settings but maybe not. This can be considered an advanced feature where multiselect can be switched on when needed.
I believe this will be very usable once the bugs are fixed.

dimprofi

2014-04-02 19:24

reporter   ~0074122

@Juha Manninen

"With single selection, when you right-click on an item which is not already selected, the pop-up operation works on a previously selected item.
The newly clicked item gets selected _after_ the operation is done.
It is counter-intuitive, the clicked item should be selected first."
---
It looks like a bug in a TListBox - I changed nothing in clicking/selecting of list items :)


"The move up/down arrows are enabled also with multiselect but they work wrong. Only the first/last selected item is affected."
---
OK. Didn't thought about this functionality - moving a group of a paths :)


I also noticed that the text formats for clipboard and file are different. Maybe it is intentional and needed, I don't know.
Clipboard gets a comma-separated list, file gets a newline-separated list.
---
Yes, I added line breaks for a file explicitly.


First I thought the multiselect setting should be stored environment settings but maybe not. This can be considered an advanced feature where multiselect can be switched on when needed.
---
I'm planning to implement global group of paths later, like paths templates now.
But we need to clear a question where and how (XML-Structure) to store it.


I believe this will be very usable once the bugs are fixed.
---
Gonna add a moving of multi-selected items up/down.
It's not really a bug fix, just new feature.
The problems with a TListbox require separate bug report and fix :)

dimprofi

2014-04-02 19:33

reporter   ~0074123

Last edited: 2014-04-02 19:39

View 2 revisions

@Juha Manninen

"The move up/down arrows are enabled also with multiselect but they work wrong. Only the first/last selected item is affected."
---
I have two basic ideas to this functionality.

1. Add "First" / "Last" Button.

2. Make Drag and Drop for changing order and remove buttons Up/Down at all? :)

For 2. it would be usefull to implement this Kind of functionality directly in TListBox:

property ItemsMoving:boolean; // Like in TStringGrind Options/ColMoving

Juha Manninen

2014-04-02 20:49

developer   ~0074126

Last edited: 2014-04-03 18:24

View 2 revisions

> It's not really a bug fix, just new feature.

It is a bug obviously because your patch broke a feature that used to work very well.
That's why I wrote earlier: "Multiselection affects the current operation, too. It must be well tested."
A valid fix would also be to disable the arrow buttons when multiple items are selected.

For other questions and ideas please open a mail thread in Lazarus mailing list. I will answer you there.
This bug tracker issue is a wrong place for discussion.

Derit Agustin

2014-04-03 15:15

reporter   ~0074141

this feature multi selection is ok
i'm also difficulties must select choose many paths

Juha Manninen

2014-04-26 17:04

developer   ~0074608

@dimprofi, are you planning to continue with this feature?
I was prepared to answer your LCL related questions in Lazarus mailing list but I have not seen your mails.
You can also send personal mail but mailing list is preferred because there are more people reading and answering.

dimprofi

2014-04-27 19:30

reporter   ~0074628

@Juha Manninen

I have never used a Mailing Lists - I'm gonna try to do this :)

Yeah, gonna continue this feature next week.
It was too much work, sorry :)

Juha Manninen

2014-08-11 22:11

developer   ~0076569

I implemented a simple popup menu with Copy / Paste.
If you still want to implement the multiselection, please reopen the issue and attach a new patch.

dimprofi

2014-08-18 15:08

reporter   ~0076644

@Juha Manninen
Why not loading from/to Textfile? It's the same.

Juha Manninen

2014-09-13 10:44

developer   ~0077176

> Why not loading from/to Textfile? It's the same.

Done in r46200.

Issue History

Date Modified Username Field Change
2014-03-23 15:57 dimprofi New Issue
2014-03-23 15:57 dimprofi File Added: 2014-03-23 importpaths.patch
2014-03-23 16:01 dimprofi File Added: lazarus_patheditor.jpg
2014-03-23 16:09 dimprofi Tag Attached: Feature
2014-03-23 16:29 Zeljan Rikalo Note Added: 0073911
2014-03-23 16:39 Juha Manninen Note Added: 0073912
2014-03-23 16:42 dimprofi Note Added: 0073913
2014-03-23 16:45 dimprofi Note Added: 0073914
2014-03-23 16:49 Martin Friebe Note Added: 0073915
2014-03-23 17:07 dimprofi Note Added: 0073916
2014-03-23 17:07 dimprofi Note Edited: 0073916 View Revisions
2014-03-23 17:10 dimprofi Note Edited: 0073916 View Revisions
2014-03-23 18:08 Martin Friebe Note Added: 0073917
2014-03-23 18:22 Martin Friebe Note Edited: 0073917 View Revisions
2014-03-23 19:51 dimprofi Note Added: 0073919
2014-03-24 17:21 Juha Manninen Assigned To => Juha Manninen
2014-03-24 17:21 Juha Manninen Status new => assigned
2014-03-24 17:31 Juha Manninen LazTarget => -
2014-03-24 17:31 Juha Manninen Note Added: 0073940
2014-03-24 17:31 Juha Manninen Status assigned => feedback
2014-03-24 17:40 Juha Manninen Note Edited: 0073940 View Revisions
2014-03-24 19:12 dimprofi Note Added: 0073943
2014-03-24 19:12 dimprofi Status feedback => assigned
2014-03-24 19:17 dimprofi Note Edited: 0073943 View Revisions
2014-03-24 21:01 Juha Manninen Note Added: 0073944
2014-03-24 21:21 Juha Manninen Note Edited: 0073944 View Revisions
2014-03-24 23:34 dimprofi Note Added: 0073948
2014-03-27 23:04 Juha Manninen Note Added: 0074031
2014-03-27 23:04 Juha Manninen Status assigned => feedback
2014-03-27 23:06 Juha Manninen Note Edited: 0074031 View Revisions
2014-03-27 23:07 Juha Manninen Note Edited: 0074031 View Revisions
2014-03-29 10:36 Juha Manninen Note Edited: 0074031 View Revisions
2014-03-29 14:03 dimprofi Note Added: 0074055
2014-03-29 14:03 dimprofi Status feedback => assigned
2014-03-29 14:13 dimprofi Note Edited: 0074055 View Revisions
2014-03-29 14:37 dimprofi File Added: 2014-03-29 multiselect paths.jpg
2014-03-29 14:39 dimprofi Note Added: 0074056
2014-03-29 15:49 Juha Manninen Note Added: 0074057
2014-03-29 15:50 Juha Manninen Note Edited: 0074057 View Revisions
2014-03-29 16:03 dimprofi Note Added: 0074058
2014-03-29 16:42 dimprofi File Added: 2014-03-29 paths import-export.patch
2014-03-29 16:44 dimprofi Note Added: 0074059
2014-03-29 16:46 Zeljan Rikalo Note Added: 0074060
2014-03-29 22:44 dimprofi Note Added: 0074070
2014-03-29 22:44 dimprofi Note Edited: 0074070 View Revisions
2014-03-30 21:06 Juha Manninen Note Added: 0074083
2014-03-30 21:36 Martin Friebe Note Added: 0074084
2014-03-31 22:45 Juha Manninen Note Added: 0074107
2014-03-31 23:36 Juha Manninen Note Edited: 0074107 View Revisions
2014-04-02 11:14 dimprofi File Added: 2014-04-02 paths import-export.patch
2014-04-02 11:15 dimprofi Note Added: 0074114
2014-04-02 11:19 dimprofi File Added: 2014-04-02 paths import-export for 44586.patch
2014-04-02 14:03 Juha Manninen Note Added: 0074116
2014-04-02 14:08 Juha Manninen Note Edited: 0074116 View Revisions
2014-04-02 19:24 dimprofi Note Added: 0074122
2014-04-02 19:33 dimprofi Note Added: 0074123
2014-04-02 19:39 dimprofi Note Edited: 0074123 View Revisions
2014-04-02 20:49 Juha Manninen Note Added: 0074126
2014-04-03 15:15 Derit Agustin Note Added: 0074141
2014-04-03 18:24 Juha Manninen Note Edited: 0074126 View Revisions
2014-04-26 17:04 Juha Manninen Note Added: 0074608
2014-04-26 17:04 Juha Manninen Status assigned => feedback
2014-04-27 19:30 dimprofi Note Added: 0074628
2014-04-27 19:30 dimprofi Status feedback => assigned
2014-08-11 22:11 Juha Manninen Fixed in Revision => Partially r46035
2014-08-11 22:11 Juha Manninen Note Added: 0076569
2014-08-11 22:11 Juha Manninen Status assigned => resolved
2014-08-11 22:11 Juha Manninen Resolution open => fixed
2014-08-18 15:08 dimprofi Note Added: 0076644
2014-09-13 10:44 Juha Manninen Note Added: 0077176
2014-09-13 10:44 Juha Manninen Fixed in Revision Partially r46035 => Partially r46035, r46200