* * *

Author Topic: New package TSortGrid, a sortable StringGrid  (Read 870 times)

John Landmesser

  • New member
  • *
  • Posts: 21
New package TSortGrid, a sortable StringGrid
« on: May 16, 2018, 03:06:38 pm »
Hi,

TStringGrid sorts everything as string!

To improve that i developed TSortGrid, derived from TStringGrid, but capable of sorting Integer, Float, Date, Time, String and show up- and down- Arrows in Titlebar.

See

https://github.com/JohnML1/SortGrid.git



... hope its useful :-)
« Last Edit: May 16, 2018, 03:08:41 pm by John Landmesser »

JD

  • Hero Member
  • *****
  • Posts: 1703
Re: New package TSortGrid, a sortable StringGrid
« Reply #1 on: May 16, 2018, 03:16:05 pm »
Hi,

TStringGrid sorts everything as string!

To improve that i developed TSortGrid, derived from TStringGrid, but capable of sorting Integer, Float, Date, Time, String and show up- and down- Arrows in Titlebar.

See

https://github.com/JohnML1/SortGrid.git



... hope its useful :-)

Very good. Thanks for sharing.

JD
Windows (10, 7) - Lazarus 1.8/FPC 3.0.4, NewPascal, Delphi
Linux Mint Cinnamon  - Lazarus 1.8/FPC 3.0.4, NewPascal

Indy 10.6 series; mORMot; Zeos 7.2.1; SQLite, Firebird, PostgreSQL & MariaDB; VirtualTreeView 5.5.3 R1

GetMem

  • Hero Member
  • *****
  • Posts: 3018
Re: New package TSortGrid, a sortable StringGrid
« Reply #2 on: May 17, 2018, 09:15:01 pm »
Hi John,

I would like to add SortGrid to OPM, but please do the following modifications  first:
1. Rename the lpk file to something more meaningful like laz_sortgrid.lpk instead of sortgrid1.lpk
2. Add a description to the lpk file, currently is: "Selbstkompilierte Komponenten". If it's possible add a description in english, you can translate it to other languages too if you like
3. Add a license to the lpk file

Thanks for sharing.
« Last Edit: May 17, 2018, 09:17:19 pm by GetMem »

wp

  • Hero Member
  • *****
  • Posts: 4483
Re: New package TSortGrid, a sortable StringGrid
« Reply #3 on: May 17, 2018, 10:39:25 pm »
Another hint: Since Lazarus 1.8+ supports high-resolution screens the component icons should be provided in three resolutions:
  • the first one 24x24, named like the component itself (i.e., 'tsortgrid.png')
  • the second one at 36x36 with '_150' appended to the component name (i.e. 'tsortgrid_150.png')
  • and the third one at 48x48 with '_200' appended to the component name (i.e. 'tsortgrid_200.png').
The numbers indicate the magnification factor.

Otherwise the normal icon (24x24) will be scaled up and become blurry. If your icon source does not offer these resolutions you may copy the icons in (lazarus)/images/components and add corresponding overlays images.
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

Alextp

  • Hero Member
  • *****
  • Posts: 612
    • UVviewsoft
Re: New package TSortGrid, a sortable StringGrid
« Reply #4 on: May 18, 2018, 01:04:50 pm »
IMHO better longer name, like TSortStringGrid, TSortableStringGrid, to show that its child of StringGrid...

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3365
  • I like bugs.
Re: New package TSortGrid, a sortable StringGrid
« Reply #5 on: May 18, 2018, 01:35:14 pm »
1. Rename the lpk file to something more meaningful like laz_sortgrid.lpk instead of sortgrid1.lpk
Is that needed? The package name will be shown in a list of Lazarus packages. Thus everybody knows it is for Lazarus. Besides, the suffix .lpk stands for "Lazarus PacKage" as opposed to Delphi or any other package. It is unambiguous.
We already have many packages in Lazarus distribution starting with "laz_" which looks stupid because it is redundant and useless information.
That is my opinion anyway. It is a matter of taste of course.

IMHO better longer name, like TSortStringGrid, TSortableStringGrid, to show that its child of StringGrid...
I guess the component introduces pseudo-types for the columns. The actual data are still strings which must be converted every time for comparison.
It is slow but nevertheless usefull in many situations.
However I agree with Alextp that name "StringGrid" should be included in the name of this derived class to indicate its actual data type.
« Last Edit: May 18, 2018, 01:41:11 pm by JuhaManninen »

wp

  • Hero Member
  • *****
  • Posts: 4483
Re: New package TSortGrid, a sortable StringGrid
« Reply #6 on: May 18, 2018, 02:35:42 pm »
The suffix "Package", "Pck", or "Pkg" is useful to distinguish the auto-generated package unit from a "real" source unit.

