For Pritpal: in Browse columns values are different alignned due monospaced and proportional fonts

92 views
Skip to first unread message

Zoran Sibinovic

unread,
Mar 16, 2023, 7:01:06 AM3/16/23
to QtContribs
Hi to all,
in the attachment, there are 2 different browse behaviour due to the usage of monospaced and proportional fonts.

in the creation of the browse object was definded:

in aaUntitled.png , the usage of the "Arial Regular" font
in bbUntitled.png , the usage of the "Courier New" 

As it can be seen, the columns alignment, by using proportional fonts are different from the expected behaviour: the dates are aligned to left instead to center and the numeric values are aligned to center instead to right. The character columns are ok.

When entering the cells, to edit them, the alignment is ok for every value type.

Have someone some workaround to resolve that? Thanks

Regards
Zoran
bbUntitled.png
aaUntitled.png

Pritpal Bedi

unread,
Mar 17, 2023, 5:47:51 PM3/17/23
to QtContribs
Hi Zoran

Non-monospaced font must not be used in HbQtBrowser. Behavior is undetermined as character widths etc can not be calculated and than applied to controls. Width of the browser columns is calculated per fixed pitch. When you edit, font is changed to Courier New.

Pritpal Bedi
a student of software analysis & concepts'

Zoran Sibinovic

unread,
Mar 18, 2023, 2:21:41 PM3/18/23
to QtContribs
Hi Pritpal,
Thank you for the answer.
You confirm the behaviour that cannot be changed, since the columns width is calculated on width of the "A" letter, but is interesting that the usage of non-monospaced fonts has an unusual effect also to their alignment. The interesting fact, is that, apart the columns width, the dates are alignet to the left and the numbers at the center of the column. The character are ok, aligned to the left.

Regards     
Zoran

Zoran Sibinovic

unread,
Mar 18, 2023, 2:24:27 PM3/18/23
to QtContribs
... i forgot, the alignment effect is just on the showed data and not and not when we start edit process when we enter in the field to enter data.

Francesco Perillo

unread,
Mar 20, 2023, 5:38:22 AM3/20/23
to qtcon...@googlegroups.com
On Thu, Mar 16, 2023 at 11:39 AM Zoran Sibinovic <zoran.s...@gmail.com> wrote:

Have someone some workaround to resolve that? Thanks


Here you are using HbQtBrowse, a really big class that want to mimick a dbedit() and also add some other stuff. HbQtBrowse uses QTableView, so it uses a QModel and this model is queried for various stuff, from the text to be shown, the color AND text alignment.

From browdb.prg source, columns are defined this way.

   oColumn            := HbQtColumnNew( "Last Name"  , {|| TEST->last     } )
   oColumn:colorBlock := {|| iif( SubStr( TEST->first,1,1 ) $ "ANLH", { 6,2 }, { 1,2 } ) }
   oBrowse:addColumn( oColumn )


and HbQtColumn object stores a alignment value ! It is calulated and can't be overriden at the moment:

   ::dAlignment := iif( ::valtype == "N", Qt_AlignRight, iif( ::valtype $ "DL", Qt_AlignHCenter, Qt_AlignLeft ) )
   ::dAlignment += Qt_AlignVCenter



When QTableView needs to print a cell, it asks the model several stuff, including the alignment, and it is handled in fetchColumnInfo
      CASE Qt_TextAlignmentRole
         RETURN ::columns[ nCol ]:dAlignment

This behaviour is confirmed by the screenshots with mono fonts.

The width of a cell is calculated by using the width of a mono font, but this is only for the width.

So, my idea, is that your code, somehow, rewrites ::dAlignment member of a column object.


Zoran Sibinovic

unread,
Mar 20, 2023, 6:19:03 AM3/20/23
to QtContribs
Hi Francesco,

In the meantime I found something else ...
I noticed that if I keep using the monospaced fonts and define it at the moment of the browse creation with something like this:
oBrowse := MyHbQtBrowseNew( 10, 10, oDlg:height()-40, oDlg:width()-10, oDlg:frameBrowse, QFont( "Courier New", 10 ) )
everithing is fine, then I wanted to changed the font size ex to 15 ... the displayed values reflects that size but, when I enter in the edit mode the characters are small, in other words remain at 10 of the size.
So, I fount that If I add in the 

 METHOD HbQtBrowse:editCell( cPicture, cColor, bWhen, bValid, nKey )
in the QREAD PARENT oDlg LASTGETBLOCK {|| oDlg:done( 1 ) } NOFOCUSFRAME FONT ::oFont 

when entering in the edit mode all the values are displayed also in the size of 15.

In this case the question is for Pritpal: "It is ok to add this piece of code and, eventually in all the QREAD instances of hbqtbrowse.prg?"

