Developer advice needed for InputFields

Here's the place for discussion related to coding in FreeCAD, C++ or Python. Design, interfaces and structures.
chrisb
Posts: 1659
Joined: Tue Mar 17, 2015 9:14 am

Developer advice needed for InputFields

Postby chrisb » Fri Jan 06, 2017 11:13 pm

I have worked on the problem of unwanted x10 multiplication in input fields occuring here and there in FreeCAD. I have a solution, but to make it clean and globally available it would be very kind if one of the experienced developers could give me a helping hand and give me some hints: viewtopic.php?f=10&t=18833&start=10#p152007.
Thank you.
mlampert
Posts: 283
Joined: Fri Sep 16, 2016 9:28 pm

Re: Developer advice needed for InputFields

Postby mlampert » Fri Jan 06, 2017 11:44 pm

Hey Chris, we just discovered the InputField and are starting to convert to it. While some dialogs in Path currently use it most of them treat it like a text field. What we should really do is use Units.Quantity to convert to and from strings.

So if there is a distance or length the conversion we should set the display string to

Code: Select all

inputFieldWidget.setText(FreeCAD.Units.Quantity(<value>, FreeCAD.Units.Length).UserString)


And again, to retrieve the value from an input field:

Code: Select all

FreeCADUnits.Quantity(inputFieldWidget.text()).Value
sebste
Posts: 7
Joined: Tue Sep 01, 2015 9:23 am

Re: Developer advice needed for InputFields

Postby sebste » Sun Jan 08, 2017 3:05 pm

I was playing with it a bit last night and applied the changes mlampert suggested while sliptonic pointed me into the right direction on IRC.
https://github.com/FreeCAD/FreeCAD/pull/427
I hope it is helpful and I have got the git / pull request stuff right.
Cheers
chrisb
Posts: 1659
Joined: Tue Mar 17, 2015 9:14 am

Re: Developer advice needed for InputFields

Postby chrisb » Mon Jan 09, 2017 2:32 pm

That's phantastic. I had promised a week and thought it would be fast enough and now it is done after one day. I would like to see a commercial program having that speed.
sebste
Posts: 7
Joined: Tue Sep 01, 2015 9:23 am

PR430 / more fixes in TooltableEditor (Re: Developer advice needed for InputFields)

Postby sebste » Tue Jan 10, 2017 6:52 pm

Found the same issue in the TooltableEditor and fixed within
https://github.com/FreeCAD/FreeCAD/pull/430
Also fixed export / import of tool tables to handle non-ascii characters in filenames, added exception handling for reading and writing and fixed german translation string that broke file type selection filter in file open dialog.

At this occasion, I stumbled across some more unicode issues with the Toolnames. Since the QStrings are cast to Strings, they cant handle non-ascii characters. Casting with unicode() does not work, probably because the Tool class is defined in c++ and name is of type char? Any Ideas on how to deal with this?

I would strongly recommend avoiding casting QStrings from Gui imput to String, as it will likely cause trouble with unicode characters. As I general rule of thumb, I have learned, that in Python2, QStrings should be cast to Unicode at the earliest time possible. Is there a convention within FreeCAD, if not, should there be one? What do you think?

I hope this helps a bit. This git / PR stuff and working on code with others is pretty new to me, so please bear with me and let me know if I got something wrong.

Cheers
Sebastian
wmayer
Site Admin
Posts: 11232
Joined: Thu Feb 19, 2009 10:32 am

Re: Developer advice needed for InputFields

Postby wmayer » Wed Jan 11, 2017 9:34 am

https://github.com/FreeCAD/FreeCAD/pull/430

Your PR is broken and has some merge conflicts.

Since the QStrings are cast to Strings, they cant handle non-ascii characters. Casting with unicode() does not work, probably because the Tool class is defined in c++ and name is of type char? Any Ideas on how to deal with this?

What do you mean with casting a QString to a string? And are you talking about C++ now or Python?
Anyway, inside C++ it's always safe to convert a QString to utf8-encoded char* by using toUtf8() and fromUtf8(). If a utf8-encoded string gets serialized e.g. by macro recording then it's recommended to "escape" it using the method escapedUnicodeFromUtf8 (defined inside src/Base/Tools.h).

As I general rule of thumb, I have learned, that in Python2, QStrings should be cast to Unicode at the earliest time possible. Is there a convention within FreeCAD, if not, should there be one? What do you think?

The convention is that any string coming from user input (path names, text, ...) must be considered as unicode text and if passed to a function that expects a char* then toUtf8()/fromUtf8() must be used. If it's clear that a text is 7-bit ASCII then toLatin1()/fromLatin1() are allowed.

If in C++ we have a utf8 string and call a Python function then the string should be escaped and inside Python handled as a unicode object.