Since many of our packages orginate from Delphi ancestors where they have a package file for every version, the prefix "laz" may be justified to highlight the Lazarus version in contrast to the Delphi versions, in addition to the extension. But your are right: the prefix usually is not necessary. I know I myself am guilty of some of these abuses. Is there a non-destructive way of renaming a package without breaking existing projects? And how does OPM handle the case that a package such as "laz_chemtext.lp", is renamed to "chemtext.lpk"? Will it remove the old "laz_chemtext" from the system when "chemtext" is installed? If not, the user will be in trouble because the contained component now exists twice.

I am a bit in doubt whether a grid which just implements a sorting method is justified to occupy a place in the component palette. Just for sorting if would be enough to put the Compare routine into a separate unit which might just be called to enable this feature in any existing string grid. (I did not have a too close look at TSortGrid, though).

In the long term I'd prefer a more general extended gird, not one just for sorting, to prevent cluttering the component palette of lots of dedicated grids.
« Last Edit: May 18, 2018, 02:43:12 pm by wp »
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

GetMem

  • Hero Member
  • *****
  • Posts: 3018
Re: New package TSortGrid, a sortable StringGrid
« Reply #7 on: May 18, 2018, 03:18:55 pm »
@JuhaManninen
Quote
Is that needed?
No, not necessarily. It was just an idea. I did not like the "1" in the package name "sortgrid1.lpk". I feel an uncontrollable urge to delete the "1"   :)