Francesco,  about the alignment, I also found that the alignment is ported in this part of code and I tried using the Arial Regular, size10
 
   CASE Qt_TextAlignmentRole
         RETURN ::columns[ nCol ]:dAlignment

I then in this moment tried this

      CASE Qt_TextAlignmentRole
          DO CASE
               CASE ::columns[ nCol ]:valtype = "C" ; RETURN Qt_AlignLeft
               CASE ::columns[ nCol ]:valtype = "N" ; RETURN Qt_AlignRight
               CASE ::columns[ nCol ]:valtype = "D" ; RETURN Qt_AlignCenter
               CASE ::columns[ nCol ]:valtype = "L" ; RETURN Qt_AlignCenter    
          ENDCASE

        RETURN Qt_AlignCenter

... Interesting, the displayed results are, but not, the same using this 2 ways. Looks that something is missing inbetween. The character field in the first variant position starts ok, in the second is moved more right but not in the center,
also the numeric field in the first variant was centerd, in the second is quietly aligned to the right, the date remains aligned to left in both variants insteda in center. 
The goal is to align the displayed values (not in the edit role)  similar as in MS Excel.
The alignment in the edit role is ok (of course the numbers in the edit cell are proportional but are edited ok)
Must dig more

Regards
Zoran

Francesco Perillo

unread,
Mar 20, 2023, 6:42:49 AM3/20/23
to qtcon...@googlegroups.com
in fetchColumnInfo try this change:
               RETURN strtran(::cellValue( nRow, nCol )," ","#")
and see if now, with "visible"spaces, the text is centered.

If it is, this means you need a alltrim( ::cellValue( nRow, nCol ))


--
You received this message because you are subscribed to the Google Groups "QtContribs" group.
To unsubscribe from this group and stop receiving emails from it, send an email to qtcontribs+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/qtcontribs/14981e64-aaf3-40d6-ae39-ceec36b70cfdn%40googlegroups.com.

Zoran Sibinovic

unread,
Mar 20, 2023, 8:24:43 AM3/20/23
to qtcon...@googlegroups.com
I tried both, but your second line shows that, no matter what the value valtype is, the alignment for all the types of data is to the left.
Ex. all the displayed numbers are aligned to the left, the date and the character fields data too. 
Seems that the values are displayed as simple text.
Looking at this, I can suppose that the alignment doesn't have any meaning (dAlignment) in the display itself but helps to retransform the value to some picture to meet the alignment effect.
Ex. I have  the number 11500.00, and defined the field cell to br N, 10, 2. While edit, it is treated  as a number, you cannot got out of the boundaries, while, on the display "somewhere" the data is transformed in text a where are added 2 spaces ahead of it to product the alignment effect, in my case the number is displayed as "  11500.00" so visually it becomes right aligned. The date is represented ex. as "  01.01.2023  " to meet the center alignment.   

Regards


_________________________________

 Zoran Sibinović
dipl.menadžer i inž.informatike i statistike
Zaječar, mob.064 18 76 338


ooUntitled.png
qqUntitled.png

Francesco Perillo

unread,
Mar 20, 2023, 10:19:27 AM3/20/23
to qtcon...@googlegroups.com
Ok Zoran,
so now we have confirmed that ::cellValue returns a string. I imagine that coming from a text-mode world, it is padded so that it overwrites the old value on screen.

cellValues return aCellValues that to be populted by readRecord that is inherited by TBrowse.... I think it is populated here

         FOR EACH aCol, cValue, aColor IN ::aColData, ::aCellValues[ nRow ], ::aCellColors[ nRow ]
            oCol := aCol[ _TBCI_COLOBJECT ]
            cValue := Eval( oCol:block )
            aColor := _CELLCOLORS( aCol, cValue, nColors )
            IF ValType( cValue ) $ "CMNDTL"
               cValue := PadR( Transform( cValue, iif( HB_ISSTRING( oCol:picture ), oCol:picture, NIL ) ), aCol[ _TBCI_CELLWIDTH ] )
            ELSE
               cValue := Space( aCol[ _TBCI_CELLWIDTH ] )
            ENDIF
         NEXT

So, it seems to me that  Eval( oCol:block ) returns the real value/type of the cell, while aCellValues aka cellValue always returns a string with the proper PICTURE applied.

I just remembered that in the other thread you wrote:
I develop myHbQtbrowse instance inherit the default hbqtbrowse.prg, why? Well, there are lot of restrictions in the native Clipper code of column and browse creation, starting from the colors you can use, the fonts, the edit in freezeed columns, allowed text lenght, alignment and rows in the header, not allowed images in the header, resizing etc.

I'm now looking at the standard HbQtBrowse so I can't know which changes you made. Probably it is time to check if the alignment values are correct, so I'd change the code to return
RETURN ::columns[ nCol ]:valtype + "-" + str(::columns[ nCol ]:dAlignment )

