Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2014-11

Having more than 32 elements in a set (TGridOptions of TCustomGrid)

16 messages · 11 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Werner Pamler

For fpspreadsheet I would like to implement the feature of Excel or Libre/OpenOffice that multiple cell ranges can be selected. The grid component in this package, TsSpreadsheetGrid, currently can select only a single range (if goRangeSelect is in the grid's Options) due to its inheritance from TCustomGrid.

My idea is to add a new "goMultiSelect" option to TCustomGrid directly since this might be an interesting feature for other applications as well, and then to write additional code to store multiple range rectangles. It shouldn't be too difficult, but I am failing already at the very first step: adding the new option to the type TGridOption. This is the new declaration:

type
TGridOption = (
goFixedVertLine, // Ya
goFixedHorzLine, // Ya
goVertLine, // Ya
goHorzLine, // Ya
goRangeSelect, // Ya
goDrawFocusSelected, // Ya
goRowSizing, // Ya
goColSizing, // Ya
goRowMoving, // Ya
goColMoving, // Ya
goEditing, // Ya
goAutoAddRows, // JuMa
goTabs, // Ya
goRowSelect, // Ya
goAlwaysShowEditor, // Ya
goThumbTracking, // ya

     // Additional Options
     goColSpanning,        // Enable cellextent calcs
     goRelaxedRowSelect,   // User can see focused cell on goRowSelect
     goDblClickAutoSize,   // dblclicking columns borders (on hdrs)

resize col.
goSmoothScroll, // Switch scrolling mode (pixel scroll is by default)
goFixedRowNumbering, // Ya
goScrollKeepVisible, // keeps focused cell visible while scrolling goHeaderHotTracking, // Header cells change look when mouse is over them
goHeaderPushedLook, // Header cells looks pushed when clicked goSelectionActive, // Setting grid.Selection moves also cell cursor goFixedColSizing, // Allow to resize fixed columns goDontScrollPartCell, // clicking partially visible cells will not scroll
goCellHints, // show individual cell hints goTruncCellHints, // show cell hints if cell text is too long goCellEllipsis, // show "..." if cell text is too long goAutoAddRowsSkipContentCheck,//BB Also add a row (if AutoAddRows in Options) if last row is empty
goRowHighlight, // Highlight the current Row goMultiSelect // Enable selection of multiple ranges <<<< NEW

   );
   TGridOptions = set of TGridOption;

Recompiling the package LCLBase fails with the error: "Property can't have a default value". I think this message is misleading and confusing because the true issue seems to me that the set of TGridOptions now contains 33 elements. In my understanding, the elements of a set correspond to the bits of an integer. In a 32-bit OS, therefore, a set can only contain 32 elements - there is one too many now...

Is this interpretation correct?

OK, here I could circumvent this issue by introducing a new boolean property "MultiSelect" which is evaluated when goRangeSelect is active. Maybe this is even better than the goMultiSelect option because it bypasses the conflict with goRangeSelect.

But what if I would not have this possibility? Is there a way to extend the set to more than 32 elements? If not, split the Options into groups of options like VirtualTreeView does? I fear the options of the grid components will require a major redsign soon.

leledumbo
to Werner Pamler
Show quoted text 5 lines
In my understanding, the elements of a set correspond to the bits of an integer. In a 32-bit OS, therefore, a set can only contain 32 elements - there is one too many now... Is this interpretation correct?

http://www.freepascal.org/docs-html/prog/progsu163.html#x207-2200008.2.8

Michael Van Canneyt
to Werner Pamler: For fpspreadsheet I would like to implement the feature of Excel or Libre/OpenOffice that…
Werner Pamler wrote 15 lines
For fpspreadsheet I would like to implement the feature of Excel or Libre/OpenOffice that multiple cell ranges can be selected. The grid component in this package, TsSpreadsheetGrid, currently can select only a single range (if goRangeSelect is in the grid's Options) due to its inheritance from TCustomGrid. > Recompiling the package LCLBase fails with the error: "Property can't have a default value". I think this message is misleading and confusing because the true issue seems to me that the set of TGridOptions now contains 33 elements. In my understanding, the elements of a set correspond to the bits of an integer. In a 32-bit OS, therefore, a set can only contain 32 elements - there is one too many now... Is this interpretation correct?

Yes.

Show quoted text 10 lines
OK, here I could circumvent this issue by introducing a new boolean property "MultiSelect" which is evaluated when goRangeSelect is active. Maybe this is even better than the goMultiSelect option because it bypasses the conflict with goRangeSelect. But what if I would not have this possibility? Is there a way to extend the set to more than 32 elements? If not, split the Options into groups of options like VirtualTreeView does? I fear the options of the grid components will require a major redsign soon.

The 32-bit limit cannot be circumvented easily.
It would require a major redesign of streaming and rtti. Your fastest path is splitting the options.

Michael.

Bart
to Werner Pamler: For fpspreadsheet I would like to implement the feature of Excel or Libre/OpenOffice that…
Werner Pamler wrote 8 lines
Recompiling the package LCLBase fails with the error: "Property can't have a default value". I think this message is misleading and confusing because the true issue seems to me that the set of TGridOptions now contains 33 elements. In my understanding, the elements of a set correspond to the bits of an integer. In a 32-bit OS, therefore, a set can only contain 32 elements - there is one too many now... Is this interpretation correct?

I think it's not.

Default values must be of ordinal, pointer or small set type (Delphi) (See: http://docwiki.embarcadero.com/RADStudio/XE7/en/E2146_Default_values_must_be_of_ordinal,_pointer_or_small_set_type_%28Delphi%29)

After you added the 33-rd option now SizeOf(TGridOptions) = 32 bytes. Every option is stored as a bit, so you can have 256 (=32*8) options (I think).

Bart

Rik van Kekem
to Werner Pamler: For fpspreadsheet I would like to implement the feature of Excel or Libre/OpenOffice that…

So it's not that the set can't hold more than 32 items... It's just you can't use *default* for a property if the set's base has more than 32 values.

This is from the Delphi manual (but I'm sure it also applies to FPC): <quote>
The default and nodefault directives are supported only for ordinal types and for set types, *provided the upper and lower bounds of the set's base type have ordinal values between 0 and 31;* </quote>
Source: http://docwiki.embarcadero.com/RADStudio/XE6/en/Properties

So the error message is not misleading at all ;)
<quote>
Error: Property can?t have a default value
Set properties or indexed properties cannot have a default value. </quote>

Maybe you can skip the default command for property and set the default in Create. (Will that work correctly?)

Werner Pamler wrote 8 lines
Recompiling the package LCLBase fails with the error: "Property can't have a default value". I think this message is misleading and confusing because the true issue seems to me that the set of TGridOptions now contains 33 elements. In my understanding, the elements of a set correspond to the bits of an integer. In a 32-bit OS, therefore, a set can only contain 32 elements - there is one too many now... Is this interpretation correct?
Werner Pamler

Thanks to all. What I learn from the answers is that a set *can* contain more than 32 elements, but exceeding this number would break existing forms. And the option of not specifying a default value would break existing forms as well because their non-stored defaults would not be there any more.

Anyway, I know a solution for my problem: Introduce an additional property "RangeSelectMode=(rsmSingleRange, rsmMultiRange)" which allows to fine-tune the behavior of the goRangeSelect option of the grid. I'll post a corresponding patch maybe later today or tomorrow.

The next guy wanting to add a new option to TGridOptions, however, will face that same issue again. Maybe new options will have to be split off into a new OptionsEx property.

Mattias Gaertner
to Werner Pamler
[...] The next guy wanting to add a new option to TGridOptions, however, will face that same issue again. Maybe new options will have to be split off into a new OptionsEx property.

You can name it Options2 like TSynEdit.

Mattias

Frederic Da Vitoria
to Rik van Kekem: So it's not that the set can't hold more than 32 items... It's just you can't use…

2014-11-05 18:35 GMT+01:00 Rik van Kekem :

Show quoted text 18 lines
So it's not that the set can't hold more than 32 items... It's just you can't use *default* for a property if the set's base has more than 32 values. This is from the Delphi manual (but I'm sure it also applies to FPC): <quote> The default and nodefault directives are supported only for ordinal types and for set types, *provided the upper and lower bounds of the set's base type have ordinal values between 0 and 31;* </quote> Source: http://docwiki.embarcadero.com/RADStudio/XE6/en/Properties So the error message is not misleading at all ;) <quote> Error: Property can?t have a default value Set properties or indexed properties cannot have a default value. </quote>

This may be me misunderstanding English, but I feel that it is misleading: To me, "Set properties cannot have a default value" means that even a set with 2 elements could not have a default value.

Frederic Da Vitoria (davitof) Membre de l'April - ? promouvoir et d?fendre le logiciel libre ? - http://www.april.org -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20141105/1a62e965/attachment.html>
Rik van Kekem
to Frederic Da Vitoria
Frederic Da Vitoria wrote 11 lines
So the error message is not misleading at all ;) <quote> Error: Property can?t have a default value Set properties or indexed properties cannot have a default value. </quote> This may be me misunderstanding English, but I feel that it is misleading: To me, "Set properties cannot have a default value" means that even a set with 2 elements could not have a default value.

You are absolutely correct. But it does point in the right direction (unlike Werner expected) ;) However expanding the error-message to include the text that it only applies to sets with base types with more than 32 values would make it not fit on screen. But the help-page for the message could be expanded to include this text. (I got it from http://www.freepascal.org/docs-html/user/userse62.html)

So it should be something like this (with my limited English): *Error: Property can?t have a default value*
Set properties or indexed properties cannot have a default value if the upper and lower bounds of the set's base type have ordinal values between 0 and 31.

This message also comes when you right-click the error and choose help. So it could be clarified there too.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20141105/f7429d52/attachment.html>

Howard Page-Clark
to Rik van Kekem
Rik van Kekem wrote 5 lines
So it should be something like this (with my limited English): *Error: Property can't have a default value* Set properties or indexed properties cannot have a default value if the upper and lower bounds of the set's base type have ordinal values between 0 and 31.

I think you meant:
"... cannot have a default value if the upper or lower bounds of the set's (or array's) base type have ordinal values *outside* the range 0..31."

Howard
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20141105/4c9586bf/attachment.html>

Rik van Kekem
to Howard Page-Clark
Howard Page-Clark wrote
I think you meant: "... cannot have a default value if the upper or lower bounds of the set's (or array's) base type have ordinal values *outside* the range 0..31."

Yep.... That would be better ;) (That's what you get when you try to merge two opposite English sentences together.)
(From http://docwiki.embarcadero.com/RADStudio/XE6/en/Properties and http://www.freepascal.org/docs-html/user/userse62.html)

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20141105/ec0b695e/attachment.html>

Flávio Etrusco
to Bart: I think it's not. Default values must be of ordinal, pointer or small set type (Delphi)…
Bart wrote 12 lines
On 11/5/14, Werner Pamler wrote: > Recompiling the package LCLBase fails with the error: "Property can't > have a default value". I think this message is misleading and confusing > because the true issue seems to me that the set of TGridOptions now > contains 33 elements. In my understanding, the elements of a set > correspond to the bits of an integer. In a 32-bit OS, therefore, a set > can only contain 32 elements - there is one too many now... > > Is this interpretation correct? I think it's not.

AFAICS it is.

Show quoted text 5 lines
Default values must be of ordinal, pointer or small set type (Delphi) (See: http://docwiki.embarcadero.com/RADStudio/XE7/en/E2146_Default_values_must_be_of_ordinal,_pointer_or_small_set_type_%28Delphi%29) After you added the 33-rd option now SizeOf(TGridOptions) = 32 bytes. Every option is stored as a bit, so you can have 256 (=32*8) options (I think).

No, SizeOf(TGridOptions) = 4 (bytes) = 32 bits = 32 options.

Best regards,
Fl?vio

leledumbo
to Rik van Kekem: Yep.... That would be better ;) (That's what you get when you try to merge two opposite…

Rik van Kekem wrote

Show quoted text 18 lines
On 05-11-2014 20:11, Howard Page-Clark wrote: > I think you meant: > "... cannot have a default value if the upper or lower bounds of the > set's (or array's) base type have ordinal values *outside* the range > 0..31." Yep.... That would be better ;) (That's what you get when you try to merge two opposite English sentences together.) (From http://docwiki.embarcadero.com/RADStudio/XE6/en/Properties and http://www.freepascal.org/docs-html/user/userse62.html) -- _______________________________________________ Lazarus mailing list Lazarus at .freepascal http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

Anybody wants to file an error message enhancement to the bugtracker?

Sven Barth
to Flávio Etrusco: AFAICS it is. No, SizeOf(TGridOptions) = 4 (bytes) = 32 bits = 32 options. Fl?vio
Fl?vio Etrusco wrote 7 lines
> Default values must be of ordinal, pointer or small set type (Delphi) > (See: http://docwiki.embarcadero.com/RADStudio/XE7/en/E2146_Default_values_must_be_of_ordinal,_pointer_or_small_set_type_%28Delphi%29) > > After you added the 33-rd option now SizeOf(TGridOptions) = 32 bytes. > Every option is stored as a bit, so you can have 256 (=32*8) options (I think). No, SizeOf(TGridOptions) = 4 (bytes) = 32 bits = 32 options.

If a 33rd option is added he's right:

=== code begin ===

program tsettest;

type
TTest = (
t1,
t2,
t3,
t4,
t5,
t6,
t7,
t8,
t9,
t10,
t11,
t12,
t13,
t14,
t15,
t16,
t17,
t18,
t19,
t20,
t21,
t22,
t23,
t24,
t25,
t26,
t27,
t28,
t29,
t30,
t31,
t32,
t33

   );
   TTests = set of TTest;
var
   t: TTests;
begin
   Writeln(SizeOf(t));
end.

=== code end ===

=== output begin ===

% ./tsettest
32

=== output end ===

Regards,
Sven

Flávio Etrusco
to Sven Barth
Sven Barth wrote 76 lines
On 06.11.2014 04:43, Fl?vio Etrusco wrote: >> >> Default values must be of ordinal, pointer or small set type (Delphi) >> (See: >> http://docwiki.embarcadero.com/RADStudio/XE7/en/E2146_Default_values_must_be_of_ordinal,_pointer_or_small_set_type_%28Delphi%29) >> >> After you added the 33-rd option now SizeOf(TGridOptions) = 32 bytes. >> Every option is stored as a bit, so you can have 256 (=32*8) options (I >> think). > > > No, SizeOf(TGridOptions) = 4 (bytes) = 32 bits = 32 options. If a 33rd option is added he's right: === code begin === program tsettest; type TTest = ( t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22, t23, t24, t25, t26, t27, t28, t29, t30, t31, t32, t33 ); TTests = set of TTest; var t: TTests; begin Writeln(SizeOf(t)); end. === code end === === output begin === % ./tsettest 32 === output end === Regards, Sven

Oh, OK, I misread the message. He was not implying the streaming would allow that :-$
Sorry.

-Fl?vio

taazz
to Werner Pamler: Thanks to all. What I learn from the answers is that a set *can* contain more than 32…
Werner Pamler wrote 5 lines
Thanks to all. What I learn from the answers is that a set *can* contain more than 32 elements, but exceeding this number would break existing forms. And the option of not specifying a default value would break existing forms as well because their non-stored defaults would not be there any more.

*Wrong *the default values are not stored because there is no need to store them being there would effectively have no value what so ever. Keep in mind that the default specifier in a property is there to inform the streaming mechanism for the default value *_and only to inform_* You are required to make sure that the property is initialized to that value in the constructor of the class otherwise you will have problems mostly with expecting one behavior and getting an other.

Anyway, I know a solution for my problem:

You only have an assumed problem not a real one try it for your self.

Show quoted text 9 lines
Introduce an additional property "RangeSelectMode=(rsmSingleRange, rsmMultiRange)" which allows to fine-tune the behavior of the goRangeSelect option of the grid. I'll post a corresponding patch maybe later today or tomorrow. The next guy wanting to add a new option to TGridOptions, however, will face that same issue again. Maybe new options will have to be split off into a new OptionsEx property.

There are reasons to do that mostly it has to do with support of external specifications like COM/ActiveX but there is no reason for the internal stuff (yet anyway) not until you have more than 255 values.