Recent

Author Topic: Sortable StringGrid example  (Read 12847 times)

John Landmesser

  • New Member
  • *
  • Posts: 31
Sortable StringGrid example
« on: April 26, 2017, 04:06:13 pm »
Hi,

because i didn't find a StringGrid that sorts Integer, Float, Date, Time , DateTime, string as expected i developed JStringGrid.

See attached example project.

You need jstringgrid.pas and jstringgrid_icon.lrs in your own package, but you can test attached project without installing TJStringGrid.

Hope thats usefull for someone else :-)
« Last Edit: April 26, 2017, 05:06:37 pm by John Landmesser »

Graeme

  • Hero Member
  • *****
  • Posts: 1428
    • Graeme on the web
Re: Sortable StringGrid example
« Reply #1 on: April 26, 2017, 05:14:04 pm »
You could have just Googled it. In fact I did so just a few days ago, and found many Delphi examples on how to sort a StringGrid even with different data types.
--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

kapibara

  • Hero Member
  • *****
  • Posts: 610
Re: Sortable StringGrid example
« Reply #2 on: April 26, 2017, 08:38:40 pm »
This is useful. Thank you.

Hope thats usefull for someone else :-)
Lazarus trunk / fpc 3.2.2 / Kubuntu 22.04 - 64 bit

wp

  • Hero Member
  • *****
  • Posts: 11830
Re: Sortable StringGrid example
« Reply #3 on: April 26, 2017, 09:56:14 pm »
because i didn't find a StringGrid that sorts Integer, Float, Date, Time , DateTime, string as expected i developed JStringGrid.
All these sorting jobs can be done with the standard TStringGrid. It even paints the sort icons in the column headers. The only thing I don't like is that the icons cannot be changed (and that the arrow points in the wrong direction, in my opinion).

Try the attached demo.

A remark on your code:
You should not call AnsiCompareStr in your sorting routine to compare strings. This is old Delphi, Lazarus uses UTF8 strings. Utf8CompareStr is the correct function.


valdir.marcos

  • Hero Member
  • *****
  • Posts: 1106
Re: Sortable StringGrid example
« Reply #4 on: April 27, 2017, 04:17:25 am »
because i didn't find a StringGrid that sorts Integer, Float, Date, Time , DateTime, string as expected i developed JStringGrid.

You could have just Googled it. In fact I did so just a few days ago, and found many Delphi examples on how to sort a StringGrid even with different data types.

This is useful. Thank you.

All these sorting jobs can be done with the standard TStringGrid. It even paints the sort icons in the column headers. The only thing I don't like is that the icons cannot be changed (and that the arrow points in the wrong direction, in my opinion).

A remark on your code:
You should not call AnsiCompareStr in your sorting routine to compare strings. This is old Delphi, Lazarus uses UTF8 strings. Utf8CompareStr is the correct function.

Since developers may need it and you have already done it, can't your work patch and improve official Lazarus TStringGrid?
Can't this sorting thing already be available in official Lazarus TStringGrid as component's methods?
« Last Edit: April 27, 2017, 04:20:48 am by valdir.marcos »

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4458
  • I like bugs.
Re: Sortable StringGrid example
« Reply #5 on: April 27, 2017, 09:17:59 am »
You should not call AnsiCompareStr in your sorting routine to compare strings. This is old Delphi, Lazarus uses UTF8 strings. Utf8CompareStr is the correct function.
No, AnsiCompareStr is perfectly OK with our "better" Unicode support. See:
 http://wiki.freepascal.org/Better_Unicode_Support_in_Lazarus#RTL_Ansi....28.29_Unicode_functions
This is also 100% compatible with Delphi at source code level which is nice and important.

See procedure InitLazUtf8 in file winlazutf8.inc in package LazUtils.
Among other callback functions it sets:
Code: Pascal  [Select][+][-]
  1. widestringmanager.CompareStrAnsiStringProc:=@UTF8CompareStr;