You won't have the real cell values but only the type and dAlignment values for that cell.
The values you see in the cells and how they are written, must match. If the values report a align right cell and it is drawn left aligned, something wrong is happening somewhere.

Zoran Sibinovic

unread,
Mar 20, 2023, 3:51:43 PM3/20/23
to QtContribs
Hi to all,

2 things ...

The first is a repetiotion.

METHOD HbQtBrowse:editCell( cPicture, cColor, bWhen, bValid, nKey )
...
QREAD PARENT oDlg LASTGETBLOCK {|| oDlg:done( 1 ) } NOFOCUSFRAME FONT ::oFont 
...

is needed to match the chosen font size at the oBrowse creation with the font siye when we edit the field.

The second is a kind of anomaly regarding the alignment of the fields in the columns.
Since we use monospaced fonts, the columns are formatted with the exact column boundaries that matches the values width so we havent the opportunity to see some side effects because everything seems ok, but

METHOD HbQtColumn:init( cHeading, bBlock )
...
::dAlignment := iif( ::valtype == "N", Qt_AlignRight, iif( ::valtype $ "DL", Qt_AlignHCenter, Qt_AlignLeft ) )
...
carry the alignment of the entire column. Maybe, but going on through the code  the dAlignment  becomes, for all the columns 1 or Qt_AlignLeft. Don't know why eithere where happends.

In other words 

METHOD MyHbQtBrowse:fetchColumnInfo( nCall, nRole, nArea, nRow, nCol )
...
      CASE Qt_TextAlignmentRole
                RETURN ::columns[ nCol ]:dAlignment
...
always returns 1

the other, on what I discussed today with Francesco,

METHOD MyHbQtBrowse:fetchColumnInfo( nCall, nRole, nArea, nRow, nCol )
...
      CASE Qt_DisplayRole
 ...
            ELSE
               RETURN ::cellValue( nRow, nCol )
...
always returns a text value filled with the spaces that replace the missing area of the field value to meet the dbase field lenght. It fills from the beginning or from the end of the data depending of the type of the value to simulate the column alignment, for a number field "      1500.00", for the character field "wertreer        ". 
Ad everything, visually, seems ok
Now ... change the monospaced font with ex "Arial regular" that is proportional and you will get displayed a mess.

The problem, from what I found, is how the roles are handled.

So I use 
METHOD MyHbQtBrowse:fetchColumnInfo( nCall, nRole, nArea, nRow, nCol )
...
      CASE Qt_TextAlignmentRole
       
     RETURN
iif( VALTYPE(Eval( ::columns[ nCol ]:block )) == "N", Qt_AlignRight, iif( VALTYPE(Eval( ::columns[ nCol ]:block )) == "L", Qt_AlignHCenter, Qt_AlignLeft ) )

// instead of    RETURN ::columns[ nCol ]:dAlignment    -  this code always returns 1 Qt_AlignLeft
...

to remind the hole display that there are more that one alignments.

With these code changes (in red) the things are almost solved. Remains to solve what happends with the dates alignment

::dAlignment := iif( ::valtype == "N", Qt_AlignRight, iif( ::valtype $ "DL", Qt_AlignHCenter, Qt_AlignLeft ) )

 IF I use the global rule for the alignment with "DL" instead of "L" in

     RETURN iif( VALTYPE(Eval( ::columns[ nCol ]:block )) == "N", Qt_AlignRight, iif( VALTYPE(Eval( ::columns[ nCol ]:block )) == "L", Qt_AlignHCenter, Qt_AlignLeft ) )

the dates are displayed in the center, but now I see that the editcell editing goes left, a little bit but goes and where ... it always goes, even we use monospaced fonts. Thi effect is due the visual feeling that everything is in center since the dates column boundaries are very near to the value and, all the dates are of a same width and the font used is monospaced.

In the attachment you can see the display with the changed code and with the use of the font Calibri, size 13

That is for now 
Thank you

Regards
Zoran
 
calibri 2.png
calibri 1.png

Francesco Perillo

unread,
Mar 20, 2023, 3:57:50 PM3/20/23
to qtcontribs
Is it possible that dAlignment is 1 because during ::init the eval returns NIL ? Or undefined?

--
You received this message because you are subscribed to the Google Groups "QtContribs" group.
To unsubscribe from this group and stop receiving emails from it, send an email to qtcontribs+...@googlegroups.com.

Zoran Sibinovic

unread,
Mar 21, 2023, 6:37:38 AM3/21/23
to QtContribs
Hi to all,

about the alignment ... if in your code you can to access to ::columns

after added the column using
 oBrw:AddColumn( HbQtColumnNew( FieldName( n ), __fieldBlock( cAlias, n ) ) )  or something similar

