Sortier Bug in TCustomGrid ?

Für Fehler in Lazarus, um diese von anderen verifizieren zu lassen.
Antworten
Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1496
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Sortier Bug in TCustomGrid ?

Beitrag von corpsman »

Servus, ich bastle gerade in bischen mit Tstringgrid rum, dort möchte ich durch klick auf die Header automatisch die Zellen sortieren lassen.

Meiner Meinung müsste das gehen wenn ich folgendes mache :

1. Definieren der StringGrid1CompareCells Methode
2. Stringgrid1.SortOrder := soDescending; oder Stringgrid1.SortOrder := soAscending;
3. Stringgrid1.SortColRow(true, index, 1, StringGrid1.RowCount - 1); // aufrufen (das 1 verhindert, dass meine Beschriftung mit Sortiert wird)


Das Problem ist nun dass Stringgrid1.SortOrder nicht berücksichtigt wird.

Nun hab ich ein bischen rumprobiert und gesehen das letzt endes die Routine

procedure TCustomGrid.Sort(ColSorting: Boolean; index, IndxFrom, IndxTo: Integer); ( grids.pas Zeile 2912)

Aufgerufen wird.

Leider berücksichtigt die dort stehende Routine SortOrder nicht. Der Fix, sollte es ein Bug sein ist Trivial, und würde so aussehen :

Code: Alles auswählen

 
if ColSorting then begin
if SortOrder = soAscending then begin // neu
          while DoCompareCells(index, P, index, I)>0 do I:=I+1;
          while DoCompareCells(index, P, index, J)<0 do J:=J-1;
end else begin// neu
          while DoCompareCells(index, P, index, I)<0 do I:=I+1;// neu
          while DoCompareCells(index, P, index, J)>0 do J:=J-1;// neu
end;// neu
        end else begin
if SortOrder = soAscending then begin // neu
          while DoCompareCells(P, index, I, index)>0 do I:=I+1;
          while DoCompareCells(P, index, J, index)<0 do J:=J-1;
end else begin// neu
          while DoCompareCells(P, index, I, index)<0 do I:=I+1;// neu
          while DoCompareCells(P, index, J, index)>0 do J:=J-1;// neu
end;// neu
        end;
 


Bevor ich es als Bug Reporte, die Frage, nutze ich die Komponente falsch ?
Gruß
Corpsman

SVN Revision : 44121
FPC : 2.6.2-5
Widgetset : GTK2
--
Just try it

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: Sortier Bug in TCustomGrid ?

Beitrag von Michl »

Also bei mir funktioniert das Sortieren (allerdings Columns einfügen) problemlos, eben schnell zusammengeklimpert und getestet (auf- und abwärts), Bsp anbei (Leere Form, ein StringGrid drauf) und:

Code: Alles auswählen

function ZufallString: String;
var
  i: Integer;
begin
  Result:='';
  for i:=0 to Random(10) + 1 do Result:=Result + Char(Ord('A') + Random(26));
end;
 
procedure TForm1.FormCreate(Sender: TObject);
var
  i, j: Integer;
begin
  StringGrid1.RowCount:=10;
  StringGrid1.ColCount:=0;
  for i:=0 to 4 do begin
    StringGrid1.Columns.Add;
    for j:=1 to 9 do StringGrid1.Cells[i, j]:=ZufallString;
  end;
  StringGrid1.FixedRows:=1;
  StringGrid1.ColumnClickSorts:=True;
end;
Sortieren per HeaderClick, Win7, Lazarus 1.0.14
Dateianhänge
StringGridSortTest.zip
(125.89 KiB) 73-mal heruntergeladen

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1496
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Sortier Bug in TCustomGrid ?

Beitrag von corpsman »

Füge deinem Beispiel, den Folgenden Code hinzu, und es funktioniert nicht mehr :

Code: Alles auswählen

 
procedure TForm1.StringGrid1CompareCells(Sender: TObject; ACol, ARow, BCol,
  BRow: Integer; var Result: integer);