Just to repeat: Code dealing with Unicode strings can be compatible with Delphi at source code level despite their different encodings.
It can be compatible even if you must deal with individual codepoints, by using unit LazUnicode.
Such code is also compatible with a possible future UTF-16 solution provided by Lazarus.
Only Windows system codepages impose a problem and must be converted explicitly, but fortunately they are used less and less.
« Last Edit: April 27, 2017, 09:31:39 am by JuhaManninen »
Mostly Lazarus trunk and FPC 3.2 on Manjaro Linux 64-bit.

John Landmesser

  • New Member
  • *
  • Posts: 31
Re: Sortable StringGrid example
« Reply #6 on: April 27, 2017, 09:23:25 am »
to wp:

thanks for  your example app. Just learnt to use property columns -> wrong(!!) arrow appears, but thats better than my hassle with Column Header icon!!

It's a pleasure to read your code ... i still have to learn much :-)

As poster mentioned allready: please deliver a patch to standard lazarus TStringGrid, so anybody has a working sort-feature in Lazarus TStringGrid ( or is that freepascal?)

Quote
A remark on your code:
You should not call AnsiCompareStr in your sorting routine to compare strings. This is old Delphi, Lazarus uses UTF8 strings. Utf8CompareStr is the correct function.

... will do!

... and thanks for Lazarus Mailing List Reader !
« Last Edit: April 27, 2017, 09:36:57 am by JuhaManninen »

wp

  • Hero Member
  • *****
  • Posts: 11830
Re: Sortable StringGrid example
« Reply #7 on: April 27, 2017, 09:31:29 am »
Since developers may need it and you have already done it, can't your work patch and improve official Lazarus TStringGrid?
Can't this sorting thing already be available in official Lazarus TStringGrid as component's methods?
No. A StringGrid is a grid for strings, not for numbers or dates. Why should a standard developer using a grid for strings pack all the unused code of rare use cases into his application? That's why events like OnCompareCells are here: to extend the behavior of the standard component.

If you need a sortable grid which has built-in support for sorting different data types you go the right way: derive your own grid from TCustomStringGrid. If was just responding to your opinion that you did not find a way how to sort a StringGrid for floats or dates.

BTW: If you allow different data types to be stored in a string grid you must be aware of data loss. Because this grid only stores strings you lose accuracy if you store numbers rounded to a few decimals only. You should try TsWorksheetGrid from the fpspreadsheet package which stores data as a TCell record retaining the full precision of numeric values.

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4458
  • I like bugs.
Re: Sortable StringGrid example
« Reply #8 on: April 27, 2017, 09:41:52 am »
Quote
A remark on your code:
You should not call AnsiCompareStr in your sorting routine to compare strings. This is old Delphi, Lazarus uses UTF8 strings. Utf8CompareStr is the correct function.
... will do!
Don't.
Actually the Ansi...() string functions are not only old Delphi, they are also new Delphi and used for Unicode.
In old Delphi they were used for Ansi system codepages.
Yes, the name is confusing but they are now the "standard" way to deal with Unicode in both Delphi and Lazarus.
« Last Edit: April 27, 2017, 10:31:58 am by JuhaManninen »
Mostly Lazarus trunk and FPC 3.2 on Manjaro Linux 64-bit.

wp

  • Hero Member
  • *****
  • Posts: 11830
Re: Sortable StringGrid example
« Reply #9 on: April 27, 2017, 09:51:23 am »
Really VERY confusing! I'd understand if a function CompareStr would change its behavior according to the type of string, but I'll never understand why a function named AnsiCompareStr should work for UTF16 strings! What should a developer do who wants to sort real AnsiStrings?

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4458
  • I like bugs.
