diff --git a/src/Mod/Draft/CMakeLists.txt b/src/Mod/Draft/CMakeLists.txt index fea8a7f78c..abb7db357f 100644 --- a/src/Mod/Draft/CMakeLists.txt +++ b/src/Mod/Draft/CMakeLists.txt @@ -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 diff --git a/src/Mod/Draft/DraftGui.py b/src/Mod/Draft/DraftGui.py index 8076310f39..703d24f097 100644 --- a/src/Mod/Draft/DraftGui.py +++ b/src/Mod/Draft/DraftGui.py @@ -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 diff --git a/src/Mod/Draft/draftutils/units.py b/src/Mod/Draft/draftutils/units.py new file mode 100644 index 0000000000..af5f433ec7 --- /dev/null +++ b/src/Mod/Draft/draftutils/units.py @@ -0,0 +1,124 @@ +# *************************************************************************** +# * Copyright (c) 2009 Yorik van Havre * +# * Copyright (c) 2020 Eliud Cabrera Castillo * +# * * +# * 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