Recent

Author Topic: add a column to TshellListView?  (Read 14049 times)

kormoran

  • New Member
  • *
  • Posts: 31
add a column to TshellListView?
« on: April 04, 2015, 03:51:48 pm »
Hello, I need to calc a value for each file in a directory and show it.

TShellListView would be perfect, IF I could add another column to it... but I can't find a way. Can this be (easily) done or do I need to derive from TCustomShellListView and make my own?

Thanks  :)

(edit: OOPS wrong board... plz move to Lazarus->Programming->LCL)
« Last Edit: April 04, 2015, 04:02:39 pm by kormoran »

typo

  • Hero Member
  • *****
  • Posts: 3051
Re: add a column to TshellListView?
« Reply #1 on: April 04, 2015, 07:40:44 pm »
Code: [Select]
  ShellListView1.Columns.Add;
  ShellListView1.Column[ShellListView1.ColumnCount - 1].Caption := 'abc';   

You need to derive from TShellListView or TCustomShellListView and make property Columns public. Or make a Feature Request in BugTracker in order to make it public on TCustomListView source (since Column and ColumnCount are public too).
« Last Edit: April 04, 2015, 08:22:32 pm by typo »

howardpc

  • Hero Member
  • *****
  • Posts: 3150
Re: add a column to TshellListView?
« Reply #2 on: April 04, 2015, 08:23:45 pm »
Here's an example of one way to achieve this.

Code: [Select]
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, ShellCtrls, ComCtrls;

type

  { TShellListViewEx }

  TShellListViewEx = class(TShellListView)
  private
    FNewColumn: TListColumn;
    FNewColumnCaption: string;
    function FileStringFunction(const aFilePath: string): string; // supply your file processing logic here
    procedure PopulateWithRootEx;
  public
    constructor CreateEx(AOwner: TComponent; const anExtraColumn: string);
    property ExColumnCaption: string read FNewColumnCaption;
  end;

  { TForm1 }

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    slvEx: TShellListViewEx;
  end;

var
  Form1: TForm1;

implementation

uses LazLogger;

{$R *.lfm}

{ TShellListViewEx }

function TShellListViewEx.FileStringFunction(const aFilePath: string): string;
begin
  if FileIsReadOnly(aFilePath) then
    Result:='ReadOnly'
  else Result:='Writeable';
end;

procedure TShellListViewEx.PopulateWithRootEx;
var
  Files: TStringList;
  i: integer;
  li: TListItem;
  curFilePath, filePath: string;
begin
  inherited PopulateWithRoot;
  if (csDesigning in ComponentState) then Exit;
  if Trim(Root) = '' then Exit;

  Files := TStringList.Create;
  try
    TCustomShellTreeView.GetFilesInDir(Root, Mask, ObjectTypes, Files);
    curFilePath:=IncludeTrailingPathDelimiter(Root);
    for i := 0 to Files.Count - 1 do
    begin
      li:=Items.FindCaption(0,Files[i],False,True,true);
      if (li <> nil) then begin
        filePath:=curFilePath + Files[i];
        li.SubItems.Add(FileStringFunction(filePath));
      end
      else DebugLn('Filename %s was not in items list',[Files[i]]);
    end;
  finally
    Files.Free;
  end;
end;

constructor TShellListViewEx.CreateEx(AOwner: TComponent;
  const anExtraColumn: string);
begin
  inherited Create(AOwner);
  FNewColumn:=Columns.Add;
  FNewColumn.Caption:=anExtraColumn;
  Root:='C:\';                      // customise these properties appropriately
  Mask:='*.*';
  ObjectTypes:=[otFolders, otNonFolders];
  PopulateWithRootEx;
end;

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  slvEx:=TShellListViewEx.CreateEx(Self, 'Readonly attribute');
  slvEx.Align:=alClient;
  slvEx.Parent:=Self;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FreeAndNil(slvEx);
end;

end.

kormoran

  • New Member
  • *
  • Posts: 31