Re: Sortable StringGrid example
« Reply #10 on: April 27, 2017, 10:29:46 am »
Really VERY confusing! I'd understand if a function CompareStr would change its behavior according to the type of string, but I'll never understand why a function named AnsiCompareStr should work for UTF16 strings!
Yes it is confusing. :)
The most logical thing would be to have overloaded functions without Ansi-prefix for Unicode and for other string types.
However the functions without Ansi... are reserved for dummy ASCII compatible compare without locale or sorting info.
See:
 http://docwiki.embarcadero.com/Libraries/Berlin/en/System.SysUtils.CompareStr
 http://docwiki.embarcadero.com/Libraries/Berlin/en/System.SysUtils.AnsiCompareStr
It is a historical remain I guess.

What should a developer do who wants to sort real AnsiStrings?
IIRC Delphi has overloads of AnsiCompareStr() for AnsiString and UnicodeString. Both take the locale info + its sorting rules into account.
Remember, AnsiString in Delphi uses the Windows system codepage.
Lazarus + its Unicode support now does not support "real AnsiString", meaning the Windows system codepage. You must convert such data and use Unicode.
After that AnsiCompareStr() works like magic and is Delphi compatible when using "String" type.

BTW, I was reading about the new Delphi compiler for Linux. They had made big changes for string types. Parts of it did not look very "Delphi compatible". I don't remember the details now but our UTF-8 everywhere solution looked more compatible.
« Last Edit: April 27, 2017, 10:37:23 am by JuhaManninen »
Mostly Lazarus trunk and FPC 3.2 on Manjaro Linux 64-bit.

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4458
  • I like bugs.
Re: Sortable StringGrid example
« Reply #11 on: April 27, 2017, 10:58:30 am »
All these sorting jobs can be done with the standard TStringGrid. It even paints the sort icons in the column headers. The only thing I don't like is that the icons cannot be changed (and that the arrow points in the wrong direction, in my opinion).
I added the default icons a long time ago, maybe at 2010. I just rotated some existing icon 90 degrees. Please feel free to change them.
Actually the icons can be changed by providing them externally. I don't remember details any more but it was a laborous process, yet it was the only way to get those icons before I added the default ones.
Supporting sort without icons is confusing, thus it is good to have some default.
Mostly Lazarus trunk and FPC 3.2 on Manjaro Linux 64-bit.

wp

  • Hero Member
  • *****
  • Posts: 11830
Re: Sortable StringGrid example
« Reply #12 on: April 27, 2017, 11:49:37 am »
All these sorting jobs can be done with the standard TStringGrid. It even paints the sort icons in the column headers. The only thing I don't like is that the icons cannot be changed (and that the arrow points in the wrong direction, in my opinion).
I added the default icons a long time ago, maybe at 2010. I just rotated some existing icon 90 degrees. Please feel free to change them.
Actually the icons can be changed by providing them externally. I don't remember details any more but it was a laborous process, yet it was the only way to get those icons before I added the default ones.
Supporting sort without icons is confusing, thus it is good to have some default.
Yes, sortasc.png points down, and sortdesc.png points up. I interchanged them in r54753/4.
« Last Edit: April 27, 2017, 12:16:39 pm by wp »

wp

  • Hero Member
  • *****
  • Posts: 11830
Re: Sortable StringGrid example
« Reply #13 on: April 27, 2017, 12:21:37 pm »
Actually the icons can be changed by providing them externally. I don't remember details any more but it was a laborous process, yet it was the only way to get those icons before I added the default ones.
There is a TitleImageList. How about adding properties SortAscImageIndex and SortDescImageIndex? If they are not set the builtin icon should be used from the res file.

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4458
  • I like bugs.
Re: Sortable StringGrid example
« Reply #14 on: April 27, 2017, 12:35:05 pm »
There is a TitleImageList. How about adding properties SortAscImageIndex and SortDescImageIndex? If they are not set the builtin icon should be used from the res file.
Sounds good.
Mostly Lazarus trunk and FPC 3.2 on Manjaro Linux 64-bit.

 

TinyPortal © 2005-2018