Recent

Author Topic: BUG: TListView - SORT/RENDERING issue.  (Read 9801 times)

ozznixon

  • Jr. Member
  • **
  • Posts: 85
    • http://www.modernpascal.com/
BUG: TListView - SORT/RENDERING issue.
« on: January 03, 2008, 09:04:37 pm »
It appears (especially after reviewing the inc file) that the implementation of TListView, when sorting sorts the StringList - but not the actual elements which are visually rendered.

* How to reproduce: New Project, Add TTreeView, TListView, TStatusBar. Set TListView properties to ViewStyle=vsReport and Add Two Columns (0=FileName, 1=Size) save Unit1 as umainform - then paste the following code in and run it - when you double click on the lines in the TListView - you will notice the showmessage code shows the sorted value - however, the GUI widget is not sorted!

-- my source -- BuildTree (tried many different implementation - note this code works in Delphi fine - so the code logic works),

Code: [Select]

unit umainform;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, ComCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    ListView1: TListView;
    StatusBar1: TStatusBar;
    TreeView1: TTreeView;
    procedure FormShow(Sender: TObject);
    procedure ListView1ColumnClick(Sender: TObject; Column: TListColumn);
    procedure ListView1DblClick(Sender: TObject);
    procedure TreeView1DblClick(Sender: TObject);
  private
    { private declarations }
    procedure BuildTree(Path:String);
  public
    { public declarations }
    CurrentPath:String;
  end;

var
  Form1: TForm1;

implementation

uses
   dxstring;

{ TForm1 }

procedure TForm1.BuildTree(Path:String);
Var
   SRec:TSearchRec;
   Err:Integer;
   TreeNode:TTreeNode;
   ListItem:TListItem;

begin
   CurrentPath:=dxstring.AddBackSlash(Path);
   Statusbar1.SimpleText:=CurrentPath;
   TreeView1.SortType:=stNone;
   TreeView1.Items.Clear;
   TreeView1.BeginUpdate;
   ListView1.SortType:=stNone;
   ListView1.Items.Clear;
   ListView1.BeginUpdate;
   Err:=FindFirst(Statusbar1.SimpleText+'*',faAnyFile,SRec);
   While Err=0 do begin
      if (SRec.Attr and faDirectory)=faDirectory then begin
         if (SRec.Name<>'.') then begin
{$IFDEF LINUX}
            if (CurrentPath='/') and (SRec.Name='..') then continue;
{$ELSE}
            if (Length(CurrentPath)=3) and (SRec.Name='..') then continue;
{$ENDIF}
            TreeView1.Items.Add(Nil,SRec.Name);
         end;
      end
      else begin
         ListItem:=ListView1.Items.Add;
         ListItem.Caption:=SRec.Name;
         ListItem.SubItems.Add(IntToStr(SRec.Size));
      end;
      Err:=FindNext(SRec);
   end;
   FindClose(SRec);
   ListView1.SortType:=stText; // causes sort to be called! {visually broken}
   ListView1.EndUpdate;
   TreeView1.SortType:=stText; // causes sort to be called! {works}
   TreeView1.EndUpdate;
End;

procedure TForm1.FormShow(Sender: TObject);
Begin
   ListView1.FlatScrollBars:=True;
   ListView1.GridLines:=True;
   BuildTree(ExtractFilePath(Paramstr(0)));
end;

procedure TForm1.ListView1ColumnClick(Sender: TObject; Column: TListColumn);
begin
   ListView1.SortColumn:=Column.Index;
end;

procedure TForm1.ListView1DblClick(Sender: TObject);
Var
   StrList:TStringList;
   
begin
   StrList:=TStringList.Create;
   StrList.LoadFromFile(CurrentPath+ListView1.Selected.Caption);
   ShowMessage(ExtractFileName(ListView1.Selected.Caption));
   StrList.Free;
end;

procedure TForm1.TreeView1DblClick(Sender: TObject);
Const
{$IFDEF LINUX}
   Slash = '/';
{$ELSE}
   Slash = '\';
{$ENDIF}