begin
  result := CompareStr(TStringGrid(sender).Cells[acol,arow],TStringGrid(sender).Cells[bcol,brow]  );
end;
 


Kannst du das ebenfalls Reproduzieren ?
--
Just try it

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: Sortier Bug in TCustomGrid ?

Beitrag von Michl »

corpsman hat geschrieben:Kannst du das ebenfalls Reproduzieren ?
Ja

Testest Du aber auf die Sortierrichtung und beachtest diese, funktioniert es (zumindest hier):

Code: Alles auswählen

procedure TForm1.StringGrid1CompareCells(Sender: TObject; ACol, ARow, BCol,
  BRow: Integer; var Result: integer);
begin
  if TStringGrid(Sender).SortOrder = soAscending then
    Result := CompareStr(TStringGrid(Sender).Cells[ACol, ARow], TStringGrid(Sender).Cells[BCol, BRow])
  else
    Result := - CompareStr(TStringGrid(Sender).Cells[ACol, ARow], TStringGrid(Sender).Cells[BCol, BRow]);
end

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1496
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Sortier Bug in TCustomGrid ?

Beitrag von corpsman »

Mein Aktuell implementierter Workaround macht es ziemlich genau so.


http://bugs.freepascal.org/view.php?id=25772

Mal sehen was draus wird. ;)

Corpsman
--
Just try it

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: Sortier Bug in TCustomGrid ?

Beitrag von Michl »

:shock: Wo siehst Du da einen Bug???

Sobald Du OnCompareCells zuweist (damit sagst Du ja, dass Du selber sortieren möchtest), musst Du dem Result einen Wert zuweisen. Dabei hattest Du nur nicht auf ASC bzw. DESC getestet. Mit dem Test ist doch alles i.O.! Willst Du nicht selber sortieren, dann weise doch einfach OnCompareCells nicht zu!

Willst Du z.B. per Buttonclick sortieren, dann funktioniert bei mir

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
begin
  StringGrid1.SortOrder:=soAscending; //oder soDescending
  StringGrid1.SortColRow(True, 0);
end
problemlos.

Eine normale Stringgrid (ohne Columns - hast dann keine Pfeile) sortieren, funktioniert auch, indem Du im Objektinspektor einfach ColumnClickSort auf True stellst - das wars (ASC + DESC funktioniert bei mir problemlos). ButtonClick s.O. funktioniert auch!

PS: Falls Du OnCompareCells nicht zuweist, dann würde bei

Code: Alles auswählen

function TCustomStringGrid.DoCompareCells(Acol, ARow, Bcol, BRow: Integer
  ): Integer;
begin
  if Assigned(OnCompareCells) then
    Result:=inherited DoCompareCells(Acol, ARow, Bcol, BRow)
  else begin
    Result:=UTF8CompareText(Cells[ACol,ARow], Cells[BCol,BRow]);
    if SortOrder=soDescending then
      result:=-result;
  end;
end;
die Sortoder hier auf ASC/DESC getestet und mit Deinem vorgeschlagenen Patch im Konflikt stehen!

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1496
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Sortier Bug in TCustomGrid ?

Beitrag von corpsman »

Hmm.

Mir scheint wir sind hier unterschiedlicher Meinung.

Ich verstehe unter der Definition von OnCompareCell, genau das was der Name sagt. Nämlich eine Callback Routine, welche dem Aufrufer sagt wie die Beiden übergebenen Zellen bezogen auf eine Ordnung relativ zueinander stehen.

Aus meiner Sicht ist diese Relative differenz immer Gleich. Mit dem Parameter Sortorder erwarte ich dann, dass der Algorithmus Auf- oder Absteigend Sortiert.

Auch deine Interpretation macht natürlich sinn. Welche hier Treffender ist wird wohl der entscheiden, welcher das Ticket bearbeitet.

Gruß

Corpsman
--
Just try it

Antworten