you can put somewhere this code
 ::columns[ n ]:dAlignment := iif( VALTYPE(Eval( ::columns[ n ]:block )) == "N", Qt_AlignRight+Qt_AlignVCenter, iif( VALTYPE(Eval( ::columns[ n ]:block )) == "DL", Qt_AlignHCenter+Qt_AlignVCenter, Qt_AlignLeft+Qt_AlignVCenter ) )

Then, the method
METHOD HbQtBrowse:fetchColumnInfo( nCall, nRole, nArea, nRow, nCol )
can remain unchanged

the ::columns[ nCol ]:valtype in the hbqtbrowse.prg seems always returns nil as far I tried to get its value through various METHOD's 

Another interesting thing. I put ALERT( "aaaaa" ) in hbqtcolumn.prg

FUNCTION HbQtColumnNew( cHeading, bBlock )
         ALERT( "aaaaa" )
   RETURN HbQtColumn():new( cHeading, bBlock )

and also in

METHOD HbQtColumn:init( cHeading, bBlock )

   ::TBColumn:init( cHeading, bBlock )

   ::valtype       := valtype( Eval( ::bBlock ) )
   ::blankVariable := iif( ::valtype == "N", 0, iif( ::valtype == "D", ctod( "" ), iif( ::valtype == "L", .f., "" ) ) )


   ::dAlignment := iif( ::valtype == "N", Qt_AlignRight, iif( ::valtype $ "DL", Qt_AlignHCenter, Qt_AlignLeft ) )
   ::dAlignment += Qt_AlignVCenter

ALERT(  ::dAlignment   ) and  to MEMOWRIT the values to an *.txt  

   RETURN Self


to get some infos. The processes in the code are evaluated but no message is showed or .txt file is written, like the app not passes through this function/init.

Regards
Zoran

Francesco Perillo

unread,
Mar 21, 2023, 10:05:15 AM3/21/23
to qtcontribs
I spent some time compiling hbqtwidgets\tests\browdb.prg.
I then canged font from Courier New to Arial and the problem is clearly shown.
So I added
   oColumn:dAlignment := Qt_AlignRight
to the "Salary" column that is now shown without problems.

Then I added some debug messages and then reconnected two dots.... ::dAlignment is always ONE... but we have
   ::dAlignment := iif( ::tipo == "N", Qt_AlignRight, iif( ::tipo $ "DL", Qt_AlignHCenter, Qt_AlignLeft ) )
   ::dAlignment += Qt_AlignVCenter
and Qt_AlignVCenter is 0x0080

So ::dAlignment is clearly not updated in ::init...

And you also confirmed that you think that HbQtColumn:INIT is never called..

AND INFACT IT IS NEVER CALLED....

Now change hbqtcolumn:init to   
METHOD new( cHeading, bBlock )


METHOD HbQtColumn:new( cHeading, bBlock )
   ::TBColumn:new( cHeading, bBlock )

And now it works !

With hbqtColumnNew you create a hbqtColumn():new()  but that new() method is from the parent object TBColumn.... !




Zoran Sibinovic

unread,
Mar 21, 2023, 1:22:39 PM3/21/23
to QtContribs
Francesco,
Thank you for the effort. I will try later what you find and also dig more.

In may previous message I also put that in all the oBrowse life using at first 

oBrw:AddColumn( HbQtColumnNew( FieldName( n ), __fieldBlock( cAlias, n ) ) ) ,

in hbqtcolumn.prg

FUNCTION HbQtColumnNew( cHeading, bBlock )
         ALERT( "aaaaa" )
   RETURN HbQtColumn():new( cHeading, bBlock )

do not pop up any window or message or some error to notify "Hi we are at this code line!". IMHO something weird happens here :).

I tried to rename the HbQtColumnNew function ... to see if the function is called from elswhere but when compiling, my app said that this is what is missing.
So, hbqtcolumn.prg is the location from where is called.

About the ::columns, the values in it are always texts. As I know every Qt creator object with some data treated this data as text. There are no numbers, dates, logical or else type of data in .ui, only texts and at the moment you retrieve this texts you transform them in the type yue expect. That is why the aligment is always to the left because all are texts.
That make sense but affects other part of the enviromnment that is not completely handled.

Regards
Zoran


Francesco Perillo

unread,
Mar 21, 2023, 1:35:29 PM3/21/23
to qtcontribs
 HbQtColumn():new( cHeading, bBlock )
Does not exist. New() is not overridden. In that line You are calling tbcolumn():new() that correctly sets ::bBlock...



--
You received this message because you are subscribed to the Google Groups "QtContribs" group.
To unsubscribe from this group and stop receiving emails from it, send an email to qtcontribs+...@googlegroups.com.

Zoran Sibinovic

unread,
Mar 21, 2023, 1:57:27 PM3/21/23
to QtContribs
Yes, indeed, just wanted another opinion
We call :new() but instead exists :init(). 
Is that why all the DATA in the class are only initializated with their INIT values and later some of them are filled, but ::dAlignment is not updated also.