begin
   if TreeView1.Selected.Text='..' then begin
      Delete(CurrentPath,Length(CurrentPath),1); // drop existing trailing slash
      While (length(CurrentPath)>0) and
         (Copy(CurrentPath,Length(CurrentPath),1)<>Slash) do
         Delete(CurrentPath,Length(CurrentPath),1);
      If CurrentPath='' then CurrentPath := Slash;
      BuildTree(CurrentPath);
   end
   else begin
      BuildTree(CurrentPath+TreeView1.Selected.Text);
   end;
end;

initialization
  {$I umainform.lrs}

end.
---
Want to kick the tires to a Free Pascal like script engine? http://www.ModernPascal.com/

Leledumbo

  • Hero Member
  • *****
  • Posts: 8112
  • Programming + Glam Metal + Tae Kwon Do = Me
RE: BUG: TListView - SORT/RENDERING issue.
« Reply #1 on: January 07, 2008, 10:11:46 am »
Have you tried to force the List View to paint? I mean, something like calling ListView1.Paint;

Marc

  • Administrator
  • Hero Member
  • *
  • Posts: 2496
RE: BUG: TListView - SORT/RENDERING issue.
« Reply #2 on: January 07, 2008, 10:49:02 am »
better call Listview1.invalidate.

But it won't work, listview sorting is not yet implemented.
//--
{$I stdsig.inc}
//-I still can't read someones mind
//-Bugs reported here will be forgotten. Use the bug tracker

Leledumbo

  • Hero Member
  • *****
  • Posts: 8112
  • Programming + Glam Metal + Tae Kwon Do = Me
RE: BUG: TListView - SORT/RENDERING issue.
« Reply #3 on: January 07, 2008, 11:35:44 am »
Oh, yeah! I've done a sort to a ListView in one of my programs. Download the source here.
After compiling, run the program, add some files (or dirs) and click one of the column header.

ozznixon

  • Jr. Member
  • **
  • Posts: 85
    • http://www.modernpascal.com/
RE: BUG: TListView - SORT/RENDERING issue.
« Reply #4 on: January 11, 2008, 08:35:06 pm »
Not to argue - but just an FYI - WINDOWS returns the directory sorted alphabetically when you do FindFirst. Linux returns the TSearchRec in the order the iNodes are returns when you do an "ls". Thus giving you the false perception that it is sorted under Windows. I downloaded your code, tweaked it, ran in Linux - same problem. Running FPC 2.2.0 and Laz 0.9.24b.

FYI, I had originally coded w/ .Invalidate() and Paint() - that is when I cracked open the source, to find the WIDGET is not sorting it - based upon implementation.
---
Want to kick the tires to a Free Pascal like script engine? http://www.ModernPascal.com/

Leledumbo

  • Hero Member
  • *****
  • Posts: 8112
  • Programming + Glam Metal + Tae Kwon Do = Me
RE: BUG: TListView - SORT/RENDERING issue.
« Reply #5 on: January 13, 2008, 07:19:09 am »
Actually, the sorting algorithm doesn't have any relation with FindFirst or TSearchRec. Both are only used to add items to the ListView. For sorting, I only use QuickSort. Did you do what I tell (add some files, then click one of the column header)? Column click does the sorting, adding files doesn't.

ozznixon

  • Jr. Member
  • **
  • Posts: 85
    • http://www.modernpascal.com/
RE: BUG: TListView - SORT/RENDERING issue.
« Reply #6 on: February 20, 2008, 01:28:20 am »
Yes I did what you stated. The component does not have .Sort() implemented correctly. I ended up writing my own component. The deeper we dug into the base widgets that come in the LCL, the more we found things are "started", however, are not fully implemented. For example the TDataSet is not implemented completely, while it does provide a great starting point for a port - you can quickly get tripped up "assuming" the LCL is complete.

So, we just elected to rewrite one component at a time - so we know (a) it is complete, (b) it works.

Thank you for your assistance though!
G.E. Ozz Nixon Jr.
http://www.3famous.com/
---
Want to kick the tires to a Free Pascal like script engine? http://www.ModernPascal.com/

Bart

  • Hero Member
  • *****
  • Posts: 3541
    • Bart en Mariska's Webstek
Re: RE: BUG: TListView - SORT/RENDERING issue.
« Reply #7 on: February 20, 2008, 03:11:36 pm »
Quote from: "ozznixon"
Not to argue - but just an FYI - WINDOWS returns the directory sorted alphabetically when you do FindFirst.

Since when is that.

On WinXP en Win9x this is definately not the case.

Bart