@wp
Quote
I know I myself am guilty of some of these abuses.
I don't think it's an abuse. Many people added the laz prefix/suffix to their package name. Indylaz, LazRichView, LazSerial, LazAutoUpdate, etc..just to mention a few. Propably to distinguish between Lazarus/Delphi packages.
Quote
And how does OPM handle the case that a package such as "laz_chemtext.lp", is renamed to "chemtext.lpk"?
I have to modify the main json too. The package name and the absolute path of the package inside the zip, must stay the same. It wouldn't be to hard to make the necessary adjustments but in my opinion it's not worth the effort. 
Quote
I am a bit in doubt whether a grid which just implements a sorting method is justified to occupy a place in the component palette. Just for sorting if would be enough to put the Compare routine into a separate unit which might just be called to enable this feature in any existing string grid. (I did not have a too close look at TSortGrid, though).
In the long term I'd prefer a more general extended gird, not one just for sorting, to prevent cluttering the component palette of lots of dedicated grids.
True, but in the beginning I promised that every package will be accepted(http://forum.lazarus.freepascal.org/index.php/topic,34297.msg224412.html#msg224412), and since the install is optional it wont' interfere with the component palette(unless you install it, of course).
« Last Edit: May 18, 2018, 03:37:07 pm by GetMem »

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3365
  • I like bugs.
Re: New package TSortGrid, a sortable StringGrid
« Reply #8 on: May 18, 2018, 05:18:20 pm »
I checked the actual code.
I am a bit in doubt whether a grid which just implements a sorting method is justified to occupy a place in the component palette. Just for sorting if would be enough to put the Compare routine into a separate unit which might just be called to enable this feature in any existing string grid. (I did not have a too close look at TSortGrid, though).
DoCompareCells is an overridden method. It requires an inherited class.
Otherwise the code is not very clever. It is slower than it should be. There is no handling of error situations. With mixed valid / invalid data it will give unexpected results.

function SortStringGridByColumn has:
Code: Pascal  [Select]
  1. if TryStrToFloat(s,AFloat) or TryStrToFloat(s1, AFloat1) then
  2. begin
  3.   AFloat := StrToFloatDef(s, 0) - StrToFloatDef(s1, 0);
  4.   ...
  5.  
... + similar code for StrToInt, StrToTime and StrToDateTime.
Why the conversion is done twice for every piece of data? Why the or operator between the Try...() conversions? If only one of the values is valid, the result makes no sense.
Maybe a pseudo-datatype for every column with proper error handling would be more robust and useful.
It depends on a particular use case of course.

wp

  • Hero Member
  • *****
  • Posts: 4483
Re: New package TSortGrid, a sortable StringGrid
« Reply #9 on: May 18, 2018, 07:10:26 pm »
I checked the actual code.
I am a bit in doubt whether a grid which just implements a sorting method is justified to occupy a place in the component palette. Just for sorting if would be enough to put the Compare routine into a separate unit which might just be called to enable this feature in any existing string grid. (I did not have a too close look at TSortGrid, though).
DoCompareCells is an overridden method. It requires an inherited class.
Otherwise the code is not very clever. It is slower than it should be. There is no handling of error situations. With mixed valid / invalid data it will give unexpected results.

Correct. My statement was not very precise- I meant if the compare function were available as a function to be called by the OnCompareCells event of the grid then it could be applied without installing anything. Something like this:

Code: Pascal  [Select]
  1. function GeneralCompareValues(s1, s2: String): Integer;
  2. var
  3.   float1, float2: Double;
  4.   int1, int2: Integer;
  5.   dt1, dt2: TDateTime;
  6.   t1, t2: TTime;
  7. begin
  8.   if (s1 = '') and (s2 = '') then
  9.     Result := 0
  10.   else
  11.   if (s1 = '') then
  12.     Result := +1
  13.   else
  14.   if (s2 = '') then
  15.     Result := -1
  16.   else begin
  17.     if TryStrToFloat(s1, float1) and TryStrToFloat(s2, float2) then
  18.       Result := CompareValue(float1, float2)
  19.     else
  20.     if TryStrToInt(s1, int1) and TryStrToInt(s2, int2) then
  21.       Result := CompareValue(int1, int2)
  22.     else
  23.     if TryStrToDateTime(s1, dt1) and TryStrToDateTime(s2, dt2) then
  24.       Result := CompareValue(dt1, dt2)
  25.     else
  26.     if TryStrToTime(s1, t1) and TryStrToTime(s2, t2) then
  27.       Result := CompareValue(t1, t2)
  28.     else
  29.       Result := CompareStr(s1, s2);
  30.   end;
  31. end;
  32.  
  33. { TForm1 }
  34.  
  35. procedure TForm1.StringGrid1CompareCells(Sender: TObject; ACol, ARow, BCol,
  36.   BRow: Integer; var Result: integer);
  37. var
  38.   s1, s2: String;
  39. begin
  40.   s1 := TStringGrid(Sender).Cells[ACol, ARow];
  41.   s2 := TStringGrid(Sender).Cells[BCol, BRow];
  42.   Result := GeneralCompareValues(s1, s2);
  43.   if TStringGrid(Sender).SortOrder = soDescending then Result := -Result;
  44. end;

In fact, using the approprate Compare functions available at several places within the LCL, the entire project becomes very short, and I wonder if this really justifies its own component.
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

John Landmesser

  • New member
  • *
  • Posts: 21
Re: New package TSortGrid, a sortable StringGrid
« Reply #10 on: May 18, 2018, 07:47:40 pm »
@wp

you are right!
I first used my poor code as a function call  in OnCompareCells.

But as i'm lazy: why not include that in my first(!) self developed component!

Sideeffect: TStringGrid does not show up- and down-arrow until you set
Code: Pascal  [Select]
  1. Columns[x].Title.ImageIndex:=1;

I tried in vain to change that ImagIndex:=1 in grids.pas

constructor TGridColumnTitle.Create(TheColumn: TGridColumn);
begin
  inherited Create;
  FColumn := TheColumn;
  FIsDefaultTitleFont := True;
  FFont := TFont.Create;
  FillTitleDefaultFont;
  FFont.OnChange := @FontChanged;
  FImageIndex := -1;
  FImageLayout := blGlyphRight;
  FIsDefaultCaption := true;
end;


so i gave up and was happy with this TSortGrid.


wp

  • Hero Member
  • *****
  • Posts: 4483
Re: New package TSortGrid, a sortable StringGrid
« Reply #11 on: May 18, 2018, 11:12:57 pm »
No need to fiddle around with auxiliary columns any more: I just fixed your bug report and added a new option goShowSortArrows to trunk. Add this to the grid's Options2 to see the sort arrows in the header even if no columns are defined.

I am not yet sure about the correct default value: To keep the behavior of grids with columns the option should be added by default, but this would force the symbol "goShowSortArrow" into the lfm file, and this would make an error if a form edited by Laz trunk is loaded into Laz 1.8.x


No - I had to undo the commit, I messed it up.
« Last Edit: May 19, 2018, 01:01:18 am by wp »
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

John Landmesser

  • New member
  • *
  • Posts: 21
Re: New package TSortGrid, a sortable StringGrid
« Reply #12 on: May 19, 2018, 10:23:23 am »
ok, i'll wait until it's done and keep my

Code: Pascal  [Select]
  1. Columns[x].Title.ImageIndex:=1;

"Columns" seems to be a restricted word for this forum software?!!

wp

  • Hero Member
  • *****
  • Posts: 4483
Re: New package TSortGrid, a sortable StringGrid
« Reply #13 on: May 19, 2018, 12:26:36 pm »
I gave it another try, did not see any regression so far. Please try the current trunk revision (no additional option required ATM).
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus