Draft: move units functions outside DraftGui.py

The functions `getDefaultUnit`, `makeFormatSpec`, `displayExternal`
are used to get the default unit schema for lengths and angles,
and display a string with a particular format.

They aren't used in `DraftGui.py`, but are used by the
viewprovider of the Dimension objects. Therefore, they are moved
into a separate module, so that they can be imported without
using the entire `DraftGui` module.
This commit is contained in:
vocx-fc
2020-06-23 08:38:23 -05:00
committed by Yorik van Havre
parent 94b0fe1599
commit aaeab8bc5d
3 changed files with 134 additions and 64 deletions

View File

@@ -70,6 +70,7 @@ SET(Draft_utilities
draftutils/__init__.py
draftutils/init_tools.py
draftutils/init_draft_statusbar.py
draftutils/units.py
draftutils/utils.py
draftutils/gui_utils.py
draftutils/todo.py

View File

@@ -39,20 +39,16 @@ Report to Draft.py for info
import os
import sys
import math
import PySide.QtCore as QtCore
import PySide.QtGui as QtGui
import FreeCAD
import FreeCADGui
import Draft
import DraftVecUtils
from PySide import QtCore, QtGui
import draftutils.translate
translate = draftutils.translate.translate
import draftutils.utils
utf8_decode = draftutils.utils.utf8_decode
from draftutils.translate import translate
from draftutils.utils import utf8_decode
# in-command shortcut definitions: Shortcut / Translation / related UI control
inCommandShortcuts = {
@@ -78,65 +74,14 @@ inCommandShortcuts = {
"NearSnap": [Draft.getParam("inCommandShortcutNearSnap", "N"),translate("draft","Toggle near snap on/off"), None],
}
import draftutils.todo
todo = draftutils.todo.ToDo
from draftutils.todo import todo
#---------------------------------------------------------------------------
# UNITS handling
#---------------------------------------------------------------------------
def getDefaultUnit(dim):
'''return default Unit of Measure for a Dimension based on user preference
Units Schema'''
# only Length and Angle so far
if dim == 'Length':
qty = FreeCAD.Units.Quantity(1.0,FreeCAD.Units.Length)
UOM = qty.getUserPreferred()[2]
elif dim == 'Angle':
qty = FreeCAD.Units.Quantity(1.0,FreeCAD.Units.Angle)
UOM = qty.getUserPreferred()[2]
else:
UOM = "xx"
return UOM
def makeFormatSpec(decimals=4,dim='Length'):
''' return a % format spec with specified decimals for a specified
dimension based on on user preference Units Schema'''
if dim == 'Length':
fmtSpec = "%." + str(decimals) + "f "+ getDefaultUnit('Length')
elif dim == 'Angle':
fmtSpec = "%." + str(decimals) + "f "+ getDefaultUnit('Angle')
else:
fmtSpec = "%." + str(decimals) + "f " + "??"
return fmtSpec
def displayExternal(internValue,decimals=None,dim='Length',showUnit=True,unit=None):
'''return an internal value (ie mm) Length or Angle converted for display according
to Units Schema in use. Unit can be used to force the value to express in a certain unit'''
if dim == 'Length':
q = FreeCAD.Units.Quantity(internValue,FreeCAD.Units.Length)
if not unit:
if (decimals is None) and showUnit:
return q.UserString
conversion = q.getUserPreferred()[1]
uom = q.getUserPreferred()[2]
else:
uom = unit
internValue = q.getValueAs(unit)
conversion = 1
elif dim == 'Angle':
return FreeCAD.Units.Quantity(internValue,FreeCAD.Units.Angle).UserString
else:
conversion = 1.0
if decimals is None:
decimals = 2
uom = "??"
if not showUnit:
uom = ""
decimals = abs(decimals) # prevent negative values
fmt = "{0:."+ str(decimals) + "f} "+ uom
displayExt = fmt.format(float(internValue) / float(conversion))
displayExt = displayExt.replace(".",QtCore.QLocale().decimalPoint())
return displayExt
from draftutils.units import (getDefaultUnit,
makeFormatSpec,
displayExternal)
#---------------------------------------------------------------------------
# Customized widgets

View File

@@ -0,0 +1,124 @@
# ***************************************************************************
# * Copyright (c) 2009 Yorik van Havre <yorik@uncreated.net> *
# * Copyright (c) 2020 Eliud Cabrera Castillo <e.cabrera-castillo@tum.de> *
# * *
# * This file is part of the FreeCAD CAx development system. *
# * *
# * This program is free software; you can redistribute it and/or modify *
# * it under the terms of the GNU Lesser General Public License (LGPL) *
# * as published by the Free Software Foundation; either version 2 of *
# * the License, or (at your option) any later version. *
# * for detail see the LICENCE text file. *
# * *
# * FreeCAD is distributed in the hope that it will be useful, *
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# * GNU Library General Public License for more details. *
# * *
# * You should have received a copy of the GNU Library General Public *
# * License along with FreeCAD; if not, write to the Free Software *
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
# * USA *
# * *
# ***************************************************************************
"""Provides utility functions related to unit handling."""
## @package units
# \ingroup DRAFT
# \brief Provides utility functions related to unit handling.
from PySide import QtCore
import FreeCAD as App
def get_default_unit(dim):
"""Return default Unit of Measure for a dimension.
It is based on the user preferences.
"""
if dim == 'Length':
qty = App.Units.Quantity(1.0, App.Units.Length)
uom = qty.getUserPreferred()[2]
elif dim == 'Angle':
qty = App.Units.Quantity(1.0, App.Units.Angle)
uom = qty.getUserPreferred()[2]
else:
uom = "xx"
return uom
getDefaultUnit = get_default_unit
def make_format_spec(decimals=4, dim='Length'):
"""Return a string format specifier with decimals for a dimension.
It is based on the user preferences.
"""
if dim == 'Length':
fmt_spec = "%." + str(decimals) + "f " + get_default_unit('Length')
elif dim == 'Angle':
fmt_spec = "%." + str(decimals) + "f " + get_default_unit('Angle')
else:
fmt_spec = "%." + str(decimals) + "f " + "??"
return fmt_spec
makeFormatSpec = make_format_spec
def display_external(internal_value,
decimals=None, dim='Length', showUnit=True, unit=None):
"""Return a converted value for display, according to the unit schema.
Parameters
----------
internal_value: float
A value that will be transformed depending on the other parameters.
decimals: float, optional
It defaults ot `None`, in which case, the decimals are 2.
dim: str, optional
It defaults to `'Length'`. It can also be `'Angle'`.
showUnit: bool, optional
It defaults to `True`.
If it is `False` it won't show the unit.
unit: str, optional
A unit string such as `'mm'`, `'cm'`, `'m'`, `'in'`, `'ft'`,
in which to express the returned value.
"""
if dim == 'Length':
q = App.Units.Quantity(internal_value, App.Units.Length)
if not unit:
if not decimals and showUnit:
return q.UserString
conversion = q.getUserPreferred()[1]
uom = q.getUserPreferred()[2]
else:
uom = unit
internal_value = q.getValueAs(unit)
conversion = 1
elif dim == 'Angle':
return App.Units.Quantity(internal_value, App.Units.Angle).UserString
else:
conversion = 1.0
if not decimals:
decimals = 2
uom = "??"
if not showUnit:
uom = ""
decimals = abs(decimals) # prevent negative values
fmt = "{0:." + str(decimals) + "f} " + uom
display = fmt.format(float(internal_value) / float(conversion))
display = display.replace(".", QtCore.QLocale().decimalPoint())
return display
displayExternal = display_external