Merge branch 'master' of ssh://free-cad.git.sourceforge.net/gitroot/free-cad/free-cad

This commit is contained in:
Joachim Zettler 2012-08-20 21:56:20 +02:00
commit b0dcfe6dcf
883 changed files with 201338 additions and 115083 deletions

View File

@ -52,6 +52,10 @@ if(CMAKE_COMPILER_IS_GNUCXX)
add_definitions(-Wno-write-strings)
add_definitions(-Wno-deprecated)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
# get linker errors as soon as possible and not at runtime e.g. for modules
if(UNIX)
# SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--no-undefined")
endif(UNIX)
endif(CMAKE_COMPILER_IS_GNUCXX)
@ -96,7 +100,21 @@ OPTION(FREECAD_MAINTAINERS_BUILD "Build FreeCAD for Maintainers, with Docu and 3
OPTION(FREECAD_BUILD_CAM "Build the FreeCAD CAM module and the needed libs, be aware, unfinished code!" OFF)
OPTION(FREECAD_BUILD_FEM "Build the FreeCAD FEM module, be aware, unfinished code!" ON)
OPTION(FREECAD_BUILD_SANDBOX "Build the FreeCAD Sandbox module which is only for testing purposes" OFF)
OPTION(FREECAD_BUILD_TEMPLATE "Build the FreeCAD template module which is only for testing purposes" OFF)
OPTION(FREECAD_BUILD_DEBIAN "Prepare for a build of a Debian package" OFF)
OPTION(FREECAD_USE_EXTERNAL_ZIPIOS "Use system installed zipios++ instead of the bundled." OFF)
OPTION(FREECAD_USE_EXTERNAL_PIVY "Use system installed python-pivy instead of the bundled." OFF)
if(MSVC)
OPTION(FREECAD_USE_3DCONNEXION "Use the 3D connexion SDK to support 3d mouse." ON)
else(MSVC)
set(FREECAD_USE_3DCONNEXION OFF)
endif(MSVC)
# if this is set override some options
if (FREECAD_BUILD_DEBIAN)
set(FREECAD_USE_EXTERNAL_ZIPIOS ON)
set(FREECAD_USE_EXTERNAL_PIVY ON)
endif (FREECAD_BUILD_DEBIAN)
# ==============================================================================
@ -104,6 +122,7 @@ if(FREECAD_LIBPACK_USE)
# checking for a unique file in LibPack location to make sure the right version of the LibPack is there
find_file(FREECAD_LIBPACK_CHECKFILE6X boost_program_options-vc80-mt-gd.lib ${FREECAD_LIBPACK_DIR}/lib )
find_file(FREECAD_LIBPACK_CHECKFILE7X boost_program_options-vc90-mt-gd-1_39.lib ${FREECAD_LIBPACK_DIR}/lib )
find_file(FREECAD_LIBPACK_CHECKFILE8X boost_program_options-vc90-mt-gd-1_48.lib ${FREECAD_LIBPACK_DIR}/lib )
find_file(FREECAD_LIBPACK_CHECKCUSTOM boost_program_options-vc90-mt-gd-1_41.lib ${FREECAD_LIBPACK_DIR}/lib )
IF(FREECAD_LIBPACK_CHECKFILE6X)
include(cMake/UseLibPack6x.cmake)
@ -115,6 +134,13 @@ if(FREECAD_LIBPACK_USE)
set(FREECAD_LIBPACK6 NOTFOUND CACHE STRING "Displays if the libpack has been found")
MARK_AS_ADVANCED(FORCE FREECAD_LIBPACK6)
set(FREECAD_LIBPACK7 FOUND CACHE STRING "Displays if the libpack has been found")
ELSEIF(FREECAD_LIBPACK_CHECKFILE8X)
include(cMake/UseLibPack8x.cmake)
set(FREECAD_LIBPACK6 NOTFOUND CACHE STRING "Displays if the libpack has been found")
set(FREECAD_LIBPACK7 NOTFOUND CACHE STRING "Displays if the libpack has been found")
set(SWIG_EXECUTABLE ${FREECAD_LIBPACK_DIR}/tools/swigwin-1.3.40/swig.exe)
MARK_AS_ADVANCED(FORCE FREECAD_LIBPACK6)
set(FREECAD_LIBPACK8 FOUND CACHE STRING "Displays if the libpack has been found")
ELSEIF(FREECAD_LIBPACK_CHECKCUSTOM)
include(cMake/UseLibPackCustom.cmake)
set(FREECAD_LIBPACKX FOUND CACHE STRING "Displays if the libpack has been found")
@ -185,7 +211,7 @@ MARK_AS_ADVANCED(FORCE FREECAD_LIBPACK_CHECKFILE6X FREECAD_LIBPACK_CHECKFILE7X)
if( ${OCE_FOUND} )
message("-- OpenCASCADE Community Edition has been found.")
add_definitions ( -DHAVE_CONFIG_H )
set( OCC_LIBRARIES "TKFillet;TKMesh;TKernel;TKG2d;TKG3d;TKMath;TKIGES;TKSTL;TKShHealing;TKXSBase;TKBool;TKBO;TKBRep;TKTopAlgo;TKGeomAlgo;TKGeomBase;TKOffset;TKPrim;TKSTEP;TKSTEPBase;TKSTEPAttr;TKHLR" ) #lib list copied from FreeCAD's FindOpenCasCade.cmake
set( OCC_LIBRARIES "TKFeat;TKFillet;TKMesh;TKernel;TKG2d;TKG3d;TKMath;TKIGES;TKSTL;TKShHealing;TKXSBase;TKBool;TKBO;TKBRep;TKTopAlgo;TKGeomAlgo;TKGeomBase;TKOffset;TKPrim;TKSTEP;TKSTEPBase;TKSTEPAttr;TKHLR" ) #lib list copied from FreeCAD's FindOpenCasCade.cmake
set( OCC_INCLUDE_DIR ${OCE_INCLUDE_DIRS} )
set( OCC_FOUND ${OCE_FOUND} )
else() #look for OpenCASCADE
@ -198,12 +224,6 @@ MARK_AS_ADVANCED(FORCE FREECAD_LIBPACK_CHECKFILE6X FREECAD_LIBPACK_CHECKFILE7X)
ENDIF()
endif()
# -------------------------------- f2c ----------------------------------
IF(OCC_FOUND)
find_package(F2C REQUIRED)
ENDIF(OCC_FOUND)
# -------------------------------- Salome SMESH --------------------------
# Salome SMESH sources are under src/3rdParty now
@ -247,22 +267,22 @@ MARK_AS_ADVANCED(FORCE FREECAD_LIBPACK_CHECKFILE6X FREECAD_LIBPACK_CHECKFILE7X)
# -------------------------------- ODE ----------------------------------
find_package(ODE)
# find_package(ODE)
# -------------------------------- Qt --------------------------------
# sets ${QT_LIBRARIES}
SET(QT_MIN_VERSION 4.1.4)
SET(QT_MIN_VERSION 4.5.0)
set(QT_USE_QTNETWORK TRUE)
set(QT_USE_QTXML TRUE)
if(FREECAD_BUILD_GUI)
set(QT_USE_QTOPENGL TRUE)
set(QT_USE_QTSVG TRUE)
set(QT_USE_QTUITOOLS TRUE)
set(QT_USE_QTWEBKIT TRUE)
endif(FREECAD_BUILD_GUI)
find_package(Qt4)
if(FREECAD_BUILD_GUI)
set(QT_USE_QTOPENGL TRUE)
set(QT_USE_QTSVG TRUE)
set(QT_USE_QTUITOOLS TRUE)
set(QT_USE_QTWEBKIT TRUE)
endif(FREECAD_BUILD_GUI)
find_package(Qt4 REQUIRED)
include(${QT_USE_FILE})
@ -271,7 +291,7 @@ MARK_AS_ADVANCED(FORCE FREECAD_LIBPACK_CHECKFILE6X FREECAD_LIBPACK_CHECKFILE7X)
ENDIF(NOT QT4_FOUND)
IF(NOT QT_QTWEBKIT_FOUND)
MESSAGE("QT Webkit not found, will not build browser integration!")
MESSAGE("Qt Webkit not found, will not build browser integration!")
ENDIF(NOT QT_QTWEBKIT_FOUND)
@ -282,22 +302,24 @@ MARK_AS_ADVANCED(FORCE FREECAD_LIBPACK_CHECKFILE6X FREECAD_LIBPACK_CHECKFILE7X)
# There is probably a cleaner solution than this
macro(fc_wrap_cpp outfiles )
# get include dirs
QT4_GET_MOC_FLAGS(moc_includes)
QT4_GET_MOC_FLAGS(moc_flags)
QT4_EXTRACT_OPTIONS(moc_files moc_options ${ARGN})
# fixes bug 0000585: bug with boost 1.48
SET(moc_options ${moc_options} -DBOOST_TT_HAS_OPERATOR_HPP_INCLUDED)
foreach(it ${moc_files})
get_filename_component(it ${it} ABSOLUTE)
QT4_MAKE_OUTPUT_FILE(${it} moc_ cpp outfile)
QT4_CREATE_MOC_COMMAND(${it} ${outfile} "${moc_includes}" "${moc_options}")
QT4_CREATE_MOC_COMMAND(${it} ${outfile} "${moc_flags}" "${moc_options}")
set(${outfiles} ${${outfiles}} ${outfile})
add_file_dependencies(${it} ${outfile})
endforeach(it)
endmacro(fc_wrap_cpp)
if(FREECAD_BUILD_GUI)
# -------------------------------- OpenGL --------------------------------
find_package(OpenGL)
find_package(OpenGL)
include(FindPackageMessage)
if(OPENGL_GLU_FOUND)
find_package_message(OPENGL_GLU
@ -309,16 +331,16 @@ MARK_AS_ADVANCED(FORCE FREECAD_LIBPACK_CHECKFILE6X FREECAD_LIBPACK_CHECKFILE7X)
# -------------------------------- Coin3D --------------------------------
find_package(Coin3D REQUIRED)
find_package(SoQt REQUIRED)
find_package(Coin3D REQUIRED)
find_package(SoQt REQUIRED)
# ------------------------------ Spaceball -------------------------------
if (WIN32)
#future
else(WIN32)
find_package(Spnav)
endif(WIN32)
if (WIN32)
#future
else(WIN32)
find_package(Spnav)
endif(WIN32)
# ------------------------------------------------------------------------
@ -330,7 +352,9 @@ endif(FREECAD_LIBPACK_USE)
# copy build convenient files for M$
if(WIN32)
configure_file(BuildAll.bat ${CMAKE_BINARY_DIR}/BuildAll.bat COPYONLY)
if (EXISTS BuildAll.bat)
configure_file(BuildAll.bat ${CMAKE_BINARY_DIR}/BuildAll.bat COPYONLY)
endif (EXISTS BuildAll.bat)
#configure_file(BuildAllNice.bat ${CMAKE_BINARY_DIR}/BuildAllNice.bat COPYONLY)
endif(WIN32)
@ -383,6 +407,10 @@ IF(MINGW)
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -mthreads -Wl,--export-all-symbols")
LINK_LIBRARIES(-lgdi32)
ENDIF(MINGW)
# 0000661: cmake build on Mac OS: dealing with dylib versus so
IF(APPLE)
SET(CMAKE_SHARED_LIBRARY_SUFFIX ".so")
ENDIF(APPLE)
add_subdirectory(src)
add_subdirectory(data)
@ -410,7 +438,7 @@ if(FREECAD_MAINTAINERS_BUILD AND NOT WIN32)
set(PKG_ARCH amd64)
ENDIF( CMAKE_SIZEOF_VOID_P EQUAL 4 )
set(CPACK_DEBIAN_PACKAGE_SECTION "science")
set(CPACK_DEBIAN_PACKAGE_DEPENDS "python, oce | opencascade, libqtgui4, libcoin60, libode1, libsoqt4-20, libxerces-c3.1, libgts-0.7-5, zlib1g, libboost-dev, libeigen2-dev")
set(CPACK_DEBIAN_PACKAGE_DEPENDS "python, oce | opencascade, libqtgui4, libcoin60, libsoqt4-20, libxerces-c3.1, zlib1g, libboost-dev, libeigen2-dev")
set(CPACK_PACKAGE_CONTACT "<root@localhost>")
set(CPACK_PACKAGE_FILE_NAME "${PACKAGE_NAME}-${PACKAGE_VERSION}_${PKG_ARCH}")

View File

@ -78,6 +78,7 @@ IF(OCC_LIBRARY)
TKSTEPBase
TKSTEPAttr
TKHLR
TKFeat
)
ENDIF(OCC_LIBRARY)

331
cMake/UseLibPack8x.cmake Normal file
View File

@ -0,0 +1,331 @@
# ================================================================================
# == Win32 is default behaviour use the LibPack copied in Source tree ============
# --------------------------------------------------------------------------------
# General includes
link_directories(${FREECAD_LIBPACK_DIR}/lib)
include_directories(${FREECAD_LIBPACK_DIR}/include)
# OpenGL
set(OPENGL_gl_LIBRARY opengl32 glu32)
# Python
set(PYTHON_DEBUG_LIBRARY python26_d.lib)
set(PYTHON_LIBRARY python26.lib)
set(PYTHON_INCLUDE_PATH ${FREECAD_LIBPACK_DIR}/include/python)
set(PYTHON_EXECUTABLE ${FREECAD_LIBPACK_DIR}/bin/python.exe)
set(PYTHONLIBS_FOUND TRUE)
# XercesC
set(XERCESC_INCLUDE_DIR ${FREECAD_LIBPACK_DIR}/include/xercesc)
set(XERCESC_LIBRARIES xerces-c_2.lib)
set(XERCESC_DEBUG_LIBRARIES xerces-c_2D.lib)
set(XERCESC_FOUND TRUE)
# Boost
set(Boost_INCLUDE_DIR ${FREECAD_LIBPACK_DIR}/include/boost)
set(Boost_LIBRARIES
optimized boost_filesystem-vc90-mt-1_48.lib
optimized boost_system-vc90-mt-1_48.lib
optimized boost_graph-vc90-mt-1_48.lib
optimized boost_program_options-vc90-mt-1_48.lib
optimized boost_regex-vc90-mt-1_48.lib
optimized boost_signals-vc90-mt-1_48.lib
optimized boost_thread-vc90-mt-1_48.lib
)
set(Boost_DEBUG_LIBRARIES
debug boost_filesystem-vc90-mt-gd-1_48.lib
debug boost_date_time-vc90-mt-gd-1_48.lib
debug boost_filesystem-vc90-mt-gd-1_48.lib
debug boost_iostreams-vc90-mt-gd-1_48.lib
debug boost_math_c99f-vc90-mt-gd-1_48.lib
debug boost_math_tr1f-vc90-mt-gd-1_48.lib
debug boost_thread-vc90-mt-gd-1_48.lib
debug boost_system-vc90-mt-gd-1_48.lib
debug boost_graph-vc90-mt-gd-1_48.lib
debug boost_program_options-vc90-mt-gd-1_48.lib
debug boost_regex-vc90-mt-gd-1_48.lib
debug boost_signals-vc90-mt-gd-1_48.lib
)
set(Boost_FOUND TRUE)
# Zlib
set(ZLIB_INCLUDE_DIR ${FREECAD_LIBPACK_DIR}/include/zlib)
set(ZLIB_LIBRARIES zdll.lib)
set(ZLIB_FOUND TRUE)
# SMESH
set(SMESH_INCLUDE_DIR ${FREECAD_LIBPACK_DIR}/include/smesh)
set(SMESH_LIBRARIES
StdMeshers.lib
MEFISTO2.lib
SMESH.lib
DriverUNV.lib
SMESHDS.lib
DriverSTL.lib
DriverDAT.lib
Driver.lib
SMDS.lib
)
set(SMESH_FOUND TRUE)
# Coin3D
set(COIN3D_INCLUDE_DIR ${FREECAD_LIBPACK_DIR}/include/coin)
set(COIN3D_LIBRARY_DEBUG coin3d.lib)
set(COIN3D_LIBRARY_RELEASE coin3.lib)
set(COIN3D_FOUND TRUE)
# QT
set(QT_INCLUDE_DIR
${FREECAD_LIBPACK_DIR}/include/QT/
${FREECAD_LIBPACK_DIR}/include/QT/Qt
${FREECAD_LIBPACK_DIR}/include/QT/QtCore
${FREECAD_LIBPACK_DIR}/include/QT/QtGui
${FREECAD_LIBPACK_DIR}/include/QT/QtDesigner
${FREECAD_LIBPACK_DIR}/include/QT/QtSvg
${FREECAD_LIBPACK_DIR}/include/QT/QtNetwork
${FREECAD_LIBPACK_DIR}/include/QT/QtSql
${FREECAD_LIBPACK_DIR}/include/QT/QtTest
${FREECAD_LIBPACK_DIR}/include/QT/QtUiTools
${FREECAD_LIBPACK_DIR}/include/QT/QtXml
${FREECAD_LIBPACK_DIR}/include/QT/QtOpenGl
${FREECAD_LIBPACK_DIR}/include/QT/QtWebKit
)
set(QT_QTCORE_INCLUDE_DIR
${FREECAD_LIBPACK_DIR}/include/QT/
${FREECAD_LIBPACK_DIR}/include/QT/QtCore
)
set(QT_LIBRARIES
optimized QtCore4.lib
optimized QtGui4.lib
optimized QtDesigner4.lib
optimized QtSvg4.lib
optimized QtNetwork4.lib
optimized QtSql4.lib
optimized QtTest4.lib
optimized QtXml4.lib
optimized QtOpenGl4.lib
optimized QtWebKit4.lib
)
set(QT_DEBUG_LIBRARIES
debug QtCored4.lib
debug QtGuid4.lib
debug QtDesignerd4.lib
debug QtSvgd4.lib
debug QtNetworkd4.lib
debug QtSqld4.lib
debug QtTestd4.lib
debug QtXmld4.lib
debug QtOpenGld4.lib
debug QtWebKitd4.lib
)
set(QT_QTCORE_LIBRARY_DEBUG
debug QtCored4.lib
)
set(QT_QTCORE_LIBRARY
optimized QtCore4.lib
)
set(QT_UIC_EXECUTABLE ${FREECAD_LIBPACK_DIR}/bin/uic.exe)
set(QT_MOC_EXECUTABLE ${FREECAD_LIBPACK_DIR}/bin/moc.exe)
set(QT_RCC_EXECUTABLE ${FREECAD_LIBPACK_DIR}/bin/rcc.exe)
set(QT_HELPCOMPILER_EXECUTABLE ${FREECAD_LIBPACK_DIR}/bin/qhelpgenerator.exe)
set(QT_COLLECTIOMGENERATOR_EXECUTABLE ${FREECAD_LIBPACK_DIR}/bin/qcollectiongenerator.exe)
MACRO (QT4_EXTRACT_OPTIONS _qt4_files _qt4_options)
SET(${_qt4_files})
SET(${_qt4_options})
#SET(_QT4_DOING_OPTIONS FALSE)
FOREACH(_currentArg ${ARGN})
# IF ("${_currentArg}" STREQUAL "OPTIONS")
# SET(_QT4_DOING_OPTIONS TRUE)
# ELSE ("${_currentArg}" STREQUAL "OPTIONS")
# IF(_QT4_DOING_OPTIONS)
# LIST(APPEND ${_qt4_options} "${_currentArg}")
# ELSE(_QT4_DOING_OPTIONS)
LIST(APPEND ${_qt4_files} "${_currentArg}")
# ENDIF(_QT4_DOING_OPTIONS)
# ENDIF ("${_currentArg}" STREQUAL "OPTIONS")
ENDFOREACH(_currentArg)
ENDMACRO (QT4_EXTRACT_OPTIONS)
# macro used to create the names of output files preserving relative dirs
MACRO (QT4_MAKE_OUTPUT_FILE infile prefix ext outfile )
STRING(LENGTH ${CMAKE_CURRENT_BINARY_DIR} _binlength)
STRING(LENGTH ${infile} _infileLength)
SET(_checkinfile ${CMAKE_CURRENT_SOURCE_DIR})
IF(_infileLength GREATER _binlength)
STRING(SUBSTRING "${infile}" 0 ${_binlength} _checkinfile)
IF(_checkinfile STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
FILE(RELATIVE_PATH rel ${CMAKE_CURRENT_BINARY_DIR} ${infile})
ELSE(_checkinfile STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
FILE(RELATIVE_PATH rel ${CMAKE_CURRENT_SOURCE_DIR} ${infile})
ENDIF(_checkinfile STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
ELSE(_infileLength GREATER _binlength)
FILE(RELATIVE_PATH rel ${CMAKE_CURRENT_SOURCE_DIR} ${infile})
ENDIF(_infileLength GREATER _binlength)
SET(_outfile "${CMAKE_CURRENT_BINARY_DIR}/${rel}")
STRING(REPLACE ".." "__" _outfile ${_outfile})
GET_FILENAME_COMPONENT(outpath ${_outfile} PATH)
GET_FILENAME_COMPONENT(_outfile ${_outfile} NAME_WE)
FILE(MAKE_DIRECTORY ${outpath})
SET(${outfile} ${outpath}/${prefix}${_outfile}.${ext})
ENDMACRO (QT4_MAKE_OUTPUT_FILE )
MACRO (QT4_WRAP_CPP outfiles )
QT4_EXTRACT_OPTIONS(moc_files moc_options ${ARGN})
SET(ARGN)
foreach(it ${moc_files})
get_filename_component(it ${it} ABSOLUTE)
QT4_MAKE_OUTPUT_FILE(${it} moc_ cpp outfile)
ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
COMMAND ${QT_MOC_EXECUTABLE}
ARGS ${moc_options} ${it} -o ${outfile}
MAIN_DEPENDENCY ${it}
)
SET(${outfiles} ${${outfiles}} ${outfile})
endforeach(it)
ENDMACRO (QT4_WRAP_CPP)
# This is a special version of the built in macro qt4_wrap_cpp
# It is required since moc'ed files are now included instead of being added to projects directly
# It adds a reverse dependency to solve this
# This has the unfortunate side effect that some files are always rebuilt
# There is probably a cleaner solution than this
include(AddFileDependencies)
macro(fc_wrap_cpp outfiles )
QT4_EXTRACT_OPTIONS(moc_files moc_options ${ARGN})
SET(ARGN)
foreach(it ${moc_files})
get_filename_component(it ${it} ABSOLUTE)
QT4_MAKE_OUTPUT_FILE(${it} moc_ cpp outfile)
ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
COMMAND ${QT_MOC_EXECUTABLE}
ARGS ${moc_options} ${it} -o ${outfile}
MAIN_DEPENDENCY ${it}
)
SET(${outfiles} ${${outfiles}} ${outfile})
add_file_dependencies(${it} ${outfile})
endforeach(it)
endmacro(fc_wrap_cpp)
MACRO (QT4_ADD_RESOURCES outfiles )
QT4_EXTRACT_OPTIONS(rcc_files rcc_options ${ARGN})
SET(ARGN)
FOREACH (it ${rcc_files})
GET_FILENAME_COMPONENT(outfilename ${it} NAME_WE)
GET_FILENAME_COMPONENT(infile ${it} ABSOLUTE)
GET_FILENAME_COMPONENT(rc_path ${infile} PATH)
SET(outfile ${CMAKE_CURRENT_BINARY_DIR}/qrc_${outfilename}.cxx)
# parse file for dependencies
# all files are absolute paths or relative to the location of the qrc file
FILE(READ "${infile}" _RC_FILE_CONTENTS)
STRING(REGEX MATCHALL "<file[^<]+" _RC_FILES "${_RC_FILE_CONTENTS}")
SET(_RC_DEPENDS)
FOREACH(_RC_FILE ${_RC_FILES})
STRING(REGEX REPLACE "^<file[^>]*>" "" _RC_FILE "${_RC_FILE}")
STRING(REGEX MATCH "^/|([A-Za-z]:/)" _ABS_PATH_INDICATOR "${_RC_FILE}")
IF(NOT _ABS_PATH_INDICATOR)
SET(_RC_FILE "${rc_path}/${_RC_FILE}")
ENDIF(NOT _ABS_PATH_INDICATOR)
SET(_RC_DEPENDS ${_RC_DEPENDS} "${_RC_FILE}")
ENDFOREACH(_RC_FILE)
ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
COMMAND ${QT_RCC_EXECUTABLE}
ARGS ${rcc_options} -name ${outfilename} -o ${outfile} ${infile}
MAIN_DEPENDENCY ${infile}
DEPENDS ${_RC_DEPENDS})
SET(${outfiles} ${${outfiles}} ${outfile})
ENDFOREACH (it)
ENDMACRO (QT4_ADD_RESOURCES)
MACRO (QT4_WRAP_UI outfiles )
QT4_EXTRACT_OPTIONS(ui_files ui_options ${ARGN})
FOREACH (it ${ui_files})
GET_FILENAME_COMPONENT(outfile ${it} NAME_WE)
GET_FILENAME_COMPONENT(infile ${it} ABSOLUTE)
SET(outfile ${CMAKE_CURRENT_BINARY_DIR}/ui_${outfile}.h)
ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
COMMAND ${QT_UIC_EXECUTABLE}
ARGS -o ${outfile} ${infile}
MAIN_DEPENDENCY ${infile})
SET(${outfiles} ${${outfiles}} ${outfile})
ENDFOREACH (it)
ENDMACRO (QT4_WRAP_UI)
set(QT4_FOUND TRUE)
# SoQt
set(SOQT_INCLUDE_DIR ${FREECAD_LIBPACK_DIR}/include/soqt)
set(SOQT_LIBRARY_RELEASE soqt1.lib)
set(SOQT_LIBRARY_DEBUG soqt1d.lib)
set(SOQT_FOUND TRUE)
# OpenCV
set(OPENCV_INCLUDE_DIR ${FREECAD_LIBPACK_DIR}/include/opencv)
set(OPENCV_LIBRARIES cv.lib cvaux.lib cxcore.lib cxts.lib highgui.lib)
set(OPENCV_FOUND TRUE)
# OCC
set(OCC_INCLUDE_DIR ${FREECAD_LIBPACK_DIR}/include/OpenCascade)
set(OCC_LIBRARIES
TKFillet
TKMesh
TKernel
TKG2d
TKG3d
TKMath
TKIGES
TKSTL
TKShHealing
TKXSBase
TKBool
TKXSBase
TKXCAF
TKLCAF
TKCAF
TKSTEP
TKIGES
TKXDESTEP
TKXDEIGES
TKBO
TKBRep
TKTopAlgo
TKGeomAlgo
TKGeomBase
TKOffset
TKPrim
TKSTEP
TKSTEPBase
TKSTEPAttr
TKHLR
)
set(OCC_LIBRARY_DIR
${FREECAD_LIBPACK_DIR}/lib
)
set(OCC_FOUND TRUE)
SET(EIGEN2_INCLUDE_DIR ${FREECAD_LIBPACK_DIR}/include/eigen2)
set(EIGEN2_FOUND TRUE)
SET(EIGEN3_INCLUDE_DIR ${FREECAD_LIBPACK_DIR}/include/eigen3)
set(EIGEN3_FOUND TRUE)

View File