Thanks, we solved 
Zoran

Pritpal Bedi

unread,
Apr 13, 2023, 6:06:39 PM4/13/23
to QtContribs
Hi 

Thanks for digging. I confirm init() method is never call or is called internally when new() is called. I need to understand the semantics of the role of init() . I believe something is changed in the classes code after I wrote this library. On those days it was tested comprehensive but now is broken.

I have fixed the code and will commit soon with some ther changes.

Thanks again.

Pritpal Bedi
a student of the software analysis and concepts

PS: colors and multi-line implementation is good. Show me some code how you did that. Will save me few hours. I did that for pur Qt TableView but HbQt is different beast.

Przemyslaw Czerpak

unread,
Apr 14, 2023, 9:38:22 AM4/14/23
to Pritpal Bedi, QtContribs
Hi Pritpal and others,

In the past out goal was Class(y) compatible Harbour object system.
Unfortunately local extensions and improvements was introducing
to public area code which was not and couldn't be Class(y) compatible
effectively blocking farther works on it. At least for me it was enough
reason to drop the code I created and look for other things.
The problem you have now is exactly one of few created by unthought
extensions.
In Class(y) the class function does not return instance of given class.
It return class object. This class object understand method new() which
creates new object which is instance of the class described by the class
object and then call method init() of this object with parameters passed
to method new().
This is valid Class(y) code:

    oClass:=myClass()
    ? oClass == myClass() // displays: .T.

    oObj1 := oClass:new( initPar1, initPar2 )
    oObj2 := oClass:new( initPar1, initPar2 )
    ? oObj2:class == myClass() // displays: .T.
    oObj3 := oObj2:class:new( initPar1, initPar2 )

This [x]Harbour "extensions" blocked implementation of Class(y)
compatible object system in Harbour:

    // bug: in Class(y) oObj1 is class object
    oObj1 := myClass()
    // bug: in Class(y) class function parameters are ignored
    oObj2 := myClass( initPar1, initPar2 )
    // bug: in Class(y) this code executes not existing init()
    // method of class object
    oObj3 := myClass():init( initPar1, initPar2 )

Implementing own method new() as alternative constructor is also bug
because such object method does not have any special meanings in
Class(y) and is not executed automatically. If we implement Class(y)
compatible object system then such code stops to work. It works now
but it's only side effect of current unfinished object system in Harbour.
The only one valid method of creating object in Harbour which is also
Class(y) compatible is calling class function with new() method, i.e.:

    oObj := myClass():mew( initPar1, initPar2 )

And using init() method as object constructor. Why does it work?
It works because in Harbour each class definition is HbObject descendant
and this class contains method new() which calls init, i.e.:

    method new( ... ) class hbObject
        ::init( ... )
    return self

If we implement Class(y) compatible object system then this method will be
removed from HbObject class and reimplemented in different way in HbClass.
We have more of such hacks which mask that we do not have class objects at
all and class methods and variables are emulated in the object instance
name space area.
Current implementation was only temporary solution on the road  to fully
Class(y) compatible object/class system in Harbour but when details of this
temporary hack were made public and people begin to create own code
based on it it blocked farther developing.

Why in HBQT init() is not called? I can only guess that HbQt classes do not
inherits from HbClass so they not inherit also new() method presented above.

BTW xBase++ has Class(y) compatible object system.

best regards,
Przemek



W dniu 14.04.2023 o 00:06, Pritpal Bedi pisze:
--
You received this message because you are subscribed to the Google Groups "QtContribs" group.
To unsubscribe from this group and stop receiving emails from it, send an email to qtcontribs+...@googlegroups.com.

Pritpal Bedi

unread,
Apr 14, 2023, 12:20:40 PM4/14/23
to QtContribs
Hi Przemek

Thanks for the detailed clarification. 
The HbQtColumn class respects your words

>The only one valid method of creating object in Harbour which is also
>Class(y) compatible is calling class function with new() method

It is a pure Harbour class as below 

#include hbclass.ch 

FUNCTION HbQtColumnNew( cHeading, bBlock )
   RETURN HbQtColumn():new( cHeading, bBlock )


CREATE CLASS HbQtColumn INHERIT TBColumn

   METHOD init( cHeading, bBlock )

   DATA   hAlignment                              INIT      Qt_AlignHCenter + Qt_AlignVCenter
   DATA   hHeight                                 INIT      20
   DATA   hFgColor                                INIT      Qt_black
   DATA   hBgColor                                INIT      Qt_darkGray

   DATA   fAlignment                              INIT      Qt_AlignHCenter + Qt_AlignVCenter
   DATA   fHeight                                 INIT      16
   DATA   fFgColor                                INIT      Qt_black
   DATA   fBgColor                                INIT      Qt_darkGray

   DATA   dAlignment                              INIT      Qt_AlignLeft
   DATA   dHeight                                 INIT      16
   DATA   dFgColor                                INIT      Qt_black
   DATA   dBgColor                                INIT      Qt_white
   DATA   nColWidth

   DATA   valtype
   DATA   type                                    INIT      HBQTCOL_TYPE_TEXT
   DATA   blankVariable

   ENDCLASS