Re: add a column to TshellListView?
« Reply #3 on: April 04, 2015, 11:05:09 pm »
Thank you guys, excellent answers.

(Sorry for posting in the wrong place)

typo

  • Hero Member
  • *****
  • Posts: 3051
Re: add a column to TshellListView?
« Reply #4 on: April 05, 2015, 12:02:01 am »
Making a Feature Request should result, see TCustomListView source:

Code: [Select]
TShellListView = class(TCustomShellListView)
  published
    { TCustomListView properties
      The same as TListView excluding data properties }
    property Align;
    property Anchors;
    property BorderSpacing;
    property BorderStyle;
    property BorderWidth;
//    property Checkboxes;
    property Color default clWindow;
//    property Columns;

All they need to do is uncomment that line.

typo

  • Hero Member
  • *****
  • Posts: 3051

Bart

  • Hero Member
  • *****
  • Posts: 3518
    • Bart en Mariska's Webstek
Re: add a column to TshellListView?
« Reply #6 on: April 05, 2015, 12:42:32 am »
There is a reason why it is not published.
(See bugreport).

Bart

typo

  • Hero Member
  • *****
  • Posts: 3051
Re: add a column to TshellListView?
« Reply #7 on: April 05, 2015, 12:49:45 am »
Surely there is a reasonable reason why he/she should not delete the first 3 columns.

Bart

  • Hero Member
  • *****
  • Posts: 3518
    • Bart en Mariska's Webstek
Re: add a column to TshellListView?
« Reply #8 on: April 05, 2015, 12:52:32 am »
Yes, and we like to not "help" people to shoot in their own foot (we're not C).

Bart

typo

  • Hero Member
  • *****
  • Posts: 3051
Re: add a column to TshellListView?
« Reply #9 on: April 05, 2015, 02:02:35 am »
Blocking access to Colums property does not seem a very smart solution. Maybe a block to the first 3 would be better.
« Last Edit: April 05, 2015, 02:16:22 am by typo »

Timewarp

  • Full Member
  • ***
  • Posts: 144
Re: add a column to TshellListView?
« Reply #10 on: April 05, 2015, 09:19:02 am »
If all needed is to publish columns, just add this to project:
Code: [Select]
type
  TShellListView = class(ShellCtrls.TShellListView)
    published property Columns;
  end;

typo

  • Hero Member
  • *****
  • Posts: 3051
Re: add a column to TshellListView?
« Reply #11 on: April 05, 2015, 09:46:20 am »
I agree.

Bart

  • Hero Member
  • *****
  • Posts: 3518
    • Bart en Mariska's Webstek
Re: add a column to TshellListView?
« Reply #12 on: April 05, 2015, 10:58:54 am »
Blocking access to Colums property does not seem a very smart solution. Maybe a block to the first 3 would be better.

Yes.
Not sure how to do that though.
Any ideas?

Bart

typo

  • Hero Member
  • *****
  • Posts: 3051
Re: add a column to TshellListView?
« Reply #13 on: April 05, 2015, 11:04:40 am »
First idea:

Code: [Select]
    procedure AddColumn(ACaption :string);
    procedure DeleteColumn(AIndex :integer);

{...}

procedure TCustomShellListView.AddColumn(ACaption :string);
begin
  Columns.Add;
  Column[ColumnCount - 1].Caption := ACaption;
end;

procedure TCustomShellListView.DeleteColumn(AIndex :integer);
begin
  if AIndex > 2 then
    Columns.Delete(AIndex);
end;               

Bart

  • Hero Member
  • *****
  • Posts: 3518
    • Bart en Mariska's Webstek
Re: add a column to TshellListView?
« Reply #14 on: April 05, 2015, 11:24:21 am »
Still leaves the possibility to do
Code: [Select]
  ShellListView1.Columns.Delete(0);

(If Columns were to be published.)

While it is possible to replace TTreeNode with a subclass (which I have done), such a mechanisme is not provided for columns.

But just introducing AddColumn and DeleteColumn might be a feasible idea.

Bart