@ -329,6 +329,7 @@ set(OCC_LIBRARIES
TKSTEPBase
TKSTEPAttr
TKHLR
TKFeat
)
set(OCC_LIBRARY_DIR
${FREECAD_LIBPACK_DIR}/lib

View File

@ -795,6 +795,26 @@ AC_ARG_ENABLE([sandbox],
AM_CONDITIONAL(BUILD_SANDBOX, test x"$fc_set_sandbox" = xtrue)
AC_ARG_ENABLE([assembly],
AC_HELP_STRING([--enable-assembly], [Enable the build of the Assembly module (disabled by default)]),
[case $enableval in
no | false) fc_set_assembly=false ;;
*) fc_set_assembly=true ;;
esac],
[fc_set_assembly=false])
AM_CONDITIONAL(BUILD_ASSEMBLY, test x"$fc_set_assembly" = xtrue)
AC_ARG_ENABLE([cam],
AC_HELP_STRING([--enable-cam], [Enable the build of the Cam module (disabled by default)]),
[case $enableval in
no | false) fc_set_cam=false ;;
*) fc_set_cam=true ;;
esac],
[fc_set_cam=false])
AM_CONDITIONAL(BUILD_CAM, test x"$fc_set_cam" = xtrue)
dnl Check if you want debug information enabled, or not
dnl **************************************************************************
@ -952,6 +972,13 @@ src/Main/Makefile
src/Doc/Makefile
src/Doc/BuildDevDoc.cfg
src/Mod/Makefile
src/Mod/Assembly/App/Makefile
src/Mod/Assembly/Gui/Resources/Makefile
src/Mod/Assembly/Gui/Makefile
src/Mod/Assembly/Makefile
src/Mod/Cam/App/Makefile
src/Mod/Cam/Gui/Makefile
src/Mod/Cam/Makefile
src/Mod/Part/Makefile
src/Mod/Part/App/Makefile
src/Mod/Part/Gui/Makefile
@ -1055,7 +1082,10 @@ AC_MSG_NOTICE([
RTTI enabled (forced): true
Compiler warnings enabled: $fc_set_warn
installation prefix: $prefix
enable-assembly: $fc_set_assembly
enable-cam: $fc_set_cam
enable-sandbox: $fc_set_sandbox
enable-template: $fc_set_template
Now, run 'make' to build FreeCAD.
**************************************************************************

View File

@ -7,8 +7,8 @@ by the authors who actually wrote it.
Version 2, June 1991
Copyright (C) 1991 Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA.
51 Franklin Street - Fifth Floor
Boston, MA 02110-1301, USA.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.

BIN
data/tests/PadTest.fcstd Normal file

Binary file not shown.

BIN
data/tests/PocketTest.fcstd Normal file

Binary file not shown.

View File

@ -20,7 +20,7 @@ elseif(FREECAD_BUILD_GUI AND FREECAD_LIBPACK_CHECKFILE7X)
#endif(MINGW)
# applies for Unix, MinGW and Windows with custom LibPack
elseif(FREECAD_BUILD_GUI)
if (NOT FREECAD_BUILD_DEBIAN)
if (NOT FREECAD_USE_EXTERNAL_PIVY)
find_path(COIN_VERSION3 Inventor/scxml/ScXML.h ${COIN3D_INCLUDE_DIR})
if (COIN_VERSION3)
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/Pivy-0.5)
@ -31,7 +31,7 @@ elseif(FREECAD_BUILD_GUI)
add_subdirectory(Pivy)
endif (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/Pivy)
endif(COIN_VERSION3)
endif (NOT FREECAD_BUILD_DEBIAN)
endif (NOT FREECAD_USE_EXTERNAL_PIVY)
endif(FREECAD_BUILD_GUI AND FREECAD_LIBPACK_CHECKFILE6X)
# For Windows we have all stuff in the LibPack

View File

@ -88,7 +88,7 @@ if(MSVC)
debug ${PYTHON_DEBUG_LIBRARY}
optimized ${PYTHON_LIBRARY})
else(MSVC)
set(CoinPy_LIBS
set(SoQtPy_LIBS
${SOQT_LIBRARIES}
${COIN3D_LIBRARY}
${PYTHON_LIBRARY})

View File

@ -173,7 +173,7 @@ FILE(GLOB StdMeshers_source_files src/StdMeshers/*.cpp src/MEFISTO2/*.cpp src/ME
INCLUDE_DIRECTORIES(src/StdMeshers)
ADD_LIBRARY(StdMeshers SHARED ${StdMeshers_source_files})
TARGET_LINK_LIBRARIES(StdMeshers SMESH TKernel TKMath TKAdvTools f2c gfortran)
TARGET_LINK_LIBRARIES(StdMeshers SMESH TKernel TKMath TKAdvTools gfortran)
SET(StdMeshers_CFLAGS "")
IF(WIN32)
SET(StdMeshers_CFLAGS "-DSTDMESHERS_EXPORTS -DMEFISTO2D_EXPORTS")

View File

@ -63,6 +63,11 @@
#include "SMESHDS_Mesh.hxx"
#include "SMESHDS_GroupBase.hxx"
#include <cmath>
#ifndef PI
#define PI M_PI
#endif
/*
AUXILIARY METHODS

View File

@ -82,6 +82,10 @@
#include <numeric>
#include <limits>
#ifndef PI
#define PI M_PI
#endif
#define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
using namespace std;

View File

@ -74,6 +74,11 @@
#include "SMESH_subMesh.hxx"
#include "utilities.h"
#include <cmath>
#ifndef PI
#define PI M_PI
#endif
using namespace std;

View File

@ -37,6 +37,11 @@
#include <TopExp.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <cmath>
#ifndef PI
#define PI M_PI
#endif
using namespace std;

View File

@ -56,6 +56,11 @@
#include <list>
#include <set>
#include <vector>
#include <cmath>
#ifndef PI
#define PI M_PI
#endif
#ifdef _DEBUG_

View File

@ -47,6 +47,11 @@ typedef NCollection_Array1<TColStd_SequenceOfInteger> StdMeshers_Array1OfSequenc
#include <SMESH_Array1.hxx>
typedef SMESH_Array1<TColStd_SequenceOfInteger> StdMeshers_Array1OfSequenceOfInteger;
#endif
#include <cmath>
#ifndef PI
#define PI M_PI
#endif
//=======================================================================
//function : StdMeshers_QuadToTriaAdaptor

View File

@ -54,6 +54,11 @@
#include <TColgp_SequenceOfPnt2d.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <cmath>
#ifndef PI
#define PI M_PI
#endif
using namespace std;

View File

@ -1188,13 +1188,13 @@ void Application::processCmdLineFiles(void)
Application::_pcSingleton->openDocument(File.filePath().c_str());
}
else if (File.hasExtension("fcscript")||File.hasExtension("fcmacro")) {
Base::Interpreter().runFile(File.filePath().c_str(), false);
Base::Interpreter().runFile(File.filePath().c_str(), true);
}
else if (File.hasExtension("py")) {
//FIXME: Does this make any sense? I think we should do the ame as for
// fcmacro or fcscript.
//Base::Interpreter().loadModule(File.fileNamePure().c_str());
Base::Interpreter().runFile(File.filePath().c_str(), false);
Base::Interpreter().runFile(File.filePath().c_str(), true);
}
else {
std::vector<std::string> mods = App::GetApplication().getImportModules(Ext.c_str());
@ -1210,8 +1210,7 @@ void Application::processCmdLineFiles(void)
}
}
catch (const Base::SystemExitException&) {
Base::PyGILStateLocker locker;
Base::Interpreter().systemExit();
throw; // re-throw to main() function
}
catch (const Base::Exception& e) {
Console().Error("Exception while processing file: %s [%s]\n", File.filePath().c_str(), e.what());
@ -1220,6 +1219,32 @@ void Application::processCmdLineFiles(void)
Console().Error("Unknown exception while processing file: %s \n", File.filePath().c_str());
}
}
const std::map<std::string,std::string>& cfg = Application::Config();
std::map<std::string,std::string>::const_iterator it = cfg.find("SaveFile");
if (it != cfg.end()) {
std::string output = it->second;
Base::FileInfo fi(output);
std::string ext = fi.extension();
try {
std::vector<std::string> mods = App::GetApplication().getExportModules(ext.c_str());
if (!mods.empty()) {
Base::Interpreter().loadModule(mods.front().c_str());
Base::Interpreter().runStringArg("import %s",mods.front().c_str());
Base::Interpreter().runStringArg("%s.export(App.ActiveDocument.Objects, '%s')"
,mods.front().c_str(),output.c_str());
}
else {
Console().Warning("File format not supported: %s \n", output.c_str());
}
}
catch (const Base::Exception& e) {
Console().Error("Exception while saving to file: %s [%s]\n", output.c_str(), e.what());
}
catch (...) {
Console().Error("Unknown exception while saving to file: %s \n", output.c_str());
}
}
}
void Application::runApplication()
@ -1314,7 +1339,7 @@ void Application::LoadParameters(void)
// fix weird error while linking boost (all versions of VC)
// VS2010: https://sourceforge.net/apps/phpbb/free-cad/viewtopic.php?f=4&t=1886&p=12553&hilit=boost%3A%3Afilesystem%3A%3Aget#p12553
namespace boost { namespace program_options { std::string arg="arg"; } }
#if (defined (BOOST_VERSION) && (BOOST_VERSION == 104100))
#if (defined (BOOST_VERSION) && (BOOST_VERSION >= 104100))
namespace boost { namespace program_options {
const unsigned options_description::m_default_line_length = 80;
} }
@ -1419,9 +1444,14 @@ void Application::ParseOptions(int ac, char ** av)
// in config file, but will not be shown to the user.
boost::program_options::options_description hidden("Hidden options");
hidden.add_options()
("input-file", boost::program_options::value< vector<string> >(), "input file")
("input-file", boost::program_options::value< vector<string> >(), "input file")
("output", boost::program_options::value<string>(),"output file")
("hidden", "don't show the main window")
// this are to ignore for the window system (QApplication)
("style", boost::program_options::value< string >(), "set the application GUI style")
("stylesheet", boost::program_options::value< string >(), "set the application stylesheet")
("session", boost::program_options::value< string >(), "restore the application from an earlier session")
("reverse", "set the application's layout direction from right to left")
("display", boost::program_options::value< string >(), "set the X-Server")
("geometry ", boost::program_options::value< string >(), "set the X-Window geometry")
("font", boost::program_options::value< string >(), "set the X-Window font")
@ -1444,11 +1474,35 @@ void Application::ParseOptions(int ac, char ** av)
//x11.add_options()
// ("display", boost::program_options::value< string >(), "set the X-Server")
// ;
//0000723: improper handling of qt specific comand line arguments
std::vector<std::string> args;
bool merge=false;
for (int i=1; i<ac; i++) {
if (merge) {
merge = false;
args.back() += "=";
args.back() += av[i];
}
else {
args.push_back(av[i]);
}
if (strcmp(av[i],"-style") == 0) {
merge = true;
}
else if (strcmp(av[i],"-stylesheet") == 0) {
merge = true;
}
else if (strcmp(av[i],"-session") == 0) {
merge = true;
}
}
options_description cmdline_options;
// 0000659: SIGABRT on startup in boost::program_options (Boost 1.49)
// Add some text to the constructor
options_description cmdline_options("Command-line options");
cmdline_options.add(generic).add(config).add(hidden);
boost::program_options::options_description config_file_options;
boost::program_options::options_description config_file_options("Config");
config_file_options.add(config).add(hidden);
boost::program_options::options_description visible("Allowed options");
@ -1459,28 +1513,32 @@ void Application::ParseOptions(int ac, char ** av)
variables_map vm;
try {
store( boost::program_options::command_line_parser(ac, av).
store( boost::program_options::command_line_parser(args).
options(cmdline_options).positional(p).extra_parser(customSyntax).run(), vm);
std::ifstream ifs("FreeCAD.cfg");
store(parse_config_file(ifs, config_file_options), vm);
if (ifs)
store(parse_config_file(ifs, config_file_options), vm);
notify(vm);
}
catch (const std::exception& e) {
cerr << e.what() << endl << endl << visible << endl;
exit(1);
std::stringstream str;
str << e.what() << endl << endl << visible << endl;
throw UnknownProgramOption(str.str());
}
catch (...) {
cerr << "Wrong or unknown option, bailing out!" << endl << endl << visible << endl;
exit(1);
std::stringstream str;
str << "Wrong or unknown option, bailing out!" << endl << endl << visible << endl;
throw UnknownProgramOption(str.str());
}
if (vm.count("help")) {
cout << mConfig["ExeName"] << endl << endl;
cout << "For detailed descripton see http://free-cad.sf.net" << endl<<endl;
cout << "Usage: " << mConfig["ExeName"] << " [options] File1 File2 ..." << endl << endl;
cout << visible << endl;
exit(0);
std::stringstream str;
str << mConfig["ExeName"] << endl << endl;
str << "For detailed descripton see http://free-cad.sf.net" << endl<<endl;
str << "Usage: " << mConfig["ExeName"] << " [options] File1 File2 ..." << endl << endl;
str << visible << endl;
throw Base::ProgramInformation(str.str());
}
if (vm.count("response-file")) {
@ -1488,9 +1546,10 @@ void Application::ParseOptions(int ac, char ** av)
std::ifstream ifs(vm["response-file"].as<string>().c_str());
if (!ifs) {
Base::Console().Error("Could no open the response file\n");
cerr << "Could no open the response file: '"
<< vm["response-file"].as<string>() << "'" << endl;
exit(1);
std::stringstream str;
str << "Could no open the response file: '"
<< vm["response-file"].as<string>() << "'" << endl;
throw Base::UnknownProgramOption(str.str());
}
// Read the whole file into a string
stringstream ss;
@ -1501,14 +1560,15 @@ void Application::ParseOptions(int ac, char ** av)
vector<string> args;
copy(tok.begin(), tok.end(), back_inserter(args));
// Parse the file and store the options
store( boost::program_options::command_line_parser(ac, av).
store( boost::program_options::command_line_parser(args).
options(cmdline_options).positional(p).extra_parser(customSyntax).run(), vm);
}
if (vm.count("version")) {
std::cout << mConfig["ExeName"] << " " << mConfig["ExeVersion"]
<< " Revision: " << mConfig["BuildRevision"] << std::endl;
exit(0);
std::stringstream str;
str << mConfig["ExeName"] << " " << mConfig["ExeVersion"]
<< " Revision: " << mConfig["BuildRevision"] << std::endl;
throw Base::ProgramInformation(str.str());
}
if (vm.count("console")) {
@ -1548,6 +1608,15 @@ void Application::ParseOptions(int ac, char ** av)
mConfig["OpenFileCount"] = buffer.str();
}
if (vm.count("output")) {
string file = vm["output"].as<string>();
mConfig["SaveFile"] = file;
}
if (vm.count("hidden")) {
mConfig["StartHidden"] = "1";
}
if (vm.count("write-log")) {
mConfig["LoggingFile"] = "1";
//mConfig["LoggingFileName"] = vm["write-log"].as<string>();

View File

@ -383,23 +383,36 @@ PyObject* Application::sGetVersion(PyObject * /*self*/, PyObject *args,PyObject
if (!PyArg_ParseTuple(args, "")) // convert args: Python->C
return NULL; // NULL triggers exception
PyObject* pList = PyList_New(5);
PyObject *pItem;
pItem = PyString_FromString(Application::Config()["BuildVersionMajor"].c_str());
PyList_SetItem(pList, 0, pItem);
pItem = PyString_FromString(Application::Config()["BuildVersionMinor"].c_str());
PyList_SetItem(pList, 1, pItem);
pItem = PyString_FromString(Application::Config()["BuildRevision"].c_str());
PyList_SetItem(pList, 2, pItem);
pItem = PyString_FromString(Application::Config()["BuildRepositoryURL"].c_str());
PyList_SetItem(pList, 4, pItem);
pItem = PyString_FromString(Application::Config()["BuildCurrentDate"].c_str());
PyList_SetItem(pList, 6, pItem);
Py::List list;
const std::map<std::string, std::string>& cfg = Application::Config();
std::map<std::string, std::string>::const_iterator it;
return pList;
it = cfg.find("BuildVersionMajor");
list.append(Py::String(it != cfg.end() ? it->second : ""));
it = cfg.find("BuildVersionMinor");
list.append(Py::String(it != cfg.end() ? it->second : ""));
it = cfg.find("BuildRevision");
list.append(Py::String(it != cfg.end() ? it->second : ""));
it = cfg.find("BuildRepositoryURL");
list.append(Py::String(it != cfg.end() ? it->second : ""));
it = cfg.find("BuildRevisionDate");
list.append(Py::String(it != cfg.end() ? it->second : ""));
it = cfg.find("BuildRevisionBranch");
if (it != cfg.end())
list.append(Py::String(it->second));
it = cfg.find("BuildRevisionHash");
if (it != cfg.end())
list.append(Py::String(it->second));
return Py::new_reference_to(list);
}
PyObject* Application::sAddImportType(PyObject * /*self*/, PyObject *args,PyObject * /*kwd*/)
{
char *psKey,*psMod;

View File

@ -52,6 +52,7 @@ recompute path. Also enables more complicated dependencies beyond trees.
#include "PreCompiled.h"
#ifndef _PreComp_
# include <algorithm>
# include <sstream>
# include <climits>
#endif
@ -62,6 +63,7 @@ recompute path. Also enables more complicated dependencies beyond trees.
#include <boost/graph/visitors.hpp>
#include <boost/graph/graphviz.hpp>
#include <boost/bind.hpp>
#include <boost/regex.hpp>
#include "Document.h"
@ -845,6 +847,31 @@ unsigned int Document::getMemSize (void) const
return size;
}
void Document::exportGraphviz(std::ostream& out)
{
std::vector<std::string> names;
names.reserve(d->objectMap.size());
DependencyList DepList;
std::map<DocumentObject*,Vertex> VertexObjectList;
// Filling up the adjacency List
for (std::map<std::string,DocumentObject*>::const_iterator It = d->objectMap.begin(); It != d->objectMap.end();++It) {
// add the object as Vertex and remember the index
VertexObjectList[It->second] = add_vertex(DepList);
names.push_back(It->second->Label.getValue());
}
// add the edges
for (std::map<std::string,DocumentObject*>::const_iterator It = d->objectMap.begin(); It != d->objectMap.end();++It) {
std::vector<DocumentObject*> OutList = It->second->getOutList();
for (std::vector<DocumentObject*>::const_iterator It2=OutList.begin();It2!=OutList.end();++It2) {
if (*It2)
add_edge(VertexObjectList[It->second],VertexObjectList[*It2],DepList);
}
}
boost::write_graphviz(out, DepList, boost::make_label_writer(&(names[0])));
}
// Save the document under the name it has been opened
bool Document::save (void)
{
@ -1452,20 +1479,48 @@ void Document::breakDependency(DocumentObject* pcObject, bool clear)
}
}
}
else if (pt->second->getTypeId().isDerivedFrom(PropertyLinkSubList::getClassTypeId())) {
PropertyLinkSubList* link = static_cast<PropertyLinkSubList*>(pt->second);
if (link->getContainer() == pcObject && clear) {
link->setValues(std::vector<DocumentObject*>(), std::vector<std::string>());
}
else {
const std::vector<DocumentObject*>& links = link->getValues();
const std::vector<std::string>& sub = link->getSubValues();
std::vector<DocumentObject*> newLinks;
std::vector<std::string> newSub;
if (std::find(links.begin(), links.end(), pcObject) != links.end()) {
std::vector<DocumentObject*>::const_iterator jt;
std::vector<std::string>::const_iterator kt;
for (jt = links.begin(),kt = sub.begin(); jt != links.end() && kt != sub.end(); ++jt, ++kt) {
if (*jt != pcObject) {
newLinks.push_back(*jt);
newSub.push_back(*kt);
}
}
link->setValues(newLinks, newSub);
}
}
}
}
}
}
DocumentObject* Document::_copyObject(DocumentObject* obj, std::map<DocumentObject*,
DocumentObject*>& copy_map, bool recursive)
DocumentObject*>& copy_map, bool recursive,
bool keepdigitsatend)
{
if (!obj) return 0;
// remove number from end to avoid lengthy names
std::string objname = obj->getNameInDocument();
size_t lastpos = objname.length()-1;
while (objname[lastpos] >= 48 && objname[lastpos] <= 57)
lastpos--;
objname = objname.substr(0, lastpos+1);
if (!keepdigitsatend) {
size_t lastpos = objname.length()-1;
while (objname[lastpos] >= 48 && objname[lastpos] <= 57)
lastpos--;
objname = objname.substr(0, lastpos+1);
}
DocumentObject* copy = addObject(obj->getTypeId().getName(),objname.c_str());
if (!copy) return 0;
copy->addDynamicProperties(obj);
@ -1485,7 +1540,7 @@ DocumentObject* Document::_copyObject(DocumentObject* obj, std::map<DocumentObje
static_cast<PropertyLink*>(it->second)->setValue(pt->second);
}
else if (recursive) {
DocumentObject* link_copy = _copyObject(link, copy_map, recursive);
DocumentObject* link_copy = _copyObject(link, copy_map, recursive, keepdigitsatend);
copy_map[link] = link_copy;
static_cast<PropertyLink*>(it->second)->setValue(link_copy);
}
@ -1504,7 +1559,7 @@ DocumentObject* Document::_copyObject(DocumentObject* obj, std::map<DocumentObje
links_copy.push_back(pt->second);
}
else {
links_copy.push_back(_copyObject(*jt, copy_map, recursive));
links_copy.push_back(_copyObject(*jt, copy_map, recursive, keepdigitsatend));
copy_map[*jt] = links_copy.back();
}
}
@ -1534,10 +1589,10 @@ DocumentObject* Document::_copyObject(DocumentObject* obj, std::map<DocumentObje
return copy;
}
DocumentObject* Document::copyObject(DocumentObject* obj, bool recursive)
DocumentObject* Document::copyObject(DocumentObject* obj, bool recursive, bool keepdigitsatend)
{
std::map<DocumentObject*, DocumentObject*> copy_map;
DocumentObject* copy = _copyObject(obj, copy_map, recursive);
DocumentObject* copy = _copyObject(obj, copy_map, recursive, keepdigitsatend);
return copy;
}
@ -1663,6 +1718,20 @@ std::vector<DocumentObject*> Document::getObjectsOfType(const Base::Type& typeId
return Objects;
}
std::vector<DocumentObject*> Document::findObjects(const Base::Type& typeId, const char* objname) const
{
boost::regex rx(objname);
boost::cmatch what;
std::vector<DocumentObject*> Objects;
for (std::vector<DocumentObject*>::const_iterator it = d->objectArray.begin(); it != d->objectArray.end(); ++it) {
if ((*it)->getTypeId().isDerivedFrom(typeId)) {
if (boost::regex_match((*it)->getNameInDocument(), what, rx))
Objects.push_back(*it);
}
}
return Objects;
}
int Document::countObjectsOfType(const Base::Type& typeId) const
{
int ct=0;

View File

@ -114,6 +114,7 @@ public:
/// Restore the document from the file in Property Path
void restore (void);
void exportObjects(const std::vector<App::DocumentObject*>&, std::ostream&);
void exportGraphviz(std::ostream&);
std::vector<App::DocumentObject*> importObjects(std::istream&);
/// Opens the document from its file name
//void open (void);
@ -140,7 +141,7 @@ public:
* are copied as well. By default \a recursive is false.
* Returns the copy of the object or 0 if the creation failed.
*/
DocumentObject* copyObject(DocumentObject* obj, bool recursive=false);
DocumentObject* copyObject(DocumentObject* obj, bool recursive=false, bool keepdigitsatend=false);
/** Move an object from another document to this document
* If \a recursive is true then all objects this object depends on
* are moved as well. By default \a recursive is false.
@ -161,6 +162,7 @@ public:
/// Returns a list of all Objects
std::vector<DocumentObject*> getObjects() const;
std::vector<DocumentObject*> getObjectsOfType(const Base::Type& typeId) const;
std::vector<DocumentObject*> findObjects(const Base::Type& typeId, const char* objname) const;
/// Returns an array with the correct types already.
template<typename T> inline std::vector<T*> getObjectsOfType() const;
int countObjectsOfType(const Base::Type& typeId) const;
@ -260,7 +262,7 @@ protected:
void _remObject(DocumentObject* pcObject);
void _addObject(DocumentObject* pcObject, const char* pObjectName);
DocumentObject* _copyObject(DocumentObject* obj, std::map<DocumentObject*,
DocumentObject*>&, bool recursive=false);
DocumentObject*>&, bool recursive=false, bool keepdigitsatend=false);
/// checks if a valid transaction is open
void _checkTransaction(void);
void breakDependency(DocumentObject* pcObject, bool clear);

View File

@ -37,7 +37,7 @@ PROPERTY_SOURCE(App::DocumentObjectGroup, App::DocumentObject)
DocumentObjectGroup::DocumentObjectGroup()
{
ADD_PROPERTY_TYPE(Group,(0),"Base",(App::PropertyType)(Prop_ReadOnly|Prop_Output),"List of referenced objects");
ADD_PROPERTY_TYPE(Group,(0),"Base",(App::PropertyType)(Prop_Output),"List of referenced objects");
}
DocumentObjectGroup::~DocumentObjectGroup()
@ -179,13 +179,13 @@ PyObject *DocumentObjectGroup::getPyObject()
return Py::new_reference_to(PythonObject);
}
// Python Sketcher feature ---------------------------------------------------------
// Python feature ---------------------------------------------------------
namespace App {
/// @cond DOXERR
PROPERTY_SOURCE_TEMPLATE(App::DocumentObjectGroupPython, App::DocumentObjectGroup)
template<> const char* App::DocumentObjectGroupPython::getViewProviderName(void) const {
return "Gui::ViewProviderDocumentObjectGroup";
return "Gui::ViewProviderDocumentObjectGroupPython";
}
/// @endcond

View File

@ -23,6 +23,11 @@
<UserDocu>Restore the document from disc</UserDocu>
</Documentation>
</Methode>
<Methode Name="exportGraphviz">
<Documentation>
<UserDocu>Export the dependencies of the objects as graph</UserDocu>
</Documentation>
</Methode>
<Methode Name="openTransaction">
<Documentation>
<UserDocu>Open a new Undo/Redo transaction.</UserDocu>

View File

@ -92,6 +92,25 @@ PyObject* DocumentPy::restore(PyObject * args)
Py_Return;
}
PyObject* DocumentPy::exportGraphviz(PyObject * args)
{
char* fn=0;
if (!PyArg_ParseTuple(args, "|s",&fn)) // convert args: Python->C
return NULL; // NULL triggers exception
if (fn) {
Base::FileInfo fi(fn);
Base::ofstream str(fi);
getDocumentPtr()->exportGraphviz(str);
str.close();
Py_Return;
}
else {
std::stringstream str;
getDocumentPtr()->exportGraphviz(str);
return PyString_FromString(str.str().c_str());
}
}
PyObject* DocumentPy::addObject(PyObject *args)
{
char *sType,*sName=0;
@ -163,12 +182,12 @@ PyObject* DocumentPy::removeObject(PyObject *args)
PyObject* DocumentPy::copyObject(PyObject *args)
{
PyObject *obj, *rec=0;
if (!PyArg_ParseTuple(args, "O!|O!",&(DocumentObjectPy::Type),&obj,&PyBool_Type,&rec))
PyObject *obj, *rec=0, *keep=0;
if (!PyArg_ParseTuple(args, "O!|O!O!",&(DocumentObjectPy::Type),&obj,&PyBool_Type,&rec,&PyBool_Type,&keep))
return NULL; // NULL triggers exception
DocumentObjectPy* docObj = static_cast<DocumentObjectPy*>(obj);
DocumentObject* copy = getDocumentPtr()->copyObject(docObj->getDocumentObjectPtr(), rec==Py_True);
DocumentObject* copy = getDocumentPtr()->copyObject(docObj->getDocumentObjectPtr(), rec==Py_True, keep==Py_True);
if (copy) {
return copy->getPyObject();
}
@ -290,42 +309,36 @@ PyObject* DocumentPy::findObjects(PyObject *args)
char *sType="App::DocumentObject", *sName=0;
if (!PyArg_ParseTuple(args, "|ss",&sType, &sName)) // convert args: Python->C
return NULL; // NULL triggers exception
Base::Type type = Base::Type::fromName(sType);
if (type == Base::Type::badType()) {
PyErr_Format(PyExc_Exception, "'%s' is not a valid type", sType);
return NULL;
}
if (!type.isDerivedFrom(App::DocumentObject::getClassTypeId())) {
PyErr_Format(PyExc_Exception, "Type '%s' does not inherit from 'App::DocumentObject'", sType);
return NULL;
}
std::vector<DocumentObject*> res;
std::vector<DocumentObject*> objs = getDocumentPtr()->getObjectsOfType(type);
if (sName) {
try {
boost::regex rx(sName);
boost::cmatch what;
for (std::vector<DocumentObject*>::const_iterator It = objs.begin();It != objs.end();++It) {
if (boost::regex_match((*It)->getNameInDocument(), what, rx))
res.push_back(*It);
}
}
catch (const boost::regex_error& e) {
PyErr_SetString(PyExc_RuntimeError, e.what());
return 0;
}
}
else {
res = objs;
}
Py_ssize_t index=0;
PyObject* list = PyList_New((Py_ssize_t)res.size());
for (std::vector<DocumentObject*>::const_iterator It = res.begin();It != res.end();++It, index++)
Base::Type type = Base::Type::fromName(sType);
if (type == Base::Type::badType()) {
PyErr_Format(PyExc_Exception, "'%s' is not a valid type", sType);
return NULL;
}
if (!type.isDerivedFrom(App::DocumentObject::getClassTypeId())) {
PyErr_Format(PyExc_Exception, "Type '%s' does not inherit from 'App::DocumentObject'", sType);
return NULL;
}
std::vector<DocumentObject*> res;
if (sName) {
try {
res = getDocumentPtr()->findObjects(type, sName);
}
catch (const boost::regex_error& e) {
PyErr_SetString(PyExc_RuntimeError, e.what());
return 0;
}
}
else {
res = getDocumentPtr()->getObjectsOfType(type);
}
Py_ssize_t index=0;
PyObject* list = PyList_New((Py_ssize_t)res.size());
for (std::vector<DocumentObject*>::const_iterator It = res.begin();It != res.end();++It, index++)
PyList_SetItem(list, index, (*It)->getPyObject());
return list;
}

View File

@ -257,13 +257,18 @@ void PropertyFileIncluded::setPyObject(PyObject *value)
void PropertyFileIncluded::Save (Base::Writer &writer) const
{
if (writer.isForceXML()) {
writer.Stream() << writer.ind() << "<FileIncluded file=\"\">" << endl;
// write the file in the XML stream
if (!_cValue.empty())
if (!_cValue.empty()) {
Base::FileInfo file(_cValue.c_str());
writer.Stream() << writer.ind() << "<FileIncluded data=\"" <<
file.fileName() << "\">" << std::endl;
// write the file in the XML stream
writer.incInd();
writer.insertBinFile(_cValue.c_str());
writer.Stream() << writer.ind() <<"</FileIncluded>" << endl ;
writer.decInd();
writer.Stream() << writer.ind() <<"</FileIncluded>" << endl;
}
else
writer.Stream() << writer.ind() << "<FileIncluded data=\"\"/>" << std::endl;
}
else {
// instead initiate an extra file
@ -280,23 +285,36 @@ void PropertyFileIncluded::Save (Base::Writer &writer) const
void PropertyFileIncluded::Restore(Base::XMLReader &reader)
{
reader.readElement("FileIncluded");
string file (reader.getAttribute("file") );
if (!file.empty()) {
// initate a file read
reader.addFile(file.c_str(),this);
// is in the document transient path
aboutToSetValue();
_cValue = getDocTransientPath() + "/" + file;
_BaseFileName = file;
hasSetValue();
if (reader.hasAttribute("file")) {
string file (reader.getAttribute("file") );
if (!file.empty()) {
// initate a file read
reader.addFile(file.c_str(),this);
// is in the document transient path
aboutToSetValue();
_cValue = getDocTransientPath() + "/" + file;
_BaseFileName = file;
hasSetValue();
}
}
// section is XML stream
else if (reader.hasAttribute("data")) {
string file (reader.getAttribute("data") );
if (!file.empty()) {
// is in the document transient path
aboutToSetValue();
_cValue = getDocTransientPath() + "/" + file;
reader.readBinFile(_cValue.c_str());
reader.readEndElement("FileIncluded");
_BaseFileName = file;
hasSetValue();
}
}
}
void PropertyFileIncluded::SaveDocFile (Base::Writer &writer) const
{
std::ifstream from(_cValue.c_str());
Base::ifstream from(Base::FileInfo(_cValue.c_str()));
if (!from)
throw Base::Exception("PropertyFileIncluded::SaveDocFile() "
"File in document transient dir deleted");
@ -311,7 +329,7 @@ void PropertyFileIncluded::SaveDocFile (Base::Writer &writer) const
void PropertyFileIncluded::RestoreDocFile(Base::Reader &reader)
{
std::ofstream to(_cValue.c_str());
Base::ofstream to(Base::FileInfo(_cValue.c_str()));
if (!to)
throw Base::Exception("PropertyFileIncluded::RestoreDocFile() "
"File in document transient dir deleted");
@ -328,10 +346,10 @@ void PropertyFileIncluded::RestoreDocFile(Base::Reader &reader)
Property *PropertyFileIncluded::Copy(void) const
{
PropertyFileIncluded *p= new PropertyFileIncluded();
PropertyFileIncluded *prop = new PropertyFileIncluded();
// remember the base name
p->_BaseFileName = _BaseFileName;
prop->_BaseFileName = _BaseFileName;
if (!_cValue.empty()) {
Base::FileInfo file(_cValue);
@ -343,11 +361,11 @@ Property *PropertyFileIncluded::Copy(void) const
bool done = file.renameFile(NewName.filePath().c_str());
assert(done);
// remember the new name for the Undo
Base::Console().Log("Copy this=%p Befor=%s After=%s\n",p,p->_cValue.c_str(),NewName.filePath().c_str());
p->_cValue = NewName.filePath().c_str();
Base::Console().Log("Copy this=%p Before=%s After=%s\n",prop,prop->_cValue.c_str(),NewName.filePath().c_str());
prop->_cValue = NewName.filePath().c_str();
}
return p;
return prop;
}
void PropertyFileIncluded::Paste(const Property &from)
@ -358,6 +376,9 @@ void PropertyFileIncluded::Paste(const Property &from)
file.deleteFile();
const PropertyFileIncluded &fileInc = dynamic_cast<const PropertyFileIncluded&>(from);
// set the base name
_BaseFileName = fileInc._BaseFileName;
if (!fileInc._cValue.empty()) {
// move the saved files back in place
Base::FileInfo NewFile(fileInc._cValue);

View File

@ -185,6 +185,9 @@ public:
/** This method returns a string representation of the property
*/
const Base::Matrix4D &getValue(void) const;
const char* getEditorName(void) const {
return "Gui::PropertyEditor::PropertyMatrixItem";
}
virtual PyObject *getPyObject(void);
virtual void setPyObject(PyObject *);

View File

@ -130,12 +130,18 @@ void PropertyLink::Restore(Base::XMLReader &reader)
assert(getContainer()->getTypeId().isDerivedFrom(App::DocumentObject::getClassTypeId()) );
if (name != "") {
DocumentObject *pcObject = static_cast<DocumentObject*>(getContainer())->
getDocument()->getObject(name.c_str());
if (!pcObject)
DocumentObject* parent = static_cast<DocumentObject*>(getContainer());
DocumentObject* object = parent->getDocument()->getObject(name.c_str());
if (!object) {
Base::Console().Warning("Lost link to '%s' while loading, maybe "
"an object was not loaded correctly\n",name.c_str());
setValue(pcObject);
}
else if (parent == object) {
Base::Console().Warning("Object '%s' links to itself, nullify it\n",name.c_str());
object = 0;
}
setValue(object);
}
else {
setValue(0);

View File

@ -35,6 +35,7 @@
#include <Base/Console.h>
#include <Base/Interpreter.h>
#include <iostream>
#include <boost/regex.hpp>
using namespace App;
@ -82,10 +83,20 @@ std::string PropertyPythonObject::toString() const
std::string repr;
Base::PyGILStateLocker lock;
try {
Py::Module pickle(PyImport_ImportModule("cPickle"),true);
Py::Module pickle(PyImport_ImportModule("json"),true);
Py::Callable method(pickle.getAttr(std::string("dumps")));
Py::Object dump;
if (this->object.hasAttr("__getstate__")) {
Py::Tuple args(0);
Py::Callable state(this->object.getAttr("__getstate__"));
dump = state.apply(args);
}
else if (this->object.hasAttr("__dict__")) {
dump = this->object.getAttr("__dict__");
}
Py::Tuple args(1);
args.setItem(0, this->object);
args.setItem(0, dump);
Py::Object res = method.apply(args);
Py::String str(res);
repr = str.as_std_string();
@ -102,12 +113,21 @@ void PropertyPythonObject::fromString(const std::string& repr)
{
Base::PyGILStateLocker lock;
try {
Py::Module pickle(PyImport_ImportModule("cPickle"),true);
Py::Module pickle(PyImport_ImportModule("json"),true);
Py::Callable method(pickle.getAttr(std::string("loads")));
Py::Tuple args(1);
args.setItem(0, Py::String(repr));
Py::Object res = method.apply(args);
this->object = res;
if (this->object.hasAttr("__setstate__")) {
Py::Tuple args(1);
args.setItem(0, res);
Py::Callable state(this->object.getAttr("__setstate__"));
state.apply(args);
}
else {
this->object.setAttr("__dict__", res);
}
}
catch (Py::Exception&) {
Base::PyException e; // extract the Python error text
@ -115,6 +135,32 @@ void PropertyPythonObject::fromString(const std::string& repr)
}
}
void PropertyPythonObject::loadPickle(const std::string& str)
{
// find the custom attributes and restore them
Base::PyGILStateLocker lock;
try {
std::string buffer = str;
boost::regex pickle("S'(\\w+)'.+S'(\\w+)'\\n");
boost::match_results<std::string::const_iterator> what;
std::string::const_iterator start, end;
start = buffer.begin();
end = buffer.end();
while (boost::regex_search(start, end, what, pickle)) {
std::string key = std::string(what[1].first, what[1].second);
std::string val = std::string(what[2].first, what[2].second);
this->object.setAttr(key, Py::String(val));
buffer = std::string(what[2].second, end);
start = buffer.begin();
end = buffer.end();
}
}
catch (Py::Exception&) {
Base::PyException e; // extract the Python error text
Base::Console().Warning("PropertyPythonObject::loadPickle: %s\n", e.what());
}
}
std::string PropertyPythonObject::encodeValue(const std::string& str) const
{
std::string tmp;
@ -210,7 +256,25 @@ void PropertyPythonObject::Save (Base::Writer &writer) const
repr = Base::base64_encode((const unsigned char*)repr.c_str(), repr.size());
std::string val = /*encodeValue*/(repr);
writer.Stream() << writer.ind() << "<Python value=\"" << val
<<"\" encoded=\"yes\"";
<< "\" encoded=\"yes\"";
Base::PyGILStateLocker lock;
try {
if (this->object.hasAttr("__module__") && this->object.hasAttr("__class__")) {
Py::String mod(this->object.getAttr("__module__"));
Py::Object cls(this->object.getAttr("__class__"));
if (cls.hasAttr("__name__")) {
Py::String name(cls.getAttr("__name__"));
writer.Stream() << " module=\"" << (std::string)mod << "\""
<< " class=\"" << (std::string)name << "\"";
}
}
}
catch (Py::Exception&) {
Base::PyException e; // extract the Python error text
Base::Console().Warning("PropertyPythonObject::Save: %s\n", e.what());
}
saveObject(writer);
writer.Stream() << "/>" << std::endl;
//}
@ -228,6 +292,8 @@ void PropertyPythonObject::Restore(Base::XMLReader &reader)
reader.addFile(file.c_str(),this);
}
else {
bool load_json=false;
bool load_pickle=false;
std::string buffer = reader.getAttribute("value");
if (reader.hasAttribute("encoded") &&
strcmp(reader.getAttribute("encoded"),"yes") == 0) {
@ -237,8 +303,39 @@ void PropertyPythonObject::Restore(Base::XMLReader &reader)
buffer = decodeValue(buffer);
}
Base::PyGILStateLocker lock;
try {
boost::regex pickle("^\\(i(\\w+)\\n(\\w+)\\n");
boost::match_results<std::string::const_iterator> what;
std::string::const_iterator start, end;
start = buffer.begin();
end = buffer.end();
if (reader.hasAttribute("module") && reader.hasAttribute("class")) {
Py::Module mod(PyImport_ImportModule(reader.getAttribute("module")),true);
this->object = PyInstance_NewRaw(mod.getAttr(reader.getAttribute("class")).ptr(), 0);
load_json = true;
}
else if (boost::regex_search(start, end, what, pickle)) {
std::string nam = std::string(what[1].first, what[1].second);
std::string cls = std::string(what[2].first, what[2].second);
Py::Module mod(PyImport_ImportModule(nam.c_str()),true);
this->object = PyInstance_NewRaw(mod.getAttr(cls).ptr(), 0);
load_pickle = true;
buffer = std::string(what[2].second, end);
}
}
catch (Py::Exception&) {
Base::PyException e; // extract the Python error text
Base::Console().Warning("PropertyPythonObject::Restore: %s\n", e.what());
}
aboutToSetValue();
this->fromString(buffer);
if (load_json)
this->fromString(buffer);
else if (load_pickle)
this->loadPickle(buffer);
else
Base::Console().Warning("PropertyPythonObject::Restore: unsupported serialisation: %s\n", buffer.c_str());
restoreObject(reader);
hasSetValue();
}

View File

@ -77,6 +77,7 @@ private:
void restoreObject(Base::XMLReader &reader);
std::string encodeValue(const std::string& str) const;
std::string decodeValue(const std::string& str) const;
void loadPickle(const std::string& str);
Py::Object object;
};

View File

@ -394,9 +394,6 @@ protected:
const Constraints* _ConstStruct;
};
class AppExport PropertyFloatList: public PropertyLists
{
TYPESYSTEM_HEADER();
@ -470,10 +467,11 @@ public:
*/
virtual ~PropertyString();
void setValue(const char* sString);
void setValue(const std::string &sString);
const char* getValue(void) const;
const std::string& getStrValue(void) const
{ return _cValue; }
bool isEmpty(void){return _cValue.empty();}
virtual const char* getEditorName(void) const { return "Gui::PropertyEditor::PropertyStringItem"; }

View File

@ -192,7 +192,6 @@ PyObject* BoundBoxPy::getIntersectionPoint(PyObject *args)
*(static_cast<Base::VectorPy*>(object2)->getVectorPtr()),
point, epsilon);
// IsInBox() doesn't handle border points correctly
BoundBoxPy::PointerType bb = getBoundBoxPtr();
if (ok) {
return new VectorPy(point);
}
@ -209,6 +208,7 @@ PyObject* BoundBoxPy::move(PyObject *args)
{
double x,y,z;
PyObject *object;
Base::Vector3d vec;
if (PyArg_ParseTuple(args, "ddd", &x,&y,&z)) {

View File

@ -68,7 +68,7 @@ if(SWIG_FOUND)
add_definitions(-DHAVE_SWIG=1)
endif(SWIG_FOUND)
if (EXISTS ${CMAKE_SOURCE_DIR}/src/zipios++ AND NOT FREECAD_BUILD_DEBIAN)
if (EXISTS ${CMAKE_SOURCE_DIR}/src/zipios++ AND NOT FREECAD_USE_EXTERNAL_ZIPIOS)
SET(zipios_SRCS
../zipios++/backbuffer.h
../zipios++/basicentry.cpp
@ -122,12 +122,7 @@ SET(zipios_SRCS
../zipios++/zipoutputstream.h
)
SOURCE_GROUP("zipios" FILES ${zipios_SRCS})
else (EXISTS ${CMAKE_SOURCE_DIR}/src/zipios++ AND NOT FREECAD_BUILD_DEBIAN)
set(FreeCADBase_LIBS
${FreeCADBase_LIBS}
-lzipios
)
endif (EXISTS ${CMAKE_SOURCE_DIR}/src/zipios++ AND NOT FREECAD_BUILD_DEBIAN)
endif ()
SET(pycxx_SRCS
../CXX/Config.hxx
@ -157,6 +152,7 @@ SET(FreeCADBase_XML_SRCS
SOURCE_GROUP("XML" FILES ${FreeCADBase_XML_SRCS})
set(FreeCADBase_MOC_HDRS
Debugger.h
FutureWatcherProgress.h
)
fc_wrap_cpp(FreeCADBase_MOC_SRCS ${FreeCADBase_MOC_HDRS})
@ -187,6 +183,7 @@ SET(FreeCADBase_CPP_SRCS
BoundBoxPyImp.cpp
Builder3D.cpp
Console.cpp
Debugger.cpp
Exception.cpp
Factory.cpp
FileInfo.cpp
@ -239,6 +236,7 @@ SET(FreeCADBase_HPP_SRCS
BoundBox.h
Builder3D.h
Console.h
Debugger.h
Exception.h
Factory.h
FileInfo.h
@ -281,7 +279,6 @@ SET(FreeCADBase_HPP_SRCS
)
SET(FreeCADBase_SRCS
${zipios_SRCS}
${pycxx_SRCS}
${FreeCADBase_CPP_SRCS}
${FreeCADBase_HPP_SRCS}
@ -293,6 +290,27 @@ SET(FreeCADBase_SRCS
PreCompiled.h
)
# Use external zipios++ if specified.
if(FREECAD_USE_EXTERNAL_ZIPIOS)
find_library(ZIPIOS_LIBRARY zipios)
find_path(ZIPIOS_INCLUDES zipios++/zipios-config.h)
if(ZIPIOS_LIBRARY)
message(STATUS "Found zipios++: ${ZIPIOS}")
endif()
if(ZIPIOS_INCLUDES)
message(STATUS "Found zipios++ headers.")
endif()
if(ZIPIOS_LIBRARY AND ZIPIOS_INCLUDES)
list(APPEND FreeCADBase_LIBS ${ZIPIOS_LIBRARY})
include_directories(${ZIPIOS_INCLUDES})
else()
message(FATAL_ERROR "Using external zipios++ was specified but was not found.")
endif()
else(FREECAD_USE_EXTERNAL_ZIPIOS)
list(APPEND FreeCADBase_SRCS ${zipios_SRCS})
endif(FREECAD_USE_EXTERNAL_ZIPIOS)
if(MSVC)
add_definitions(-D_PreComp_)
ADD_MSVC_PRECOMPILED_HEADER("PreCompiled.h" "PreCompiled.cpp" FreeCADBase_CPP_SRCS)

80
src/Base/Debugger.cpp Normal file
View File

@ -0,0 +1,80 @@
/***************************************************************************
* Copyright (c) 2012 Werner Mayer <wmayer[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library 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 this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 51 Franklin Street, *
* Fifth Floor, Boston, MA 02110-1301, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QCoreApplication>
# include <QEvent>
#endif
#include "Debugger.h"
#include "Console.h"
using namespace Base;
Debugger::Debugger(QObject* parent)
: QObject(parent), isAttached(false)
{
}
Debugger::~Debugger()
{
}
void Debugger::attach()
{
QCoreApplication::instance()->installEventFilter(this);
isAttached = true;
}
void Debugger::detach()
{
QCoreApplication::instance()->removeEventFilter(this);
isAttached = false;
}
bool Debugger::eventFilter(QObject*, QEvent* event)
{
if (event->type() == QEvent::KeyPress) {
if (loop.isRunning()) {
loop.quit();
return true;
}
}
return false;
}
int Debugger::exec()
{
if (isAttached)
Base::Console().Message("TO CONTINUE PRESS ANY KEY...\n");
return loop.exec();
}
void Debugger::quit()
{
loop.quit();
}
#include "moc_Debugger.cpp"

76
src/Base/Debugger.h Normal file
View File

@ -0,0 +1,76 @@
/***************************************************************************
* Copyright (c) 2012 Werner Mayer <wmayer[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library 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 this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 51 Franklin Street, *
* Fifth Floor, Boston, MA 02110-1301, USA *
* *
***************************************************************************/
#ifndef BASE_DEBUGGER_H
#define BASE_DEBUGGER_H
#include <QObject>
#include <QEventLoop>
namespace Base {
/**
This is a utility class to break the application at a point to inspect e.g. the result of
an algorithm.
You usually use it like this
\code
...
Base::Debugger dbg;
dbg.attach();
dbg.exec();
...
\endcode
Or you can connect it with a button and let the user click it in order to continue.
\code
QPushButton* btn = new QPushButton();
btn->setText("Continue");
btn->show();
Base::Debugger dbg;
connect(btn, SIGNAL(clicked()), &dbg, SLOT(quit()));
dbg.exec();
\endcode
\author Werner Mayer
*/
class BaseExport Debugger : public QObject
{
Q_OBJECT
public:
Debugger(QObject* parent=0);
~Debugger();
void attach();
void detach();
bool eventFilter(QObject*, QEvent*);
int exec();
public Q_SLOTS:
void quit();
private:
bool isAttached;
QEventLoop loop;
};
}
#endif // BASE_DEBUGGER_H

View File

@ -202,6 +202,40 @@ AbnormalProgramTermination::AbnormalProgramTermination(const AbnormalProgramTerm
// ---------------------------------------------------------
UnknownProgramOption::UnknownProgramOption(const char * sMessage)
: Exception(sMessage)
{
}
UnknownProgramOption::UnknownProgramOption(const std::string& sMessage)
: Exception(sMessage)
{
}
UnknownProgramOption::UnknownProgramOption(const UnknownProgramOption &inst)
: Exception(inst)
{
}
// ---------------------------------------------------------
ProgramInformation::ProgramInformation(const char * sMessage)
: Exception(sMessage)
{
}
ProgramInformation::ProgramInformation(const std::string& sMessage)
: Exception(sMessage)
{
}
ProgramInformation::ProgramInformation(const ProgramInformation &inst)
: Exception(inst)
{
}
// ---------------------------------------------------------
#if defined(__GNUC__) && defined (FC_OS_LINUX)
#include <stdexcept>
#include <iostream>

View File

@ -174,6 +174,38 @@ public:
virtual ~AbnormalProgramTermination() throw() {}
};
/**
* The UnknownProgramOption can be used to indicate an unknown program option.
* @author Werner Mayer
*/
class BaseExport UnknownProgramOption : public Exception
{
public:
/// Construction
UnknownProgramOption(const char * sMessage);
UnknownProgramOption(const std::string& sMessage);
/// Construction
UnknownProgramOption(const UnknownProgramOption &inst);
/// Destruction
virtual ~UnknownProgramOption() throw() {}
};
/**
* The ProgramInformation can be used to show information about the program.
* @author Werner Mayer
*/
class BaseExport ProgramInformation : public Exception
{
public:
/// Construction
ProgramInformation(const char * sMessage);
ProgramInformation(const std::string& sMessage);
/// Construction
ProgramInformation(const ProgramInformation &inst);
/// Destruction
virtual ~ProgramInformation() throw() {}
};
inline void Exception::setMessage(const char * sMessage)
{

View File

@ -190,7 +190,6 @@ void InterpreterSingleton::runInteractiveString(const char *sCmd)
presult = PyRun_String(sCmd, Py_single_input, dict, dict); /* eval direct */
if (!presult) {
if (PyErr_ExceptionMatches(PyExc_SystemExit)) {
//systemExit();
throw SystemExitException();
}
/* get latest python exception information */

View File

@ -587,6 +587,16 @@ void Matrix_invert (Matrix a, Matrix inva)
Matrix_gauss(temp,inva);
}
void Matrix4D::inverseOrthogonal(void)
{
Base::Vector3d c(dMtrx4D[0][3],dMtrx4D[1][3],dMtrx4D[2][3]);
transpose();
c = this->operator * (c);
dMtrx4D[0][3] = -c.x; dMtrx4D[3][0] = 0;
dMtrx4D[1][3] = -c.y; dMtrx4D[3][1] = 0;
dMtrx4D[2][3] = -c.z; dMtrx4D[3][2] = 0;
}
void Matrix4D::inverseGauss (void)
{
double matrix [16];
@ -691,3 +701,98 @@ void Matrix4D::fromString(const std::string &str)
input >> dMtrx4D[i][j];
}
}
// Analyse the a transformation Matrix and describe the transformation
std::string Matrix4D::analyse(void) const
{
const double eps=1.0e-06;
bool hastranslation = (dMtrx4D[0][3] != 0.0 ||
dMtrx4D[1][3] != 0.0 || dMtrx4D[2][3] != 0.0);
const Base::Matrix4D unityMatrix = Base::Matrix4D();
std::string text;
if (*this == unityMatrix)
{
text = "Unity Matrix";
}
else
{
if (dMtrx4D[3][0] != 0.0 || dMtrx4D[3][1] != 0.0 ||
dMtrx4D[3][2] != 0.0 || dMtrx4D[3][3] != 1.0)
{
text = "Projection";
}
else //translation and affine
{
if (dMtrx4D[0][1] == 0.0 && dMtrx4D[0][2] == 0.0 &&
dMtrx4D[1][0] == 0.0 && dMtrx4D[1][2] == 0.0 &&
dMtrx4D[2][0] == 0.0 && dMtrx4D[2][1] == 0.0) //scaling
{
std::ostringstream stringStream;
stringStream << "Scale [" << dMtrx4D[0][0] << ", " <<
dMtrx4D[1][1] << ", " << dMtrx4D[2][2] << "]";
text = stringStream.str();
}
else
{
Base::Matrix4D sub;
sub[0][0] = dMtrx4D[0][0]; sub[0][1] = dMtrx4D[0][1];
sub[0][2] = dMtrx4D[0][2]; sub[1][0] = dMtrx4D[1][0];
sub[1][1] = dMtrx4D[1][1]; sub[1][2] = dMtrx4D[1][2];
sub[2][0] = dMtrx4D[2][0]; sub[2][1] = dMtrx4D[2][1];
sub[2][2] = dMtrx4D[2][2];
Base::Matrix4D trp = sub;
trp.transpose();
trp = trp * sub;
bool ortho = true;
for (int i=0; i<4 && ortho; i++) {
for (int j=0; j<4 && ortho; j++) {
if (i != j) {
if (fabs(trp[i][j]) > eps) {
ortho = false;
break;
}
}
}
}
double determinant = sub.determinant();
if (ortho)
{
if (fabs(determinant-1.0)<eps ) //rotation
{
text = "Rotation Matrix";
}
else
{
if (fabs(determinant+1.0)<eps ) //rotation
{
text = "Rotinversion Matrix";
}
else //scaling with rotation
{
std::ostringstream stringStream;
stringStream << "Scale and Rotate ";
if (determinant<0.0 )
stringStream << "and Invert ";
stringStream << "[ " <<
sqrt(trp[0][0]) << ", " << sqrt(trp[1][1]) << ", " <<
sqrt(trp[2][2]) << "]";
text = stringStream.str();
}
}
}
else
{
std::ostringstream stringStream;
stringStream << "Affine with det= " <<
determinant;
text = stringStream.str();
}
}
}
if (hastranslation)
text += " with Translation";
}
return text;
}

View File

@ -88,6 +88,8 @@ public:
inline const double* operator[] (unsigned short usNdx) const;
/// Compute the determinant of the matrix
double determinant() const;
/// Analyse the transformation
std::string analyse(void) const;
//@}
void getMatrix (double dMtrx[16]) const;
@ -133,6 +135,8 @@ public:
void transform (const Vector3f& rclVct, const Matrix4D& rclMtrx);
void transform (const Vector3d& rclVct, const Matrix4D& rclMtrx);
void inverse (void);
/// if matrix is orthogonal a special way of getting the inverse is used
void inverseOrthogonal(void);
void inverseGauss (void);
void transpose (void);
//@}

View File

@ -125,6 +125,14 @@ Get the sub-matrix. The parameter must be in the range [1,4].
</UserDocu>
</Documentation>
</Methode>
<Methode Name="analyze">
<Documentation>
<UserDocu>
analyze() -> string
Analyzes the type of transformation.
</UserDocu>
</Documentation>
</Methode>
<Attribute Name="A11" ReadOnly="false">
<Documentation>
<UserDocu>The matrix elements</UserDocu>

View File

@ -474,6 +474,18 @@ PyObject* MatrixPy::transpose(PyObject * args)
PY_CATCH;
}
PyObject* MatrixPy::analyze(PyObject * args)
{
if (!PyArg_ParseTuple(args, ""))
return NULL;
PY_TRY {
std::string type = getMatrixPtr()->analyse();
return PyString_FromString(type.c_str());
}
PY_CATCH;
}
Py::Float MatrixPy::getA11(void) const
{
double val = (*this->getMatrixPtr())[0][0];

View File

@ -75,6 +75,14 @@ Placement(Base, Axis, Angle) -- define position and rotation
</UserDocu>
</Documentation>
</Methode>
<Methode Name="isNull">
<Documentation>
<UserDocu>
isNull() -> Bool
returns True if the placement has no displacement and no rotation
</UserDocu>
</Documentation>
</Methode>
<Attribute Name="Base" ReadOnly="false">
<Documentation>
<UserDocu>Vector to the Base Position of the Placement</UserDocu>

View File

@ -83,9 +83,9 @@ int PlacementPy::PyInit(PyObject* args, PyObject* /*kwd*/)
PyObject* d;
double angle;
if (PyArg_ParseTuple(args, "O!O!d", &(Base::VectorPy::Type), &o,
&(Base::VectorPy::Type), &d, &angle)) {
// NOTE: The first parameter defines the translation, the second the rotation axis
// and the last parameter defines the rotation angle in degree.
&(Base::VectorPy::Type), &d, &angle)) {
// NOTE: The first parameter defines the translation, the second the rotation axis
// and the last parameter defines the rotation angle in degree.
Base::Rotation rot(static_cast<Base::VectorPy*>(d)->value(), angle/180.0*D_PI);
*getPlacementPtr() = Base::Placement(static_cast<Base::VectorPy*>(o)->value(),rot);
return 0;
@ -145,13 +145,13 @@ PyObject* PlacementPy::multVec(PyObject * args)
getPlacementPtr()->multVec(pnt, pnt);
return new VectorPy(new Vector3d(pnt));
}
PyObject* PlacementPy::copy(PyObject * args)
{
if (!PyArg_ParseTuple(args, ""))
return NULL;
return new PlacementPy(new Placement(*getPlacementPtr()));
}
PyObject* PlacementPy::copy(PyObject * args)
{
if (!PyArg_ParseTuple(args, ""))
return NULL;
return new PlacementPy(new Placement(*getPlacementPtr()));
}
PyObject* PlacementPy::toMatrix(PyObject * args)
{
@ -169,6 +169,19 @@ PyObject* PlacementPy::inverse(PyObject * args)
return new PlacementPy(new Placement(p));
}
PyObject* PlacementPy::isNull(PyObject *args)
{
if (!PyArg_ParseTuple(args, ""))
return NULL;
Base::Vector3d pos = getPlacementPtr()->getPosition();
Base::Rotation rot = getPlacementPtr()->getRotation();
Base::Vector3d nullvec(0,0,0);
Base::Rotation nullrot(0,0,0,1);
Base::Rotation nullrotinv(0,0,0,-1);
bool null = (pos == nullvec) & ((rot == nullrot) | (rot == nullrotinv));
return Py_BuildValue("O", (null ? Py_True : Py_False));
}
Py::Object PlacementPy::getBase(void) const
{
return Py::Vector(getPlacementPtr()->getPosition());

View File

@ -105,6 +105,8 @@
// QtCore
#include <QBuffer>
#include <QByteArray>
#include <QCoreApplication>
#include <QEvent>
#include <QIODevice>
#include <QDataStream>
#include <QWriteLocker>

View File

@ -377,8 +377,10 @@ const char *PP_Init(const char *modname) {
//#ifdef FC_OS_LINUX /* cannot convert `const char *' to `char *' in assignment */
if (modname!=NULL) return modname;
{ /* we assume here that the caller frees allocated memory */
char* __main__=(char *)malloc(sizeof("__main__"));
return __main__="__main__";
// #0000716: strange assignment and a memory leak
return "__main__";
//char* __main__=(char *)malloc(sizeof("__main__"));
//return __main__="__main__";
}
//#else
// return modname == NULL ? "__main__" : modname; /* default to '__main__' */

View File

@ -34,6 +34,7 @@
/// Here the FreeCAD includes sorted by Base,App,Gui......
#include "Reader.h"
#include "Base64.h"
#include "Exception.h"
#include "Persistence.h"
#include "InputSource.h"
@ -79,6 +80,7 @@ Base::XMLReader::XMLReader(const char* FileName, std::istream& str)
//parser->setFeature(XMLUni::fgXercesDynamic, true);
parser->setContentHandler(this);
parser->setLexicalHandler(this);
parser->setErrorHandler(this);
try {
@ -127,7 +129,7 @@ long Base::XMLReader::getAttributeAsInteger(const char* AttrName) const
if (pos != AttrMap.end())
return atol(pos->second.c_str());
else
// wrong name, use hasAttribute if not shure!
// wrong name, use hasAttribute if not sure!
assert(0);
return 0;
@ -140,7 +142,7 @@ unsigned long Base::XMLReader::getAttributeAsUnsigned(const char* AttrName) cons
if (pos != AttrMap.end())
return strtoul(pos->second.c_str(),0,10);
else
// wrong name, use hasAttribute if not shure!
// wrong name, use hasAttribute if not sure!
assert(0);
return 0;
@ -153,7 +155,7 @@ double Base::XMLReader::getAttributeAsFloat (const char* AttrName) const
if (pos != AttrMap.end())
return atof(pos->second.c_str());
else
// wrong name, use hasAttribute if not shure!
// wrong name, use hasAttribute if not sure!
assert(0);
return 0.0;
@ -166,7 +168,7 @@ const char* Base::XMLReader::getAttribute (const char* AttrName) const
if (pos != AttrMap.end())
return pos->second.c_str();
else
// wrong name, use hasAttribute if not shure!
// wrong name, use hasAttribute if not sure!
assert(0);
return "";
@ -255,6 +257,22 @@ void Base::XMLReader::readCharacters(void)
{
}
void Base::XMLReader::readBinFile(const char* filename)
{
Base::FileInfo fi(filename);
Base::ofstream to(fi, std::ios::out | std::ios::binary);
if (!to)
throw Base::Exception("XMLReader::readBinFile() Could not open file!");
bool ok;
do {
ok = read(); if (!ok) break;
} while (ReadType != EndCDATA);
to << Base::base64_decode(Characters);
to.close();
}
void Base::XMLReader::readFiles(zipios::ZipInputStream &zipstream) const
{
// It's possible that not all objects inside the document could be created, e.g. if a module
@ -370,15 +388,32 @@ void Base::XMLReader::endElement (const XMLCh* const /*uri*/, const XMLCh *cons
ReadType = EndElement;
}
void Base::XMLReader::startCDATA ()
{
ReadType = StartCDATA;
}
void Base::XMLReader::endCDATA ()
{
ReadType = EndCDATA;
}
#if (XERCES_VERSION_MAJOR == 2)
void Base::XMLReader::characters(const XMLCh* const chars, const unsigned int length)
#else
void Base::XMLReader::characters(const XMLCh* const chars, const XMLSize_t length)
#endif
{
Characters = StrX(chars).c_str();
ReadType = Chars;
CharacterCount += length;
}
#if (XERCES_VERSION_MAJOR == 2)
void Base::XMLReader::ignorableWhitespace( const XMLCh* const /*chars*/, const unsigned int /*length*/)
#else
void Base::XMLReader::ignorableWhitespace( const XMLCh* const /*chars*/, const XMLSize_t /*length*/)
#endif
{
//fSpaceCount += length;
}

View File

@ -131,6 +131,8 @@ public:
void readEndElement(const char* ElementName=0);
/// read until characters are found
void readCharacters(void);
/// read binary file
void readBinFile(const char*);
//@}
/** @name Attribute handling */
@ -171,8 +173,15 @@ protected:
// -----------------------------------------------------------------------
virtual void startElement(const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname, const XERCES_CPP_NAMESPACE_QUALIFIER Attributes& attrs);
virtual void endElement (const XMLCh* const uri, const XMLCh *const localname, const XMLCh *const qname);
virtual void characters (const XMLCh* const chars, const unsigned int length);
virtual void startCDATA ();
virtual void endCDATA ();
#if (XERCES_VERSION_MAJOR == 2)
virtual void characters (const XMLCh* const chars, const unsigned int length);
virtual void ignorableWhitespace(const XMLCh* const chars, const unsigned int length);
#else
virtual void characters (const XMLCh* const chars, const XMLSize_t length);
virtual void ignorableWhitespace(const XMLCh* const chars, const XMLSize_t length);
#endif
virtual void resetDocument();
@ -198,7 +207,9 @@ protected:
Chars,
StartElement,
StartEndElement,
EndElement
EndElement,
StartCDATA,
EndCDATA
} ReadType;

View File

@ -48,6 +48,14 @@
</UserDocu>
</Documentation>
</Methode>
<Methode Name="isNull">
<Documentation>
<UserDocu>
isNull() -> Bool
returns True if the rotation equals the unity matrix
</UserDocu>
</Documentation>
</Methode>
<Attribute Name="Q" ReadOnly="false">
<Documentation>
<UserDocu>The rotation elements (as quaternion)</UserDocu>

View File

@ -144,6 +144,17 @@ PyObject* RotationPy::toEuler(PyObject * args)
return Py::new_reference_to(tuple);
}
PyObject* RotationPy::isNull(PyObject *args)
{
if (!PyArg_ParseTuple(args, ""))
return NULL;
Base::Rotation rot = * getRotationPtr();
Base::Rotation nullrot(0,0,0,1);
Base::Rotation nullrotinv(0,0,0,-1);
bool null = (rot == nullrot) | (rot == nullrotinv);
return Py_BuildValue("O", (null ? Py_True : Py_False));
}
Py::Tuple RotationPy::getQ(void) const
{
double q0, q1, q2, q3;

View File

@ -85,6 +85,7 @@ UnitsSchema *UnitsApi::UserPrefSystem = new UnitsSchemaInternal();
double UnitsApi::UserPrefFactor [50];
QString UnitsApi::UserPrefUnit [50];
int UnitsApi::UserPrefDecimals = 2;
UnitsApi::UnitsApi(const char* filter)
{
@ -196,6 +197,16 @@ const double UnitsApi::getPrefFactorOf(QuantityType t)
return UserPrefFactor[t];
}
void UnitsApi::setDecimals(int prec)
{
UserPrefDecimals = prec;
}
int UnitsApi::getDecimals()
{
return UserPrefDecimals;
}
void UnitsApi::setDefaults(void)
{
setPrefOf( Length ,"mm" );

View File

@ -101,6 +101,10 @@ public:
static const QString getQuantityName(QuantityType t);
/// get the translation factor for the default unit of a quantity
static const double getPrefFactorOf(QuantityType t);
// set the number of decimals
static void setDecimals(int);
// fet the number of decimals
static int getDecimals();
/// set the application defaults
static void setDefaults(void);
//@}
@ -119,6 +123,8 @@ protected:
static double UserPrefFactor [50] ;
/// name of the unit the user wants to use as quantities
static QString UserPrefUnit [50] ;
/// number of decimals for floats
static int UserPrefDecimals;
// do the real work
static double parse(const char*,bool &UsedUnit);

View File

@ -20,90 +20,127 @@
</Documentation>
<Methode Name="add" Const="true">
<Documentation>
<UserDocu>add(Vector) - return the sum of the two vectors</UserDocu>
<UserDocu>add(Vector)
returns the sum of this and another vector
</UserDocu>
</Documentation>
</Methode>
<Methode Name="sub" Const="true">
<Documentation>
<UserDocu>sub(Vector) - return the difference of the two vectors</UserDocu>
<UserDocu>sub(Vector)
returns the difference of this and another vector
</UserDocu>
</Documentation>
</Methode>
<Methode Name="scale">
<Documentation>
<UserDocu>scale(Float,Float,Float) - scale (multiplies) this vector by a factor</UserDocu>
<UserDocu>scale(Float,Float,Float)
scales (multiplies) this vector by a factor
</UserDocu>
</Documentation>
</Methode>
<Methode Name="multiply">
<Documentation>
<UserDocu>multiply(Float) - multiplies (scales) this vector by a single factor</UserDocu>
<UserDocu>multiply(Float)
multiplies (scales) this vector by a single factor
</UserDocu>
</Documentation>
</Methode>
<Methode Name="dot" Const="true">
<Documentation>
<UserDocu>dot(Vector) - return the dot product of the two vectors</UserDocu>
<UserDocu>dot(Vector)
returns the dot product of the this vector with another one
</UserDocu>
</Documentation>
</Methode>
<Methode Name="cross" Const="true">
<Documentation>
<UserDocu>cross(Vector) - return the cross product of the two vectors</UserDocu>
<UserDocu>cross(Vector)
returns the cross product between this and another vector
</UserDocu>
</Documentation>
</Methode>
<Methode Name="getAngle" Const="true">
<Documentation>
<UserDocu>getAngle(Vector) - return the angle in radians between the two vectors</UserDocu>
<UserDocu>getAngle(Vector)
returns the angle in radians between this and another vector
</UserDocu>
</Documentation>
</Methode>
<Methode Name="normalize">
<Documentation>
<UserDocu>Normalize the vector to the length of 1.0</UserDocu>
<UserDocu>normalize()
normalizes the vector to the length of 1.0
</UserDocu>
</Documentation>
</Methode>
<Methode Name="projectToLine">
<Documentation>
<UserDocu>Deliver the projection point to a given line</UserDocu>
<UserDocu>projectToLine(Vector,Vector)
projects the vector on a line defined by a base point and a direction
</UserDocu>
</Documentation>
</Methode>
<Methode Name="projectToPlane">
<Documentation>
<UserDocu>Deliver the projection point to a given plane</UserDocu>
<UserDocu>projectToPlane(Vector,Vector)
projects the vector on a plane defined by a base point and a normal
</UserDocu>
</Documentation>
</Methode>
<Methode Name="distanceToLine" Const="true">
<Documentation>
<UserDocu>Deliver the distance of the point to a given line</UserDocu>
<UserDocu>distanceToLine(Vector,Vector)
returns the distance between this vector and a line defined by
a base point and a direction
</UserDocu>
</Documentation>
</Methode>
<Methode Name="distanceToLineSegment" Const="true">
<Documentation>
<UserDocu>Deliver the distance of the point to a given line segment</UserDocu>
<UserDocu>distanceToLineSegment(Vector,Vector)
returns the distance between this vector and a line segment defined by
a base point and a direction
</UserDocu>
</Documentation>
</Methode>
<Methode Name="distanceToPlane" Const="true">
<Documentation>
<UserDocu>Deliver the distance of the point to a given plane</UserDocu>
<UserDocu>distanceToPlane(Vector,Vector)
returns the distance between this vector and a plane defined by
a base point and a normal
</UserDocu>
</Documentation>
</Methode>
<Attribute Name="Length" ReadOnly="false">
<Documentation>
<UserDocu>To read or modifiy the length of the vector</UserDocu>
<UserDocu>Length([Float]) -> Float
gets or sets the length of this vector
</UserDocu>
</Documentation>
<Parameter Name="Type" Type="Float" />
</Attribute>
<Attribute Name="x" ReadOnly="false">
<Documentation>
<UserDocu>The X component of the vector</UserDocu>
<UserDocu>x([Float]) -> Float
gets or sets the X component of this vector
</UserDocu>
</Documentation>
<Parameter Name="x" Type="Float"/>
</Attribute>
<Attribute Name="y" ReadOnly="false">
<Documentation>
<UserDocu>The Y component of the vector</UserDocu>
<UserDocu>y([Float]) -> Float
gets or sets the Y component of this vector
</UserDocu>
</Documentation>
<Parameter Name="y" Type="Float"/>
</Attribute>
<Attribute Name="z" ReadOnly="false">
<Documentation>
<UserDocu>The Z component of the vector</UserDocu>
<UserDocu>z([Float]) -> Float
gets or sets the Z component of this vector
</UserDocu>
</Documentation>
<Parameter Name="z" Type="Float"/>
</Attribute>
@ -128,4 +165,4 @@
{ return *(getVectorPtr()); }
</ClassDeclarations>
</PythonExport>
</GenerateModel>
</GenerateModel>

View File

@ -32,6 +32,7 @@
#include "Exception.h"
#include "Base64.h"
#include "FileInfo.h"
#include "Stream.h"
#include "Tools.h"
#include <algorithm>
@ -59,32 +60,31 @@ Writer::~Writer()
void Writer::insertAsciiFile(const char* FileName)
{
std::ifstream from(FileName);
if (!from) throw Base::Exception("Writer::insertAsciiFile() Could not open file!");
Base::FileInfo fi(FileName);
Base::ifstream from(fi);
if (!from)
throw Base::Exception("Writer::insertAsciiFile() Could not open file!");
Stream() << "<![CDATA[" << endl;
Stream() << "<![CDATA[";
char ch;
while (from.get(ch)) Stream().put(ch);
Stream() << endl << "]]>" << endl;
while (from.get(ch))
Stream().put(ch);
Stream() << "]]>" << endl;
}
void Writer::insertBinFile(const char* FileName)
{
std::ifstream from(FileName);
if (!from) throw Base::Exception("Writer::insertAsciiFile() Could not open file!");
Stream() << "<![CDATA[" << endl;
unsigned char buf[60];
std::string encoded;
unsigned int i;
while (from){
for(i=0 ; i<60 && from;i++)
buf[i] = from.get();
Stream() << Base::base64_encode(buf,i) << endl;
}
Base::FileInfo fi(FileName);
Base::ifstream from(fi, std::ios::in | std::ios::binary | std::ios::ate);
if (!from)
throw Base::Exception("Writer::insertAsciiFile() Could not open file!");
Stream() << "<![CDATA[";
std::ifstream::pos_type fileSize = from.tellg();
from.seekg(0, std::ios::beg);
std::vector<unsigned char> bytes(fileSize);
from.read((char*)&bytes[0], fileSize);
Stream() << Base::base64_encode(&bytes[0], fileSize);
Stream() << "]]>" << endl;
}

View File

@ -12,6 +12,10 @@ if(FREECAD_BUILD_GUI)
configure_file(Doc/freecad.qch ${CMAKE_BINARY_DIR}/doc/freecad.qch COPYONLY)
endif(FREECAD_BUILD_GUI)
if(FREECAD_BUILD_TEMPLATE)
add_subdirectory(Tools/_TEMPLATE_)
endif(FREECAD_BUILD_TEMPLATE)
if(FREECAD_MAINTAINERS_BUILD)
add_subdirectory(Doc)
endif(FREECAD_MAINTAINERS_BUILD)

View File

@ -12,10 +12,15 @@ The Draft module offer several convenient functions to work with simple objects.
.. automodule:: DraftSnap
:members:
The draftlibs contain two submodules, widely used throughout the Draft module: fcvec, which contains useful methods for dealing with vectors, and fcgeo, which offers many tools for working with Part shape objects.
The Draft module also contains two submodules, widely used throughout the Draft and Arch modules: DraftVecUtils, which contains useful methods for dealing with vectors, and DraftGeomUtils, which offers many tools for working with OpenCascade geometry.
.. automodule:: draftlibs.fcvec
.. automodule:: DraftVecUtils
:members:
.. automodule:: draftlibs.fcgeo
:members:
.. automodule:: DraftGeomUtils
:members:
The Draft module also features a module that contains trackers, special objects made to display 3D temporary geometry in the 3D scene, that have no real existence in the FreeCAD document.
.. automodule:: DraftTrackers
:members:

View File

@ -0,0 +1,718 @@
/*
Development tools and related technology provided under license from 3Dconnexion.
(c) 1992 - 2012 3Dconnexion. All rights reserved
*/
/*
Support for Qt added by David Dibben at
http://www.codegardening.com/2011/02/using-3dconnexion-mouse-with-qt.html
*/
/*
See also:
http://www.3dconnexion.com/forum/viewtopic.php?f=19&t=4968&sid=72c018bdcf0e6edc99a6effb5c0c48d9
*/
#include "PreCompiled.h"
#include <QGlobalStatic>
#include <QMainWindow>
#include <QWidget>
#include <FCConfig.h>
#include <Base/Console.h>
#include "GuiApplicationNativeEventAware.h"
#include "SpaceballEvent.h"
// Windows dependencies, enumerators and global variables
#ifdef _USE_3DCONNEXION_SDK
#include <QApplication>
#include <windows.h>
#include <math.h>
#define LOGITECH_VENDOR_ID 0x46d
#define _CONSTANT_INPUT_PERIOD 0
#ifndef RIDEV_DEVNOTIFY
#define RIDEV_DEVNOTIFY 0x00002000
#endif
#define _TRACE_WM_INPUT_PERIOD 0
#define _TRACE_RI_TYPE 0
#define _TRACE_RIDI_DEVICENAME 0
#define _TRACE_RIDI_DEVICEINFO 0
#define _TRACE_RI_RAWDATA 0
#define _TRACE_3DINPUT_PERIOD 0
#ifdef _WIN64
typedef unsigned __int64 QWORD;
#endif // _WIN64
static const int kTimeToLive = 5;
enum e3dconnexion_pid {
eSpacePilot = 0xc625,
eSpaceNavigator = 0xc626,
eSpaceExplorer = 0xc627,
eSpaceNavigatorForNotebooks = 0xc628,
eSpacePilotPRO = 0xc629
};
enum e3dmouse_virtual_key
{
V3DK_INVALID=0
, V3DK_MENU=1, V3DK_FIT
, V3DK_TOP, V3DK_LEFT, V3DK_RIGHT, V3DK_FRONT, V3DK_BOTTOM, V3DK_BACK
, V3DK_CW, V3DK_CCW
, V3DK_ISO1, V3DK_ISO2
, V3DK_1, V3DK_2, V3DK_3, V3DK_4, V3DK_5, V3DK_6, V3DK_7, V3DK_8, V3DK_9, V3DK_10
, V3DK_ESC, V3DK_ALT, V3DK_SHIFT, V3DK_CTRL
, V3DK_ROTATE, V3DK_PANZOOM, V3DK_DOMINANT
, V3DK_PLUS, V3DK_MINUS
};
struct tag_VirtualKeys
{
e3dconnexion_pid pid;
size_t nKeys;
e3dmouse_virtual_key *vkeys;
};
static const e3dmouse_virtual_key SpaceExplorerKeys [] =
{
V3DK_INVALID // there is no button 0
, V3DK_1, V3DK_2
, V3DK_TOP, V3DK_LEFT, V3DK_RIGHT, V3DK_FRONT
, V3DK_ESC, V3DK_ALT, V3DK_SHIFT, V3DK_CTRL
, V3DK_FIT, V3DK_MENU
, V3DK_PLUS, V3DK_MINUS
, V3DK_ROTATE
};
static const e3dmouse_virtual_key SpacePilotKeys [] =
{
V3DK_INVALID
, V3DK_1, V3DK_2, V3DK_3, V3DK_4, V3DK_5, V3DK_6
, V3DK_TOP, V3DK_LEFT, V3DK_RIGHT, V3DK_FRONT
, V3DK_ESC, V3DK_ALT, V3DK_SHIFT, V3DK_CTRL
, V3DK_FIT, V3DK_MENU
, V3DK_PLUS, V3DK_MINUS
, V3DK_DOMINANT, V3DK_ROTATE
};
static const struct tag_VirtualKeys _3dmouseVirtualKeys[]=
{
eSpacePilot
, sizeof(SpacePilotKeys)/sizeof(SpacePilotKeys[0])
, const_cast<e3dmouse_virtual_key *>(SpacePilotKeys),
eSpaceExplorer
, sizeof(SpaceExplorerKeys)/sizeof(SpaceExplorerKeys[0])
, const_cast<e3dmouse_virtual_key *>(SpaceExplorerKeys)
};
// Methods for windows events
/*!
Converts a hid device keycode (button identifier) of a pre-2009 3Dconnexion USB device to the standard 3d mouse virtual key definition.
\a pid USB Product ID (PID) of 3D mouse device
\a hidKeyCode Hid keycode as retrieved from a Raw Input packet
\return The standard 3d mouse virtual key (button identifier) or zero if an error occurs.
Converts a hid device keycode (button identifier) of a pre-2009 3Dconnexion USB device
to the standard 3d mouse virtual key definition.
*/
unsigned short HidToVirtualKey(unsigned long pid, unsigned short hidKeyCode)
{
unsigned short virtualkey=hidKeyCode;
for (size_t i=0; i<sizeof(_3dmouseVirtualKeys)/sizeof(_3dmouseVirtualKeys[0]); ++i)
{
if (pid == _3dmouseVirtualKeys[i].pid)
{
if (hidKeyCode < _3dmouseVirtualKeys[i].nKeys)
virtualkey = _3dmouseVirtualKeys[i].vkeys[hidKeyCode];
else
virtualkey = V3DK_INVALID;
break;
}
}
// Remaining devices are unchanged
return virtualkey;
}
bool Gui::GUIApplicationNativeEventAware::RawInputEventFilter(void* msg, long* result)
{
if (gMouseInput == 0) return false;
MSG* message = (MSG*)(msg);
if (message->message == WM_INPUT) {
HRAWINPUT hRawInput = reinterpret_cast<HRAWINPUT>(message->lParam);
gMouseInput->OnRawInput(RIM_INPUT,hRawInput);
if (result != 0) {
result = 0;
}
return true;
}
return false;
}
/*!
Access the mouse parameters structure
*/
I3dMouseParam& Gui::GUIApplicationNativeEventAware::MouseParams()
{
return f3dMouseParams;
}
/*!
Access the mouse parameters structure
*/
const I3dMouseParam& Gui::GUIApplicationNativeEventAware::MouseParams() const
{
return f3dMouseParams;
}
/*!
Called with the processed motion data when a 3D mouse event is received
The default implementation emits a Move3d signal with the motion data
*/
void Gui::GUIApplicationNativeEventAware::Move3d(HANDLE device, std::vector<float>& motionData)
{
Q_UNUSED(device);
QWidget *currentWidget = this->focusWidget();
if (!currentWidget)
currentWidget = mainWindow;
int x, y, z, rx, ry, rz;
x = ceil(motionData[0])*(-1);
y = ceil(motionData[1]);
z = ceil(motionData[2]);
rx = ceil(motionData[3])*(-1);
ry = ceil(motionData[4]);
rz = ceil(motionData[5]);
Spaceball::MotionEvent *motionEvent = new Spaceball::MotionEvent();
motionEvent->setTranslations(x, y, z);
motionEvent->setRotations(rx, ry, rz);
this->postEvent(currentWidget, motionEvent);
}
/*!
Called when a 3D mouse key is pressed
The default implementation emits a On3dmouseKeyDown signal with the key code.
*/
void Gui::GUIApplicationNativeEventAware::On3dmouseKeyDown(HANDLE device, int virtualKeyCode)
{
Q_UNUSED(device);
QWidget *currentWidget = this->focusWidget();
if (!currentWidget)
currentWidget = mainWindow;
Spaceball::ButtonEvent *buttonEvent = new Spaceball::ButtonEvent();
buttonEvent->setButtonNumber(virtualKeyCode - 1);
buttonEvent->setButtonStatus(Spaceball::BUTTON_PRESSED);
this->postEvent(currentWidget, buttonEvent);
}
/*!
Called when a 3D mouse key is released
The default implementation emits a On3dmouseKeyUp signal with the key code.
*/
void Gui::GUIApplicationNativeEventAware::On3dmouseKeyUp(HANDLE device, int virtualKeyCode)
{
Q_UNUSED(device);
QWidget *currentWidget = this->focusWidget();
if (!currentWidget)
currentWidget = mainWindow;
Spaceball::ButtonEvent *buttonEvent = new Spaceball::ButtonEvent();
buttonEvent->setButtonNumber(virtualKeyCode - 1);
buttonEvent->setButtonStatus(Spaceball::BUTTON_RELEASED);
this->postEvent(currentWidget, buttonEvent);
}
/*!
Get an initialized array of PRAWINPUTDEVICE for the 3D devices
pNumDevices returns the number of devices to register. Currently this is always 1.
*/
static PRAWINPUTDEVICE GetDevicesToRegister(unsigned int* pNumDevices)
{
// Array of raw input devices to register
static RAWINPUTDEVICE sRawInputDevices[] = {
{0x01, 0x08, 0x00, 0x00} // Usage Page = 0x01 Generic Desktop Page, Usage Id= 0x08 Multi-axis Controller
};
if (pNumDevices) {
*pNumDevices = sizeof(sRawInputDevices) / sizeof(sRawInputDevices[0]);
}
return sRawInputDevices;
}
/*!
Detect the 3D mouse
*/
bool Gui::GUIApplicationNativeEventAware::Is3dmouseAttached()
{
unsigned int numDevicesOfInterest = 0;
PRAWINPUTDEVICE devicesToRegister = GetDevicesToRegister(&numDevicesOfInterest);
unsigned int nDevices = 0;
if (::GetRawInputDeviceList(NULL, &nDevices, sizeof(RAWINPUTDEVICELIST)) != 0) {
return false;
}
if (nDevices == 0) return false;
std::vector<RAWINPUTDEVICELIST> rawInputDeviceList(nDevices);
if (::GetRawInputDeviceList(&rawInputDeviceList[0], &nDevices, sizeof(RAWINPUTDEVICELIST)) == static_cast<unsigned int>(-1)) {
return false;
}
for (unsigned int i = 0; i < nDevices; ++i) {
RID_DEVICE_INFO rdi = {sizeof(rdi)};
unsigned int cbSize = sizeof(rdi);
if (GetRawInputDeviceInfo(rawInputDeviceList[i].hDevice, RIDI_DEVICEINFO, &rdi, &cbSize) > 0) {
//skip non HID and non logitec (3DConnexion) devices
if (rdi.dwType != RIM_TYPEHID || rdi.hid.dwVendorId != LOGITECH_VENDOR_ID) {
continue;
}
//check if devices matches Multi-axis Controller
for (unsigned int j = 0; j < numDevicesOfInterest; ++j) {
if (devicesToRegister[j].usUsage == rdi.hid.usUsage
&& devicesToRegister[j].usUsagePage == rdi.hid.usUsagePage) {
return true;
}
}
}
}
return false;
}
/*!
Initialize the window to recieve raw-input messages
This needs to be called initially so that Windows will send the messages from the 3D mouse to the window.
*/
bool Gui::GUIApplicationNativeEventAware::InitializeRawInput(HWND hwndTarget)
{
fWindow = hwndTarget;
// Simply fail if there is no window
if (!hwndTarget) return false;
unsigned int numDevices = 0;
PRAWINPUTDEVICE devicesToRegister = GetDevicesToRegister(&numDevices);
if (numDevices == 0) return false;
// Get OS version.
OSVERSIONINFO osvi = {sizeof(OSVERSIONINFO),0};
::GetVersionEx(&osvi);
unsigned int cbSize = sizeof (devicesToRegister[0]);
for (size_t i = 0; i < numDevices; i++) {
// Set the target window to use
//devicesToRegister[i].hwndTarget = hwndTarget;
// If Vista or newer, enable receiving the WM_INPUT_DEVICE_CHANGE message.
if (osvi.dwMajorVersion >= 6) {
devicesToRegister[i].dwFlags |= RIDEV_DEVNOTIFY;
}
}
return (::RegisterRawInputDevices(devicesToRegister, numDevices, cbSize) != FALSE);
}
/*!
Get the raw input data from Windows
Includes workaround for incorrect alignment of the RAWINPUT structure on x64 os
when running as Wow64 (copied directly from 3DConnexion code)
*/
UINT Gui::GUIApplicationNativeEventAware::GetRawInputBuffer(PRAWINPUT pData, PUINT pcbSize, UINT cbSizeHeader)
{
#ifdef _WIN64
return ::GetRawInputBuffer(pData, pcbSize, cbSizeHeader);
#else
BOOL bIsWow64 = FALSE;
::IsWow64Process(GetCurrentProcess(), &bIsWow64);
if (!bIsWow64 || pData==NULL) {
return ::GetRawInputBuffer(pData, pcbSize, cbSizeHeader);
} else {
HWND hwndTarget = fWindow; //fParent->winId();
size_t cbDataSize=0;
UINT nCount=0;
PRAWINPUT pri = pData;
MSG msg;
while (PeekMessage(&msg, hwndTarget, WM_INPUT, WM_INPUT, PM_NOREMOVE)) {
HRAWINPUT hRawInput = reinterpret_cast<HRAWINPUT>(msg.lParam);
size_t cbSize = *pcbSize - cbDataSize;
if (::GetRawInputData(hRawInput, RID_INPUT, pri, &cbSize, cbSizeHeader) == static_cast<UINT>(-1)) {
if (nCount==0) {
return static_cast<UINT>(-1);
} else {
break;
}
}
++nCount;
// Remove the message for the data just read
PeekMessage(&msg, hwndTarget, WM_INPUT, WM_INPUT, PM_REMOVE);
pri = NEXTRAWINPUTBLOCK(pri);
cbDataSize = reinterpret_cast<ULONG_PTR>(pri) - reinterpret_cast<ULONG_PTR>(pData);
if (cbDataSize >= *pcbSize) {
cbDataSize = *pcbSize;
break;
}
}
return nCount;
}
#endif
}
/*!
Process the raw input device data
On3dmouseInput() does all the preprocessing of the rawinput device data before
finally calling the Move3d method.
*/
void Gui::GUIApplicationNativeEventAware::On3dmouseInput()
{
// Don't do any data processing in background
bool bIsForeground = (::GetActiveWindow() != NULL);
if (!bIsForeground) {
// set all cached data to zero so that a zero event is seen and the cached data deleted
for (std::map<HANDLE, TInputData>::iterator it = fDevice2Data.begin(); it != fDevice2Data.end(); it++) {
it->second.fAxes.assign(6, .0);
it->second.fIsDirty = true;
}
}
DWORD dwNow = ::GetTickCount(); // Current time;
DWORD dwElapsedTime; // Elapsed time since we were last here
if (0 == fLast3dmouseInputTime) {
dwElapsedTime = 10; // System timer resolution
} else {
dwElapsedTime = dwNow - fLast3dmouseInputTime;
if (fLast3dmouseInputTime > dwNow) {
dwElapsedTime = ~dwElapsedTime+1;
}
if (dwElapsedTime<1) {
dwElapsedTime=1;
} else if (dwElapsedTime > 500) {
// Check for wild numbers because the device was removed while sending data
dwElapsedTime = 10;
}
}
#if _TRACE_3DINPUT_PERIOD
qDebug("On3DmouseInput() period is %dms\n", dwElapsedTime);
#endif
float mouseData2Rotation;
// v = w * r, we don't know r yet so lets assume r=1.)
float mouseData2PanZoom;
// Grab the I3dmouseParam interface
I3dMouseParam& i3dmouseParam = f3dMouseParams;
// Take a look at the users preferred speed setting and adjust the sensitivity accordingly
I3dMouseSensor::ESpeed speedSetting = i3dmouseParam.GetSpeed();
// See "Programming for the 3D Mouse", Section 5.1.3
float speed = (speedSetting == I3dMouseSensor::kLowSpeed ? 0.25f : speedSetting == I3dMouseSensor::kHighSpeed ? 4.f : 1.f);
// Multiplying by the following will convert the 3d mouse data to real world units
mouseData2PanZoom = speed;
mouseData2Rotation = speed;
std::map<HANDLE, TInputData>::iterator iterator=fDevice2Data.begin();
while (iterator != fDevice2Data.end()) {
// If we have not received data for a while send a zero event
if ((--(iterator->second.fTimeToLive)) == 0) {
iterator->second.fAxes.assign(6, .0);
} else if (/*!t_bPoll3dmouse &&*/ !iterator->second.fIsDirty) {
// If we are not polling then only handle the data that was actually received
++iterator;
continue;
}
iterator->second.fIsDirty=false;
// get a copy of the device
HANDLE hdevice = iterator->first;
// get a copy of the motion vectors and apply the user filters
std::vector<float> motionData = iterator->second.fAxes;
// apply the user filters
// Pan Zoom filter
// See "Programming for the 3D Mouse", Section 5.1.2
if (!i3dmouseParam.IsPanZoom()) {
// Pan zoom is switched off so set the translation vector values to zero
motionData[0] = motionData[1] = motionData[2] = 0.;
}
// Rotate filter
// See "Programming for the 3D Mouse", Section 5.1.1
if (!i3dmouseParam.IsRotate()) {
// Rotate is switched off so set the rotation vector values to zero
motionData[3] = motionData[4] = motionData[5] = 0.;
}
// convert the translation vector into physical data
for (int axis = 0; axis < 3; axis++) {
motionData[axis] *= mouseData2PanZoom;
}
// convert the directed Rotate vector into physical data
// See "Programming for the 3D Mouse", Section 7.2.2
for (int axis = 3; axis < 6; axis++) {
motionData[axis] *= mouseData2Rotation;
}
// Now that the data has had the filters and sensitivty settings applied
// calculate the displacements since the last view update
for (int axis = 0; axis < 6; axis++) {
motionData[axis] *= dwElapsedTime;
}
// Now a bit of book keeping before passing on the data
if (iterator->second.IsZero()) {
iterator = fDevice2Data.erase(iterator);
} else {
++iterator;
}
// Work out which will be the next device
HANDLE hNextDevice = 0;
if (iterator != fDevice2Data.end()) {
hNextDevice = iterator->first;
}
// Pass the 3dmouse input to the view controller
Move3d(hdevice, motionData);
// Because we don't know what happened in the previous call, the cache might have
// changed so reload the iterator
iterator = fDevice2Data.find(hNextDevice);
}
if (!fDevice2Data.empty()) {
fLast3dmouseInputTime = dwNow;
} else {
fLast3dmouseInputTime = 0;
}
}
/*!
Called when new raw input data is available
*/
void Gui::GUIApplicationNativeEventAware::OnRawInput(UINT nInputCode, HRAWINPUT hRawInput)
{
const size_t cbSizeOfBuffer=1024;
BYTE pBuffer[cbSizeOfBuffer];
PRAWINPUT pRawInput = reinterpret_cast<PRAWINPUT>(pBuffer);
UINT cbSize = cbSizeOfBuffer;
if (::GetRawInputData(hRawInput, RID_INPUT, pRawInput, &cbSize, sizeof(RAWINPUTHEADER)) == static_cast<UINT>(-1)) {
return;
}
bool b3dmouseInput = TranslateRawInputData(nInputCode, pRawInput);
::DefRawInputProc(&pRawInput, 1, sizeof(RAWINPUTHEADER));
// Check for any buffered messages
cbSize = cbSizeOfBuffer;
UINT nCount = this->GetRawInputBuffer(pRawInput, &cbSize, sizeof(RAWINPUTHEADER));
if (nCount == (UINT)-1) {
qDebug ("GetRawInputBuffer returned error %d\n", GetLastError());
}
while (nCount>0 && nCount != static_cast<UINT>(-1)) {
PRAWINPUT pri = pRawInput;
UINT nInput;
for (nInput=0; nInput<nCount; ++nInput) {
b3dmouseInput |= TranslateRawInputData(nInputCode, pri);
// clean the buffer
::DefRawInputProc(&pri, 1, sizeof(RAWINPUTHEADER));
pri = NEXTRAWINPUTBLOCK(pri);
}
cbSize = cbSizeOfBuffer;
nCount = this->GetRawInputBuffer(pRawInput, &cbSize, sizeof(RAWINPUTHEADER));
}
// If we have mouse input data for the app then tell tha app about it
if (b3dmouseInput) {
On3dmouseInput();
}
}
bool Gui::GUIApplicationNativeEventAware::TranslateRawInputData(UINT nInputCode, PRAWINPUT pRawInput)
{
bool bIsForeground = (nInputCode == RIM_INPUT);
#if _TRACE_RI_TYPE
qDebug("Rawinput.header.dwType=0x%x\n", pRawInput->header.dwType);
#endif
// We are not interested in keyboard or mouse data received via raw input
if (pRawInput->header.dwType != RIM_TYPEHID) return false;
#if _TRACE_RIDI_DEVICENAME
UINT dwSize=0;
if (::GetRawInputDeviceInfo(pRawInput->header.hDevice, RIDI_DEVICENAME, NULL, &dwSize) == 0) {
std::vector<wchar_t> szDeviceName(dwSize+1);
if (::GetRawInputDeviceInfo(pRawInput->header.hDevice, RIDI_DEVICENAME, &szDeviceName[0], &dwSize) >0) {
qDebug("Device Name = %s\nDevice handle = 0x%x\n", &szDeviceName[0], pRawInput->header.hDevice);
}
}
#endif
RID_DEVICE_INFO sRidDeviceInfo;
sRidDeviceInfo.cbSize = sizeof(RID_DEVICE_INFO);
UINT cbSize = sizeof(RID_DEVICE_INFO);
if (::GetRawInputDeviceInfo(pRawInput->header.hDevice, RIDI_DEVICEINFO, &sRidDeviceInfo, &cbSize) == cbSize) {
#if _TRACE_RIDI_DEVICEINFO
switch (sRidDeviceInfo.dwType) {
case RIM_TYPEMOUSE:
qDebug("\tsRidDeviceInfo.dwType=RIM_TYPEMOUSE\n");
break;
case RIM_TYPEKEYBOARD:
qDebug("\tsRidDeviceInfo.dwType=RIM_TYPEKEYBOARD\n");
break;
case RIM_TYPEHID:
qDebug("\tsRidDeviceInfo.dwType=RIM_TYPEHID\n");
qDebug("\tVendor=0x%x\n\tProduct=0x%x\n\tUsagePage=0x%x\n\tUsage=0x%x\n",
sRidDeviceInfo.hid.dwVendorId,
sRidDeviceInfo.hid.dwProductId,
sRidDeviceInfo.hid.usUsagePage,
sRidDeviceInfo.hid.usUsage);
break;
}
#endif
if (sRidDeviceInfo.hid.dwVendorId == LOGITECH_VENDOR_ID) {
if (pRawInput->data.hid.bRawData[0] == 0x01) { // Translation vector
TInputData& deviceData = fDevice2Data[pRawInput->header.hDevice];
deviceData.fTimeToLive = kTimeToLive;
if (bIsForeground) {
short* pnRawData = reinterpret_cast<short*>(&pRawInput->data.hid.bRawData[1]);
// Cache the pan zoom data
deviceData.fAxes[0] = static_cast<float>(pnRawData[0]);
deviceData.fAxes[1] = static_cast<float>(pnRawData[1]);
deviceData.fAxes[2] = static_cast<float>(pnRawData[2]);
#if _TRACE_RI_RAWDATA
qDebug("Pan/Zoom RI Data =\t0x%x,\t0x%x,\t0x%x\n",
pnRawData[0], pnRawData[1], pnRawData[2]);
#endif
if (pRawInput->data.hid.dwSizeHid >= 13) {// Highspeed package
// Cache the rotation data
deviceData.fAxes[3] = static_cast<float>(pnRawData[3]);
deviceData.fAxes[4] = static_cast<float>(pnRawData[4]);
deviceData.fAxes[5] = static_cast<float>(pnRawData[5]);
deviceData.fIsDirty = true;
#if _TRACE_RI_RAWDATA
qDebug("Rotation RI Data =\t0x%x,\t0x%x,\t0x%x\n",
pnRawData[3], pnRawData[4], pnRawData[5]);
#endif
return true;
}
} else { // Zero out the data if the app is not in forground
deviceData.fAxes.assign(6, 0.f);
}
} else if (pRawInput->data.hid.bRawData[0] == 0x02) { // Rotation vector
// If we are not in foreground do nothing
// The rotation vector was zeroed out with the translation vector in the previous message
if (bIsForeground) {
TInputData& deviceData = fDevice2Data[pRawInput->header.hDevice];
deviceData.fTimeToLive = kTimeToLive;
short* pnRawData = reinterpret_cast<short*>(&pRawInput->data.hid.bRawData[1]);
// Cache the rotation data
deviceData.fAxes[3] = static_cast<float>(pnRawData[0]);
deviceData.fAxes[4] = static_cast<float>(pnRawData[1]);
deviceData.fAxes[5] = static_cast<float>(pnRawData[2]);
deviceData.fIsDirty = true;
#if _TRACE_RI_RAWDATA
qDebug("Rotation RI Data =\t0x%x,\t0x%x,\t0x%x\n",
pnRawData[0], pnRawData[1], pnRawData[2]);
#endif
return true;
}
} else if (pRawInput->data.hid.bRawData[0] == 0x03) { // Keystate change
// this is a package that contains 3d mouse keystate information
// bit0=key1, bit=key2 etc.
unsigned long dwKeystate = *reinterpret_cast<unsigned long*>(&pRawInput->data.hid.bRawData[1]);
#if _TRACE_RI_RAWDATA
qDebug("ButtonData =0x%x\n", dwKeystate);
#endif
// Log the keystate changes
unsigned long dwOldKeystate = fDevice2Keystate[pRawInput->header.hDevice];
if (dwKeystate != 0) {
fDevice2Keystate[pRawInput->header.hDevice] = dwKeystate;
} else {
fDevice2Keystate.erase(pRawInput->header.hDevice);
}
// Only call the keystate change handlers if the app is in foreground
if (bIsForeground) {
unsigned long dwChange = dwKeystate ^ dwOldKeystate;
for (int nKeycode=1; nKeycode<33; nKeycode++) {
if (dwChange & 0x01) {
int nVirtualKeyCode = HidToVirtualKey(sRidDeviceInfo.hid.dwProductId, nKeycode);
if (nVirtualKeyCode) {
if (dwKeystate&0x01) {
On3dmouseKeyDown(pRawInput->header.hDevice, nVirtualKeyCode);
} else {
On3dmouseKeyUp(pRawInput->header.hDevice, nVirtualKeyCode);
}
}
}
dwChange >>=1;
dwKeystate >>=1;
}
}
}
}
}
return false;
}
#endif // _USE_3DCONNEXION_SDK

View File

@ -0,0 +1,91 @@
/*
Development tools and related technology provided under license from 3Dconnexion.
(c) 1992 - 2012 3Dconnexion. All rights reserved
*/
#ifndef I3D_MOUSE_PARAMS_H
#define I3D_MOUSE_PARAMS_H
/*
Parameters for the 3D mouse based on the SDK from 3Dconnexion
*/
class I3dMouseSensor
{
public:
enum ESpeed {
kLowSpeed = 0,
kMidSpeed,
kHighSpeed
};
virtual bool IsPanZoom() const = 0;
virtual bool IsRotate() const = 0;
virtual ESpeed GetSpeed() const = 0;
virtual void SetPanZoom(bool isPanZoom) = 0;
virtual void SetRotate(bool isRotate) = 0;
virtual void SetSpeed(ESpeed speed) = 0;
protected:
virtual ~I3dMouseSensor() {}
};
class I3dMouseNavigation
{
public:
enum EPivot {
kManualPivot = 0,
kAutoPivot,
kAutoPivotOverride
};
enum ENavigation {
kObjectMode = 0,
kCameraMode,
kFlyMode,
kWalkMode,
kHelicopterMode
};
enum EPivotVisibility {
kHidePivot = 0,
kShowPivot,
kShowMovingPivot
};
virtual ENavigation GetNavigationMode() const = 0;
virtual EPivot GetPivotMode() const = 0;
virtual EPivotVisibility GetPivotVisibility() const = 0;
virtual bool IsLockHorizon() const = 0;
virtual void SetLockHorizon(bool bOn) = 0;
virtual void SetNavigationMode(ENavigation navigation) = 0;
virtual void SetPivotMode(EPivot pivot) = 0;
virtual void SetPivotVisibility(EPivotVisibility visibility) = 0;
protected:
virtual ~I3dMouseNavigation(){}
};
class I3dMouseParam : public I3dMouseSensor, public I3dMouseNavigation
{
public:
virtual ~I3dMouseParam() {}
};
#endif // I3D_MOUSE_PARAMS_H

View File

@ -0,0 +1,95 @@
/*
Development tools and related technology provided under license from 3Dconnexion.
(c) 1992 - 2012 3Dconnexion. All rights reserved
*/
#include "PreCompiled.h"
#include "MouseParameters.h"
MouseParameters::MouseParameters(): fNavigation(kObjectMode)
, fPivot(kAutoPivot)
, fPivotVisibility(kShowPivot)
, fIsLockHorizon(true)
, fIsPanZoom(true)
, fIsRotate(true)
, fSpeed(kLowSpeed)
{
}
MouseParameters::~MouseParameters()
{
}
bool MouseParameters::IsPanZoom() const
{
return fIsPanZoom;
}
bool MouseParameters::IsRotate() const
{
return fIsRotate;
}
MouseParameters::ESpeed MouseParameters::GetSpeed() const
{
return fSpeed;
}
void MouseParameters::SetPanZoom(bool isPanZoom)
{
fIsPanZoom=isPanZoom;
}
void MouseParameters::SetRotate(bool isRotate)
{
fIsRotate=isRotate;
}
void MouseParameters::SetSpeed(ESpeed speed)
{
fSpeed=speed;
}
MouseParameters::ENavigation MouseParameters::GetNavigationMode() const
{
return fNavigation;
}
MouseParameters::EPivot MouseParameters::GetPivotMode() const
{
return fPivot;
}
MouseParameters::EPivotVisibility MouseParameters::GetPivotVisibility() const
{
return fPivotVisibility;
}
bool MouseParameters::IsLockHorizon() const
{
return fIsLockHorizon;
}
void MouseParameters::SetLockHorizon(bool bOn)
{
fIsLockHorizon=bOn;
}
void MouseParameters::SetNavigationMode(ENavigation navigation)
{
fNavigation=navigation;
}
void MouseParameters::SetPivotMode(EPivot pivot)
{
if (fPivot!=kManualPivot || pivot!=kAutoPivotOverride)
fPivot = pivot;
}
void MouseParameters::SetPivotVisibility(EPivotVisibility visibility)
{
fPivotVisibility = visibility;
}

View File

@ -0,0 +1,56 @@
/*
Development tools and related technology provided under license from 3Dconnexion.
(c) 1992 - 2012 3Dconnexion. All rights reserved
*/
#ifndef T3D_MOUSE_PARAMS_H
#define T3D_MOUSE_PARAMS_H
#include "I3dMouseParams.h"
class MouseParameters : public I3dMouseParam
{
public:
MouseParameters();
~MouseParameters();
// I3dmouseSensor interface
bool IsPanZoom() const;
bool IsRotate() const;
ESpeed GetSpeed() const;
void SetPanZoom(bool isPanZoom);
void SetRotate(bool isRotate);
void SetSpeed(ESpeed speed);
// I3dmouseNavigation interface
ENavigation GetNavigationMode() const;
EPivot GetPivotMode() const;
EPivotVisibility GetPivotVisibility() const;
bool IsLockHorizon() const;
void SetLockHorizon(bool bOn);
void SetNavigationMode(ENavigation navigation);
void SetPivotMode(EPivot pivot);
void SetPivotVisibility(EPivotVisibility visibility);
private:
MouseParameters (const MouseParameters&);
const MouseParameters& operator =(const MouseParameters&);
ENavigation fNavigation;
EPivot fPivot;
EPivotVisibility fPivotVisibility;
bool fIsLockHorizon;
bool fIsPanZoom;
bool fIsRotate;
ESpeed fSpeed;
};
#endif // T3D_MOUSE_PARAMS_H

View File

@ -115,14 +115,14 @@
<property name="spacing">
<number>6</number>
</property>
<item row="3" column="0">
<item row="4" column="0">
<widget class="QLabel" name="labelPlatform">
<property name="text">
<string>Platform</string>
</property>
</widget>
</item>
<item row="3" column="1">
<item row="4" column="1">
<widget class="QLabel" name="labelBuildPlatform">
<property name="text">
<string notr="true">&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;/head&gt;&lt;body style=&quot; white-space: pre-wrap; font-family:MS Shell Dlg 2; font-size:7.8pt; font-weight:400; font-style:normal; text-decoration:none;&quot;&gt;&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Unknown&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@ -171,34 +171,48 @@
</property>
</widget>
</item>
<item row="5" column="0">
<item row="6" column="0">
<widget class="QLabel" name="labelBranch">
<property name="text">
<string notr="true">Branch</string>
</property>
</widget>
</item>
<item row="5" column="1">
<item row="6" column="1">
<widget class="QLabel" name="labelBuildBranch">
<property name="text">
<string notr="true">&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;/head&gt;&lt;body style=&quot; white-space: pre-wrap; font-family:MS Shell Dlg 2; font-size:7.8pt; font-weight:400; font-style:normal; text-decoration:none;&quot;&gt;&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Unknown&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="6" column="1">
<item row="7" column="1">
<widget class="QLabel" name="labelBuildHash">
<property name="text">
<string notr="true">&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;/head&gt;&lt;body style=&quot; white-space: pre-wrap; font-family:MS Shell Dlg 2; font-size:7.8pt; font-weight:400; font-style:normal; text-decoration:none;&quot;&gt;&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Unknown&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="6" column="0">
<item row="7" column="0">
<widget class="QLabel" name="labelHash">
<property name="text">
<string notr="true">Hash</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="labelOS">
<property name="text">
<string>Operating system</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="labelBuildOS">
<property name="text">
<string notr="true">&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;/head&gt;&lt;body style=&quot; white-space: pre-wrap; font-family:MS Shell Dlg 2; font-size:7.8pt; font-weight:400; font-style:normal; text-decoration:none;&quot;&gt;&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Unknown&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>

View File

@ -28,6 +28,7 @@
# include <boost/bind.hpp>
# include <QActionEvent>
# include <QApplication>
# include <QDesktopWidget>
# include <QEvent>
# include <QMessageBox>
# include <QToolBar>
@ -345,6 +346,18 @@ WorkbenchComboBox::~WorkbenchComboBox()
{
}
void WorkbenchComboBox::showPopup()
{
int rows = count();
if (rows > 0) {
int height = view()->sizeHintForRow(0);
int maxHeight = QApplication::desktop()->height();
view()->setMinimumHeight(qMin(height * rows, maxHeight/2));
}
QComboBox::showPopup();
}
void WorkbenchComboBox::actionEvent ( QActionEvent* e )
{
QAction *action = e->action();

View File

@ -124,6 +124,7 @@ class GuiExport WorkbenchComboBox : public QComboBox
public:
WorkbenchComboBox(WorkbenchGroup* wb, QWidget* parent=0);
virtual ~WorkbenchComboBox();
void showPopup();
public Q_SLOTS:
void onActivated(int);

View File

@ -52,6 +52,7 @@
#include <Base/Factory.h>
#include <Base/FileInfo.h>
#include <Base/Tools.h>
#include <Base/UnitsApi.h>
#include <App/Document.h>
#include <App/DocumentObjectPy.h>
@ -328,6 +329,10 @@ Application::Application(bool GUIenabled)
Translator::instance()->activateLanguage(hPGrp->GetASCII("Language", (const char*)lang.toAscii()).c_str());
GetWidgetFactorySupplier();
ParameterGrp::handle hUnits = App::GetApplication().GetParameterGroupByPath
("User parameter:BaseApp/Preferences/Units");
Base::UnitsApi::setDecimals(hUnits->GetInt("Decimals", Base::UnitsApi::getDecimals()));
// setting up Python binding
Base::PyGILStateLocker lock;
PyObject* module = Py_InitModule3("FreeCADGui", Application::Methods,
@ -341,6 +346,10 @@ Application::Application(bool GUIenabled)
"workbenches.");
Py::Module(module).setAttr(std::string("ActiveDocument"),Py::None());
UiLoaderPy::init_type();
Base::Interpreter().addType(UiLoaderPy::type_object(),
module,"UiLoader");
//insert Selection module
PyObject* pSelectionModule = Py_InitModule3("Selection", SelectionSingleton::Methods,
"Selection module");
@ -860,8 +869,13 @@ void Application::tryClose(QCloseEvent * e)
// ask all documents if closable
std::map<const App::Document*, Gui::Document*>::iterator It;
for (It = d->documents.begin();It!=d->documents.end();It++) {
// a document may have several views attached, so ask it directly
#if 0
MDIView* active = It->second->getActiveView();
e->setAccepted(active->canClose());
#else
e->setAccepted(It->second->canClose());
#endif
if (!e->isAccepted())
return;
}
@ -1352,13 +1366,13 @@ void messageHandlerCoin(const SoError * error, void * userdata)
switch (dbg->getSeverity())
{
case SoDebugError::INFO:
Base::Console().Message( msg );
Base::Console().Message("%s\n", msg);
break;
case SoDebugError::WARNING:
Base::Console().Warning( msg );
Base::Console().Warning("%s\n", msg);
break;
default: // error
Base::Console().Error( msg );
Base::Console().Error("%s\n", msg);
break;
}
#ifdef FC_OS_WIN32
@ -1415,6 +1429,7 @@ void Application::initTypes(void)
Gui::ViewProviderDocumentObject ::init();
Gui::ViewProviderFeature ::init();
Gui::ViewProviderDocumentObjectGroup ::init();
Gui::ViewProviderDocumentObjectGroupPython ::init();
Gui::ViewProviderGeometryObject ::init();
Gui::ViewProviderInventorObject ::init();
Gui::ViewProviderVRMLObject ::init();
@ -1442,9 +1457,10 @@ namespace Gui {
*/
class GUIApplication : public GUIApplicationNativeEventAware
{
int systemExit;
public:
GUIApplication(int & argc, char ** argv)
: GUIApplicationNativeEventAware(argc, argv)
GUIApplication(int & argc, char ** argv, int exitcode)
: GUIApplicationNativeEventAware(argc, argv), systemExit(exitcode)
{
}
@ -1465,6 +1481,10 @@ public:
else
return QApplication::notify(receiver, event);
}
catch (const Base::SystemExitException&) {
qApp->exit(systemExit);
return true;
}
catch (const Base::Exception& e) {
Base::Console().Error("Unhandled Base::Exception caught in GUIApplication::notify.\n"
"The error message is: %s\n", e.what());
@ -1528,10 +1548,19 @@ void Application::runApplication(void)
Base::Console().Log("Init: Creating Gui::Application and QApplication\n");
// if application not yet created by the splasher
int argc = App::Application::GetARGC();
GUIApplication mainApp(argc, App::Application::GetARGV());
int systemExit = 1000;
GUIApplication mainApp(argc, App::Application::GetARGV(), systemExit);
// set application icon and window title
const std::map<std::string,std::string>& cfg = App::Application::Config();
std::map<std::string,std::string>::const_iterator it;
it = cfg.find("Application");
if (it != cfg.end()) {
mainApp.setApplicationName(QString::fromUtf8(it->second.c_str()));
}
else {
mainApp.setApplicationName(QString::fromUtf8(App::GetApplication().getExecutableName()));
}
mainApp.setWindowIcon(Gui::BitmapFactory().pixmap(App::Application::Config()["AppIcon"].c_str()));
mainApp.setApplicationName(QString::fromAscii(App::GetApplication().getExecutableName()));
QString plugin;
plugin = QString::fromUtf8(App::GetApplication().GetHomePath());
plugin += QLatin1String("/plugins");
@ -1591,8 +1620,6 @@ void Application::runApplication(void)
QString home = QString::fromUtf8(App::GetApplication().GetHomePath());
const std::map<std::string,std::string>& cfg = App::Application::Config();
std::map<std::string,std::string>::const_iterator it;
it = cfg.find("WindowTitle");
if (it != cfg.end()) {
QString title = QString::fromUtf8(it->second.c_str());
@ -1620,9 +1647,15 @@ void Application::runApplication(void)
logo->setFrameShape(QFrame::NoFrame);
}
}
bool hidden = false;
it = cfg.find("StartHidden");
if (it != cfg.end()) {
hidden = true;
}
// show splasher while initializing the GUI
mw.startSplasher();
if (!hidden)
mw.startSplasher();
// running the GUI init script
try {
@ -1656,8 +1689,10 @@ void Application::runApplication(void)
app.activateWorkbench(start.c_str());
// show the main window
Base::Console().Log("Init: Showing main window\n");
mw.loadWindowSettings();
if (!hidden) {
Base::Console().Log("Init: Showing main window\n");
mw.loadWindowSettings();
}
//initialize spaceball.
mainApp.initSpaceball(&mw);
@ -1687,9 +1722,15 @@ void Application::runApplication(void)
Base::Console().Log("Init: Entering event loop\n");
try {
mainApp.exec();
int ret = mainApp.exec();
if (ret == systemExit)
throw Base::SystemExitException();
}
catch(...) {
catch (const Base::SystemExitException&) {
Base::Console().Message("System exit\n");
throw;
}
catch (...) {
// catching nasty stuff coming out of the event loop
App::Application::destructObserver();
Base::Console().Error("Event loop left through unhandled exception\n");

View File

@ -231,6 +231,8 @@ public:
PYFUNCDEF_S(sActiveDocument);
PYFUNCDEF_S(sGetDocument);
PYFUNCDEF_S(sDoCommand);
static PyMethodDef Methods[];
private:

View File

@ -26,6 +26,7 @@
#ifndef _PreComp_
# include <qfileinfo.h>
# include <qdir.h>
# include <QPrinter>
#endif
@ -36,6 +37,7 @@
#include "MainWindow.h"
#include "EditorView.h"
#include "PythonEditor.h"
#include "View3DInventor.h"
#include "WidgetFactory.h"
#include "Workbench.h"
#include "WorkbenchManager.h"
@ -126,6 +128,9 @@ PyMethodDef Application::Methods[] = {
{"getDocument", (PyCFunction) Application::sGetDocument, 1,
"getDocument(string) -> object\n\n"
"Get a document by its name"},
{"doCommand", (PyCFunction) Application::sDoCommand, 1,
"doCommand(string) -> None\n\n"
"Prints the given string in the python console and runs it"},
{NULL, NULL} /* Sentinel */
};
@ -357,10 +362,33 @@ PyObject* Application::sExport(PyObject * /*self*/, PyObject *args,PyObject * /*
if (ext == QLatin1String("iv") || ext == QLatin1String("wrl") ||
ext == QLatin1String("vrml") || ext == QLatin1String("wrz") ||
ext == QLatin1String("svg") || ext == QLatin1String("idtf")) {
QString cmd = QString::fromLatin1(
"Gui.getDocument(\"%1\").ActiveView.dump(\"%2\")"
).arg(QLatin1String(doc->getName())).arg(fi.absoluteFilePath());
Base::Interpreter().runString(cmd.toUtf8());
Gui::Document* gui_doc = Application::Instance->getDocument(doc);
std::list<MDIView*> view3d = gui_doc->getMDIViewsOfType(View3DInventor::getClassTypeId());
if (view3d.empty()) {
PyErr_SetString(PyExc_Exception, "Cannot export to SVG because document doesn't have a 3d view");
return 0;
}
else {
QString cmd = QString::fromLatin1(
"Gui.getDocument(\"%1\").mdiViewsOfType('Gui::View3DInventor')[0].dump(\"%2\")"
).arg(QLatin1String(doc->getName())).arg(fi.absoluteFilePath());
Base::Interpreter().runString(cmd.toUtf8());
}
}
else if (ext == QLatin1String("pdf")) {
Gui::Document* gui_doc = Application::Instance->getDocument(doc);
if (gui_doc) {
Gui::MDIView* view = gui_doc->getActiveView();
if (view) {
View3DInventor* view3d = qobject_cast<View3DInventor*>(view);
if (view3d)
view3d->viewAll();
QPrinter printer(QPrinter::ScreenResolution);
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setOutputFileName(fileName);
view->print(&printer);
}
}
}
}
} PY_CATCH;
@ -748,3 +776,12 @@ PyObject* Application::sRunCommand(PyObject * /*self*/, PyObject *args,PyObject
return 0;
}
}
PyObject* Application::sDoCommand(PyObject * /*self*/, PyObject *args,PyObject * /*kwd*/)
{
char *pstr=0;
if (!PyArg_ParseTuple(args, "s", &pstr)) // convert args: Python->C
return NULL; // NULL triggers exception
Command::doCommand(Command::Doc,pstr);
return Py_None;
}

View File

@ -181,6 +181,7 @@ SbBool BlenderNavigationStyle::processSoEvent(const SoEvent * const ev)
else if (press && (this->currentmode == NavigationStyle::PANNING ||
this->currentmode == NavigationStyle::ZOOMING)) {
newmode = NavigationStyle::DRAGGING;
saveCursorPosition(ev);
this->centerTime = ev->getTime();
processed = TRUE;
}
@ -221,6 +222,7 @@ SbBool BlenderNavigationStyle::processSoEvent(const SoEvent * const ev)
if (press && (this->currentmode == NavigationStyle::PANNING ||
this->currentmode == NavigationStyle::ZOOMING)) {
newmode = NavigationStyle::DRAGGING;
saveCursorPosition(ev);
this->centerTime = ev->getTime();
processed = TRUE;
}
@ -285,6 +287,7 @@ SbBool BlenderNavigationStyle::processSoEvent(const SoEvent * const ev)
else if (this->currentmode == NavigationStyle::DRAGGING) {
this->addToLog(event->getPosition(), event->getTime());
this->spin(posn);
moveCursorPosition();
processed = TRUE;
}
}
@ -338,6 +341,9 @@ SbBool BlenderNavigationStyle::processSoEvent(const SoEvent * const ev)
newmode = NavigationStyle::PANNING;
break;
case BUTTON3DOWN:
if (newmode != NavigationStyle::DRAGGING) {
saveCursorPosition(ev);
}
newmode = NavigationStyle::DRAGGING;
break;
case CTRLDOWN|SHIFTDOWN|BUTTON2DOWN:

View File

@ -210,6 +210,7 @@ SbBool CADNavigationStyle::processSoEvent(const SoEvent * const ev)
else if (press && (this->currentmode == NavigationStyle::PANNING ||
this->currentmode == NavigationStyle::ZOOMING)) {
newmode = NavigationStyle::DRAGGING;
saveCursorPosition(ev);
this->centerTime = ev->getTime();
processed = TRUE;
}
@ -250,6 +251,7 @@ SbBool CADNavigationStyle::processSoEvent(const SoEvent * const ev)
if (press && (this->currentmode == NavigationStyle::PANNING ||
this->currentmode == NavigationStyle::ZOOMING)) {
newmode = NavigationStyle::DRAGGING;
saveCursorPosition(ev);
this->centerTime = ev->getTime();
processed = TRUE;
}
@ -314,6 +316,7 @@ SbBool CADNavigationStyle::processSoEvent(const SoEvent * const ev)
else if (this->currentmode == NavigationStyle::DRAGGING) {
this->addToLog(event->getPosition(), event->getTime());
this->spin(posn);
moveCursorPosition();
processed = TRUE;
}
}
@ -379,6 +382,9 @@ SbBool CADNavigationStyle::processSoEvent(const SoEvent * const ev)
newmode = NavigationStyle::PANNING;
break;
case SHIFTDOWN|BUTTON2DOWN:
if (newmode != NavigationStyle::DRAGGING) {
saveCursorPosition(ev);
}
newmode = NavigationStyle::DRAGGING;
break;
case CTRLDOWN|SHIFTDOWN|BUTTON2DOWN:

View File

@ -3,6 +3,9 @@
if(WIN32)
add_definitions(-DFCGui -DQIIS_MAKEDLL)
endif(WIN32)
if (FREECAD_USE_3DCONNEXION)
add_definitions(-D_USE_3DCONNEXION_SDK)
endif(FREECAD_USE_3DCONNEXION)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
@ -78,6 +81,17 @@ SET(FreeCADGui_XML_SRCS
)
SOURCE_GROUP("XML" FILES ${FreeCADApp_XML_SRCS})
# The 3D Connexion SDK files
if(FREECAD_USE_3DCONNEXION)
SET(FreeCADGui_SDK_SRCS
3Dconnexion/I3dMouseParams.h
3Dconnexion/MouseParameters.cpp
3Dconnexion/MouseParameters.h
3Dconnexion/GuiApplicationNativeEventAwareWin32.cpp
)
SOURCE_GROUP("3D connexion SDK" FILES ${FreeCADGui_SDK_SRCS})
endif(FREECAD_USE_3DCONNEXION)
set(Gui_MOC_HDRS
Action.h
CallTips.h
@ -769,6 +783,7 @@ SET(FreeCADGui_SRCS
)
SET(FreeCADGui_SRCS
${FreeCADGui_SDK_SRCS}
${FreeCADGui_CPP_SRCS}
${FreeCADGui_XML_SRCS}
${iis_MOC_SRCS}

View File

@ -64,6 +64,8 @@ CombiView::CombiView(Gui::Document* pcDocument, QWidget *parent)
// tree widget
tree = new TreeWidget(this);
//tree->setRootIsDecorated(false);
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/TreeView");
tree->setIndentation(hGrp->GetInt("Indentation", tree->indentation()));
splitter->addWidget(tree);
// property view

View File

@ -281,6 +281,9 @@ void Command::invoke(int i)
if (isActive())
activated( i );
}
catch (const Base::SystemExitException&) {
throw;
}
catch (Base::PyException &e) {
e.ReportException();
Base::Console().Error("Stack Trace: %s\n",e.getStackTrace().c_str());

View File

@ -24,12 +24,21 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QClipboard>
# include <QEventLoop>
# include <QFileDialog>
# include <QGraphicsScene>
# include <QGraphicsView>
# include <QLabel>
# include <QStatusBar>
# include <QPointer>
# include <QProcess>
# include <sstream>
# include <Inventor/nodes/SoCamera.h>
#endif
#include <algorithm>
#include <Base/Exception.h>
#include <Base/FileInfo.h>
#include <Base/Interpreter.h>
#include <Base/Sequencer.h>
#include <App/Document.h>
@ -192,6 +201,11 @@ void StdCmdImport::activated(int iMsg)
getActiveGuiDocument()->getDocument()->getName(),
it.value().toAscii());
}
std::list<Gui::MDIView*> views = getActiveGuiDocument()->getMDIViewsOfType(Gui::View3DInventor::getClassTypeId());
for (std::list<MDIView*>::iterator it = views.begin(); it != views.end(); ++it) {
(*it)->viewAll();
}
}
bool StdCmdImport::isActive(void)
@ -279,9 +293,9 @@ StdCmdMergeProjects::StdCmdMergeProjects()
void StdCmdMergeProjects::activated(int iMsg)
{
QString exe = QString::fromUtf8(App::GetApplication().getExecutableName());
QString exe = qApp->applicationName();
QString project = QFileDialog::getOpenFileName(Gui::getMainWindow(),
QString::fromUtf8(QT_TR_NOOP("Merge project")), QString(),
QString::fromUtf8(QT_TR_NOOP("Merge project")), QDir::homePath(),
QString::fromUtf8(QT_TR_NOOP("%1 document (*.fcstd)")).arg(exe));
if (!project.isEmpty()) {
App::Document* doc = App::GetApplication().getActiveDocument();
@ -294,9 +308,6 @@ void StdCmdMergeProjects::activated(int iMsg)
return;
}
QString dir1 = proj.absoluteDir().filePath(proj.baseName());
QString dir2 = info.absoluteDir().filePath(info.baseName());
Base::FileInfo fi((const char*)project.toUtf8());
Base::ifstream str(fi, std::ios::in | std::ios::binary);
MergeDocuments md(doc);
@ -309,6 +320,120 @@ bool StdCmdMergeProjects::isActive(void)
return this->hasActiveDocument();
}
//===========================================================================
// Std_ExportGraphviz
//===========================================================================
namespace Gui {
class ImageView : public MDIView
{
public:
ImageView(const QPixmap& p, QWidget* parent=0) : MDIView(0, parent)
{
scene = new QGraphicsScene();
scene->addPixmap(p);
view = new QGraphicsView(scene, this);
view->show();
setCentralWidget(view);
}
~ImageView()
{
delete scene;
delete view;
}
QGraphicsScene* scene;
QGraphicsView* view;
};
}
DEF_STD_CMD_A(StdCmdExportGraphviz);
StdCmdExportGraphviz::StdCmdExportGraphviz()
: Command("Std_ExportGraphviz")
{
// seting the
sGroup = QT_TR_NOOP("Tools");
sMenuText = QT_TR_NOOP("Dependency graph...");
sToolTipText = QT_TR_NOOP("Show the dependency graph of the objects in the active document");
sStatusTip = QT_TR_NOOP("Show the dependency graph of the objects in the active document");
sWhatsThis = "Std_ExportGraphviz";
eType = 0;
}
void StdCmdExportGraphviz::activated(int iMsg)
{
App::Document* doc = App::GetApplication().getActiveDocument();
std::stringstream str;
doc->exportGraphviz(str);
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Paths");
QProcess proc;
QStringList args;
args << QLatin1String("-Tpng");
#ifdef FC_OS_LINUX
QString path = QString::fromUtf8(hGrp->GetASCII("Graphviz", "/usr/bin").c_str());
#else
QString path = QString::fromUtf8(hGrp->GetASCII("Graphviz").c_str());
#endif
bool pathChanged = false;
#ifdef FC_OS_WIN32
QString exe = QString::fromAscii("\"%1/dot\"").arg(path);
#else
QString exe = QString::fromAscii("%1/dot").arg(path);
#endif
proc.setEnvironment(QProcess::systemEnvironment());
do {
proc.start(exe, args);
if (!proc.waitForStarted()) {
int ret = QMessageBox::warning(getMainWindow(),
qApp->translate("Std_ExportGraphviz","Graphviz not found"),
qApp->translate("Std_ExportGraphviz","Graphviz couldn't be found on your system.\n"
"Do you want to specify its installation path if it's already installed?"),
QMessageBox::Yes, QMessageBox::No);
if (ret == QMessageBox::No)
return;
path = QFileDialog::getExistingDirectory(Gui::getMainWindow(),
qApp->translate("Std_ExportGraphviz","Graphviz installation path"));
if (path.isEmpty())
return;
pathChanged = true;
#ifdef FC_OS_WIN32
exe = QString::fromAscii("\"%1/dot\"").arg(path);
#else
exe = QString::fromAscii("%1/dot").arg(path);
#endif
}
else {
if (pathChanged)
hGrp->SetASCII("Graphviz", (const char*)path.toUtf8());
break;
}
}
while(true);
proc.write(str.str().c_str(), str.str().size());
proc.closeWriteChannel();
if (!proc.waitForFinished())
return;
QPixmap px;
if (px.loadFromData(proc.readAll(), "PNG")) {
Gui::ImageView* view = new Gui::ImageView(px);
view->setWindowTitle(qApp->translate("Std_ExportGraphviz","Dependency graph"));
getMainWindow()->addWindow(view);
}
else {
QMessageBox::warning(getMainWindow(),
qApp->translate("Std_ExportGraphviz","Graphviz failed"),
qApp->translate("Std_ExportGraphviz","Graphviz failed to create an image file"));
}
}
bool StdCmdExportGraphviz::isActive(void)
{
return (getActiveGuiDocument() ? true : false);
}
//===========================================================================
// Std_New
//===========================================================================
@ -769,9 +894,9 @@ bool StdCmdPaste::isActive(void)
return getMainWindow()->canInsertFromMimeData(mime);
}
DEF_STD_CMD_A(StdCmdDDuplicateSelection);
DEF_STD_CMD_A(StdCmdDuplicateSelection);
StdCmdDDuplicateSelection::StdCmdDDuplicateSelection()
StdCmdDuplicateSelection::StdCmdDuplicateSelection()
:Command("Std_DuplicateSelection")
{
sAppModule = "Edit";
@ -782,7 +907,7 @@ StdCmdDDuplicateSelection::StdCmdDDuplicateSelection()
sStatusTip = QT_TR_NOOP("Put duplicates of the selected objects to the active document");
}
void StdCmdDDuplicateSelection::activated(int iMsg)
void StdCmdDuplicateSelection::activated(int iMsg)
{
App::Document* act = App::GetApplication().getActiveDocument();
if (!act)
@ -839,7 +964,7 @@ void StdCmdDDuplicateSelection::activated(int iMsg)
}
}
bool StdCmdDDuplicateSelection::isActive(void)
bool StdCmdDuplicateSelection::isActive(void)
{
return Gui::Selection().hasSelection();
}
@ -1052,16 +1177,27 @@ void StdCmdAlignment::activated(int iMsg)
model.addGroups(groupMap);
align->setModel(model);
Base::Type style = Base::Type::fromName("Gui::CADNavigationStyle");
Base::Vector3d upDir(0,1,0), viewDir(0,0,-1);
Gui::Document* doc = Application::Instance->activeDocument();
if (doc) {
View3DInventor* mdi = qobject_cast<View3DInventor*>(doc->getActiveView());
if (mdi) {
style = mdi->getViewer()->navigationStyle()->getTypeId();
View3DInventorViewer* viewer = mdi->getViewer();
SoCamera* camera = viewer->getCamera();
if (camera) {
SbVec3f up(0,1,0), dir(0,0,-1);
camera->orientation.getValue().multVec(dir, dir);
viewDir.Set(dir[0],dir[1],dir[2]);
camera->orientation.getValue().multVec(up, up);
upDir.Set(up[0],up[1],up[2]);
}
style = viewer->navigationStyle()->getTypeId();
}
}
align->setMinPoints(1);
align->startAlignment(style);
align->setViewingDirections(viewDir,upDir, viewDir,upDir);
Gui::Selection().clearSelection();
}
@ -1081,7 +1217,7 @@ StdCmdEdit::StdCmdEdit()
:Command("Std_Edit")
{
sGroup = QT_TR_NOOP("Edit");
sMenuText = QT_TR_NOOP("Toggle &Editmode");
sMenuText = QT_TR_NOOP("Toggle &Edit mode");
sToolTipText = QT_TR_NOOP("Toggles the selected object's edit mode");
sWhatsThis = "Std_Edit";
sStatusTip = QT_TR_NOOP("Enters or leaves the selected object's edit mode");
@ -1124,6 +1260,7 @@ void CreateDocCommands(void)
rcCmdMgr.addCommand(new StdCmdImport());
rcCmdMgr.addCommand(new StdCmdExport());
rcCmdMgr.addCommand(new StdCmdMergeProjects());
rcCmdMgr.addCommand(new StdCmdExportGraphviz());
rcCmdMgr.addCommand(new StdCmdSave());
rcCmdMgr.addCommand(new StdCmdSaveAs());
@ -1138,7 +1275,7 @@ void CreateDocCommands(void)
rcCmdMgr.addCommand(new StdCmdCut());
rcCmdMgr.addCommand(new StdCmdCopy());
rcCmdMgr.addCommand(new StdCmdPaste());
rcCmdMgr.addCommand(new StdCmdDDuplicateSelection());
rcCmdMgr.addCommand(new StdCmdDuplicateSelection());
rcCmdMgr.addCommand(new StdCmdSelectAll());
rcCmdMgr.addCommand(new StdCmdDelete());
rcCmdMgr.addCommand(new StdCmdRefresh());

View File

@ -193,13 +193,7 @@ Action * StdCmdAbout::createAction(void)
{
Action *pcAction;
QString exe;
std::map<std::string,std::string>& cfg = App::Application::Config();
std::map<std::string,std::string>::iterator it = cfg.find("Application");
if (it != cfg.end())
exe = QString::fromUtf8(it->second.c_str());
else
exe = QString::fromUtf8(App::GetApplication().getExecutableName());
QString exe = qApp->applicationName();
pcAction = new Action(this,getMainWindow());
pcAction->setText(QCoreApplication::translate(
this->className(), sMenuText, 0,
@ -235,13 +229,7 @@ void StdCmdAbout::activated(int iMsg)
void StdCmdAbout::languageChange()
{
if (_pcAction) {
QString exe;
std::map<std::string,std::string>& cfg = App::Application::Config();
std::map<std::string,std::string>::iterator it = cfg.find("Application");
if (it != cfg.end())
exe = QString::fromUtf8(it->second.c_str());
else
exe = QString::fromUtf8(App::GetApplication().getExecutableName());
QString exe = qApp->applicationName();
_pcAction->setText(QCoreApplication::translate(
this->className(), sMenuText, 0,
QCoreApplication::CodecForTr).arg(exe));
@ -588,7 +576,7 @@ void CreateStdCommands(void)
rcCmdMgr.addCommand(new StdCmdOnlineHelpWebsite());
rcCmdMgr.addCommand(new StdCmdFreeCADWebsite());
rcCmdMgr.addCommand(new StdCmdPythonWebsite());
rcCmdMgr.addCommand(new StdCmdMeasurementSimple());
//rcCmdMgr.addCommand(new StdCmdMeasurementSimple());
//rcCmdMgr.addCommand(new StdCmdDownloadOnlineHelp());
//rcCmdMgr.addCommand(new StdCmdDescription());
}

View File

@ -58,6 +58,8 @@
#include "SceneInspector.h"
#include "DemoMode.h"
#include "TextureMapping.h"
#include "Utilities.h"
#include "NavigationStyle.h"
#include <Base/Console.h>
#include <Base/Exception.h>
@ -450,6 +452,7 @@ void StdCmdFreezeViews::languageChange()
}
}
//===========================================================================
// Std_ToggleClipPlane
//===========================================================================
@ -520,8 +523,8 @@ Gui::Action * StdCmdDrawStyle::createAction(void)
pcAction->setDropDownMenu(true);
applyCommandData(pcAction);
QAction* a0 = pcAction->addAction(QString());
QAction* a1 = pcAction->addAction(QString());
pcAction->addAction(QString());
pcAction->addAction(QString());
_pcAction = pcAction;
languageChange();
return pcAction;
@ -1171,7 +1174,7 @@ StdViewDockUndockFullscreen::StdViewDockUndockFullscreen()
: Command("Std_ViewDockUndockFullscreen")
{
sGroup = QT_TR_NOOP("Standard-View");
sMenuText = QT_TR_NOOP("Display mode");
sMenuText = QT_TR_NOOP("Document window");
sToolTipText= QT_TR_NOOP("Display the active view either in fullscreen, in undocked or docked mode");
sWhatsThis = "Std_ViewDockUndockFullscreen";
sStatusTip = QT_TR_NOOP("Display the active view either in fullscreen, in undocked or docked mode");
@ -1816,13 +1819,7 @@ void StdViewZoomIn::activated(int iMsg)
View3DInventor* view = qobject_cast<View3DInventor*>(getMainWindow()->activeWindow());
if ( view ) {
View3DInventorViewer* viewer = view->getViewer();
// send an event to the GL widget to use the internal View3DInventorViewer::zoom() method
// do only one step to zoom in
SoMouseButtonEvent e;
e.setButton(SoMouseButtonEvent::BUTTON5);
e.setState(SoMouseButtonEvent::DOWN);
viewer->sendSoEvent(&e);
viewer->navigationStyle()->zoomIn();
}
}
@ -1856,12 +1853,7 @@ void StdViewZoomOut::activated(int iMsg)
View3DInventor* view = qobject_cast<View3DInventor*>(getMainWindow()->activeWindow());
if (view) {
View3DInventorViewer* viewer = view->getViewer();
// send an event to the GL widget to use the internal View3DInventorViewer::zoom() method
// do only one step to zoom out
SoMouseButtonEvent e;
e.setButton(SoMouseButtonEvent::BUTTON4);
e.setState(SoMouseButtonEvent::DOWN);
viewer->sendSoEvent(&e);
viewer->navigationStyle()->zoomOut();
}
}
@ -1900,6 +1892,83 @@ void StdViewBoxZoom::activated(int iMsg)
}
}
//===========================================================================
// Std_BoxSelection
//===========================================================================
DEF_3DV_CMD(StdBoxSelection);
StdBoxSelection::StdBoxSelection()
: Command("Std_BoxSelection")
{
sGroup = QT_TR_NOOP("Standard-View");
sMenuText = QT_TR_NOOP("Box selection");
sToolTipText = QT_TR_NOOP("Box selection");
sWhatsThis = "Std_ViewBoxZoom";
sStatusTip = QT_TR_NOOP("Box selection");
#if QT_VERSION >= 0x040200
sPixmap = "edit-select-box";
#endif
sAccel = "Shift+B";
eType = AlterSelection;
}
static void selectionCallback(void * ud, SoEventCallback * cb)
{
Gui::View3DInventorViewer* view = reinterpret_cast<Gui::View3DInventorViewer*>(cb->getUserData());
view->removeEventCallback(SoMouseButtonEvent::getClassTypeId(), selectionCallback, ud);
std::vector<SbVec2f> picked = view->getGLPolygon();
SoCamera* cam = view->getCamera();
SbViewVolume vv = cam->getViewVolume();
Gui::ViewVolumeProjection proj(vv);
Base::Polygon2D polygon;
if (picked.size() == 2) {
SbVec2f pt1 = picked[0];
SbVec2f pt2 = picked[1];
polygon.Add(Base::Vector2D(pt1[0], pt1[1]));
polygon.Add(Base::Vector2D(pt1[0], pt2[1]));
polygon.Add(Base::Vector2D(pt2[0], pt2[1]));
polygon.Add(Base::Vector2D(pt2[0], pt1[1]));
}
else {
for (std::vector<SbVec2f>::const_iterator it = picked.begin(); it != picked.end(); ++it)
polygon.Add(Base::Vector2D((*it)[0],(*it)[1]));
}
App::Document* doc = App::GetApplication().getActiveDocument();
if (doc) {
cb->setHandled();
std::vector<App::GeoFeature*> geom = doc->getObjectsOfType<App::GeoFeature>();
for (std::vector<App::GeoFeature*>::iterator it = geom.begin(); it != geom.end(); ++it) {
std::vector<App::Property*> props;
(*it)->getPropertyList(props);
for (std::vector<App::Property*>::iterator jt = props.begin(); jt != props.end(); ++jt) {
if ((*jt)->isDerivedFrom(App::PropertyGeometry::getClassTypeId())) {
App::PropertyGeometry* prop = static_cast<App::PropertyGeometry*>(*jt);
Base::BoundBox3d bbox = prop->getBoundingBox();
Base::Vector3d pt2d;
pt2d = proj(bbox.CalcCenter());
if (polygon.Contains(Base::Vector2D(pt2d.x, pt2d.y))) {
Gui::Selection().addSelection(doc->getName(), (*it)->getNameInDocument());
}
break;
}
}
}
}
}
void StdBoxSelection::activated(int iMsg)
{
View3DInventor* view = qobject_cast<View3DInventor*>(getMainWindow()->activeWindow());
if ( view ) {
View3DInventorViewer* viewer = view->getViewer();
if (!viewer->isSelecting()) {
viewer->startSelection(View3DInventorViewer::Rectangle);
viewer->addEventCallback(SoMouseButtonEvent::getClassTypeId(), selectionCallback);
}
}
}
//===========================================================================
// Std_TreeSelection
//===========================================================================
@ -2113,6 +2182,7 @@ void CreateViewStdCommands(void)
rcCmdMgr.addCommand(new StdViewZoomIn());
rcCmdMgr.addCommand(new StdViewZoomOut());
rcCmdMgr.addCommand(new StdViewBoxZoom());
rcCmdMgr.addCommand(new StdBoxSelection());
rcCmdMgr.addCommand(new StdCmdTreeSelection());
rcCmdMgr.addCommand(new StdCmdMeasureDistance());
rcCmdMgr.addCommand(new StdCmdSceneInspector());

View File

@ -34,7 +34,7 @@
<item>
<widget class="QLabel" name="textLabel1">
<property name="text">
<string>Display mode:</string>
<string>Document window:</string>
</property>
</widget>
</item>

View File

@ -175,12 +175,22 @@ void DlgGeneralImp::loadSettings()
ParameterGrp::handle hGrp = WindowParameter::getDefaultParameter()->GetGroup("General");
QString lang = QLocale::languageToString(QLocale::system().language());
QByteArray language = hGrp->GetASCII("Language", (const char*)lang.toAscii()).c_str();
Languages->addItem(Gui::Translator::tr("English"), QByteArray("English"));
int index = 1;
TStringList list = Translator::instance()->supportedLanguages();
for (TStringList::iterator it = list.begin(); it != list.end(); ++it, index++) {
QByteArray lang = it->c_str();
Languages->addItem(Gui::Translator::tr(lang.constData()), lang);
Languages->addItem(QString::fromAscii("English"), QByteArray("English"));
TStringMap list = Translator::instance()->supportedLocales();
for (TStringMap::iterator it = list.begin(); it != list.end(); ++it, index++) {
QLocale locale(QString::fromAscii(it->second.c_str()));
QByteArray lang = it->first.c_str();
QString langname = QString::fromAscii(lang.constData());
#if QT_VERSION >= 0x040800
QString native = locale.nativeLanguageName();
if (!native.isEmpty()) {
if (native[0].isLetter())
native[0] = native[0].toUpper();
langname = native;
}
#endif
Languages->addItem(langname, lang);
if (language == lang) {
Languages->setCurrentIndex(index);
}

View File

@ -25,6 +25,7 @@
#ifndef _PreComp_
# include <cstring>
# include <algorithm>
# include <QDebug>
# include <QMessageBox>
#endif
@ -89,6 +90,15 @@ void DlgPreferencesImp::setupPages()
}
fileName = std::string("preferences-") + fileName;
QPixmap icon = Gui::BitmapFactory().pixmapFromSvg(fileName.c_str(), QSize(96,96));
if (icon.isNull()) {
icon = Gui::BitmapFactory().pixmap(fileName.c_str());
if (icon.isNull()) {
qWarning() << "No group icon found for " << fileName.c_str();
}
else if (icon.size() != QSize(96,96)) {
qWarning() << "Group icon for " << fileName.c_str() << " is not of size 96x96";
}
}
item->setIcon(icon);
item->setTextAlignment(Qt::AlignHCenter);
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);

View File

@ -1,45 +1,62 @@
<ui version="4.0" >
<author></author>
<comment></comment>
<exportmacro></exportmacro>
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Gui::Dialog::DlgSettingsMacro</class>
<widget class="QWidget" name="Gui::Dialog::DlgSettingsMacro" >
<property name="geometry" >
<widget class="QWidget" name="Gui::Dialog::DlgSettingsMacro">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>384</width>
<height>388</height>
<width>391</width>
<height>407</height>
</rect>
</property>
<property name="windowTitle" >
<property name="windowTitle">
<string>Macro</string>
</property>
<layout class="QGridLayout" >
<property name="margin" >
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item row="0" column="0" >
<widget class="QGroupBox" name="GroupBox6" >
<property name="title" >
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>General macro settings</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="Gui::PrefCheckBox" name="PrefCheckBox_LocalEnv">
<property name="text">
<string>Run macros in local environment</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="prefEntry" stdset="0">
<cstring>LocalEnvironment</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Macro</cstring>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="GroupBox6">
<property name="title">
<string>Macro recording settings</string>
</property>
<layout class="QGridLayout" >
<property name="margin" >
<layout class="QGridLayout">
<property name="margin">
<number>9</number>
</property>
<property name="spacing" >
<property name="spacing">
<number>6</number>
</property>
<item row="3" column="0" >
<item row="3" column="0">
<spacer>
<property name="orientation" >
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" >
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
@ -47,56 +64,56 @@
</property>
</spacer>
</item>
<item row="2" column="0" >
<widget class="QGroupBox" name="groupBox4" >
<property name="title" >
<item row="2" column="0">
<widget class="QGroupBox" name="groupBox4">
<property name="title">
<string>Logging Commands</string>
</property>
<layout class="QVBoxLayout" >
<property name="margin" >
<number>11</number>
</property>
<property name="spacing" >
<layout class="QVBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="margin">
<number>11</number>
</property>
<item>
<widget class="Gui::PrefCheckBox" name="PConsoleCheckBox" >
<property name="text" >
<widget class="Gui::PrefCheckBox" name="PConsoleCheckBox">
<property name="text">
<string>Show script commands in python console</string>
</property>
<property name="checked" >
<bool>true</bool>
</property>
<property name="prefEntry" stdset="0" >
<property name="checked">
<bool>true</bool>
</property>
<property name="prefEntry" stdset="0">
<cstring>ScriptToPyConsole</cstring>
</property>
<property name="prefPath" stdset="0" >
<property name="prefPath" stdset="0">
<cstring>Macro</cstring>
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefCheckBox" name="FileLogCheckBox" >
<property name="text" >
<widget class="Gui::PrefCheckBox" name="FileLogCheckBox">
<property name="text">
<string>Log all commands issued by menus to file:</string>
</property>
<property name="prefEntry" stdset="0" >
<property name="prefEntry" stdset="0">
<cstring>ScriptToFile</cstring>
</property>
<property name="prefPath" stdset="0" >
<property name="prefPath" stdset="0">
<cstring>Macro</cstring>
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefFileChooser" name="MacroPath_2" >
<property name="fileName" >
<widget class="Gui::PrefFileChooser" name="MacroPath_2">
<property name="fileName">
<string>FullScript.FCScript</string>
</property>
<property name="prefEntry" stdset="0" >
<property name="prefEntry" stdset="0">
<cstring>ScriptFile</cstring>
</property>
<property name="prefPath" stdset="0" >
<property name="prefPath" stdset="0">
<cstring>Macro</cstring>
</property>
</widget>
@ -104,46 +121,46 @@
</layout>
</widget>
</item>
<item row="1" column="0" >
<widget class="QGroupBox" name="GroupBox7" >
<property name="title" >
<item row="1" column="0">
<widget class="QGroupBox" name="GroupBox7">
<property name="title">
<string>Gui commands</string>
</property>
<layout class="QGridLayout" >
<property name="margin" >
<layout class="QGridLayout">
<property name="margin">
<number>11</number>
</property>
<property name="spacing" >
<property name="spacing">
<number>6</number>
</property>
<item row="0" column="0" >
<widget class="Gui::PrefCheckBox" name="PrefCheckBox_RecordGui" >
<property name="text" >
<item row="0" column="0">
<widget class="Gui::PrefCheckBox" name="PrefCheckBox_RecordGui">
<property name="text">
<string>Recording GUI commands</string>
</property>
<property name="checked" >
<property name="checked">
<bool>true</bool>
</property>
<property name="prefEntry" stdset="0" >
<property name="prefEntry" stdset="0">
<cstring>RecordGui</cstring>
</property>
<property name="prefPath" stdset="0" >
<property name="prefPath" stdset="0">
<cstring>Macro</cstring>
</property>
</widget>
</item>
<item row="1" column="0" >
<widget class="Gui::PrefCheckBox" name="PrefCheckBox_GuiAsComment" >
<property name="text" >
<item row="1" column="0">
<widget class="Gui::PrefCheckBox" name="PrefCheckBox_GuiAsComment">
<property name="text">
<string>Record as comment</string>
</property>
<property name="checked" >
<property name="checked">
<bool>true</bool>
</property>
<property name="prefEntry" stdset="0" >
<property name="prefEntry" stdset="0">
<cstring>GuiAsComment</cstring>
</property>
<property name="prefPath" stdset="0" >
<property name="prefPath" stdset="0">
<cstring>Macro</cstring>
</property>
</widget>
@ -151,27 +168,27 @@
</layout>
</widget>
</item>
<item row="0" column="0" >
<widget class="QGroupBox" name="GroupBox8" >
<property name="title" >
<item row="0" column="0">
<widget class="QGroupBox" name="GroupBox8">
<property name="title">
<string>Macro path</string>
</property>
<layout class="QGridLayout" >
<property name="margin" >
<layout class="QGridLayout">
<property name="margin">
<number>11</number>
</property>
<property name="spacing" >
<property name="spacing">
<number>6</number>
</property>
<item row="0" column="0" >
<widget class="Gui::PrefFileChooser" name="MacroPath" >
<property name="mode" >
<item row="0" column="0">
<widget class="Gui::PrefFileChooser" name="MacroPath">
<property name="mode">
<enum>Gui::FileChooser::Directory</enum>
</property>
<property name="prefEntry" stdset="0" >
<property name="prefEntry" stdset="0">
<cstring>MacroPath</cstring>
</property>
<property name="prefPath" stdset="0" >
<property name="prefPath" stdset="0">
<cstring>Macro</cstring>
</property>
</widget>
@ -184,21 +201,22 @@
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11" />
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>Gui::PrefCheckBox</class>
<extends>QCheckBox</extends>
<header>Gui/PrefWidgets.h</header>
<container>0</container>
<pixmap></pixmap>
<class>Gui::FileChooser</class>
<extends>QWidget</extends>
<header>Gui/FileDialog.h</header>
</customwidget>
<customwidget>
<class>Gui::PrefFileChooser</class>
<extends>Gui::FileChooser</extends>
<header>Gui/PrefWidgets.h</header>
<container>0</container>
<pixmap></pixmap>
</customwidget>
<customwidget>
<class>Gui::PrefCheckBox</class>
<extends>QCheckBox</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
</customwidgets>
<resources/>
@ -209,11 +227,11 @@
<receiver>PrefCheckBox_GuiAsComment</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<hint type="sourcelabel">
<x>20</x>
<y>20</y>
</hint>
<hint type="destinationlabel" >
<hint type="destinationlabel">
<x>20</x>
<y>20</y>
</hint>

View File

@ -54,6 +54,7 @@ DlgSettingsMacroImp::~DlgSettingsMacroImp()
void DlgSettingsMacroImp::saveSettings()
{
PrefCheckBox_LocalEnv->onSave();
MacroPath->onSave();
PrefCheckBox_RecordGui->onSave();
PrefCheckBox_GuiAsComment->onSave();
@ -64,6 +65,7 @@ void DlgSettingsMacroImp::saveSettings()
void DlgSettingsMacroImp::loadSettings()
{
PrefCheckBox_LocalEnv->onRestore();
MacroPath->onRestore();
PrefCheckBox_RecordGui->onRestore();
PrefCheckBox_GuiAsComment->onRestore();

View File

@ -66,10 +66,14 @@ void DlgSettingsViewColor::saveSettings()
checkBoxSelection->onSave();
HighlightColor->onSave();
SelectionColor->onSave();
CursorTextColor->onSave();
EditedEdgeColor->onSave();
EditedVertexColor->onSave();
ConstructionColor->onSave();
FullyConstrainedColor->onSave();
DefaultShapeColor->onSave();
DefaultShapeLineColor->onSave();
DefaultShapeLineWidth->onSave();
}
void DlgSettingsViewColor::loadSettings()
@ -85,10 +89,14 @@ void DlgSettingsViewColor::loadSettings()
checkBoxSelection->onRestore();
HighlightColor->onRestore();
SelectionColor->onRestore();
CursorTextColor->onRestore();
EditedEdgeColor->onRestore();
EditedVertexColor->onRestore();
ConstructionColor->onRestore();
FullyConstrainedColor->onRestore();
DefaultShapeColor->onRestore();
DefaultShapeLineColor->onRestore();
DefaultShapeLineWidth->onRestore();
}
/**

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>601</width>
<height>407</height>
<height>445</height>
</rect>
</property>
<property name="windowTitle">
@ -361,7 +361,20 @@
<string>Default colors</string>
</property>
<layout class="QGridLayout" name="colgridLayout">
<item row="0" column="0">
<item row="2" column="1">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0">
<layout class="QGridLayout" name="_2">
<property name="margin">
<number>0</number>
@ -369,7 +382,7 @@
<property name="spacing">
<number>6</number>
</property>
<item row="0" column="0">
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="minimumSize">
<size>
@ -382,31 +395,31 @@
</property>
</widget>
</item>
<item row="1" column="0">
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Edited vertex color</string>
</property>
</widget>
</item>
<item row="2" column="0">
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Construction geometry</string>
</property>
</widget>
</item>
<item row="3" column="0">
<item row="4" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Fully constrained geometry</string>
</property>
</widget>
</item>
<item row="2" column="1">
<item row="3" column="1">
<widget class="Gui::PrefColorButton" name="ConstructionColor">
<property name="toolTip">
<string>The color of construction geometry in editmode</string>
<string>The color of construction geometry in edit mode</string>
</property>
<property name="color">
<color>
@ -423,10 +436,10 @@
</property>
</widget>
</item>
<item row="3" column="1">
<item row="4" column="1">
<widget class="Gui::PrefColorButton" name="FullyConstrainedColor">
<property name="toolTip">
<string>The color of fully constrained geometry in editmode</string>
<string>The color of fully constrained geometry in edit mode</string>
</property>
<property name="color">
<color>
@ -443,7 +456,7 @@
</property>
</widget>
</item>
<item row="1" column="1">
<item row="2" column="1">
<widget class="Gui::PrefColorButton" name="EditedVertexColor">
<property name="toolTip">
<string>The color of vertices being edited</string>
@ -463,7 +476,7 @@
</property>
</widget>
</item>
<item row="0" column="1">
<item row="1" column="1">
<widget class="Gui::PrefColorButton" name="EditedEdgeColor">
<property name="toolTip">
<string>The color of edges being edited</string>
@ -483,20 +496,124 @@
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Cursor text color</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="Gui::PrefColorButton" name="CursorTextColor">
<property name="color">
<color>
<red>0</red>
<green>0</green>
<blue>255</blue>
</color>
</property>
<property name="prefEntry" stdset="0">
<cstring>CursorTextColor</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="1">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
<item row="0" column="0">
<layout class="QGridLayout" name="_1">
<item row="0" column="0">
<widget class="QLabel" name="label_6">
<property name="minimumSize">
<size>
<width>240</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Default shape color</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="Gui::PrefColorButton" name="DefaultShapeColor">
<property name="toolTip">
<string>The default color for new shapes</string>
</property>
<property name="color">
<color>
<red>204</red>
<green>204</green>
<blue>204</blue>
</color>
</property>
<property name="prefEntry" stdset="0">
<cstring>DefaultShapeColor</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<layout class="QGridLayout" name="_5">
<item row="0" column="0">
<widget class="QLabel" name="label_7">
<property name="minimumSize">
<size>
<width>182</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Default line width and color</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="Gui::PrefColorButton" name="DefaultShapeLineColor">
<property name="toolTip">
<string>The default line color for new shapes</string>
</property>
<property name="color">
<color>
<red>25</red>
<green>25</green>
<blue>25</blue>
</color>
</property>
<property name="prefEntry" stdset="0">
<cstring>DefaultShapeLineColor</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="Gui::PrefSpinBox" name="DefaultShapeLineWidth">
<property name="toolTip">
<string>The default line thickness for new shapes</string>
</property>
<property name="suffix">
<string>px</string>
</property>
<property name="value">
<number>2</number>
</property>
<property name="prefEntry" stdset="0">
<cstring>DefaultShapeLineWidth</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
@ -509,6 +626,11 @@
<extends>QPushButton</extends>
<header>Gui/Widgets.h</header>
</customwidget>
<customwidget>
<class>Gui::PrefSpinBox</class>
<extends>QSpinBox</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
<customwidget>
<class>Gui::PrefColorButton</class>
<extends>Gui::ColorButton</extends>
@ -530,6 +652,11 @@
<tabstop>checkBoxSelection</tabstop>
<tabstop>HighlightColor</tabstop>
<tabstop>SelectionColor</tabstop>
<tabstop>CursorTextColor</tabstop>
<tabstop>EditedEdgeColor</tabstop>
<tabstop>EditedVertexColor</tabstop>
<tabstop>ConstructionColor</tabstop>
<tabstop>FullyConstrainedColor</tabstop>
<tabstop>radioButtonSimple</tabstop>
<tabstop>radioButtonGradient</tabstop>
<tabstop>checkMidColor</tabstop>

View File

@ -187,6 +187,9 @@ bool Document::setEdit(Gui::ViewProvider* p, int ModNum)
View3DInventor *activeView = dynamic_cast<View3DInventor *>(getActiveView());
if (activeView && activeView->getViewer()->setEditingViewProvider(p,ModNum)) {
d->_pcInEdit = p;
Gui::TaskView::TaskDialog* dlg = Gui::Control().activeDialog();
if (dlg)
dlg->setDocumentName(this->getDocument()->getName());
if (d->_pcInEdit->isDerivedFrom(ViewProviderDocumentObject::getClassTypeId()))
signalInEdit(*(static_cast<ViewProviderDocumentObject*>(d->_pcInEdit)));
}
@ -405,6 +408,9 @@ void Document::slotDeletedObject(const App::DocumentObject& Obj)
// cycling to all views of the document
ViewProvider* viewProvider = getViewProvider(&Obj);
#if 0 // With this we can show child objects again if this method was called by undo
viewProvider->onDelete(std::vector<std::string>());
#endif
if (viewProvider && viewProvider->getTypeId().isDerivedFrom
(ViewProviderDocumentObject::getClassTypeId())) {
// go through the views
@ -504,7 +510,7 @@ bool Document::saveAs(void)
{
getMainWindow()->statusBar()->showMessage(QObject::tr("Save document under new filename..."));
QString exe = QString::fromUtf8(App::GetApplication().getExecutableName());
QString exe = qApp->applicationName();
QString fn = QFileDialog::getSaveFileName(getMainWindow(), QObject::tr("Save %1 Document").arg(exe),
FileDialog::getWorkingDirectory(), QObject::tr("%1 document (*.FCStd)").arg(exe));
if (!fn.isEmpty()) {
@ -642,8 +648,13 @@ void Document::RestoreDocFile(Base::Reader &reader)
std::string sMsg = "SetCamera ";
sMsg += ppReturn;
if (strcmp(ppReturn, "") != 0) { // non-empty attribute
if (d->_pcAppWnd->sendHasMsgToActiveView("SetCamera"))
d->_pcAppWnd->sendMsgToActiveView(sMsg.c_str());
try {
if (d->_pcAppWnd->sendHasMsgToActiveView("SetCamera"))
d->_pcAppWnd->sendMsgToActiveView(sMsg.c_str());
}
catch (const Base::Exception& e) {
Base::Console().Error("%s\n", e.what());
}
}
}
@ -743,7 +754,7 @@ void Document::exportObjects(const std::vector<App::DocumentObject*>& obj, Base:
<< views.size() <<"\">" << std::endl;
bool xml = writer.isForceXML();
writer.setForceXML(true);
//writer.setForceXML(true);
writer.incInd(); // indention for 'ViewProvider name'
std::map<const App::DocumentObject*,ViewProvider*>::const_iterator jt;
for (jt = views.begin(); jt != views.end(); ++jt) {
@ -826,6 +837,7 @@ void Document::createView(const char* sType)
.arg(QString::fromUtf8(name)).arg(d->_iWinCount++);
view3D->setWindowTitle(title);
view3D->setWindowModified(this->isModified());
view3D->setWindowIcon(QApplication::windowIcon());
view3D->resize(400, 300);
getMainWindow()->addWindow(view3D);
@ -921,13 +933,16 @@ bool Document::canClose ()
return false;
}
else if (!Gui::Control().isAllowedAlterDocument()) {
QMessageBox::warning(getActiveView(),
QObject::tr("Document not closable"),
QObject::tr("The document is in editing mode and thus cannot be closed for the moment.\n"
"You either have to finish or cancel the editing in the task panel."));
Gui::TaskView::TaskDialog* dlg = Gui::Control().activeDialog();
if (dlg) Gui::Control().showDialog(dlg);
return false;
std::string name = Gui::Control().activeDialog()->getDocumentName();
if (name == this->getDocument()->getName()) {
QMessageBox::warning(getActiveView(),
QObject::tr("Document not closable"),
QObject::tr("The document is in editing mode and thus cannot be closed for the moment.\n"
"You either have to finish or cancel the editing in the task panel."));
Gui::TaskView::TaskDialog* dlg = Gui::Control().activeDialog();
if (dlg) Gui::Control().showDialog(dlg);
return false;
}
}
if (!isModified())
@ -967,6 +982,19 @@ std::list<MDIView*> Document::getMDIViews() const
return views;
}
std::list<MDIView*> Document::getMDIViewsOfType(const Base::Type& typeId) const
{
std::list<MDIView*> views;
for (std::list<BaseView*>::const_iterator it = d->baseViews.begin();
it != d->baseViews.end(); ++it) {
MDIView* view = dynamic_cast<MDIView*>(*it);
if (view && view->isDerivedFrom(typeId))
views.push_back(view);
}
return views;
}
/// send messages to the active view
bool Document::sendMsgToViews(const char* pMsg)
{
@ -1006,9 +1034,9 @@ MDIView* Document::getActiveView(void) const
}
}
// the active view is not part of this document, just use the first view
// the active view is not part of this document, just use the last view
if (!ok && !mdis.empty())
active = mdis.front();
active = mdis.back();
return active;
}

View File

@ -140,6 +140,8 @@ public:
void onRelabel(void);
/// returns a list of all attached MDI views
std::list<MDIView*> getMDIViews() const;
/// returns a list of all MDI views of a certain type
std::list<MDIView*> getMDIViewsOfType(const Base::Type& typeId) const;
//@}
/** @name View provider handling */

View File

@ -68,6 +68,21 @@
<UserDocu>deprecated -- use ActiveView</UserDocu>
</Documentation>
</Methode>
<Methode Name="mdiViewsOfType" Const="true">
<Documentation>
<UserDocu>Return a list if mdi views of a given type</UserDocu>
</Documentation>
</Methode>
<Methode Name="sendMsgToViews">
<Documentation>
<UserDocu>Send a message to all views of the document</UserDocu>
</Documentation>
</Methode>
<Methode Name="mergeProject">
<Documentation>
<UserDocu>Merges this document with another project file</UserDocu>
</Documentation>
</Methode>
<Attribute Name="ActiveObject" ReadOnly="false">
<Documentation>
<UserDocu>The active object of the document</UserDocu>

View File

@ -32,6 +32,7 @@
#include <App/Document.h>
#include "Document.h"
#include "MergeDocuments.h"
#include "ViewProviderExtern.h"
// inclusion of the generated files (generated out of DocumentPy.xml)
@ -201,6 +202,55 @@ PyObject* DocumentPy::activeView(PyObject *args)
} PY_CATCH;
}
PyObject* DocumentPy::mdiViewsOfType(PyObject *args)
{
char* sType;
if (!PyArg_ParseTuple(args, "s", &sType)) // convert args: Python->C
return NULL; // NULL triggers exception
Base::Type type = Base::Type::fromName(sType);
if (type == Base::Type::badType()) {
PyErr_Format(PyExc_Exception, "'%s' is not a valid type", sType);
return NULL;
}
PY_TRY {
std::list<Gui::MDIView*> views = getDocumentPtr()->getMDIViewsOfType(type);
Py::List list;
for (std::list<Gui::MDIView*>::iterator it = views.begin(); it != views.end(); ++it)
list.append(Py::asObject((*it)->getPyObject()));
return Py::new_reference_to(list);
} PY_CATCH;
}
PyObject* DocumentPy::sendMsgToViews(PyObject *args)
{
char* msg;
if (!PyArg_ParseTuple(args, "s", &msg)) // convert args: Python->C
return NULL; // NULL triggers exception
PY_TRY {
getDocumentPtr()->sendMsgToViews(msg);
Py_Return;
} PY_CATCH;
}
PyObject* DocumentPy::mergeProject(PyObject *args)
{
char* filename;
if (!PyArg_ParseTuple(args, "s", &filename)) // convert args: Python->C
return NULL; // NULL triggers exception
PY_TRY {
Base::FileInfo fi(filename);
Base::ifstream str(fi, std::ios::in | std::ios::binary);
App::Document* doc = getDocumentPtr()->getDocument();
MergeDocuments md(doc);
md.importObjects(str);
Py_Return;
} PY_CATCH;
}
Py::Object DocumentPy::getActiveObject(void) const
{
App::DocumentObject *object = getDocumentPtr()->getDocument()->getActiveObject();

View File

@ -74,6 +74,7 @@ public:
void print ();
void printPdf();
void printPreview();
void print(QPrinter*);
//@}
QStringList undoActions() const;
@ -88,7 +89,6 @@ private Q_SLOTS:
void contentsChange(int position, int charsRemoved, int charsAdded);
void undoAvailable(bool);
void redoAvailable(bool);
void print(QPrinter*);
private:
void setCurrentFileName(const QString &fileName);

View File

@ -15,8 +15,8 @@
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* write to the Free Software Foundation, Inc., 51 Franklin Street, *
* Fifth Floor, Boston, MA 02110-1301, USA *
* *
***************************************************************************/

View File

@ -169,6 +169,7 @@ FreeCAD.addExportType("Inventor V2.1 (*.iv)","FreeCADGui")
FreeCAD.addExportType("VRML V2.0 (*.wrl *.vrml *.wrz *.wrl.gz)","FreeCADGui")
#FreeCAD.addExportType("IDTF (for 3D PDF) (*.idtf)","FreeCADGui")
FreeCAD.addExportType("3D View (*.svg)","FreeCADGui")
FreeCAD.addExportType("Portable Document Format (*.pdf)","FreeCADGui")
del(InitApplications)
del(NoneWorkbench)

View File

@ -40,11 +40,10 @@
#endif
#endif
#ifdef Q_WS_WIN
#include <windows.h>
#ifdef _USE_3DCONNEXION_SDK
Gui::GUIApplicationNativeEventAware* Gui::GUIApplicationNativeEventAware::gMouseInput = 0;
#endif
Gui::GUIApplicationNativeEventAware::GUIApplicationNativeEventAware(int &argc, char *argv[]) :
QApplication (argc, argv), spaceballPresent(false)
{
@ -59,11 +58,18 @@ Gui::GUIApplicationNativeEventAware::~GUIApplicationNativeEventAware()
else
Base::Console().Log("Disconnected from spacenav daemon\n");
#endif
#ifdef _USE_3DCONNEXION_SDK
if (gMouseInput == this) {
gMouseInput = 0;
}
#endif
}
void Gui::GUIApplicationNativeEventAware::initSpaceball(QMainWindow *window)
{
mainWindow = window;
#ifdef SPNAV_FOUND
if (spnav_x11_open(QX11Info::display(), window->winId()) == -1)
Base::Console().Log("Couldn't connect to spacenav daemon\n");
@ -74,6 +80,19 @@ void Gui::GUIApplicationNativeEventAware::initSpaceball(QMainWindow *window)
}
#endif
#ifdef _USE_3DCONNEXION_SDK
spaceballPresent = Is3dmouseAttached();
if (spaceballPresent) {
fLast3dmouseInputTime = 0;
if (InitializeRawInput(mainWindow->winId())){
gMouseInput = this;
qApp->setEventFilter(Gui::GUIApplicationNativeEventAware::RawInputEventFilter);
}
}
#endif // _USE_3DCONNEXION_SDK
Spaceball::MotionEvent::MotionEventType = QEvent::registerEventType();
Spaceball::ButtonEvent::ButtonEventType = QEvent::registerEventType();
}
@ -146,15 +165,8 @@ bool Gui::GUIApplicationNativeEventAware::x11EventFilter(XEvent *event)
return true;
#else
return false;
#endif
#endif // SPNAV_FOUND
}
#endif
#ifdef Q_WS_WIN
bool Gui::GUIApplicationNativeEventAware::winEventFilter(MSG *msg, long *result)
{
return false;
}
#endif
#endif // Q_WS_X11
#include "moc_GuiApplicationNativeEventAware.cpp"

View File

@ -29,6 +29,19 @@
class QMainWindow;
#ifdef _USE_3DCONNEXION_SDK
#include "3Dconnexion/MouseParameters.h"
#include <vector>
#include <map>
// #define _WIN32_WINNT 0x0501 //target at least windows XP
#include <Windows.h>
#endif // _USE_3DCONNEXION_SDK
namespace Gui
{
class GUIApplicationNativeEventAware : public QApplication
@ -38,18 +51,65 @@ namespace Gui
GUIApplicationNativeEventAware(int &argc, char *argv[]);
~GUIApplicationNativeEventAware();
void initSpaceball(QMainWindow *window);
bool isSpaceballPresent() const {return spaceballPresent;}
bool processSpaceballEvent(QObject *object, QEvent *event);
#ifdef Q_WS_X11
bool x11EventFilter(XEvent *event);
#endif
#ifdef Q_WS_WIN
bool winEventFilter(MSG *msg, long *result);
#endif
bool isSpaceballPresent(){return spaceballPresent;}
private:
bool spaceballPresent;
QMainWindow *mainWindow;
// For X11
#ifdef Q_WS_X11
public:
bool x11EventFilter(XEvent *event);
#endif // Q_WS_X11
// For Windows
#ifdef _USE_3DCONNEXION_SDK
public:
static bool Is3dmouseAttached();
I3dMouseParam& MouseParams();
const I3dMouseParam& MouseParams() const;
virtual void Move3d(HANDLE device, std::vector<float>& motionData);
virtual void On3dmouseKeyDown(HANDLE device, int virtualKeyCode);
virtual void On3dmouseKeyUp(HANDLE device, int virtualKeyCode);
private:
bool InitializeRawInput(HWND hwndTarget);
static bool RawInputEventFilter(void* msg, long* result);
void OnRawInput(UINT nInputCode, HRAWINPUT hRawInput);
UINT GetRawInputBuffer(PRAWINPUT pData, PUINT pcbSize, UINT cbSizeHeader);
bool TranslateRawInputData(UINT nInputCode, PRAWINPUT pRawInput);
void On3dmouseInput();
class TInputData
{
public:
TInputData() : fAxes(6) {}
bool IsZero() {
return (0.==fAxes[0] && 0.==fAxes[1] && 0.==fAxes[2] &&
0.==fAxes[3] && 0.==fAxes[4] && 0.==fAxes[5]);
}
int fTimeToLive; // For telling if the device was unplugged while sending data
bool fIsDirty;
std::vector<float> fAxes;
};
HWND fWindow;
// Data cache to handle multiple rawinput devices
std::map< HANDLE, TInputData> fDevice2Data;
std::map< HANDLE, unsigned long> fDevice2Keystate;
// 3dmouse parameters
MouseParameters f3dMouseParams; // Rotate, Pan Zoom etc.
// use to calculate distance traveled since last event
DWORD fLast3dmouseInputTime;
static Gui::GUIApplicationNativeEventAware* gMouseInput;
#endif // _USE_3DCONNEXION_SDK
};
}
#endif // GUIAPPLICATIONNATIVEEVENTAWARE_H

View File

@ -56,8 +56,10 @@ EXTRA_DIST = \
edit-copy.svg \
edit-cut.svg \
edit-delete.svg \
edit-edit.svg \
edit-paste.svg \
edit-select-all.svg \
edit-select-box.svg \
edit-redo.svg \
edit-undo.svg \
preferences-system.svg \

497
src/Gui/Icons/edit-select-all.svg Normal file → Executable file
View File

@ -1,347 +1,264 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://web.resource.org/cc/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="48px"
height="48px"
id="svg4198"
width="64px"
height="64px"
id="svg2980"
sodipodi:version="0.32"
inkscape:version="0.43+devel"
sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/actions"
sodipodi:docname="edit-select-all.svg">
inkscape:version="0.48.3.1 r9886"
sodipodi:docname="edit-select-all.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.1">
<defs
id="defs4200">
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5060"
id="radialGradient5031"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
cx="605.71429"
cy="486.64789"
fx="605.71429"
fy="486.64789"
r="117.14286" />
id="defs2982">
<linearGradient
inkscape:collect="always"
id="linearGradient5060">
id="linearGradient4590">
<stop
style="stop-color:black;stop-opacity:1;"
style="stop-color:#0073ff;stop-opacity:1;"
offset="0"
id="stop5062" />
id="stop4592" />
<stop
style="stop-color:black;stop-opacity:0;"
style="stop-color:#5cd4f5;stop-opacity:1;"
offset="1"
id="stop5064" />
id="stop4594" />
</linearGradient>
<linearGradient
id="linearGradient3811">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop3813" />
<stop
style="stop-color:#bfbfbf;stop-opacity:1;"
offset="1"
id="stop3815" />
</linearGradient>
<linearGradient
id="linearGradient3864">
<stop
id="stop3866"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3868"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5060"
id="radialGradient5029"
xlink:href="#linearGradient3864"
id="radialGradient3850"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
cx="605.71429"
cy="486.64789"
fx="605.71429"
fy="486.64789"
r="117.14286" />
<linearGradient
id="linearGradient5048">
<stop
style="stop-color:black;stop-opacity:0;"
offset="0"
id="stop5050" />
<stop
id="stop5056"
offset="0.5"
style="stop-color:black;stop-opacity:1;" />
<stop
style="stop-color:black;stop-opacity:0;"
offset="1"
id="stop5052" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5048"
id="linearGradient5027"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
x1="302.85715"
y1="366.64789"
x2="302.85715"
y2="609.50507" />
<linearGradient
inkscape:collect="always"
id="linearGradient3558">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop3560" />
<stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3562" />
</linearGradient>
gradientTransform="matrix(0.6028459,1.0471639,-1.9794021,1.1395295,127.9588,-74.456907)"
cx="51.328892"
cy="31.074146"
fx="51.328892"
fy="31.074146"
r="19.571428" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 32 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="64 : 32 : 1"
inkscape:persp3d-origin="32 : 21.333333 : 1"
id="perspective2988" />
<inkscape:perspective
id="perspective2872"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3558"
id="radialGradient3564"
cx="22.571428"
cy="30.857143"
fx="22.571428"
fy="30.857143"
r="15.571428"
gradientTransform="matrix(1.000000,0.000000,0.000000,0.651376,4.638648e-15,10.75754)"
gradientUnits="userSpaceOnUse" />
xlink:href="#linearGradient3864"
id="radialGradient2890"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.58019421,1.0078171,-1.9050269,1.0967121,-8.5316607,-197.0902)"
cx="51.328892"
cy="31.074146"
fx="51.328892"
fy="31.074146"
r="19.571428" />
<inkscape:perspective
id="perspective2902"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective2902-9"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<linearGradient
id="linearGradient15218">
inkscape:collect="always"
xlink:href="#linearGradient3811"
id="linearGradient3817"
x1="36.870125"
y1="30.196993"
x2="3.3695574"
y2="39.373768"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.27764843,-1.1190823,1.1190823,0.27764843,-10.424279,50.285999)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3811-9"
id="linearGradient3817-3"
x1="6.0684204"
y1="37.207146"
x2="39.480068"
y2="37.207146"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.27764843,-1.1190823,1.1190823,0.27764843,-9.674279,55.785999)" />
<linearGradient
id="linearGradient3811-9">
<stop
style="stop-color:#f8f8f7;stop-opacity:1;"
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop15220" />
id="stop3813-8" />
<stop
id="stop2269"
offset="0.59928656"
style="stop-color:#e8e8e8;stop-opacity:1;" />
<stop
style="stop-color:#e2e2de;stop-opacity:1;"
style="stop-color:#bfbfbf;stop-opacity:1;"
offset="1"
id="stop15222" />
id="stop3815-7" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient15218"
id="linearGradient2240"
xlink:href="#linearGradient4590"
id="linearGradient4596"
x1="34.54903"
y1="1.8738226"
x2="28.02536"
y2="43.593124"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.342704,0,0,1.235378,-8.219611,-7.549457)"
x1="20.794008"
y1="18.378813"
x2="35.596001"
y2="39.60046" />
gradientTransform="translate(0,8)" />
<linearGradient
id="linearGradient4590-3">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop4592-5" />
<stop
style="stop-color:#5cd4f5;stop-opacity:1;"
offset="1"
id="stop4594-6" />
</linearGradient>
<linearGradient
y2="43.593124"
x2="28.02536"
y1="1.8738226"
x1="34.54903"
gradientTransform="translate(-1.4917871,-0.74277437)"
gradientUnits="userSpaceOnUse"
id="linearGradient4621"
xlink:href="#linearGradient4590-3"
inkscape:collect="always" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4590-8"
id="linearGradient4596-5"
x1="34.54903"
y1="1.8738226"
x2="28.02536"
y2="43.593124"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(0,8)" />
<linearGradient
id="linearGradient4590-8">
<stop
style="stop-color:#0073ff;stop-opacity:1;"
offset="0"
id="stop4592-3" />
<stop
style="stop-color:#5cd4f5;stop-opacity:1;"
offset="1"
id="stop4594-1" />
</linearGradient>
<linearGradient
y2="43.593124"
x2="28.02536"
y1="1.8738226"
x1="34.54903"
gradientTransform="translate(-0.9673922,-0.2183795)"
gradientUnits="userSpaceOnUse"
id="linearGradient3795"
xlink:href="#linearGradient4590-8"
inkscape:collect="always" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#bebebe"
borderopacity="1.0000000"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="90.3276"
inkscape:cy="8.4634153"
inkscape:zoom="2"
inkscape:cx="17.364725"
inkscape:cy="3.8561862"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:grid-bbox="true"
showgrid="true"
inkscape:document-units="px"
inkscape:grid-bbox="true"
inkscape:window-width="1280"
inkscape:window-height="949"
inkscape:window-x="26"
inkscape:window-y="69"
inkscape:showpageshadow="false"
fill="#729fcf" />
inkscape:window-height="758"
inkscape:window-x="0"
inkscape:window-y="19"
inkscape:window-maximized="0" />
<metadata
id="metadata4203">
id="metadata2985">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>Select All</dc:title>
<dc:date />
<dc:creator>
<cc:Agent>
<dc:title>Andreas Nilsson</dc:title>
</cc:Agent>
</dc:creator>
<dc:subject>
<rdf:Bag>
<rdf:li>select</rdf:li>
<rdf:li>all</rdf:li>
</rdf:Bag>
</dc:subject>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
<dc:title />
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
<cc:permits
rdf:resource="http://web.resource.org/cc/Reproduction" />
<cc:permits
rdf:resource="http://web.resource.org/cc/Distribution" />
<cc:requires
rdf:resource="http://web.resource.org/cc/Notice" />
<cc:requires
rdf:resource="http://web.resource.org/cc/Attribution" />
<cc:permits
rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
<cc:requires
rdf:resource="http://web.resource.org/cc/ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<g
style="display:inline"
id="g5022"
transform="matrix(2.382811e-2,0,0,1.448788e-2,44.94353,43.77878)">
<rect
y="-150.69685"
x="-1559.2523"
height="478.35718"
width="1339.6335"
id="rect4173"
style="opacity:0.40206185;color:black;fill:url(#linearGradient5027);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
<path
sodipodi:nodetypes="cccc"
id="path5058"
d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z "
style="opacity:0.40206185;color:black;fill:url(#radialGradient5029);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
<path
style="opacity:0.40206185;color:black;fill:url(#radialGradient5031);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z "
id="path5018"
sodipodi:nodetypes="cccc" />
</g>
<rect
style="opacity:1;fill:url(#linearGradient2240);fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:0.99999976;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4238"
width="38.996792"
height="45.003101"
x="4.5016017"
y="0.52462721"
rx="0.56650788"
ry="0.56650823" />
<rect
style="opacity:1;color:black;fill:#999;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="rect4248"
width="14"
height="2"
x="22"
y="9.0277271" />
<rect
y="15.027727"
x="22"
height="2"
width="12"
id="rect4250"
style="opacity:1;color:black;fill:#999;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
<rect
style="opacity:1;color:black;fill:#999;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="rect4252"
width="22.971531"
height="2"
x="9"
y="21.027727" />
<rect
y="27.027727"
x="9"
height="2"
width="27"
id="rect4254"
style="opacity:1;color:black;fill:#999;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
<rect
style="opacity:1;color:black;fill:#999;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="rect4256"
width="17"
height="2"
x="9"
y="33.027748" />
<rect
style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:white;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect2245"
width="37.000019"
height="43.022316"
x="5.4997153"
y="1.5274456"
rx="0"
ry="0" />
<rect
style="opacity:1;fill:#999;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4837"
width="11"
height="10"
x="9"
y="9.0277271" />
<rect
style="opacity:0.5;color:black;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="rect1323"
width="29"
height="6"
x="8"
y="13.027727" />
<rect
style="opacity:0.5;color:black;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="rect2198"
width="31"
height="6"
x="8"
y="7.0277271" />
<rect
style="opacity:0.5;color:black;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="rect2200"
width="25"
height="6"
x="8"
y="19.027727" />
<rect
style="opacity:0.5;color:black;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="rect2202"
width="29"
height="6"
x="8"
y="25.027727" />
<rect
style="opacity:0.5;color:black;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="rect2204"
width="19"
height="6"
x="8"
y="31.027727" />
<rect
style="opacity:1;color:black;fill:black;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="rect2206"
width="1"
height="7"
x="28"
y="31.027727" />
<rect
style="opacity:1;color:black;fill:black;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="rect2208"
width="1"
height="1"
x="27"
y="30.027727" />
<rect
style="opacity:1;color:black;fill:black;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="rect2210"
width="1"
height="1"
x="29"
y="30.027727" />
<rect
style="opacity:1;color:black;fill:black;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="rect2212"
width="1"
height="1"
x="29"
y="38.027748" />
<rect
style="opacity:1;color:black;fill:black;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="rect2214"
width="1"
height="1"
x="27"
y="38.027748" />
<path
style="opacity:0.54166667;color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.95121026;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 5.6060431,13.580595 0,41.676631 45.3656379,0 11.036532,-8.201181 0,-33.475449 -56.4021699,0 z"
id="rect3005-1"
inkscape:connector-curvature="0" />
<path
style="color:#000000;fill:url(#linearGradient4596);fill-opacity:1;fill-rule:evenodd;stroke:#00429a;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 2.4673922,9.7183795 0,41.6766315 45.3656378,0 11.036532,-8.201181 0,-33.4754505 -56.4021698,0 z"
id="rect3005"
inkscape:connector-curvature="0" />
<path
style="opacity:0.54166667;color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.95121026;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 26.976451,51.516804 7.134956,-6.038369 15.610921,17.475008 8.5659,-7.652164 -15.610923,-17.475007 7.696597,-6.49637 -30.16213,-11.283345 6.764679,31.470247 z"
id="rect2925-8"
sodipodi:nodetypes="cccccccc"
inkscape:connector-curvature="0" />
<path
style="color:#000000;fill:url(#linearGradient4596-5);fill-opacity:1;fill-rule:evenodd;stroke:#00429a;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 58.694952,43.504249 c 0.160894,-1.443027 -0.62697,-3.448369 -4.966718,-4.52326 0,0 -1.330371,7.361384 -5.232791,11.884645 z"
id="path3778"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="color:#000000;fill:url(#linearGradient3817);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.30602169000000012;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 26.405839,44.367917 7.134956,-6.038369 15.610921,17.475008 8.5659,-7.652164 L 42.106693,30.677385 49.80329,24.181015 19.64116,12.89767 26.405839,44.367917 z"
id="rect2925"
sodipodi:nodetypes="cccccccc"
inkscape:connector-curvature="0" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

221
src/Gui/Icons/edit-select-box.svg Executable file
View File

@ -0,0 +1,221 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64px"
height="64px"
id="svg2980"
sodipodi:version="0.32"
inkscape:version="0.48.3.1 r9886"
sodipodi:docname="Select_all.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.1">
<defs
id="defs2982">
<linearGradient
id="linearGradient4590">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop4592" />
<stop
style="stop-color:#5cd4f5;stop-opacity:1;"
offset="1"
id="stop4594" />
</linearGradient>
<linearGradient
id="linearGradient3811">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop3813" />
<stop
style="stop-color:#bfbfbf;stop-opacity:1;"
offset="1"
id="stop3815" />
</linearGradient>
<linearGradient
id="linearGradient3864">
<stop
id="stop3866"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3868"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3864"
id="radialGradient3850"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.6028459,1.0471639,-1.9794021,1.1395295,127.9588,-74.456907)"
cx="51.328892"
cy="31.074146"
fx="51.328892"
fy="31.074146"
r="19.571428" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 32 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="64 : 32 : 1"
inkscape:persp3d-origin="32 : 21.333333 : 1"
id="perspective2988" />
<inkscape:perspective
id="perspective2872"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3864"
id="radialGradient2890"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.58019421,1.0078171,-1.9050269,1.0967121,-8.5316607,-197.0902)"
cx="51.328892"
cy="31.074146"
fx="51.328892"
fy="31.074146"
r="19.571428" />
<inkscape:perspective
id="perspective2902"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective2902-9"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3811"
id="linearGradient3817"
x1="36.870125"
y1="30.196993"
x2="3.3695574"
y2="39.373768"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.27764843,-1.1190823,1.1190823,0.27764843,-10.424279,50.285999)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3811-9"
id="linearGradient3817-3"
x1="6.0684204"
y1="37.207146"
x2="39.480068"
y2="37.207146"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.27764843,-1.1190823,1.1190823,0.27764843,-9.674279,55.785999)" />
<linearGradient
id="linearGradient3811-9">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop3813-8" />
<stop
style="stop-color:#bfbfbf;stop-opacity:1;"
offset="1"
id="stop3815-7" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4590"
id="linearGradient4596"
x1="34.54903"
y1="1.8738226"
x2="28.02536"
y2="43.593124"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(0,8)" />
<linearGradient
id="linearGradient4590-3">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop4592-5" />
<stop
style="stop-color:#5cd4f5;stop-opacity:1;"
offset="1"
id="stop4594-6" />
</linearGradient>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="4"
inkscape:cx="42.774418"
inkscape:cy="24.13006"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:document-units="px"
inkscape:grid-bbox="true"
inkscape:window-width="1280"
inkscape:window-height="758"
inkscape:window-x="0"
inkscape:window-y="19"
inkscape:window-maximized="0" />
<metadata
id="metadata2985">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<rect
style="opacity:0.60250005;color:#000000;fill:none;stroke:#000000;stroke-width:7;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:14, 7;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect4714-0"
width="47"
height="44.75"
x="9"
y="7.375" />
<rect
style="color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#0095d6;stroke-width:7;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:14,7;stroke-dashoffset:0"
id="rect4714"
width="47"
height="44.75"
x="5.5"
y="4.5" />
<path
style="opacity:0.54166667;color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.95121026;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 26.976451,51.516804 7.134956,-6.038369 15.610921,17.475008 8.5659,-7.652164 -15.610923,-17.475007 7.696597,-6.49637 -30.16213,-11.283345 6.764679,31.470247 z"
id="rect2925-8"
sodipodi:nodetypes="cccccccc"
inkscape:connector-curvature="0" />
<path
style="color:#000000;fill:url(#linearGradient3817);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.30602169000000012;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 26.405839,44.367917 7.134956,-6.038369 15.610921,17.475008 8.5659,-7.652164 L 42.106693,30.677385 49.80329,24.181015 19.64116,12.89767 26.405839,44.367917 z"
id="rect2925"
sodipodi:nodetypes="cccccccc"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

@ -43,6 +43,7 @@
<file>edit-delete.svg</file>
<file>edit-paste.svg</file>
<file>edit-select-all.svg</file>
<file>edit-select-box.svg</file>
<file>edit-redo.svg</file>
<file>edit-undo.svg</file>
<file>edit-edit.svg</file>

View File

@ -275,6 +275,13 @@ public:
}
}
void setPosition(const Base::Vector3f& v)
{
this->xPos->setValue(v.x);
this->yPos->setValue(v.y);
this->zPos->setValue(v.z);
}
Base::Vector3f getPosition() const
{
return Base::Vector3f((float)this->xPos->value(),

View File

@ -279,6 +279,7 @@ SbBool InventorNavigationStyle::processSoEvent(const SoEvent * const ev)
else if (this->currentmode == NavigationStyle::DRAGGING) {
this->addToLog(event->getPosition(), event->getTime());
this->spin(posn);
moveCursorPosition();
processed = TRUE;
}
}
@ -316,6 +317,9 @@ SbBool InventorNavigationStyle::processSoEvent(const SoEvent * const ev)
}
break;
case BUTTON1DOWN:
if (newmode != NavigationStyle::DRAGGING) {
saveCursorPosition(ev);
}
newmode = NavigationStyle::DRAGGING;
break;
case BUTTON3DOWN:

View File

@ -63,6 +63,44 @@
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Gui::ActionSelector</name>
<message>
<source>Available:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Selected:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Add</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Remove</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Move up</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Move down</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Gui::AlignmentView</name>
<message>
<source>Movable object</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Fixed object</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Gui::BlenderNavigationStyle</name>
<message>
@ -160,6 +198,10 @@
<source>License...</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Copy to clipboard</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Gui::Dialog::ButtonModel</name>
@ -708,10 +750,6 @@ Please define another shortcut.</source>
<source>Viewing mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Display mode:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Plot mode:</source>
<translation type="unfinished"></translation>
@ -736,6 +774,10 @@ Please define another shortcut.</source>
<source>Color plot:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Document window:</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Gui::Dialog::DlgEditorSettings</name>
@ -1482,6 +1524,14 @@ Specify another directory, please.</source>
<source>Invert zoom</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Zoom at cursor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Zoom step</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Gui::Dialog::DlgSettings3DViewImp</name>
@ -1722,6 +1772,10 @@ Specify another directory, please.</source>
<source>Items</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Current line highlight</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Gui::Dialog::DlgSettingsImage</name>
@ -1956,6 +2010,14 @@ Specify another directory, please.</source>
<source>Macro path</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>General macro settings</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Run macros in local environment</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Gui::Dialog::DlgSettingsUnits</name>
@ -2046,14 +2108,6 @@ Specify another directory, please.</source>
<source>Fully constrained geometry</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The color of construction geometry in editmode</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The color of fully constrained geometry in editmode</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The color of vertices being edited</source>
<translation type="unfinished"></translation>
@ -2062,6 +2116,42 @@ Specify another directory, please.</source>
<source>The color of edges being edited</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The color of construction geometry in edit mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The color of fully constrained geometry in edit mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Cursor text color</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Default shape color</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The default color for new shapes</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Default line width and color</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The default line color for new shapes</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The default line thickness for new shapes</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>px</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Gui::Dialog::DlgTipOfTheDay</name>
@ -2124,7 +2214,39 @@ Specify another directory, please.</source>
<context>
<name>Gui::Dialog::DownloadDialog</name>
<message>
<source>Canceled.</source>
<source>Download</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Cancel</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Close</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>There already exists a file called %1 in the current directory. Overwrite?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to save the file %1: %2.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Downloading %1.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Download canceled.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Download failed: %1.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Downloaded %1 to current directory.</source>
<translation type="unfinished"></translation>
</message>
</context>
@ -2162,6 +2284,13 @@ Specify another directory, please.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Gui::Dialog::LicenseDialog</name>
<message>
<source>Copyright</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Gui::Dialog::MouseButtons</name>
<message>
@ -2847,6 +2976,25 @@ Do you want to save your changes?</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Gui::LocationWidget</name>
<message>
<source>X:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Y:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Z:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Direction:</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Gui::MacroCommand</name>
<message>
@ -2877,6 +3025,88 @@ Do you want to save your changes?</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Gui::ManualAlignment</name>
<message>
<source>Manual alignment</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The alignment is already in progress.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Alignment[*]</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Please, select at least one point in the left and the right view</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Please, select at least %1 points in the left and the right view</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Please pick points in the left and right view</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The alignment has finished</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The alignment has been canceled</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Too few points picked in the left view. At least %1 points are needed.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Too few points picked in the right view. At least %1 points are needed.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Different number of points picked in left and right view.
On the left view %1 points are picked,
on the right view %2 points are picked.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Try to align group of views</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The alignment failed.
How do you want to proceed?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Retry</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Ignore</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Abort</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Different number of points picked in left and right view. On the left view %1 points are picked, on the right view %2 points are picked.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Point picked at (%1,%2,%3)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No point was picked</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Gui::NetworkRetriever</name>
<message>
@ -3020,6 +3250,10 @@ Do you want to exit without saving your data?</source>
<source>Select All</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Clear console</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Gui::PythonEditor</name>
@ -3158,10 +3392,6 @@ Do you want to specify another directory?</source>
</context>
<context>
<name>Gui::TaskView::TaskAppearance</name>
<message>
<source>Display mode:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Plot mode:</source>
<translation type="unfinished"></translation>
@ -3182,6 +3412,10 @@ Do you want to specify another directory?</source>
<source>Appearance</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Document window:</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Gui::TaskView::TaskEditControl</name>
@ -3206,9 +3440,21 @@ Do you want to specify another directory?</source>
</message>
</context>
<context>
<name>Gui::Translator</name>
<name>Gui::TouchpadNavigationStyle</name>
<message>
<source>English</source>
<source>Press left mouse button</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Press SHIFT button</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Press ALT button</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Press PgUp/PgDown button</source>
<translation type="unfinished"></translation>
</message>
</context>
@ -3464,14 +3710,6 @@ Do you want to specify another directory?</source>
<source>A general error occurred while loading the workbench</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>File not found</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Cannot open file %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Save views...</source>
<translation type="unfinished"></translation>
@ -3769,6 +4007,17 @@ You either have to finish or cancel the editing in the task panel.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StdBoxSelection</name>
<message>
<source>Standard-View</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Box selection</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StdCmdAbout</name>
<message>
@ -3829,6 +4078,21 @@ You either have to finish or cancel the editing in the task panel.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StdCmdAlignment</name>
<message>
<source>Edit</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Alignment...</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Align the selected objects</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StdCmdArrangeIcons</name>
<message>
@ -3945,21 +4209,6 @@ You either have to finish or cancel the editing in the task panel.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StdCmdDDuplicateSelection</name>
<message>
<source>Edit</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Duplicate selection</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Put duplicates of the selected objects to the active document</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StdCmdDelete</name>
<message>
@ -4106,6 +4355,40 @@ You either have to finish or cancel the editing in the task panel.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StdCmdDuplicateSelection</name>
<message>
<source>Edit</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Duplicate selection</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Put duplicates of the selected objects to the active document</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StdCmdEdit</name>
<message>
<source>Edit</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Toggle &amp;Edit mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Toggles the selected object&apos;s edit mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enters or leaves the selected object&apos;s edit mode</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StdCmdExport</name>
<message>
@ -4121,7 +4404,26 @@ You either have to finish or cancel the editing in the task panel.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Supported formats</source>
<source>No selection</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Please select first the objects you want to export.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StdCmdExportGraphviz</name>
<message>
<source>Tools</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Dependency graph...</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show the dependency graph of the objects in the active document</source>
<translation type="unfinished"></translation>
</message>
</context>
@ -4297,11 +4599,11 @@ You either have to finish or cancel the editing in the task panel.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Mesure distance</source>
<source>Measures distance between two selected objects</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Measures distance between two selected objects</source>
<source>Measure distance</source>
<translation type="unfinished"></translation>
</message>
</context>
@ -4354,21 +4656,6 @@ You either have to finish or cancel the editing in the task panel.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StdCmdOnlineHelpPython</name>
<message>
<source>Help</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Python Manuals</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show the Python documentation</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StdCmdOnlineHelpWebsite</name>
<message>
@ -5183,6 +5470,36 @@ You either have to finish or cancel the editing in the task panel.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StdCmdViewRotateLeft</name>
<message>
<source>Standard-View</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Rotate Left</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Rotate the view by 90° counter-clockwise</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StdCmdViewRotateRight</name>
<message>
<source>Standard-View</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Rotate Right</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Rotate the view by 90° clockwise</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StdCmdViewTop</name>
<message>
@ -5302,7 +5619,7 @@ You either have to finish or cancel the editing in the task panel.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Display mode</source>
<source>Document window</source>
<translation type="unfinished"></translation>
</message>
<message>
@ -5366,6 +5683,34 @@ You either have to finish or cancel the editing in the task panel.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Std_ExportGraphviz</name>
<message>
<source>Graphviz not found</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Graphviz couldn&apos;t be found on your system.
Do you want to specify its installation path if it&apos;s already installed?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Graphviz installation path</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Dependency graph</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Graphviz failed</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Graphviz failed to create an image file</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Workbench</name>
<message>