METHOD HbQtColumn:init( cHeading, bBlock )

   ::TBColumn:init( cHeading, bBlock )

   ::valtype       := valtype( Eval( ::bBlock ) )
   ::blankVariable := iif( ::valtype == "N", 0, iif( ::valtype == "D", ctod( "" ), iif( ::valtype == "L", .f., "" ) ) )

   ::dAlignment := iif( ::valtype == "N", Qt_AlignRight, iif( ::valtype $ "DL", Qt_AlignHCenter, Qt_AlignLeft ) )
   ::dAlignment += Qt_AlignVCenter

   RETURN Self


Strange aspect is that method init() is never reached though TbColumn() is properly initialyzed. Seems :new() is returning the object with INIT values.

XBase++ always initiates the obkect like :new() than later :create() though you can call them on singlle line as I did for all other HbQt Classes. HbQtColumn is the only class which I did like this for TBColumn compatibility.

Please suggest a solution how to construct it. Fixing is ok if I model it like :new( cHeading, bBlock ):create() and transfer all init() code to create().

Thanks again for clarifications.

Regards
Pritpal Bedi
a student of software analysis and concepts

Pritpal Bedi

unread,
Apr 14, 2023, 12:49:46 PM4/14/23
to QtContribs
Hi Przemek 

Again on above topic. I rewrote the class like this.


FUNCTION HbQtColumnNew( cHeading, bBlock )
   RETURN HbQtColumn():new( cHeading, bBlock ):create()



CREATE CLASS HbQtColumn INHERIT TBColumn

   METHOD create()


   DATA   hAlignment                              INIT      Qt_AlignHCenter + Qt_AlignVCenter
   DATA   hHeight                                 INIT      20
   DATA   hFgColor                                INIT      Qt_black
   DATA   hBgColor                                INIT      Qt_darkGray

   DATA   fAlignment                              INIT      Qt_AlignHCenter + Qt_AlignVCenter
   DATA   fHeight                                 INIT      16
   DATA   fFgColor                                INIT      Qt_black
   DATA   fBgColor                                INIT      Qt_darkGray

   DATA   dAlignment                              INIT      Qt_AlignLeft
   DATA   dHeight                                 INIT      16
   DATA   dFgColor                                INIT      Qt_black
   DATA   dBgColor                                INIT      Qt_white
   DATA   nColWidth

   DATA   valtype
   DATA   type                                    INIT      HBQTCOL_TYPE_TEXT
   DATA   blankVariable

   ENDCLASS


METHOD HbQtColumn:create()


   ::valtype := valtype( Eval( ::bBlock ) )
   ::blankVariable := iif( ::valtype == "N", 0, iif( ::valtype == "D", ctod( "" ), iif( ::valtype == "L", .f., "" ) ) )

   ::dAlignment := iif( ::valtype == "N", Qt_AlignRight, iif( ::valtype $ "DL", Qt_AlignHCenter, Qt_AlignLeft ) )
   ::dAlignment += Qt_AlignVCenter

   RETURN Self 


And it works well. Means class constructor init() has no meaning which is called internally by Harbour.  This creates another confusion as to what parameters be sent in :new() and what in :create() . Xbase++ respects variables in both methods.


Pritpal Bedi
a student of software analysis and concepts

Zoran Sibinovic

unread,
Apr 14, 2023, 1:01:05 PM4/14/23
to qtcon...@googlegroups.com
Hi Pritpal,
If you think about multiline text in the browse columns header, there is no problem I will sent you the code, but in the next week. Now I am on vacations.
Regards

--
You received this message because you are subscribed to a topic in the Google Groups "QtContribs" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/qtcontribs/lOs6urJFF7A/unsubscribe.
To unsubscribe from this group and all its topics, send an email to qtcontribs+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/qtcontribs/38e5acba-f568-4358-90b9-2a42c3f949ecn%40googlegroups.com.

Pritpal Bedi

unread,
Apr 14, 2023, 1:03:59 PM4/14/23
to QtContribs
Hi Przemek

3rd variation.


FUNCTION HbQtColumnNew( cHeading, bBlock )
   RETURN HbQtColumn():new():create( cHeading, bBlock )