Code: Select all

        std::string unicodepath = Base::Tools::escapedUnicodeFromUtf8((*it).toUtf8().data());
        openCommand("Import Mesh");
        doCommand(Doc,"import Mesh");
        doCommand(Doc,"Mesh.insert(u\"%s\")",
                  unicodepath.c_str());
        commitCommand();


If we have a Python binding function written in C/C++ and invoked from within Python then e.g. path names are expected to be in unicode and try to convert them to utf8

Code: Select all

        char* Name;
        if (!PyArg_ParseTuple(args.ptr(), "et","utf-8",&Name))
            throw Py::Exception();

        std::string EncodedName = std::string(Name);
        PyMem_Free(Name);
sebste
Posts: 7
Joined: Tue Sep 01, 2015 9:23 am

Re: Developer advice needed for InputFields

Postby sebste » Wed Jan 11, 2017 11:05 pm

Your PR is broken and has some merge conflicts.

Thanks, for the heads up. I am sorry. I know what a merge conflict is in theory, but I have no clue how this happened and how to actually solve this. Any hints would be much appreciated :oops:

What do you mean with casting a QString to a string? And are you talking about C++ now or Python?

I was talking Python / PyQt. Normally when I get input from let's say a QLineEdit, In Python2, I immediately do unicode(lineEdit.text()) (as recommended in "Rapid GUI programming with Python and Qt"). Obviously if the data is handed to a char* this does not work.

The convention is that any string coming from user input (path names, text, ...) must be considered as unicode text and if passed to a function that expects a char* then toUtf8()/fromUtf8() must be used. If it's clear that a text is 7-bit ASCII then toLatin1()/fromLatin1() are allowed.

[/quote]
Thanks, so far so good....

My concrete example that is driving me nuts is in Mod/Path/PathScripts/PathToolLibraryManager.py in line 423

t.Name = str(editform.NameField.text()) #this results in an error with non-ascii characters


As editform.NameField is a QLineEdit, I would expect it to return a QString.
So a fix would be like so:
t.Name = editform.NameField.text().toUtf8()

But this, somehow results in an error, because it actually returns a unicode object (what I think is pretty weird)

So I could do:
t.Name = QtCore.QString(editform.NameField.text()).toUtf8()

whcih should return a QByteArray with my utf8 encoded input.

....but...
apparently in PySide, QtCore does not have a thing called QString (???)

So what actually works fine is this:
t.Name = editform.NameField.text().encode("utf-8")

But that is apparently not the way it should be done, right :-(
mlampert
Posts: 283
Joined: Fri Sep 16, 2016 9:28 pm

Re: Developer advice needed for InputFields

Postby mlampert » Thu Jan 12, 2017 1:20 am

sebste wrote:
Your PR is broken and has some merge conflicts.

Thanks, for the heads up. I am sorry. I know what a merge conflict is in theory, but I have no clue how this happened and how to actually solve this. Any hints would be much appreciated :oops:

There is an introduction here: https://help.github.com/articles/resolv ... mand-line/

Personally I like to use meld (meldmerge.org) as the mergetool for git (https://git-scm.com/docs/git-mergetool). Send me a PM, or get on IRC if you have problems and I run you through it.
wmayer
Site Admin
Posts: 11232
Joined: Thu Feb 19, 2009 10:32 am

Re: Developer advice needed for InputFields

Postby wmayer » Thu Jan 12, 2017 9:44 am

My concrete example that is driving me nuts is in Mod/Path/PathScripts/PathToolLibraryManager.py in line 423
t.Name = str(editform.NameField.text()) #this results in an error with non-ascii characters


This of course doesn't work because for PySide text() already returns a unicode object. If this contains non-7-bit-ASCII then str() doesn't know how to handle it. Now I don't know what "t.Name" allows you to assign to it. If it accepts unicode you can write:

Code: Select all

t.Name = unicode(editform.NameField.text())

If it doesn't accept unicode you have to write:

Code: Select all

t.Name = unicode(editform.NameField.text()).encode("utf-8")


....but...
apparently in PySide, QtCore does not have a thing called QString (???)

That's the biggest difference between PyQt and PySide.
sebste
Posts: 7
Joined: Tue Sep 01, 2015 9:23 am

Re: Developer advice needed for InputFields

Postby sebste » Thu Jan 12, 2017 11:47 pm

Thanks for your help, mlampert!

wmayer:
Your PR is broken and has some merge conflicts.

PR is fixed, now.

If it doesn't accept unicode you have to write:

Code: Select all

t.Name = unicode(editform.NameField.text()).encode("utf-8")



So I was not to far off, then :-)

....but...
apparently in PySide, QtCore does not have a thing called QString (???)

That's the biggest difference between PyQt and PySide

And the fact that PySide does not work on the console in interactive mode, properly.
I have not done anything with PySide, before and thought it was basically the same as PyQt.
Thanks for enlightening me. I am just digging into the FreeCAD code for a few days and already learned a ton!