File diff suppressed because it is too large Load Diff

View File

@ -23,35 +23,35 @@
<source>Angle Snap</source>
<translation>Einrastwinkel</translation>
</message>
<message>
<message utf8="true">
<source>1 °</source>
<translation>1 °</translation>
</message>
<message>
<message utf8="true">
<source>2 °</source>
<translation>2 °</translation>
</message>
<message>
<message utf8="true">
<source>5 °</source>
<translation>5 °</translation>
</message>
<message>
<message utf8="true">
<source>10 °</source>
<translation>10 °</translation>
</message>
<message>
<message utf8="true">
<source>20 °</source>
<translation>20 °</translation>
</message>
<message>
<message utf8="true">
<source>45 °</source>
<translation>45 °</translation>
</message>
<message>
<message utf8="true">
<source>90 °</source>
<translation>90 °</translation>
</message>
<message>
<message utf8="true">
<source>180 °</source>
<translation>180 °</translation>
</message>
@ -63,6 +63,44 @@
<translation>kein</translation>
</message>
</context>
<context>
<name>Gui::ActionSelector</name>
<message>
<source>Available:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Selected:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Add</source>
<translation type="unfinished">Hinzufügen</translation>
</message>
<message>
<source>Remove</source>
<translation type="unfinished">Entfernen</translation>
</message>
<message>
<source>Move up</source>
<translation type="unfinished">Noch oben verschieben</translation>
</message>
<message>
<source>Move down</source>
<translation type="unfinished">Nache unten verschieben</translation>
</message>
</context>
<context>
<name>Gui::AlignmentView</name>
<message>
<source>Movable object</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Fixed object</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Gui::BlenderNavigationStyle</name>
<message>
@ -160,6 +198,10 @@
<source>License...</source>
<translation>Lizenz...</translation>
</message>
<message>
<source>Copy to clipboard</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Gui::Dialog::ButtonModel</name>
@ -213,11 +255,11 @@
<source>Angle</source>
<translation>Winkel</translation>
</message>
<message>
<message utf8="true">
<source>90°</source>
<translation>90°</translation>
</message>
<message>
<message utf8="true">
<source>-90°</source>
<translation>-90 °</translation>
</message>
@ -711,7 +753,7 @@ Wählen Sie bitte eine andere Tastenkombination.</translation>
</message>
<message>
<source>Display mode:</source>
<translation>Anzeigemodus:</translation>
<translation type="obsolete">Anzeigemodus:</translation>
</message>
<message>
<source>Plot mode:</source>
@ -737,6 +779,10 @@ Wählen Sie bitte eine andere Tastenkombination.</translation>
<source>Color plot:</source>
<translation>Farb-Plot:</translation>
</message>
<message>
<source>Document window:</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Gui::Dialog::DlgEditorSettings</name>
@ -1486,6 +1532,14 @@ Wählen Sie bitte ein anderes Verzeichnis aus.</translation>
<source>Invert zoom</source>
<translation>Zoom umkehren</translation>
</message>
<message>
<source>Zoom at cursor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Zoom step</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Gui::Dialog::DlgSettings3DViewImp</name>
@ -1727,6 +1781,10 @@ Wählen Sie bitte ein anderes Verzeichnis aus.</translation>
<source>Items</source>
<translation>Elemente</translation>
</message>
<message>
<source>Current line highlight</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Gui::Dialog::DlgSettingsImage</name>
@ -1850,11 +1908,11 @@ Wählen Sie bitte ein anderes Verzeichnis aus.</translation>
<source>QSXGA 2560 x 2048</source>
<translation>QSXGA 2560 x 2024</translation>
</message>
<message>
<message utf8="true">
<source>QUXGA 3200 × 2400</source>
<translation>QUXGA 3200 x 2400</translation>
</message>
<message>
<message utf8="true">
<source>HUXGA 6400 × 4800</source>
<translation>HUXGA 6400 x 4800</translation>
</message>
@ -1961,6 +2019,14 @@ Wählen Sie bitte ein anderes Verzeichnis aus.</translation>
<source>Macro path</source>
<translation>Makro-Zielpfad</translation>
</message>
<message>
<source>General macro settings</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Run macros in local environment</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Gui::Dialog::DlgSettingsUnits</name>
@ -2053,11 +2119,11 @@ Wählen Sie bitte ein anderes Verzeichnis aus.</translation>
</message>
<message>
<source>The color of construction geometry in editmode</source>
<translation>Die Farbe der Konstruktionsgeometrien im Editier-Modus</translation>
<translation type="obsolete">Die Farbe der Konstruktionsgeometrien im Editier-Modus</translation>
</message>
<message>
<source>The color of fully constrained geometry in editmode</source>
<translation>Die Farbe der komplett festgelegten Geometrien im Editier-Modus</translation>
<translation type="obsolete">Die Farbe der komplett festgelegten Geometrien im Editier-Modus</translation>
</message>
<message>
<source>The color of vertices being edited</source>
@ -2067,6 +2133,42 @@ Wählen Sie bitte ein anderes Verzeichnis aus.</translation>
<source>The color of edges being edited</source>
<translation>Die Farbe der zu bearbeitenden Kanten</translation>
</message>
<message>
<source>The color of construction geometry in edit mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The color of fully constrained geometry in edit mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Cursor text color</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Default shape color</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The default color for new shapes</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Default line width and color</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The default line color for new shapes</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The default line thickness for new shapes</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>px</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Gui::Dialog::DlgTipOfTheDay</name>
@ -2131,7 +2233,43 @@ Wählen Sie bitte ein anderes Verzeichnis aus.</translation>
<name>Gui::Dialog::DownloadDialog</name>
<message>
<source>Canceled.</source>
<translation>Abgebrochen.</translation>
<translation type="obsolete">Abgebrochen.</translation>
</message>
<message>
<source>Download</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Cancel</source>
<translation type="unfinished">Abbrechen</translation>
</message>
<message>
<source>Close</source>
<translation type="unfinished">Schließen</translation>
</message>
<message>
<source>There already exists a file called %1 in the current directory. Overwrite?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unable to save the file %1: %2.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Downloading %1.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Download canceled.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Download failed: %1.</source>
<translation type="unfinished">Download fehlgeschlagen: %1.</translation>
</message>
<message>
<source>Downloaded %1 to current directory.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
@ -2168,6 +2306,13 @@ Wählen Sie bitte ein anderes Verzeichnis aus.</translation>
<translation>OK</translation>
</message>
</context>
<context>
<name>Gui::Dialog::LicenseDialog</name>
<message>
<source>Copyright</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Gui::Dialog::MouseButtons</name>
<message>
@ -2856,6 +3001,25 @@ Sollen die Änderungen gespeichert werden?</translation>
<translation>Benutzerdefiniert...</translation>
</message>
</context>
<context>
<name>Gui::LocationWidget</name>
<message>
<source>X:</source>
<translation type="unfinished">X:</translation>
</message>
<message>
<source>Y:</source>
<translation type="unfinished">Y:</translation>
</message>
<message>
<source>Z:</source>
<translation type="unfinished">Z:</translation>
</message>
<message>
<source>Direction:</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Gui::MacroCommand</name>
<message>
@ -2886,6 +3050,88 @@ Sollen die Änderungen gespeichert werden?</translation>
<translation>Alles schließen</translation>
</message>
</context>
<context>
<name>Gui::ManualAlignment</name>
<message>
<source>Manual alignment</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The alignment is already in progress.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Alignment[*]</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Please, select at least one point in the left and the right view</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Please, select at least %1 points in the left and the right view</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Please pick points in the left and right view</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The alignment has finished</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The alignment has been canceled</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Too few points picked in the left view. At least %1 points are needed.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Too few points picked in the right view. At least %1 points are needed.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Different number of points picked in left and right view.
On the left view %1 points are picked,
on the right view %2 points are picked.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Try to align group of views</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The alignment failed.
How do you want to proceed?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Retry</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Ignore</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Abort</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Different number of points picked in left and right view. On the left view %1 points are picked, on the right view %2 points are picked.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Point picked at (%1,%2,%3)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No point was picked</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Gui::NetworkRetriever</name>
<message>
@ -3031,6 +3277,10 @@ Wollen Sie sie beenden, ohne Ihre Daten zu speichern?</translation>
<source>Select All</source>
<translation>Alles auswählen</translation>
</message>
<message>
<source>Clear console</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Gui::PythonEditor</name>
@ -3175,7 +3425,7 @@ Möchten Sie ein anderes Verzeichnis angeben?</translation>
<name>Gui::TaskView::TaskAppearance</name>
<message>
<source>Display mode:</source>
<translation>Anzeigemodus:</translation>
<translation type="obsolete">Anzeigemodus:</translation>
</message>
<message>
<source>Plot mode:</source>
@ -3197,6 +3447,10 @@ Möchten Sie ein anderes Verzeichnis angeben?</translation>
<source>Appearance</source>
<translation>Erscheinungsbild</translation>
</message>
<message>
<source>Document window:</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Gui::TaskView::TaskEditControl</name>
@ -3220,11 +3474,30 @@ Möchten Sie ein anderes Verzeichnis angeben?</translation>
<translation>Selektion bearbeiten</translation>
</message>
</context>
<context>
<name>Gui::TouchpadNavigationStyle</name>
<message>
<source>Press left mouse button</source>
<translation type="unfinished">Drücken Sie die linke Maustaste</translation>
</message>
<message>
<source>Press SHIFT button</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Press ALT button</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Press PgUp/PgDown button</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Gui::Translator</name>
<message>
<source>English</source>
<translation>Englisch</translation>
<translation type="obsolete">Englisch</translation>
</message>
</context>
<context>
@ -3481,11 +3754,11 @@ Möchten Sie ein anderes Verzeichnis angeben?</translation>
</message>
<message>
<source>File not found</source>
<translation>Datei nicht gefunden</translation>
<translation type="obsolete">Datei nicht gefunden</translation>
</message>
<message>
<source>Cannot open file %1</source>
<translation>Kann Datei %1 nicht öffnen</translation>
<translation type="obsolete">Kann Datei %1 nicht öffnen</translation>
</message>
<message>
<source>Save views...</source>
@ -3792,6 +4065,17 @@ You either have to finish or cancel the editing in the task panel.</source>
Sie müssen entweder den Bearbeitungsvorgang fertigstellen oder mittels des Aufgabenfensters abbrechen.</translation>
</message>
</context>
<context>
<name>StdBoxSelection</name>
<message>
<source>Standard-View</source>
<translation type="unfinished">Standardansicht</translation>
</message>
<message>
<source>Box selection</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StdCmdAbout</name>
<message>
@ -3852,6 +4136,21 @@ Sie müssen entweder den Bearbeitungsvorgang fertigstellen oder mittels des Aufg
<translation>Vorheriges Fenster aktivieren</translation>
</message>
</context>
<context>
<name>StdCmdAlignment</name>
<message>
<source>Edit</source>
<translation type="unfinished">Bearbeiten</translation>
</message>
<message>
<source>Alignment...</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Align the selected objects</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StdCmdArrangeIcons</name>
<message>
@ -3972,15 +4271,15 @@ Sie müssen entweder den Bearbeitungsvorgang fertigstellen oder mittels des Aufg
<name>StdCmdDDuplicateSelection</name>
<message>
<source>Edit</source>
<translation>Bearbeiten</translation>
<translation type="obsolete">Bearbeiten</translation>
</message>
<message>
<source>Duplicate selection</source>
<translation>Auswahl duplizieren</translation>
<translation type="obsolete">Auswahl duplizieren</translation>
</message>
<message>
<source>Put duplicates of the selected objects to the active document</source>
<translation>Duplikate der selektierten Objekte in aktives Dokument einfügen</translation>
<translation type="obsolete">Duplikate der selektierten Objekte in aktives Dokument einfügen</translation>
</message>
</context>
<context>
@ -4129,6 +4428,40 @@ Sie müssen entweder den Bearbeitungsvorgang fertigstellen oder mittels des Aufg
<translation>Zeichenstil</translation>
</message>
</context>
<context>
<name>StdCmdDuplicateSelection</name>
<message>
<source>Edit</source>
<translation type="unfinished">Bearbeiten</translation>
</message>
<message>
<source>Duplicate selection</source>
<translation type="unfinished">Auswahl duplizieren</translation>
</message>
<message>
<source>Put duplicates of the selected objects to the active document</source>
<translation type="unfinished">Duplikate der selektierten Objekte in aktives Dokument einfügen</translation>
</message>
</context>
<context>
<name>StdCmdEdit</name>
<message>
<source>Edit</source>
<translation type="unfinished">Bearbeiten</translation>
</message>
<message>
<source>Toggle &amp;Edit mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Toggles the selected object&apos;s edit mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enters or leaves the selected object&apos;s edit mode</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StdCmdExport</name>
<message>
@ -4145,7 +4478,30 @@ Sie müssen entweder den Bearbeitungsvorgang fertigstellen oder mittels des Aufg
</message>
<message>
<source>Supported formats</source>
<translation>Unterstützte Formate</translation>
<translation type="obsolete">Unterstützte Formate</translation>
</message>
<message>
<source>No selection</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Please select first the objects you want to export.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StdCmdExportGraphviz</name>
<message>
<source>Tools</source>
<translation type="unfinished">Werkzeuge</translation>
</message>
<message>
<source>Dependency graph...</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show the dependency graph of the objects in the active document</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
@ -4321,12 +4677,16 @@ Sie müssen entweder den Bearbeitungsvorgang fertigstellen oder mittels des Aufg
</message>
<message>
<source>Mesure distance</source>
<translation>Abstand messen</translation>
<translation type="obsolete">Abstand messen</translation>
</message>
<message>
<source>Measures distance between two selected objects</source>
<translation>Misst die Distanz zwischen zwei ausgewählten Objekten</translation>
</message>
<message>
<source>Measure distance</source>
<translation type="unfinished">Abstand messen</translation>
</message>
</context>
<context>
<name>StdCmdMergeProjects</name>
@ -4381,15 +4741,15 @@ Sie müssen entweder den Bearbeitungsvorgang fertigstellen oder mittels des Aufg
<name>StdCmdOnlineHelpPython</name>
<message>
<source>Help</source>
<translation>Hilfe</translation>
<translation type="obsolete">Hilfe</translation>
</message>
<message>
<source>Python Manuals</source>
<translation>Python-Handbuch</translation>
<translation type="obsolete">Python-Handbuch</translation>
</message>
<message>
<source>Show the Python documentation</source>
<translation>Python-Dokumentation anzeigen</translation>
<translation type="obsolete">Python-Dokumentation anzeigen</translation>
</message>
</context>
<context>
@ -5206,6 +5566,36 @@ Sie müssen entweder den Bearbeitungsvorgang fertigstellen oder mittels des Aufg
<translation>Rechtsansicht</translation>
</message>
</context>
<context>
<name>StdCmdViewRotateLeft</name>
<message>
<source>Standard-View</source>
<translation type="unfinished">Standardansicht</translation>
</message>
<message>
<source>Rotate Left</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Rotate the view by 90° counter-clockwise</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StdCmdViewRotateRight</name>
<message>
<source>Standard-View</source>
<translation type="unfinished">Standardansicht</translation>
</message>
<message>
<source>Rotate Right</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Rotate the view by 90° clockwise</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StdCmdViewTop</name>
<message>
@ -5325,8 +5715,8 @@ Sie müssen entweder den Bearbeitungsvorgang fertigstellen oder mittels des Aufg
<translation>Standardansicht</translation>
</message>
<message>
<source>Display mode</source>
<translation>Anzeige-Modus</translation>
<source>Document window</source>
<translation>Dokumentfenster</translation>
</message>
<message>
<source>Display the active view either in fullscreen, in undocked or docked mode</source>
@ -5389,6 +5779,34 @@ Sie müssen entweder den Bearbeitungsvorgang fertigstellen oder mittels des Aufg
<translation>Drahtgitter-Modus</translation>
</message>
</context>
<context>
<name>Std_ExportGraphviz</name>
<message>
<source>Graphviz not found</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Graphviz couldn&apos;t be found on your system.
Do you want to specify its installation path if it&apos;s already installed?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Graphviz installation path</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Dependency graph</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Graphviz failed</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Graphviz failed to create an image file</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Workbench</name>
<message>

Some files were not shown because too many files have changed in this diff Show More