CREATE CLASS HbQtColumn INHERIT TBColumn

   METHOD create( cHeading, bBlock )


   DATA   hAlignment                              INIT      Qt_AlignHCenter + Qt_AlignVCenter
   DATA   hHeight                                 INIT      20
   DATA   hFgColor                                INIT      Qt_black
   DATA   hBgColor                                INIT      Qt_darkGray

   DATA   fAlignment                              INIT      Qt_AlignHCenter + Qt_AlignVCenter
   DATA   fHeight                                 INIT      16
   DATA   fFgColor                                INIT      Qt_black
   DATA   fBgColor                                INIT      Qt_darkGray

   DATA   dAlignment                              INIT      Qt_AlignLeft
   DATA   dHeight                                 INIT      16
   DATA   dFgColor                                INIT      Qt_black
   DATA   dBgColor                                INIT      Qt_white
   DATA   nColWidth

   DATA   valtype
   DATA   type                                    INIT      HBQTCOL_TYPE_TEXT
   DATA   blankVariable

   ENDCLASS

METHOD HbQtColumn:create( cHeading, bBlock )

   ::Super():init( cHeading, bBlock )
   
   ::valtype := ValType( Eval( ::bBlock ) )
   ::blankVariable := iif( ::valtype == "N", 0, iif( ::valtype == "D", CToD( "" ), iif( ::valtype == "L", .f., "" ) ) )


   ::dAlignment := iif( ::valtype == "N", Qt_AlignRight, iif( ::valtype $ "DL", Qt_AlignHCenter, Qt_AlignLeft ) )
   ::dAlignment += Qt_AlignVCenter

   RETURN Self

I did not pass parameters, responsible to init() the INHERITing class TBColumn. Instead tried to initialy it from create() method.
Does not work. TBColumn's  ::bBlock  is not initialyzed and error is generated in line 
:valtype := ValType( Eval( ::bBlock ) )

Regards
Pritpal Bedi
a student of software analysis and concepts

Francesco Perillo

unread,
Apr 14, 2023, 1:04:20 PM4/14/23
to qtcontribs
Probably you should call super::new()....


You received this message because you are subscribed to the Google Groups "QtContribs" group.
To unsubscribe from this group and stop receiving emails from it, send an email to qtcontribs+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/qtcontribs/CADNRZ6m5pxKLBwt%3DT%3D4QzJyxzvMeYhaiafu_AqTZoDrmqURzYg%40mail.gmail.com.

Pritpal Bedi

unread,
Apr 14, 2023, 1:13:04 PM4/14/23
to QtContribs
Hi Fancessco

Yes, it works. I had already tested this 4th variation.

I am trying to understand the semantics of our class system. Przemek can shed more clarity on the subject. May be we have a better and well organized class system. May be based on alternate hbclass{ext} protocol. Przemek can implement it for sure.

Pritpal Bedi
a student of software analysis and concepts

Francesco Perillo

unread,
Apr 14, 2023, 1:17:38 PM4/14/23
to qtcontribs

You have to call super::new() to have parent objects initialized. 


Przemyslaw Czerpak

unread,
Apr 15, 2023, 3:50:44 AM4/15/23
to qtcon...@googlegroups.com
Hi Pritpal,

The bug is inside Harbour TbColumn class.
It simply redefines method new() breaking the temporary hack
created for Class(y) compatibility so init() method is never executed.
As I can see the same problem is in other CL53 classes implemented
in Harbour.

best regards,
Przemek


W dniu 14.04.2023 o 18:20, Pritpal Bedi pisze:

Pritpal Bedi

unread,
Apr 16, 2023, 7:12:39 PM4/16/23
to QtContribs
Thanks Przemek

If it is a problem with TBColumn than I am feeling greatly relieved. It ensures that the whole HbQt library is all-right as the classes are built init() as class constructor and new() is object initiator. I can mange couple o fclasses inheriting from Harbour classes. Have fixed HbQtColumn class wnd will see what I have done with TBrowse and GET classes.

Thanks again

Regards
Pritpal Bedi
a student of software analysis & concepts

Alex Strickland

unread,
Apr 17, 2023, 5:02:45 AM4/17/23
to qtcon...@googlegroups.com

Hi

FWIW I would love to see the "correct" implementation and any competing problematic implementation could be retired. I know each "breaking" change will probably strand some users but if it is not done then everyone lives with a second rate implementation for ever.

--

Regards

Alex

Maurício Faria

unread,
Apr 17, 2023, 7:45:19 AM4/17/23
to qtcon...@googlegroups.com
HI.
 
Agree.
What about freeze 3.2, classify it as stable and start 3.5 ( as 3.4 already exists ) ???
 
[[]] Maurício Faria

Luigi Ferraris

unread,
Apr 17, 2023, 2:34:18 PM4/17/23
to QtContribs
Hi to all,
I spent a lot of time to understand Harbour class implementation (new and init) and related HbQt.
I'm the last wheel of the car and you are Guru for me but I want say something to recap

I think the init() method was think before adding this macro
#xcommand VAR <!DataName1!> [, <!DataNameN!>] [ <tp: TYPE, AS> <type> ] [ <as: ASSIGN, INIT>.....
But the macro has a problem: can only initialize var to Harbour well known value type
iow this works fine VAR m_number   INIT 0
but this fail       VAR m_font     INIT QFont() or something else
so, unuseful with complex object.

The question was: how can initialize internal var to value?
className():new() automatically call className:init() (tobject.prg but not in tclass.prg)
I've already found this function: InitClass() in tclass.prg what is its purpose?

On the other hand, init() method is public, reusable (I can call :init() by itself): why?
To reinitialize an object instance? Strange for me.
Anyway, the init() method (bad or good) is a way to "initialize" var without change new() method when inheritance involved.
In various personal class implementations, I have protected the init() method from repeated execution
using a hidden var in the class. I am forced to call the init method all the time, but I achieved the goal by overcoming the macro problem.

So my pov: I think any new() method must/need to call init() to respect Harbour behaviour.
Other names (e.g. "create") are surrogate and cannot substitute "init"; from my pov they are specialized, customized methods for this class.
OR is this a Xbase++ specified keyword/implementation about classes?

Anyway, I hope HbQt keep new() and init() as foundamental methods about classes.

Best regards.
Luigi

a small side note, little opinion: revisiting HbQtObjectHandler class using in a proper way PUBLIC, PROTECTED, HIDDEN
for datas and methods or the destructor way, can make this class more profitable.

Luigi Ferraris

unread,
Apr 18, 2023, 11:46:29 AM4/18/23
to QtContribs
Hi Pritpal,
I think this code can be right for you

CREATE CLASS HbQtColumn INHERIT TBColumn

   EXPORTED:
   METHOD new
   METHOD init
...........

METHOD new( ... ) CLASS HbQtColumn
   ::tbcolumn:new( ... ) ==> to solve TBCOLUMN not cal init
   ::init( ... ) ==> to solve HbQtColumn init standard
RETURN self

METHOD init( cHeading, bBlock ) CLASS HbQtColumn
   ::valtype := ValType( Eval( ::bBlock ) )
   ::blankVariable := iif( ::valtype == "N", 0, iif( ::valtype == "D", CToD( "" ), iif( ::valtype == "L", .f., "" ) ) )

   ::dAlignment := iif( ::valtype == "N", Qt_AlignRight, iif( ::valtype $ "DL", Qt_AlignHCenter, Qt_AlignLeft ) )
   ::dAlignment += Qt_AlignVCenter

RETURN Self


Regards
Luigi

Lailton Fernando Mariano

unread,
Apr 18, 2023, 5:05:25 PM4/18/23
to QtContribs
Good idea.
It will be useful :)

Thanks

Pritpal Bedi

unread,
Apr 20, 2023, 11:52:15 AM4/20/23
to QtContribs
Hi Luigi

Do not introduce another hack. Przemek has fixed the issue in Harbour core. 

CLASS HbQtColumn INHERIT TBColumn
   METHOD init( ... )
   ENDCLASS 

METHOD HbQtColumn:init( ... )
   // Setup Parameters
   RETURN Self 

LOCAL oHbQtColumn() := HbQtColumn():new( ... )    // will behave correctly after todays's commit by Przemek, thanks.
   // Manage Parameters
   RETURN NIL

Create() is a Xbase++ standard way to build all classes. Read their documentation why they dis so. But they have a valid point which I have exploited throughout in QtContribs. One, offcourse, can live without it. It is a matter of personal preference.



Pritpal Bedi 
a student of software analysis and concepts

Luigi Ferraris

unread,
Apr 20, 2023, 2:06:01 PM4/20/23
to qtcon...@googlegroups.com
Hi Pritpal


Il 20/04/2023 17:52, Pritpal Bedi ha scritto:
Hi Luigi

Do not introduce another hack. Przemek has fixed the issue in Harbour core.
My suggestion should have been intended "in the meantime all affected Harbour objects are fixed".
It was a workaround to check if HbQt has no other related problem. Good to know
Przemek fixed :-))


Create() is a Xbase++ standard way to build all classes. Read their documentation why they dis so. But they have a valid point which I have exploited throughout in QtContribs. One, offcourse, can live without it. It is a matter of personal preference.

Ok.
But if I (user HbQt) don't adopt (or don't know) the Xbase++ style, I could run into the error of not using that method if I were to create a class that inherits from that.
More or less what new() without init() create. Anyway only an opinion.
Thanks
Luigi

Pritpal Bedi

unread,
Apr 22, 2023, 7:07:54 PM4/22/23
to QtContribs
Hi Zoran

Probbaly you forgot to publish the code how color and multi-line header should be implemented in HbQtBrowse, which would have saved me a couple of hours digging it, but now this implementaion is available by default. Will commit in a few days inclduing some more changes.

MicrosoftTeams-image.png

Pritpal Bedi
a student of software analysis and concepts

Reply all
Reply to author
Forward
0 new messages