mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-09-24 18:54:20 +02:00
Compare commits
58 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 73075a5154 | |||
| 9875de85d7 | |||
| 48883b320e | |||
| b93d8d8baa | |||
| ae41dd7686 | |||
| 7fbbb71aac | |||
| 232724bf82 | |||
| 12f826e969 | |||
| 245aafb0d1 | |||
| 0d231ef548 | |||
| 3513f692fd | |||
| 5a27f3cf80 | |||
| d3a9adbe44 | |||
| 8ab4e24b61 | |||
| 2d2bf5ca2b | |||
| 2f6ab8f63b | |||
| 2266497b0b | |||
| dcb79b6553 | |||
| 745b4a936c | |||
| 7ac3719c37 | |||
| ddfa234943 | |||
| 9af562fcbd | |||
| c85276f61b | |||
| f3a31c291f | |||
| a06220e8dc | |||
| 79990e40ee | |||
| e1e7ea4888 | |||
| 54b8fe5df4 | |||
| be0d214b75 | |||
| 2f988e6e2c | |||
| 9786006ca4 | |||
| 91e8956734 | |||
| 6fad3390df | |||
| 231ab990c3 | |||
| f10275cb22 | |||
| 3d0e7a27a3 | |||
| f14278324c | |||
| d5318eb7b4 | |||
| f10ef3ded7 | |||
| 6f7ea63589 | |||
| 9a6029a2bb | |||
| bc0ca56c7e | |||
| 1d4c0326d4 | |||
| 3457a88e81 | |||
| 4e361f93fe | |||
| 6a8838e719 | |||
| 774f803626 | |||
| 5b0785fcce | |||
| de9b3eae06 | |||
| 032f2249a3 | |||
| 1890cee801 | |||
| 3eea3059bf | |||
| bf7f49f334 | |||
| 2ec413a578 | |||
| 61ce75e380 | |||
| 83b9f32bd0 | |||
| e35cab33f0 | |||
| 2e4bb486bb |
@@ -28,7 +28,7 @@ jobs:
|
|||||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||||
ca-certificates build-essential cmake ninja-build git pkg-config \
|
ca-certificates build-essential cmake ninja-build git pkg-config \
|
||||||
qt6-base-dev qt6-base-private-dev qt6-tools-dev qt6-tools-dev-tools \
|
qt6-base-dev qt6-base-private-dev qt6-tools-dev qt6-tools-dev-tools \
|
||||||
libqt6svg6-dev libqt6sql6-sqlite libcups2-dev \
|
libqt6svg6-dev libqt6sql6-sqlite libcups2-dev libsqlite3-dev \
|
||||||
libxkbcommon-x11-0 \
|
libxkbcommon-x11-0 \
|
||||||
xvfb openbox xdotool x11-utils
|
xvfb openbox xdotool x11-utils
|
||||||
# extra-cmake-modules and the KF6 libraries are installed rather than
|
# extra-cmake-modules and the KF6 libraries are installed rather than
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ jobs:
|
|||||||
mingw-w64-ucrt-x86_64-qt6-tools
|
mingw-w64-ucrt-x86_64-qt6-tools
|
||||||
mingw-w64-ucrt-x86_64-qt6-translations
|
mingw-w64-ucrt-x86_64-qt6-translations
|
||||||
mingw-w64-ucrt-x86_64-qt6-pdf
|
mingw-w64-ucrt-x86_64-qt6-pdf
|
||||||
|
mingw-w64-ucrt-x86_64-sqlite3
|
||||||
mingw-w64-ucrt-x86_64-pkg-config
|
mingw-w64-ucrt-x86_64-pkg-config
|
||||||
mingw-w64-ucrt-x86_64-kwidgetsaddons
|
mingw-w64-ucrt-x86_64-kwidgetsaddons
|
||||||
mingw-w64-ucrt-x86_64-kcoreaddons
|
mingw-w64-ucrt-x86_64-kcoreaddons
|
||||||
@@ -121,7 +122,8 @@ jobs:
|
|||||||
-DQET_EXPORT_PROJECT_DB=ON \
|
-DQET_EXPORT_PROJECT_DB=ON \
|
||||||
-DCMAKE_C_COMPILER_LAUNCHER=/ucrt64/bin/ccache \
|
-DCMAKE_C_COMPILER_LAUNCHER=/ucrt64/bin/ccache \
|
||||||
-DCMAKE_CXX_COMPILER_LAUNCHER=/ucrt64/bin/ccache \
|
-DCMAKE_CXX_COMPILER_LAUNCHER=/ucrt64/bin/ccache \
|
||||||
|
-DSQLite3_INCLUDE_DIR=/ucrt64/include \
|
||||||
|
-DSQLite3_LIBRARY=/ucrt64/lib/libsqlite3.dll.a \
|
||||||
..
|
..
|
||||||
ninja -j"$NPROC"
|
ninja -j"$NPROC"
|
||||||
|
|
||||||
@@ -194,6 +196,13 @@ jobs:
|
|||||||
cp /ucrt64/bin/libgcc_s_seh-1.dll "$BIN/"
|
cp /ucrt64/bin/libgcc_s_seh-1.dll "$BIN/"
|
||||||
cp /ucrt64/bin/libstdc++-6.dll "$BIN/"
|
cp /ucrt64/bin/libstdc++-6.dll "$BIN/"
|
||||||
cp /ucrt64/bin/libwinpthread-1.dll "$BIN/"
|
cp /ucrt64/bin/libwinpthread-1.dll "$BIN/"
|
||||||
|
SQLITE=$(find /ucrt64/bin -name "libsqlite3*.dll" | head -1)
|
||||||
|
if [ -n "$SQLITE" ]; then
|
||||||
|
cp "$SQLITE" "$BIN/"
|
||||||
|
echo "SQLite3 copied: $(basename $SQLITE)"
|
||||||
|
else
|
||||||
|
echo "WARNING: libsqlite3 not found in /ucrt64/bin/"
|
||||||
|
fi
|
||||||
|
|
||||||
cp "$GITHUB_WORKSPACE/build-aux/windows/QET64.nsi" "$NSIS_ROOT/"
|
cp "$GITHUB_WORKSPACE/build-aux/windows/QET64.nsi" "$NSIS_ROOT/"
|
||||||
cp "$GITHUB_WORKSPACE/build-aux/windows/lang_extra.nsh" "$NSIS_ROOT/"
|
cp "$GITHUB_WORKSPACE/build-aux/windows/lang_extra.nsh" "$NSIS_ROOT/"
|
||||||
|
|||||||
+1
-9
@@ -9,12 +9,4 @@ doc/*
|
|||||||
!doc/QElectroTech.qch
|
!doc/QElectroTech.qch
|
||||||
QElectroTech.tag
|
QElectroTech.tag
|
||||||
!doc/doc-utils
|
!doc/doc-utils
|
||||||
lang/*.qm
|
ui_*.h
|
||||||
|
|
||||||
# -- IDE settings/intermediate files --
|
|
||||||
# zed
|
|
||||||
.zed
|
|
||||||
.cache
|
|
||||||
|
|
||||||
# VS Code
|
|
||||||
.vscode
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ include(cmake/git_update_submodules.cmake)
|
|||||||
include(cmake/git_last_commit_sha.cmake)
|
include(cmake/git_last_commit_sha.cmake)
|
||||||
include(cmake/fetch_singleapplication.cmake)
|
include(cmake/fetch_singleapplication.cmake)
|
||||||
include(cmake/fetch_pugixml.cmake)
|
include(cmake/fetch_pugixml.cmake)
|
||||||
|
include(cmake/find_spacemouse.cmake)
|
||||||
include(cmake/qet_compilation_vars.cmake)
|
include(cmake/qet_compilation_vars.cmake)
|
||||||
|
|
||||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
@@ -169,6 +170,12 @@ else()
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(QET_SPACEMOUSE_BACKEND_SPNAV_ENABLED)
|
||||||
|
list(APPEND QET_SPACEMOUSE_LIBRARIES PkgConfig::SPNAV)
|
||||||
|
endif()
|
||||||
|
# A future Windows/macOS (3DxWare) backend would list.APPEND its own SDK
|
||||||
|
# libraries here, behind its own *_ENABLED guard, alongside this one.
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
# CFBundleIdentifier must not be empty. CMake's default Info.plist
|
# CFBundleIdentifier must not be empty. CMake's default Info.plist
|
||||||
# template fills it from MACOSX_BUNDLE_GUI_IDENTIFIER; with that unset
|
# template fills it from MACOSX_BUNDLE_GUI_IDENTIFIER; with that unset
|
||||||
@@ -287,6 +294,7 @@ target_link_libraries(
|
|||||||
SQLite3::SQLite3
|
SQLite3::SQLite3
|
||||||
${KF_PRIVATE_LIBRARIES}
|
${KF_PRIVATE_LIBRARIES}
|
||||||
${QET_PRIVATE_LIBRARIES}
|
${QET_PRIVATE_LIBRARIES}
|
||||||
|
${QET_SPACEMOUSE_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(
|
target_include_directories(
|
||||||
|
|||||||
+21
-7
@@ -27,12 +27,18 @@ git submodule update --init --recursive
|
|||||||
| C++17 compiler | required | GCC or Clang on Unix-like platforms; MSVC or MinGW-w64 g++ on Windows — see [Choosing a compiler](#3-choosing-a-compiler-unix) / [Building on Windows](#6-building-on-windows-msvc--mingw) |
|
| C++17 compiler | required | GCC or Clang on Unix-like platforms; MSVC or MinGW-w64 g++ on Windows — see [Choosing a compiler](#3-choosing-a-compiler-unix) / [Building on Windows](#6-building-on-windows-msvc--mingw) |
|
||||||
| Qt6 base + widgets | required | |
|
| Qt6 base + widgets | required | |
|
||||||
| Qt6 **GuiPrivate** headers | required | needed for clickable PDF hyperlinks; **hard build failure** at CMake generate time if missing, see below |
|
| Qt6 **GuiPrivate** headers | required | needed for clickable PDF hyperlinks; **hard build failure** at CMake generate time if missing, see below |
|
||||||
|
| SQLite3 | required | used by the nomenclature/summary database |
|
||||||
| Qt Linguist tools (`lrelease`) | required | compiles the tracked `.ts` files into `.qm` as part of every normal build |
|
| Qt Linguist tools (`lrelease`) | required | compiles the tracked `.ts` files into `.qm` as part of every normal build |
|
||||||
| pugixml | handled automatically | fetched and built via CMake FetchContent if not already present on the system — see [pugixml](#8-pugixml) below |
|
| pugixml | handled automatically | fetched and built via CMake FetchContent if not already present on the system — see [pugixml](#8-pugixml) below |
|
||||||
| Qt Test module | required if building tests | `PACKAGE_TESTS` is `ON` by default; QtTest ships as part of the base Qt6 dev packages listed below on every platform, no extra package needed |
|
| Qt Test module | required if building tests | `PACKAGE_TESTS` is `ON` by default; QtTest ships as part of the base Qt6 dev packages listed below on every platform, no extra package needed |
|
||||||
| KDE Frameworks (KF6) | optional | see [Building without KDE Frameworks](#9-building-without-kde-frameworks) |
|
| KDE Frameworks (KF6) | optional | see [Building without KDE Frameworks](#9-building-without-kde-frameworks) |
|
||||||
| QtPdf module | optional | see [PDF page import](#7-pdf-page-import-qtpdf) |
|
| QtPdf module | optional | see [PDF page import](#7-pdf-page-import-qtpdf) |
|
||||||
|
|
||||||
|
A note on CMake versions: the project declares a minimum of 3.5 but is
|
||||||
|
routinely built with much newer releases; if your CMake is older than 4.3 it
|
||||||
|
simply won't have the newer `SQLite3::SQLite3` target name, which the build
|
||||||
|
script compensates for automatically. There is nothing you need to do either
|
||||||
|
way.
|
||||||
|
|
||||||
## 3. Building (out-of-source build)
|
## 3. Building (out-of-source build)
|
||||||
|
|
||||||
@@ -100,7 +106,7 @@ the closest match.
|
|||||||
sudo apt install \
|
sudo apt install \
|
||||||
build-essential cmake ninja-build git \
|
build-essential cmake ninja-build git \
|
||||||
qt6-base-dev qt6-base-private-dev qt6-tools-dev qt6-tools-dev-tools \
|
qt6-base-dev qt6-base-private-dev qt6-tools-dev qt6-tools-dev-tools \
|
||||||
|
libsqlite3-dev \
|
||||||
libkf6coreaddons-dev libkf6widgetsaddons-dev
|
libkf6coreaddons-dev libkf6widgetsaddons-dev
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -132,6 +138,7 @@ sudo apt install libpugixml-dev
|
|||||||
sudo dnf install \
|
sudo dnf install \
|
||||||
cmake gcc-c++ git \
|
cmake gcc-c++ git \
|
||||||
qt6-qtbase-devel qt6-qtbase-private-devel qt6-qttools-devel \
|
qt6-qtbase-devel qt6-qtbase-private-devel qt6-qttools-devel \
|
||||||
|
sqlite-devel \
|
||||||
kf6-kcoreaddons-devel kf6-kwidgetsaddons-devel
|
kf6-kcoreaddons-devel kf6-kwidgetsaddons-devel
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -148,10 +155,11 @@ Optional, for a system pugixml: `sudo dnf install pugixml-devel`.
|
|||||||
pkg install \
|
pkg install \
|
||||||
cmake git \
|
cmake git \
|
||||||
qt6-base qt6-tools \
|
qt6-base qt6-tools \
|
||||||
|
sqlite3 \
|
||||||
kf6-kcoreaddons kf6-kwidgetsaddons
|
kf6-kcoreaddons kf6-kwidgetsaddons
|
||||||
```
|
```
|
||||||
|
|
||||||
(from ports: `devel/qt6-base`, `devel/qt6-tools`,
|
(from ports: `devel/qt6-base`, `devel/qt6-tools`, `databases/sqlite3`,
|
||||||
`devel/kf6-kcoreaddons`, `x11-toolkits/kf6-kwidgetsaddons`.) Qt6's
|
`devel/kf6-kcoreaddons`, `x11-toolkits/kf6-kwidgetsaddons`.) Qt6's
|
||||||
`GuiPrivate` headers ship as part of `qt6-base` on FreeBSD, no separate
|
`GuiPrivate` headers ship as part of `qt6-base` on FreeBSD, no separate
|
||||||
package is needed. `QtPdf` is not packaged on FreeBSD at the time of writing
|
package is needed. `QtPdf` is not packaged on FreeBSD at the time of writing
|
||||||
@@ -167,7 +175,7 @@ Optional, for a system pugixml: `pkg install pugixml` (`devel/pugixml`).
|
|||||||
Using [Homebrew](https://brew.sh):
|
Using [Homebrew](https://brew.sh):
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
brew install cmake qt ninja
|
brew install cmake qt sqlite ninja
|
||||||
```
|
```
|
||||||
|
|
||||||
Homebrew's `qt` formula is Qt6 and includes the private headers, so no
|
Homebrew's `qt` formula is Qt6 and includes the private headers, so no
|
||||||
@@ -185,7 +193,7 @@ Optional, for a system pugixml: `brew install pugixml`.
|
|||||||
|
|
||||||
See [Building on Windows](#6-building-on-windows-msvc--mingw) below — the
|
See [Building on Windows](#6-building-on-windows-msvc--mingw) below — the
|
||||||
package sources differ enough from the Unix-like platforms above (no system
|
package sources differ enough from the Unix-like platforms above (no system
|
||||||
package manager and Qt aren't provided the same way) that it gets
|
package manager, SQLite3 and Qt aren't provided the same way) that it gets
|
||||||
its own section.
|
its own section.
|
||||||
|
|
||||||
## 5. pugixml
|
## 5. pugixml
|
||||||
@@ -207,7 +215,7 @@ on Debian/Ubuntu, `pugixml-devel` on Fedora).
|
|||||||
Both toolchains QET's CMake build targets on Windows are covered here:
|
Both toolchains QET's CMake build targets on Windows are covered here:
|
||||||
**MSVC** (Visual Studio 2019/2022) and **MinGW-w64** (gcc). Unlike the
|
**MSVC** (Visual Studio 2019/2022) and **MinGW-w64** (gcc). Unlike the
|
||||||
Unix-like platforms above, there's no single system package manager, so
|
Unix-like platforms above, there's no single system package manager, so
|
||||||
Qt and (optionally) KDE Frameworks each need to be sourced
|
Qt, SQLite3 and (optionally) KDE Frameworks each need to be sourced
|
||||||
separately per toolchain.
|
separately per toolchain.
|
||||||
|
|
||||||
One piece of good news either way: unlike Debian/Fedora, the official Qt
|
One piece of good news either way: unlike Debian/Fedora, the official Qt
|
||||||
@@ -228,7 +236,11 @@ normally use `-DBUILD_WITH_KF=OFF` (see the
|
|||||||
1. Install Visual Studio with the "Desktop development with C++" workload,
|
1. Install Visual Studio with the "Desktop development with C++" workload,
|
||||||
and install Qt6 for MSVC (e.g. the `msvc2019_64` or `msvc2022_64` kit)
|
and install Qt6 for MSVC (e.g. the `msvc2019_64` or `msvc2022_64` kit)
|
||||||
via the [Qt Online Installer](https://www.qt.io/download-qt-installer).
|
via the [Qt Online Installer](https://www.qt.io/download-qt-installer).
|
||||||
2. Configure and build from an "x64 Native Tools Command Prompt for VS":
|
2. Get SQLite3 — the simplest route is [vcpkg](https://vcpkg.io):
|
||||||
|
```bat
|
||||||
|
vcpkg install sqlite3:x64-windows
|
||||||
|
```
|
||||||
|
3. Configure and build from an "x64 Native Tools Command Prompt for VS":
|
||||||
```bat
|
```bat
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
cmake .. -G "Visual Studio 17 2022" -A x64 ^
|
cmake .. -G "Visual Studio 17 2022" -A x64 ^
|
||||||
@@ -281,7 +293,9 @@ Using the Qt Online Installer's bundled MinGW kit instead: point
|
|||||||
`CMAKE_PREFIX_PATH` at that kit (e.g. `C:\Qt\6.x.x\mingw_64`) and make sure
|
`CMAKE_PREFIX_PATH` at that kit (e.g. `C:\Qt\6.x.x\mingw_64`) and make sure
|
||||||
its bundled `g++.exe` comes first on `PATH`, or pass
|
its bundled `g++.exe` comes first on `PATH`, or pass
|
||||||
`-DCMAKE_C_COMPILER`/`-DCMAKE_CXX_COMPILER` explicitly so CMake doesn't pick
|
`-DCMAKE_C_COMPILER`/`-DCMAKE_CXX_COMPILER` explicitly so CMake doesn't pick
|
||||||
up a different MinGW installation.
|
up a different MinGW installation. SQLite3 still has to come from elsewhere
|
||||||
|
in this path — vcpkg with a `mingw`-flavoured triplet, or MSYS2's package as
|
||||||
|
above.
|
||||||
|
|
||||||
## 7. Qt6 private headers (mandatory)
|
## 7. Qt6 private headers (mandatory)
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ parts:
|
|||||||
- python3-lxml
|
- python3-lxml
|
||||||
- python3-tk
|
- python3-tk
|
||||||
- libtk8.6
|
- libtk8.6
|
||||||
|
- libspnav0
|
||||||
|
|
||||||
kde-sdk-setup:
|
kde-sdk-setup:
|
||||||
plugin: nil
|
plugin: nil
|
||||||
@@ -71,6 +72,7 @@ parts:
|
|||||||
source: .
|
source: .
|
||||||
stage-packages:
|
stage-packages:
|
||||||
- git
|
- git
|
||||||
|
- sqlite3
|
||||||
- xdg-user-dirs
|
- xdg-user-dirs
|
||||||
- libqt6qml6
|
- libqt6qml6
|
||||||
# libxcb-cursor0 workaround was needed against the Qt5/KF5 core22 content
|
# libxcb-cursor0 workaround was needed against the Qt5/KF5 core22 content
|
||||||
@@ -81,7 +83,7 @@ parts:
|
|||||||
- git
|
- git
|
||||||
- cmake
|
- cmake
|
||||||
- ninja-build
|
- ninja-build
|
||||||
|
- libsqlite3-dev
|
||||||
- qt6-tools-dev
|
- qt6-tools-dev
|
||||||
- qt6-base-private-dev
|
- qt6-base-private-dev
|
||||||
- qt6-declarative-dev
|
- qt6-declarative-dev
|
||||||
@@ -91,6 +93,7 @@ parts:
|
|||||||
# runs FindCups at configure time and fails without the CUPS headers.
|
# runs FindCups at configure time and fails without the CUPS headers.
|
||||||
# Build-time only: nothing from it is staged into the snap.
|
# Build-time only: nothing from it is staged into the snap.
|
||||||
- libcups2-dev
|
- libcups2-dev
|
||||||
|
- libspnav-dev
|
||||||
override-build: |
|
override-build: |
|
||||||
displayed_version=$(cat sources/qetversion.cpp | grep "return QVersionNumber{"| head -n 1| awk -F "{" '{ print $2 }' | awk -F "}" '{ print $1 }' | sed -e 's/,/./g' -e 's/ //g')
|
displayed_version=$(cat sources/qetversion.cpp | grep "return QVersionNumber{"| head -n 1| awk -F "{" '{ print $2 }' | awk -F "}" '{ print $1 }' | sed -e 's/,/./g' -e 's/ //g')
|
||||||
snap_version="${displayed_version}-g$(git rev-parse --short=8 HEAD)"
|
snap_version="${displayed_version}-g$(git rev-parse --short=8 HEAD)"
|
||||||
@@ -105,7 +108,8 @@ parts:
|
|||||||
-DBUILD_KF=OFF \
|
-DBUILD_KF=OFF \
|
||||||
-DPACKAGE_TESTS=OFF \
|
-DPACKAGE_TESTS=OFF \
|
||||||
-DBUILD_PUGIXML=ON \
|
-DBUILD_PUGIXML=ON \
|
||||||
-DQET_EXPORT_PROJECT_DB=ON
|
-DQET_EXPORT_PROJECT_DB=ON \
|
||||||
|
-DQET_ENABLE_SPACEMOUSE=ON
|
||||||
ninja -C build -j${CRAFT_PARALLEL_BUILD_COUNT}
|
ninja -C build -j${CRAFT_PARALLEL_BUILD_COUNT}
|
||||||
DESTDIR="$CRAFT_PART_INSTALL" ninja -C build install
|
DESTDIR="$CRAFT_PART_INSTALL" ninja -C build install
|
||||||
override-stage: |
|
override-stage: |
|
||||||
|
|||||||
@@ -47,3 +47,8 @@ option(BUILD_WITH_KF "Build with KDE Frameworks" ON)
|
|||||||
# compile for everyone else. Leaving it off keeps CI and contributors on the
|
# compile for everyone else. Leaving it off keeps CI and contributors on the
|
||||||
# strict behaviour, and only developers who opt in trade that for the speed.
|
# strict behaviour, and only developers who opt in trade that for the speed.
|
||||||
option(QET_ENABLE_PCH "Use precompiled headers (developer build speed; may mask missing #includes)" OFF)
|
option(QET_ENABLE_PCH "Use precompiled headers (developer build speed; may mask missing #includes)" OFF)
|
||||||
|
|
||||||
|
# Phase 1 (Linux, libspnav) of discussion #599: 3Dconnexion SpaceMouse/
|
||||||
|
# SpacePilot pan/zoom support. Off by default -- see cmake/find_spacemouse.cmake
|
||||||
|
# for what happens when it is on but libspnav isn't found.
|
||||||
|
option(QET_ENABLE_SPACEMOUSE "Build with 3Dconnexion/libspnav 3D mouse support for pan/zoom (Linux, requires libspnav-dev and spacenavd)" OFF)
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
# Copyright 2006 The QElectroTech Team
|
||||||
|
# This file is part of QElectroTech.
|
||||||
|
#
|
||||||
|
# QElectroTech is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# QElectroTech 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 General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
message(" - find_spacemouse")
|
||||||
|
|
||||||
|
# QET_ENABLE_SPACEMOUSE (cmake/developer_options.cmake) is off by default,
|
||||||
|
# so none of this runs, and the default build is entirely unaffected: no new
|
||||||
|
# dependency, no new source files, no new symbols.
|
||||||
|
#
|
||||||
|
# When it is on, the platform decides which backend (if any) is available --
|
||||||
|
# see sources/spacemouse/spacemousebackend.h for what a backend is. Only one
|
||||||
|
# exists today: SpnavBackend, Linux, via libspnav. A Windows/macOS backend
|
||||||
|
# would need 3Dconnexion's proprietary 3DxWare SDK and is not implemented
|
||||||
|
# (see discussion #599's own phase split); until it is, turning this option
|
||||||
|
# on there downgrades cleanly with a warning rather than failing configure.
|
||||||
|
set(QET_SPACEMOUSE_ENABLED FALSE)
|
||||||
|
set(QET_SPACEMOUSE_BACKEND_SPNAV_ENABLED FALSE)
|
||||||
|
|
||||||
|
if(QET_ENABLE_SPACEMOUSE)
|
||||||
|
if(UNIX AND NOT APPLE)
|
||||||
|
# libspnav is looked for via its pkg-config file (present on every
|
||||||
|
# distro package of it this was checked against: Debian/Ubuntu's
|
||||||
|
# libspnav-dev ships /usr/share/pkgconfig/spnav.pc). Not found does
|
||||||
|
# not hard-fail the whole configure -- it downgrades the option back
|
||||||
|
# to off with a clear message, so a developer who doesn't have the
|
||||||
|
# library installed still gets a normal build instead of a configure
|
||||||
|
# error for an opt-in feature they didn't ask to block on.
|
||||||
|
find_package(PkgConfig)
|
||||||
|
if(PkgConfig_FOUND)
|
||||||
|
pkg_check_modules(SPNAV IMPORTED_TARGET spnav)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(SPNAV_FOUND)
|
||||||
|
set(QET_SPACEMOUSE_ENABLED TRUE)
|
||||||
|
set(QET_SPACEMOUSE_BACKEND_SPNAV_ENABLED TRUE)
|
||||||
|
add_definitions(-DQET_SPACEMOUSE_SUPPORT)
|
||||||
|
add_definitions(-DQET_SPACEMOUSE_BACKEND_SPNAV)
|
||||||
|
message("QET_ENABLE_SPACEMOUSE ON (backend: libspnav ${SPNAV_VERSION})")
|
||||||
|
else()
|
||||||
|
message(WARNING "QET_ENABLE_SPACEMOUSE is ON but libspnav was not found via pkg-config "
|
||||||
|
"(install libspnav-dev, or the equivalent for your distribution) -- "
|
||||||
|
"building WITHOUT 3D mouse support.")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
message(WARNING "QET_ENABLE_SPACEMOUSE is ON but no 3D mouse backend is implemented yet "
|
||||||
|
"for this platform (only Linux/libspnav exists today -- see "
|
||||||
|
"https://github.com/qelectrotech/qelectrotech-source-mirror/discussions/599) "
|
||||||
|
"-- building WITHOUT 3D mouse support.")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
@@ -297,6 +297,8 @@ set(QET_SRC_FILES
|
|||||||
${QET_DIR}/sources/autoNum/numerotationcontextcommands.h
|
${QET_DIR}/sources/autoNum/numerotationcontextcommands.h
|
||||||
${QET_DIR}/sources/autoNum/numerotationcontext.cpp
|
${QET_DIR}/sources/autoNum/numerotationcontext.cpp
|
||||||
${QET_DIR}/sources/autoNum/numerotationcontext.h
|
${QET_DIR}/sources/autoNum/numerotationcontext.h
|
||||||
|
${QET_DIR}/sources/autoNum/renumberelementscommand.cpp
|
||||||
|
${QET_DIR}/sources/autoNum/renumberelementscommand.h
|
||||||
${QET_DIR}/sources/autoNum/ui/autonumberingdockwidget.cpp
|
${QET_DIR}/sources/autoNum/ui/autonumberingdockwidget.cpp
|
||||||
${QET_DIR}/sources/autoNum/ui/autonumberingdockwidget.h
|
${QET_DIR}/sources/autoNum/ui/autonumberingdockwidget.h
|
||||||
${QET_DIR}/sources/autoNum/ui/autonumberingmanagementw.cpp
|
${QET_DIR}/sources/autoNum/ui/autonumberingmanagementw.cpp
|
||||||
@@ -307,6 +309,8 @@ set(QET_SRC_FILES
|
|||||||
${QET_DIR}/sources/autoNum/ui/formulaautonumberingw.h
|
${QET_DIR}/sources/autoNum/ui/formulaautonumberingw.h
|
||||||
${QET_DIR}/sources/autoNum/ui/numparteditorw.cpp
|
${QET_DIR}/sources/autoNum/ui/numparteditorw.cpp
|
||||||
${QET_DIR}/sources/autoNum/ui/numparteditorw.h
|
${QET_DIR}/sources/autoNum/ui/numparteditorw.h
|
||||||
|
${QET_DIR}/sources/autoNum/ui/renumberelementsdialog.cpp
|
||||||
|
${QET_DIR}/sources/autoNum/ui/renumberelementsdialog.h
|
||||||
${QET_DIR}/sources/autoNum/ui/selectautonumw.cpp
|
${QET_DIR}/sources/autoNum/ui/selectautonumw.cpp
|
||||||
${QET_DIR}/sources/autoNum/ui/selectautonumw.h
|
${QET_DIR}/sources/autoNum/ui/selectautonumw.h
|
||||||
|
|
||||||
@@ -871,6 +875,25 @@ list(APPEND QET_SRC_FILES
|
|||||||
${QET_DIR}/sources/scripting/qetscripting.h
|
${QET_DIR}/sources/scripting/qetscripting.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(QET_SPACEMOUSE_ENABLED)
|
||||||
|
list(APPEND QET_SRC_FILES
|
||||||
|
${QET_DIR}/sources/spacemouse/spacemousebackend.h
|
||||||
|
${QET_DIR}/sources/spacemouse/spacemousebuttonmap.cpp
|
||||||
|
${QET_DIR}/sources/spacemouse/spacemousebuttonmap.h
|
||||||
|
${QET_DIR}/sources/spacemouse/spacemouselistener.cpp
|
||||||
|
${QET_DIR}/sources/spacemouse/spacemouselistener.h
|
||||||
|
${QET_DIR}/sources/ui/configpage/spacemouseconfigpage.cpp
|
||||||
|
${QET_DIR}/sources/ui/configpage/spacemouseconfigpage.h
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(QET_SPACEMOUSE_BACKEND_SPNAV_ENABLED)
|
||||||
|
list(APPEND QET_SRC_FILES
|
||||||
|
${QET_DIR}/sources/spacemouse/spnavbackend.cpp
|
||||||
|
${QET_DIR}/sources/spacemouse/spnavbackend.h
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
set(TS_FILES
|
set(TS_FILES
|
||||||
${QET_DIR}/lang/qet_ar.ts
|
${QET_DIR}/lang/qet_ar.ts
|
||||||
${QET_DIR}/lang/qet_ca.ts
|
${QET_DIR}/lang/qet_ca.ts
|
||||||
|
|||||||
+1
-1
Submodule elements updated: 60eacc28a6...08e438a919
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,222 @@
|
|||||||
|
<!DOCTYPE QPH>
|
||||||
|
<QPH sourcelanguage="fr_FR" language="ca">
|
||||||
|
<phrase>
|
||||||
|
<source>Réf. croisée</source>
|
||||||
|
<target>Ref. creuada</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>armoire</source>
|
||||||
|
<target>armari</target>
|
||||||
|
<definition>cabinet / enclosure</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>bobine</source>
|
||||||
|
<target>bobina</target>
|
||||||
|
<definition>coil</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>borne</source>
|
||||||
|
<target>born</target>
|
||||||
|
<definition>terminal - a connection point on a symbol</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>bornier</source>
|
||||||
|
<target>bornes</target>
|
||||||
|
<definition>terminal strip</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>cable</source>
|
||||||
|
<target>cable</target>
|
||||||
|
<definition>cable</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>calibre</source>
|
||||||
|
<target>calibre</target>
|
||||||
|
<definition>rating - the current rating of a device</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>cartouche</source>
|
||||||
|
<target>cartutx</target>
|
||||||
|
<definition>title block - the framed information panel</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>champ de texte</source>
|
||||||
|
<target>camp de text</target>
|
||||||
|
<definition>text field</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>collection</source>
|
||||||
|
<target>col·lecció</target>
|
||||||
|
<definition>collection - the symbol library</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>conducteur</source>
|
||||||
|
<target>conductor</target>
|
||||||
|
<definition>conductor - the drawn wire between terminals</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>contact</source>
|
||||||
|
<target>contacte</target>
|
||||||
|
<definition>contact</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>contacteur</source>
|
||||||
|
<target>contactor</target>
|
||||||
|
<definition>contactor</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>courant</source>
|
||||||
|
<target>corrent</target>
|
||||||
|
<definition>current</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>disjoncteur</source>
|
||||||
|
<target>disjuntor</target>
|
||||||
|
<definition>circuit breaker</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>dossier</source>
|
||||||
|
<target>carpeta</target>
|
||||||
|
<definition>folder</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>element</source>
|
||||||
|
<target>element</target>
|
||||||
|
<definition>element - a symbol placed on a sheet</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>esclave</source>
|
||||||
|
<target>esclau</target>
|
||||||
|
<definition>slave - the contact block belonging to a master</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>fil</source>
|
||||||
|
<target>fil</target>
|
||||||
|
<definition>wire</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>folio</source>
|
||||||
|
<target>plec</target>
|
||||||
|
<definition>sheet - one drawing of a set</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>fusible</source>
|
||||||
|
<target>fusible</target>
|
||||||
|
<definition>fuse</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>grille</source>
|
||||||
|
<target>graella</target>
|
||||||
|
<definition>grid</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>interrupteur</source>
|
||||||
|
<target>interruptor</target>
|
||||||
|
<definition>switch</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>maitre</source>
|
||||||
|
<target>mestre</target>
|
||||||
|
<definition>master - the element a cross-reference points from</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>modele</source>
|
||||||
|
<target>plantilla</target>
|
||||||
|
<definition>template</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>moteur</source>
|
||||||
|
<target>motor</target>
|
||||||
|
<definition>motor</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>neutre</source>
|
||||||
|
<target>neutre</target>
|
||||||
|
<definition>neutral</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>nomenclature</source>
|
||||||
|
<target>nomenclatura</target>
|
||||||
|
<definition>parts list / bill of materials</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>numerotation</source>
|
||||||
|
<target>numeració</target>
|
||||||
|
<definition>numbering - automatic wire and part numbering</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>phase</source>
|
||||||
|
<target>fase</target>
|
||||||
|
<definition>phase</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>potentiel</source>
|
||||||
|
<target>potencial</target>
|
||||||
|
<definition>potential - conductors electrically joined as one node</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>projet</source>
|
||||||
|
<target>projecte</target>
|
||||||
|
<definition>project - the .qet file holding the sheets</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>puissance</source>
|
||||||
|
<target>potència</target>
|
||||||
|
<definition>power</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>relais</source>
|
||||||
|
<target>relé</target>
|
||||||
|
<definition>relay</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>renvoi de folio</source>
|
||||||
|
<target>referència de plec</target>
|
||||||
|
<definition>sheet cross-reference</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>repere</source>
|
||||||
|
<target>referència</target>
|
||||||
|
<definition>designation - the identifying mark on a part</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>report de folio</source>
|
||||||
|
<target>remissió de plec</target>
|
||||||
|
<definition>sheet cross-reference (the arrow symbol)</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>schema</source>
|
||||||
|
<target>esquema</target>
|
||||||
|
<definition>diagram</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>section</source>
|
||||||
|
<target>secció</target>
|
||||||
|
<definition>cross-section - conductor size in mm2</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>sommaire</source>
|
||||||
|
<target>sumari</target>
|
||||||
|
<definition>summary / table of contents</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>tension</source>
|
||||||
|
<target>tensió</target>
|
||||||
|
<definition>voltage</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>terre</source>
|
||||||
|
<target>terra</target>
|
||||||
|
<definition>earth / ground</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>texte</source>
|
||||||
|
<target>text</target>
|
||||||
|
<definition>text</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>transformateur</source>
|
||||||
|
<target>transformador</target>
|
||||||
|
<definition>transformer</definition>
|
||||||
|
</phrase>
|
||||||
|
</QPH>
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -100,4 +100,8 @@
|
|||||||
<source>traduction</source>
|
<source>traduction</source>
|
||||||
<target>Übersetzung</target>
|
<target>Übersetzung</target>
|
||||||
</phrase>
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Modifier le nom de la borne</source>
|
||||||
|
<target>Klemmenname ändern</target>
|
||||||
|
</phrase>
|
||||||
</QPH>
|
</QPH>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,918 @@
|
|||||||
|
<!DOCTYPE QPH>
|
||||||
|
<QPH sourcelanguage="fr_FR" language="en">
|
||||||
|
<phrase>
|
||||||
|
<source>Blue : Blue</source>
|
||||||
|
<target>Blue : Blue</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Blue : CornflowerBlue</source>
|
||||||
|
<target>Blue : CornflowerBlue</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Blue : DarkBlue</source>
|
||||||
|
<target>Blue : DarkBlue</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Blue : DeepSkyBlue</source>
|
||||||
|
<target>Blue : DeepSkyBlue</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Blue : DodgerBlue</source>
|
||||||
|
<target>Blue : DodgerBlue</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Blue : LightBlue</source>
|
||||||
|
<target>Blue : LightBlue</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Blue : LightSkyBlue</source>
|
||||||
|
<target>Blue : LightSkyBlue</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Blue : LightSteelBlue</source>
|
||||||
|
<target>Blue : LightSteelBlue</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Blue : MediumBlue</source>
|
||||||
|
<target>Blue : MediumBlue</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Blue : MidnightBlue</source>
|
||||||
|
<target>Blue : MidnightBlue</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Blue : Navy</source>
|
||||||
|
<target>Blue : Navy</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Blue : PowderBlue</source>
|
||||||
|
<target>Blue : PowderBlue</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Blue : RoyalBlue</source>
|
||||||
|
<target>Blue : RoyalBlue</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Blue : SkyBlue</source>
|
||||||
|
<target>Blue : SkyBlue</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Blue : SteelBlue</source>
|
||||||
|
<target>Blue : SteelBlue</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Brown : Bisque</source>
|
||||||
|
<target>Brown : Bisque</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Brown : BlanchedAlmond</source>
|
||||||
|
<target>Brown : BlanchedAlmond</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Brown : Brown</source>
|
||||||
|
<target>Brown : Brown</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Brown : Burlywood</source>
|
||||||
|
<target>Brown : Burlywood</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Brown : Chocolate</source>
|
||||||
|
<target>Brown : Chocolate</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Brown : Cornsilk</source>
|
||||||
|
<target>Brown : Cornsilk</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Brown : DarkGoldenrod</source>
|
||||||
|
<target>Brown : DarkGoldenrod</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Brown : Goldenrod</source>
|
||||||
|
<target>Brown : Goldenrod</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Brown : Maroon</source>
|
||||||
|
<target>Brown : Maroon</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Brown : NavajoWhite</source>
|
||||||
|
<target>Brown : NavajoWhite</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Brown : Peru</source>
|
||||||
|
<target>Brown : Peru</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Brown : RosyBrown</source>
|
||||||
|
<target>Brown : RosyBrown</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Brown : SaddleBrown</source>
|
||||||
|
<target>Brown : SaddleBrown</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Brown : SandyBrown</source>
|
||||||
|
<target>Brown : SandyBrown</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Brown : Sienna</source>
|
||||||
|
<target>Brown : Sienna</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Brown : Tan</source>
|
||||||
|
<target>Brown : Tan</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Brown : Wheat</source>
|
||||||
|
<target>Brown : Wheat</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Cyan : Aqua</source>
|
||||||
|
<target>Cyan : Aqua</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Cyan : Aquamarine</source>
|
||||||
|
<target>Cyan : Aquamarine</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Cyan : CadetBlue</source>
|
||||||
|
<target>Cyan : CadetBlue</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Cyan : Cyan</source>
|
||||||
|
<target>Cyan : Cyan</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Cyan : DarkCyan</source>
|
||||||
|
<target>Cyan : DarkCyan</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Cyan : DarkTurquoise</source>
|
||||||
|
<target>Cyan : DarkTurquoise</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Cyan : LightCyan</source>
|
||||||
|
<target>Cyan : LightCyan</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Cyan : LightSeaGreen</source>
|
||||||
|
<target>Cyan : LightSeaGreen</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Cyan : MediumTurquoise</source>
|
||||||
|
<target>Cyan : MediumTurquoise</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Cyan : PaleTurquoise</source>
|
||||||
|
<target>Cyan : PaleTurquoise</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Cyan : Teal</source>
|
||||||
|
<target>Cyan : Teal</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Cyan : Turquoise</source>
|
||||||
|
<target>Cyan : Turquoise</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Gray : Black</source>
|
||||||
|
<target>Gray : Black</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Gray : DarkGray</source>
|
||||||
|
<target>Gray : DarkGray</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Gray : DarkSlateGray</source>
|
||||||
|
<target>Gray : DarkSlateGray</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Gray : DimGray</source>
|
||||||
|
<target>Gray : DimGray</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Gray : Gainsboro</source>
|
||||||
|
<target>Gray : Gainsboro</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Gray : Gray</source>
|
||||||
|
<target>Gray : Gray</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Gray : LightGray</source>
|
||||||
|
<target>Gray : LightGray</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Gray : LightSlateGray</source>
|
||||||
|
<target>Gray : LightSlateGray</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Gray : Silver</source>
|
||||||
|
<target>Gray : Silver</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Gray : SlateGray</source>
|
||||||
|
<target>Gray : SlateGray</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Green : Chartreuse</source>
|
||||||
|
<target>Green : Chartreuse</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Green : DarkGreen</source>
|
||||||
|
<target>Green : DarkGreen</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Green : DarkOliveGreen</source>
|
||||||
|
<target>Green : DarkOliveGreen</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Green : DarkSeaGreen</source>
|
||||||
|
<target>Green : DarkSeaGreen</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Green : ForestGreen</source>
|
||||||
|
<target>Green : ForestGreen</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Green : Green</source>
|
||||||
|
<target>Green : Green</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Green : GreenYellow</source>
|
||||||
|
<target>Green : GreenYellow</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Green : LawnGreen</source>
|
||||||
|
<target>Green : LawnGreen</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Green : LightGreen</source>
|
||||||
|
<target>Green : LightGreen</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Green : Lime</source>
|
||||||
|
<target>Green : Lime</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Green : LimeGreen</source>
|
||||||
|
<target>Green : LimeGreen</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Green : MediumAquamarine</source>
|
||||||
|
<target>Green : MediumAquamarine</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Green : MediumSeaGreen</source>
|
||||||
|
<target>Green : MediumSeaGreen</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Green : MediumSpringGreen</source>
|
||||||
|
<target>Green : MediumSpringGreen</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Green : Olive</source>
|
||||||
|
<target>Green : Olive</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Green : OliveDrab</source>
|
||||||
|
<target>Green : OliveDrab</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Green : PaleGreen</source>
|
||||||
|
<target>Green : PaleGreen</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Green : SeaGreen</source>
|
||||||
|
<target>Green : SeaGreen</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Green : SpringGreen</source>
|
||||||
|
<target>Green : SpringGreen</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Green : YellowGreen</source>
|
||||||
|
<target>Green : YellowGreen</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Orange : Coral</source>
|
||||||
|
<target>Orange : Coral</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Orange : DarkOrange</source>
|
||||||
|
<target>Orange : DarkOrange</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Orange : Orange</source>
|
||||||
|
<target>Orange : Orange</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Orange : OrangeRed</source>
|
||||||
|
<target>Orange : OrangeRed</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Orange : Tomato</source>
|
||||||
|
<target>Orange : Tomato</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Pink : DeepPink</source>
|
||||||
|
<target>Pink: DeepPink</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Pink : HotPink</source>
|
||||||
|
<target>Pink: HotPink</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Pink : LightPink</source>
|
||||||
|
<target>Pink: LightPink</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Pink : MediumVioletRed</source>
|
||||||
|
<target>Pink: MediumVioletRed</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Pink : PaleVioletRed</source>
|
||||||
|
<target>Pink: PaleVioletRed</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Pink : Pink</source>
|
||||||
|
<target>Pink: Pink</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Purple : BlueViolet</source>
|
||||||
|
<target>Purple : BlueViolet</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Purple : DarkMagenta</source>
|
||||||
|
<target>Purple : DarkMagenta</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Purple : DarkOrchid</source>
|
||||||
|
<target>Purple : DarkOrchid</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Purple : DarkSlateBlue</source>
|
||||||
|
<target>Purple : DarkSlateBlue</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Purple : DarkViolet</source>
|
||||||
|
<target>Purple : DarkViolet</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Purple : Fuchsia</source>
|
||||||
|
<target>Purple : Fuchsia</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Purple : Indigo</source>
|
||||||
|
<target>Purple : Indigo</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Purple : Lavender</source>
|
||||||
|
<target>Purple : Lavender</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Purple : Magenta</source>
|
||||||
|
<target>Purple : Magenta</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Purple : MediumOrchid</source>
|
||||||
|
<target>Purple : MediumOrchid</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Purple : MediumPurple</source>
|
||||||
|
<target>Purple : MediumPurple</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Purple : MediumSlateBlue</source>
|
||||||
|
<target>Purple : MediumSlateBlue</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Purple : Orchid</source>
|
||||||
|
<target>Purple : Orchid</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Purple : Plum</source>
|
||||||
|
<target>Purple : Plum</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Purple : Purple</source>
|
||||||
|
<target>Purple : Purple</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Purple : SlateBlue</source>
|
||||||
|
<target>Purple : SlateBlue</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Purple : Thistle</source>
|
||||||
|
<target>Purple : Thistle</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Purple : Violet</source>
|
||||||
|
<target>Purple : Violet</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Red : Crimson</source>
|
||||||
|
<target>Red : Crimson</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Red : DarkRed</source>
|
||||||
|
<target>Red : DarkRed</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Red : DarkSalmon</source>
|
||||||
|
<target>Red: DarkSalmon</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Red : Firebrick</source>
|
||||||
|
<target>Red : Firebrick</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Red : IndianRed</source>
|
||||||
|
<target>Red: IndianRed</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Red : LightCoral</source>
|
||||||
|
<target>Red: LightCoral</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Red : LightSalmon</source>
|
||||||
|
<target>Red: LightSalmon</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Red : Red</source>
|
||||||
|
<target>Red : Red</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Red : Salmon</source>
|
||||||
|
<target>Red: Salmon</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>White : AliceBlue</source>
|
||||||
|
<target>White : AliceBlue</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>White : AntiqueWhite</source>
|
||||||
|
<target>White : AntiqueWhite</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>White : Azure</source>
|
||||||
|
<target>White : Azure</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>White : Beige</source>
|
||||||
|
<target>White : Beige</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>White : FloralWhite</source>
|
||||||
|
<target>White : FloralWhite</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>White : GhostWhite</source>
|
||||||
|
<target>White : GhostWhite</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>White : Honeydew</source>
|
||||||
|
<target>White : Honeydew</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>White : Ivory</source>
|
||||||
|
<target>White : Ivory</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>White : LavenderBlush</source>
|
||||||
|
<target>White : LavenderBlush</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>White : Linen</source>
|
||||||
|
<target>White : Linen</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>White : MintCream</source>
|
||||||
|
<target>White : MintCream</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>White : MistyRose</source>
|
||||||
|
<target>White : MistyRose</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>White : OldLace</source>
|
||||||
|
<target>White : OldLace</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>White : Seashell</source>
|
||||||
|
<target>White : Seashell</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>White : Snow</source>
|
||||||
|
<target>White : Snow</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>White : White</source>
|
||||||
|
<target>White : White</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>White : WhiteSmoke</source>
|
||||||
|
<target>White : WhiteSmoke</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Yellow : DarkKhaki</source>
|
||||||
|
<target>Yellow : DarkKhaki</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Yellow : Gold</source>
|
||||||
|
<target>Yellow : Gold</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Yellow : Khaki</source>
|
||||||
|
<target>Yellow : Khaki</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Yellow : LemonChiffon</source>
|
||||||
|
<target>Yellow : LemonChiffon</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Yellow : LightGoldenrodYellow</source>
|
||||||
|
<target>Yellow : LightGoldenrodYellow</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Yellow : LightYellow</source>
|
||||||
|
<target>Yellow : LightYellow</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Yellow : Moccasin</source>
|
||||||
|
<target>Yellow : Moccasin</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Yellow : PaleGoldenrod</source>
|
||||||
|
<target>Yellow : PaleGoldenrod</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Yellow : PapayaWhip</source>
|
||||||
|
<target>Yellow : PapayaWhip</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Yellow : PeachPuff</source>
|
||||||
|
<target>Yellow : PeachPuff</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Yellow : Yellow</source>
|
||||||
|
<target>Yellow : Yellow</target>
|
||||||
|
<definition>element part filling</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>armoire</source>
|
||||||
|
<target>cabinet</target>
|
||||||
|
<definition>cabinet / enclosure</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>bobine</source>
|
||||||
|
<target>coil</target>
|
||||||
|
<definition>coil</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>borne</source>
|
||||||
|
<target>terminal</target>
|
||||||
|
<definition>terminal - a connection point on a symbol</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>bornier</source>
|
||||||
|
<target>terminal strip</target>
|
||||||
|
<definition>terminal strip</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>cable</source>
|
||||||
|
<target>cable</target>
|
||||||
|
<definition>cable</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>calibre</source>
|
||||||
|
<target>rating</target>
|
||||||
|
<definition>rating - the current rating of a device</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>cartouche</source>
|
||||||
|
<target>title block</target>
|
||||||
|
<definition>title block - the framed information panel</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>champ de texte</source>
|
||||||
|
<target>text field</target>
|
||||||
|
<definition>text field</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>collection</source>
|
||||||
|
<target>collection</target>
|
||||||
|
<definition>collection - the symbol library</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>conducteur</source>
|
||||||
|
<target>conductor</target>
|
||||||
|
<definition>conductor - the drawn wire between terminals</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>contact</source>
|
||||||
|
<target>contact</target>
|
||||||
|
<definition>contact</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>contacteur</source>
|
||||||
|
<target>contactor</target>
|
||||||
|
<definition>contactor</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>courant</source>
|
||||||
|
<target>current</target>
|
||||||
|
<definition>current</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>disjoncteur</source>
|
||||||
|
<target>circuit breaker</target>
|
||||||
|
<definition>circuit breaker</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>dossier</source>
|
||||||
|
<target>folder</target>
|
||||||
|
<definition>folder</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>element</source>
|
||||||
|
<target>element</target>
|
||||||
|
<definition>element - a symbol placed on a sheet</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>esclave</source>
|
||||||
|
<target>slave</target>
|
||||||
|
<definition>slave - the contact block belonging to a master</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>fil</source>
|
||||||
|
<target>wire</target>
|
||||||
|
<definition>wire</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>folio</source>
|
||||||
|
<target>sheet</target>
|
||||||
|
<definition>sheet - one drawing of a set</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>fusible</source>
|
||||||
|
<target>fuse</target>
|
||||||
|
<definition>fuse</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>grille</source>
|
||||||
|
<target>grid</target>
|
||||||
|
<definition>grid</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>interrupteur</source>
|
||||||
|
<target>switch</target>
|
||||||
|
<definition>switch</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>maitre</source>
|
||||||
|
<target>master</target>
|
||||||
|
<definition>master - the element a cross-reference points from</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>modele</source>
|
||||||
|
<target>template</target>
|
||||||
|
<definition>template</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>moteur</source>
|
||||||
|
<target>motor</target>
|
||||||
|
<definition>motor</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>neutre</source>
|
||||||
|
<target>neutral</target>
|
||||||
|
<definition>neutral</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>nomenclature</source>
|
||||||
|
<target>parts list</target>
|
||||||
|
<definition>parts list / bill of materials</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>numerotation</source>
|
||||||
|
<target>numbering</target>
|
||||||
|
<definition>numbering - automatic wire and part numbering</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>phase</source>
|
||||||
|
<target>phase</target>
|
||||||
|
<definition>phase</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>potentiel</source>
|
||||||
|
<target>potential</target>
|
||||||
|
<definition>potential - conductors electrically joined as one node</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>projet</source>
|
||||||
|
<target>project</target>
|
||||||
|
<definition>project - the .qet file holding the sheets</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>puissance</source>
|
||||||
|
<target>power</target>
|
||||||
|
<definition>power</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>relais</source>
|
||||||
|
<target>relay</target>
|
||||||
|
<definition>relay</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>renvoi de folio</source>
|
||||||
|
<target>sheet cross-reference</target>
|
||||||
|
<definition>sheet cross-reference</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>repere</source>
|
||||||
|
<target>designation</target>
|
||||||
|
<definition>designation - the identifying mark on a part</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>report de folio</source>
|
||||||
|
<target>sheet cross-reference</target>
|
||||||
|
<definition>sheet cross-reference (the arrow symbol)</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>schema</source>
|
||||||
|
<target>diagram</target>
|
||||||
|
<definition>diagram</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>section</source>
|
||||||
|
<target>cross-section</target>
|
||||||
|
<definition>cross-section - conductor size in mm2</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>sommaire</source>
|
||||||
|
<target>summary</target>
|
||||||
|
<definition>summary / table of contents</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>tension</source>
|
||||||
|
<target>voltage</target>
|
||||||
|
<definition>voltage</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>terre</source>
|
||||||
|
<target>earth</target>
|
||||||
|
<definition>earth / ground</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>texte</source>
|
||||||
|
<target>text</target>
|
||||||
|
<definition>text</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>transformateur</source>
|
||||||
|
<target>transformer</target>
|
||||||
|
<definition>transformer</definition>
|
||||||
|
</phrase>
|
||||||
|
</QPH>
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,941 @@
|
|||||||
|
<!DOCTYPE QPH>
|
||||||
|
<QPH sourcelanguage="fr_FR" language="nl_BE">
|
||||||
|
<phrase>
|
||||||
|
<source> Contacts : NO : %1, NC : %2, inverseurs : %3, autres : %4
|
||||||
|
</source>
|
||||||
|
<target>Contacten: NO: %1, NC: %2, wisselcontacten: %3, andere: %4
|
||||||
|
</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source> Contacts : NO : %1/%2, NC : %3/%4, inverseurs : %5/%6, autres : %7/%8
|
||||||
|
</source>
|
||||||
|
<target>Contacten: NO: %1/%2, NC: %3/%4, wisselcontacten: %5/%6, andere: %7/%8
|
||||||
|
</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source> %</source>
|
||||||
|
<target>%</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source> (Ctrl pendant le glissement = position libre, sans accrochage à la grille)</source>
|
||||||
|
<target>(Ctrl tijdens het slepen = vrije positie, zonder vastklikken aan het raster)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source> -- %1 : mode %2</source>
|
||||||
|
<target>-- %1 : modus %2</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source> ; point rouge : glisser pour repositionner le centre de rotation</source>
|
||||||
|
<target>; rood punt: slepen om het draaipunt te verplaatsen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source> ; point turquoise : arc</source>
|
||||||
|
<target>; turquoise punt: boog</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source> ; un bord : inclinaison</source>
|
||||||
|
<target>; een rand: kanteling</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source> °</source>
|
||||||
|
<target>°</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source> — Cliquer : mode %1</source>
|
||||||
|
<target>— Klikken: modus %1</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>, Alt = créer des poignées</source>
|
||||||
|
<target>, Alt = handgrepen creëren</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>, Alt = détacher en polyligne</source>
|
||||||
|
<target>, Alt = losmaken als polylijn</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Ajoute une courbe de Bézier sur le folio actuel</source>
|
||||||
|
<target>Voegt een Béziercurve toe op het huidige blad</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Ajouter la borne %1</source>
|
||||||
|
<target>Klem %1 toevoegen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Ajouter un point à une courbe</source>
|
||||||
|
<target>Een punt aan een curve toevoegen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Ajouter une courbe</source>
|
||||||
|
<target>Een curve toevoegen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Angle</source>
|
||||||
|
<target>Hoek</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Anguleux</source>
|
||||||
|
<target>Hoekig</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Aperçu</source>
|
||||||
|
<target>Voorbeeld</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Arrondir les coins d'%1</source>
|
||||||
|
<target>Hoeken van %1 afronden</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Borne 1</source>
|
||||||
|
<target>Klem 1</target>
|
||||||
|
<definition>column title</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Borne 2</source>
|
||||||
|
<target>Klem 2</target>
|
||||||
|
<definition>column title</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Catégorie</source>
|
||||||
|
<target>Categorie</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Ce format ne prend pas en charge la transparence : l'image sera enregistrée telle qu'elle était avant l'application de la couleur transparente. Continuer ?</source>
|
||||||
|
<target>Dit formaat ondersteunt geen transparantie: de afbeelding wordt opgeslagen zoals ze was vóór het toepassen van de transparante kleur. Doorgaan?</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Champ de texte</source>
|
||||||
|
<target>Tekstveld</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Clic : positionner à la taille d'origine. Cliquer-glisser : positionner et redimensionner. Clic droit : pivoter de 90°. Ctrl+molette : ajuster la taille.</source>
|
||||||
|
<target>Klik: op oorspronkelijke grootte plaatsen. Klikken en slepen: plaatsen en formaat wijzigen. Rechtsklik: 90° draaien. Ctrl+muiswiel: formaat aanpassen.</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Clic gauche : point suivant ; double-clic ou Entrée : terminer ; clic droit : annuler le dernier point</source>
|
||||||
|
<target>Linkerklik: volgend punt; dubbelklik of Enter: beëindigen; rechtsklik: laatste punt annuleren</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Clic gauche : positionner le coin opposé (Maj = carré, Ctrl = depuis le centre + position libre, Ctrl+Maj = carré centré) ; clic droit : annuler</source>
|
||||||
|
<target>Linkerklik: tegenoverliggende hoek plaatsen (Shift = vierkant, Ctrl = vanuit het midden + vrije positie, Ctrl+Shift = gecentreerd vierkant); rechtsklik: annuleren</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Clic gauche : positionner le coin opposé (Maj = cercle, Ctrl = depuis le centre + position libre, Ctrl+Maj = cercle centré) ; clic droit : annuler</source>
|
||||||
|
<target>Linkerklik: tegenoverliggende hoek plaatsen (Shift = cirkel, Ctrl = vanuit het midden + vrije positie, Ctrl+Shift = gecentreerde cirkel); rechtsklik: annuleren</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Clic gauche : positionner le point de départ (Ctrl = position libre)</source>
|
||||||
|
<target>Linkerklik: startpunt plaatsen (Ctrl = vrije positie)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Clic gauche : positionner le point final (Ctrl = position libre) ; clic droit : annuler</source>
|
||||||
|
<target>Linkerklik: eindpunt plaatsen (Ctrl = vrije positie); rechtsklik: annuleren</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Clic gauche : positionner le premier coin (Ctrl = point central, position libre)</source>
|
||||||
|
<target>Linkerklik: eerste hoek plaatsen (Ctrl = middelpunt, vrije positie)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Clic gauche : positionner le premier point (Ctrl = position libre)</source>
|
||||||
|
<target>Linkerklik: eerste punt plaatsen (Ctrl = vrije positie)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Clic: point anguleux. Cliquer-glisser: point courbe. Clic sur le premier point: fermer. Échap/Entrée: terminer. Clic droit: annuler le dernier point.</source>
|
||||||
|
<target>Klik: hoekpunt. Klikken en slepen: curvepunt. Klik op het eerste punt: sluiten. Esc/Enter: beëindigen. Rechtsklik: laatste punt annuleren.</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Cliquer</source>
|
||||||
|
<target>Klikken</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Cliquer : mode %1</source>
|
||||||
|
<target>Klikken: modus %1</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Cliquez pour choisir une couleur</source>
|
||||||
|
<target>Klik om een kleur te kiezen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Cliquez sur l'image pour ajouter une couleur. Ajustez la tolérance de chaque couleur avec son curseur, ou cliquez sur × pour la retirer.</source>
|
||||||
|
<target>Klik op de afbeelding om een kleur toe te voegen. Pas de tolerantie van elke kleur aan met de schuifregelaar, of klik op × om ze te verwijderen.</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Cliquez sur l'image pour choisir une couleur</source>
|
||||||
|
<target>Klik op de afbeelding om een kleur te kiezen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Coins arrondis</source>
|
||||||
|
<target>Afgeronde hoeken</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Composant 1</source>
|
||||||
|
<target>Component 1</target>
|
||||||
|
<definition>column title</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Composant 2</source>
|
||||||
|
<target>Component 2</target>
|
||||||
|
<definition>column title</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Convertir %1 en courbe de Bézier</source>
|
||||||
|
<target>%1 omzetten naar Béziercurve</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Convertir %1 en polyligne</source>
|
||||||
|
<target>%1 omzetten naar polylijn</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Convertir en courbe de Bézier</source>
|
||||||
|
<target>Omzetten naar Béziercurve</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Convertir en polyligne</source>
|
||||||
|
<target>Omzetten naar polylijn</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Couleur transparente</source>
|
||||||
|
<target>Transparante kleur</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Couleur transparente...</source>
|
||||||
|
<target>Transparante kleur...</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Courant nominal</source>
|
||||||
|
<target>Nominale stroom</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Deplacer le centre de rotation</source>
|
||||||
|
<target>Draaipunt verplaatsen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Description</source>
|
||||||
|
<target>Beschrijving</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Distance in pixels between the label and the slave cross reference</source>
|
||||||
|
<target>Afstand in pixels tussen het label en de slave-kruisverwijzing</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Distance label - slave :</source>
|
||||||
|
<target>Afstand label - slave:</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Définir une couleur transparente</source>
|
||||||
|
<target>Een transparante kleur instellen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Déformer une courbe</source>
|
||||||
|
<target>Een curve vervormen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Déplacer le centre de rotation d'une image</source>
|
||||||
|
<target>Het draaipunt van een afbeelding verplaatsen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Déverrouillé : largeur et hauteur peuvent être modifiées indépendamment. Cliquer pour verrouiller.</source>
|
||||||
|
<target>Ontgrendeld: breedte en hoogte kunnen onafhankelijk worden gewijzigd. Klik om te vergrendelen.</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Enregistrer l'image d'origine sous...</source>
|
||||||
|
<target>Oorspronkelijke afbeelding opslaan als...</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Enregistrer l'image sous...</source>
|
||||||
|
<target>Afbeelding opslaan als...</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Erreur</source>
|
||||||
|
<target>Fout</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Exclure de la nomenclature</source>
|
||||||
|
<target>Uitsluiten van de stuklijst</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Faire pivoter %1</source>
|
||||||
|
<target>%1 roteren</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Faire pivoter une image</source>
|
||||||
|
<target>Een afbeelding draaien</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Faites glisser les poignées, ou l'intérieur du cadre, pour ajuster la zone à conserver.</source>
|
||||||
|
<target>Sleep de handgrepen, of het binnenste van het kader, om het te behouden gebied aan te passen.</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Fil</source>
|
||||||
|
<target>Draad</target>
|
||||||
|
<definition>column title</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Folio</source>
|
||||||
|
<target>Blad</target>
|
||||||
|
<definition>column title</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Forme fermée</source>
|
||||||
|
<target>Gesloten vorm</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser %1 : rotation (Maj = 15°)</source>
|
||||||
|
<target>Sleep %1: rotatie (Shift = 15°)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser : ajuster l'arc (Ctrl = position libre, Maj = 15°)</source>
|
||||||
|
<target>Slepen: de boog aanpassen (Ctrl = vrije positie, Shift = 15°)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser : arrondir les coins (Ctrl = position libre)</source>
|
||||||
|
<target>Slepen: hoeken afronden (Ctrl = vrije positie)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser : déformer la courbe (Ctrl = position libre, Alt = briser la tangente)</source>
|
||||||
|
<target>Slepen: de curve vervormen (Ctrl = vrije positie, Alt = de raaklijn breken)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser : déplacer ce point</source>
|
||||||
|
<target>Slepen: dit punt verplaatsen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser : déplacer le centre de rotation</source>
|
||||||
|
<target>Slepen: draaipunt verplaatsen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser : déplacer le point (Ctrl = position libre</source>
|
||||||
|
<target>Slepen: het punt verplaatsen (Ctrl = vrije positie</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser : inclinaison (Ctrl = position libre, Maj = 15°)</source>
|
||||||
|
<target>Slepen: kanteling (Ctrl = vrije positie, Shift = 15°)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser : incliner (Maj = par pas de 15°)</source>
|
||||||
|
<target>Slepen: kantelen (Shift = stappen van 15°)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser : pivoter (Maj = par pas de 15°)</source>
|
||||||
|
<target>Slepen: draaien (Shift = stappen van 15°)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser : redimensionner (Ctrl = depuis le centre + position libre, Maj = proportions</source>
|
||||||
|
<target>Slepen: formaat wijzigen (Ctrl = vanuit het midden + vrije positie, Shift = verhoudingen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser : redimensionner (Maj = conserver les proportions, Ctrl = depuis le centre)</source>
|
||||||
|
<target>Slepen: formaat wijzigen (Shift = verhoudingen behouden, Ctrl = vanuit het midden)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser : repositionner le centre de rotation (Ctrl = position libre)</source>
|
||||||
|
<target>Slepen: het draaipunt verplaatsen (Ctrl = vrije positie)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser : rotation (Ctrl = position libre, Maj = 15°)</source>
|
||||||
|
<target>Slepen: rotatie (Ctrl = vrije positie, Shift = 15°)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser le point violet : arrondir les coins</source>
|
||||||
|
<target>Sleep het paarse punt: hoeken afronden</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser un coin : pivoter (Maj = par pas de 15°) ; glisser un bord : incliner (Maj = par pas de 15°) ; point rouge : déplacer le centre de rotation</source>
|
||||||
|
<target>Sleep een hoek: draaien (Shift = stappen van 15°); sleep een rand: kantelen (Shift = stappen van 15°); rood punt: draaipunt verplaatsen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser un coin/bord : redimensionner (Ctrl = depuis le centre, Maj = conserver les proportions)</source>
|
||||||
|
<target>Sleep een hoek/rand: formaat wijzigen (Ctrl = vanuit het midden, Shift = verhoudingen behouden)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser un coin/bord : redimensionner (Ctrl = depuis le centre, Maj = proportions, Alt = détacher en polyligne)</source>
|
||||||
|
<target>Sleep een hoek/rand: formaat wijzigen (Ctrl = vanuit het midden, Shift = verhoudingen, Alt = losmaken als polylijn)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser un point : le déplacer</source>
|
||||||
|
<target>Sleep een punt: het verplaatsen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser une extrémité : la déplacer</source>
|
||||||
|
<target>Sleep een uiteinde: het verplaatsen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser une poignée ou la courbe : déformer (Alt = briser la tangente) ; Alt+glisser un point anguleux : créer des poignées ; clic droit : menu du nœud le plus proche</source>
|
||||||
|
<target>Sleep een handgreep of de curve: vervormen (Alt = de raaklijn breken); Alt+sleep een hoekpunt: handgrepen creëren; rechtsklik: menu van het dichtstbijzijnde knooppunt</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Géométrie</source>
|
||||||
|
<target>Geometrie</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Hauteur</source>
|
||||||
|
<target>Hoogte</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Image BMP (*.bmp)</source>
|
||||||
|
<target>BMP-afbeelding (*.bmp)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Image Files (*.png *.jpg *.jpeg *.bmp *.svg)</source>
|
||||||
|
<target>Afbeeldingsbestanden (*.png *.jpg *.jpeg *.bmp *.svg)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Image JPEG (*.jpg *.jpeg)</source>
|
||||||
|
<target>JPEG-afbeelding (*.jpg *.jpeg)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Image PNG (*.png)</source>
|
||||||
|
<target>PNG-afbeelding (*.png)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Image source</source>
|
||||||
|
<target>Bronafbeelding</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Image SVG (*.svg)</source>
|
||||||
|
<target>SVG-afbeelding (*.svg)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Images non incluses dans l'export DXF</source>
|
||||||
|
<target>Afbeeldingen niet inbegrepen in de DXF-export</target>
|
||||||
|
<definition>message box title</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Impossible d'enregistrer l'image à cet emplacement.</source>
|
||||||
|
<target>Kan de afbeelding niet op die locatie opslaan.</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Impossible d'enregistrer la nomenclature dans %1.
|
||||||
|
%2</source>
|
||||||
|
<target>Kan de stuklijst niet opslaan in %1.
|
||||||
|
%2</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Impossible de charger l'image.</source>
|
||||||
|
<target>Kan de afbeelding niet laden.</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Inclinaison X</source>
|
||||||
|
<target>Kanteling X</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Inclinaison Y</source>
|
||||||
|
<target>Kanteling Y</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Incliner %1</source>
|
||||||
|
<target>%1 kantelen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Incliner une image</source>
|
||||||
|
<target>Een afbeelding kantelen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>La limite fixée pour cet élément maître est atteinte (Limite: %1).
|
||||||
|
|
||||||
|
Voulez-vous tout de même lier ce contact esclave ?</source>
|
||||||
|
<target>De limiet voor dit hoofdelement is bereikt (Limiet: %1).
|
||||||
|
|
||||||
|
Wilt u dit hulpcontact toch koppelen?</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Largeur</source>
|
||||||
|
<target>Breedte</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Le format DXF utilisé ici (AC1006) ne permet pas d'inclure d'image. Les images seront représentées uniquement par un rectangle de contour (position, taille, rotation et inclinaison conservées), sans le contenu de l'image.</source>
|
||||||
|
<target>Het hier gebruikte DXF-formaat (AC1006) laat niet toe afbeeldingen op te nemen. Afbeeldingen worden enkel voorgesteld door een omtrekrechthoek (positie, grootte, rotatie en kanteling behouden), zonder de inhoud van de afbeelding.</target>
|
||||||
|
<definition>message box content</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Lisse</source>
|
||||||
|
<target>Vloeiend</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Liste de câblage</source>
|
||||||
|
<target>Bekabelingslijst</target>
|
||||||
|
<definition>window title</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Liste de câblage (base de données)</source>
|
||||||
|
<target>Bekabelingslijst (database)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Localisation :</source>
|
||||||
|
<target>Locatie:</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Longueur</source>
|
||||||
|
<target>Lengte</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>margin: 5px; font-weight: bold;</source>
|
||||||
|
<target>margin: 5px; font-weight: bold;</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>max:</source>
|
||||||
|
<target>max:</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>min:</source>
|
||||||
|
<target>min:</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Miroir horizontal</source>
|
||||||
|
<target>Horizontaal spiegelen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Miroir horizontal d'une image</source>
|
||||||
|
<target>Horizontaal spiegelen van een afbeelding</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Miroir horizontal de %1</source>
|
||||||
|
<target>Horizontaal spiegelen van %1</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Miroir impossible : inclinaison trop extrême pour cette forme</source>
|
||||||
|
<target>Spiegelen onmogelijk: kanteling te extreem voor deze vorm</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Miroir vertical</source>
|
||||||
|
<target>Verticaal spiegelen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Miroir vertical d'une image</source>
|
||||||
|
<target>Verticaal spiegelen van een afbeelding</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Miroir vertical de %1</source>
|
||||||
|
<target>Verticaal spiegelen van %1</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Modifier l'angle d'un arc</source>
|
||||||
|
<target>Hoek van een boog wijzigen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Modifier l'angle d'une forme</source>
|
||||||
|
<target>Hoek van een vorm wijzigen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Modifier l'angle d'une image</source>
|
||||||
|
<target>De hoek van een afbeelding wijzigen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Modifier l'inclinaison d'une image</source>
|
||||||
|
<target>De kanteling van een afbeelding wijzigen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Modifier la courbure d'%1</source>
|
||||||
|
<target>Kromming van %1 wijzigen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Modifier la forme d'%1</source>
|
||||||
|
<target>Vorm van %1 wijzigen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Modifier la hauteur d'une image</source>
|
||||||
|
<target>De hoogte van een afbeelding wijzigen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Modifier la largeur d'une image</source>
|
||||||
|
<target>De breedte van een afbeelding wijzigen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Modifier la longueur d'une ligne</source>
|
||||||
|
<target>Lengte van een lijn wijzigen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Modifier la taille d'une forme</source>
|
||||||
|
<target>Grootte van een vorm wijzigen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Modifier le type d'un nœud</source>
|
||||||
|
<target>Het type van een knooppunt wijzigen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Modifier une image</source>
|
||||||
|
<target>Een afbeelding wijzigen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Modèle</source>
|
||||||
|
<target>Model</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Nombre maximum de contacts esclaves définis : non défini
|
||||||
|
</source>
|
||||||
|
<target>Maximumaantal gedefinieerde hulpcontacten: niet gedefinieerd
|
||||||
|
</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Notes</source>
|
||||||
|
<target>Notities</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Nœud le plus proche</source>
|
||||||
|
<target>Dichtstbijzijnde knooppunt</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>pivoter/incliner</source>
|
||||||
|
<target>draaien/kantelen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Ponter des bornes entre-elles</source>
|
||||||
|
<target>Klemmen onderling doorverbinden</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Rayon X</source>
|
||||||
|
<target>Straal X</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Rayon Y</source>
|
||||||
|
<target>Straal Y</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>redimensionner</source>
|
||||||
|
<target>formaat wijzigen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Redimensionner %1</source>
|
||||||
|
<target>%1 vergroten/verkleinen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Redimensionner une image</source>
|
||||||
|
<target>Formaat van een afbeelding wijzigen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Remplacer l'image...</source>
|
||||||
|
<target>Afbeelding vervangen...</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Remplacer une image</source>
|
||||||
|
<target>Een afbeelding vervangen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Restaurer les proportions</source>
|
||||||
|
<target>Verhoudingen herstellen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Restaurer les proportions d'une image</source>
|
||||||
|
<target>De verhoudingen van een afbeelding herstellen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Retirer cette couleur</source>
|
||||||
|
<target>Deze kleur verwijderen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Revenir à l'image complète, sans rognage</source>
|
||||||
|
<target>Terug naar de volledige afbeelding, zonder bijsnijden</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>rgb(%1, %2, %3)</source>
|
||||||
|
<target>rgb(%1, %2, %3)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Rogner l'image</source>
|
||||||
|
<target>Afbeelding bijsnijden</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Rogner une image</source>
|
||||||
|
<target>Een afbeelding bijsnijden</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Rogner...</source>
|
||||||
|
<target>Bijsnijden...</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Rotation/Inclinaison</source>
|
||||||
|
<target>Rotatie/kanteling</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Réinitialiser</source>
|
||||||
|
<target>Herinitialiseren</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Selectionner une image...</source>
|
||||||
|
<target>Een afbeelding selecteren...</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Supprimer le nœud le plus proche</source>
|
||||||
|
<target>Het dichtstbijzijnde knooppunt verwijderen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Supprimer un point d'une courbe</source>
|
||||||
|
<target>Een punt van een curve verwijderen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Symétrique</source>
|
||||||
|
<target>Symmetrisch</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Séparation de potentiel</source>
|
||||||
|
<target>Potentiaalscheiding</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Taille</source>
|
||||||
|
<target>Grootte</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Tension nominale</source>
|
||||||
|
<target>Nominale spanning</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Tolérance pour cette couleur</source>
|
||||||
|
<target>Tolerantie voor deze kleur</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Tous les fichiers (*)</source>
|
||||||
|
<target>Alle bestanden (*)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Transformer %1</source>
|
||||||
|
<target>%1 omvormen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Transparence non conservée</source>
|
||||||
|
<target>Transparantie niet behouden</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>un arc</source>
|
||||||
|
<target>een boog</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>un coin</source>
|
||||||
|
<target>een hoek</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>un point</source>
|
||||||
|
<target>een punt</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>une courbe</source>
|
||||||
|
<target>een curve</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>une extrémité</source>
|
||||||
|
<target>een uiteinde</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>une image</source>
|
||||||
|
<target>een afbeelding</target>
|
||||||
|
<definition>part of a sentence listing the content of a diagram</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Verrouiller la numérotation automatique</source>
|
||||||
|
<target>Automatische nummering vergrendelen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Verrouiller la position</source>
|
||||||
|
<target>Positie vergrendelen</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Verrouillé : modifier la largeur ou la hauteur ajuste l'autre pour conserver les proportions. Cliquer pour déverrouiller.</source>
|
||||||
|
<target>Vergrendeld: het wijzigen van de breedte of hoogte past de andere aan om de verhoudingen te behouden. Klik om te ontgrendelen.</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Échec de l'enregistrement</source>
|
||||||
|
<target>Opslaan mislukt</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Édition des nœuds</source>
|
||||||
|
<target>Knooppunten bewerken</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>armoire</source>
|
||||||
|
<target>kast</target>
|
||||||
|
<definition>cabinet / enclosure</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>bobine</source>
|
||||||
|
<target>spoel</target>
|
||||||
|
<definition>coil</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>borne</source>
|
||||||
|
<target>klem</target>
|
||||||
|
<definition>terminal - a connection point on a symbol</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>bornier</source>
|
||||||
|
<target>klemmenstrook</target>
|
||||||
|
<definition>terminal strip</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>cable</source>
|
||||||
|
<target>kabel</target>
|
||||||
|
<definition>cable</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>calibre</source>
|
||||||
|
<target>kaliber</target>
|
||||||
|
<definition>rating - the current rating of a device</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>cartouche</source>
|
||||||
|
<target>titelblok</target>
|
||||||
|
<definition>title block - the framed information panel</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>collection</source>
|
||||||
|
<target>collectie</target>
|
||||||
|
<definition>collection - the symbol library</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>conducteur</source>
|
||||||
|
<target>geleider</target>
|
||||||
|
<definition>conductor - the drawn wire between terminals</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>contact</source>
|
||||||
|
<target>contact</target>
|
||||||
|
<definition>contact</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>contacteur</source>
|
||||||
|
<target>contacteur</target>
|
||||||
|
<definition>contactor</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>courant</source>
|
||||||
|
<target>stroom</target>
|
||||||
|
<definition>current</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>disjoncteur</source>
|
||||||
|
<target>automaat</target>
|
||||||
|
<definition>circuit breaker</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>dossier</source>
|
||||||
|
<target>map</target>
|
||||||
|
<definition>folder</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>element</source>
|
||||||
|
<target>element</target>
|
||||||
|
<definition>element - a symbol placed on a sheet</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>esclave</source>
|
||||||
|
<target>hulpcontact</target>
|
||||||
|
<definition>slave - the contact block belonging to a master</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>fusible</source>
|
||||||
|
<target>zekering</target>
|
||||||
|
<definition>fuse</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>grille</source>
|
||||||
|
<target>raster</target>
|
||||||
|
<definition>grid</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>interrupteur</source>
|
||||||
|
<target>schakelaar</target>
|
||||||
|
<definition>switch</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>maitre</source>
|
||||||
|
<target>hoofd</target>
|
||||||
|
<definition>master - the element a cross-reference points from</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>modele</source>
|
||||||
|
<target>sjabloon</target>
|
||||||
|
<definition>template</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>moteur</source>
|
||||||
|
<target>motor</target>
|
||||||
|
<definition>motor</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>neutre</source>
|
||||||
|
<target>nul</target>
|
||||||
|
<definition>neutral</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>nomenclature</source>
|
||||||
|
<target>stuklijst</target>
|
||||||
|
<definition>parts list / bill of materials</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>numerotation</source>
|
||||||
|
<target>nummering</target>
|
||||||
|
<definition>numbering - automatic wire and part numbering</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>phase</source>
|
||||||
|
<target>fase</target>
|
||||||
|
<definition>phase</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>potentiel</source>
|
||||||
|
<target>potentiaal</target>
|
||||||
|
<definition>potential - conductors electrically joined as one node</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>projet</source>
|
||||||
|
<target>project</target>
|
||||||
|
<definition>project - the .qet file holding the sheets</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>puissance</source>
|
||||||
|
<target>vermogen</target>
|
||||||
|
<definition>power</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>relais</source>
|
||||||
|
<target>relais</target>
|
||||||
|
<definition>relay</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>renvoi de folio</source>
|
||||||
|
<target>bladverwijzing</target>
|
||||||
|
<definition>sheet cross-reference</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>repere</source>
|
||||||
|
<target>aanduiding</target>
|
||||||
|
<definition>designation - the identifying mark on a part</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>report de folio</source>
|
||||||
|
<target>bladverwijzing</target>
|
||||||
|
<definition>sheet cross-reference (the arrow symbol)</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>schema</source>
|
||||||
|
<target>schema</target>
|
||||||
|
<definition>diagram</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>section</source>
|
||||||
|
<target>doorsnede</target>
|
||||||
|
<definition>cross-section - conductor size in mm2</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>sommaire</source>
|
||||||
|
<target>inhoudstafel</target>
|
||||||
|
<definition>summary / table of contents</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>tension</source>
|
||||||
|
<target>spanning</target>
|
||||||
|
<definition>voltage</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>terre</source>
|
||||||
|
<target>aarde</target>
|
||||||
|
<definition>earth / ground</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>texte</source>
|
||||||
|
<target>tekst</target>
|
||||||
|
<definition>text</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>transformateur</source>
|
||||||
|
<target>transformator</target>
|
||||||
|
<definition>transformer</definition>
|
||||||
|
</phrase>
|
||||||
|
</QPH>
|
||||||
@@ -0,0 +1,218 @@
|
|||||||
|
<!DOCTYPE QPH>
|
||||||
|
<QPH sourcelanguage="fr_FR" language="pl">
|
||||||
|
<phrase>
|
||||||
|
<source>armoire</source>
|
||||||
|
<target>Szafa</target>
|
||||||
|
<definition>cabinet / enclosure</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>bobine</source>
|
||||||
|
<target>Cewka</target>
|
||||||
|
<definition>coil</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>borne</source>
|
||||||
|
<target>Zacisk</target>
|
||||||
|
<definition>terminal - a connection point on a symbol</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>bornier</source>
|
||||||
|
<target>Listwa zaciskowa</target>
|
||||||
|
<definition>terminal strip</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>cable</source>
|
||||||
|
<target>Kabel</target>
|
||||||
|
<definition>cable</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>calibre</source>
|
||||||
|
<target>Prąd znamionowy</target>
|
||||||
|
<definition>rating - the current rating of a device</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>cartouche</source>
|
||||||
|
<target>Tabliczka rysunkowa</target>
|
||||||
|
<definition>title block - the framed information panel</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>champ de texte</source>
|
||||||
|
<target>Pole tekstowe</target>
|
||||||
|
<definition>text field</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>collection</source>
|
||||||
|
<target>Biblioteka</target>
|
||||||
|
<definition>collection - the symbol library</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>conducteur</source>
|
||||||
|
<target>Przewód</target>
|
||||||
|
<definition>conductor - the drawn wire between terminals</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>contact</source>
|
||||||
|
<target>Styk</target>
|
||||||
|
<definition>contact</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>contacteur</source>
|
||||||
|
<target>Stycznik</target>
|
||||||
|
<definition>contactor</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>courant</source>
|
||||||
|
<target>Prąd</target>
|
||||||
|
<definition>current</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>disjoncteur</source>
|
||||||
|
<target>Wyłącznik nadprądowy</target>
|
||||||
|
<definition>circuit breaker</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>dossier</source>
|
||||||
|
<target>Folder</target>
|
||||||
|
<definition>folder</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>element</source>
|
||||||
|
<target>Element</target>
|
||||||
|
<definition>element - a symbol placed on a sheet</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>esclave</source>
|
||||||
|
<target>Element podrzędny</target>
|
||||||
|
<definition>slave - the contact block belonging to a master</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>fil</source>
|
||||||
|
<target>Przewód</target>
|
||||||
|
<definition>wire</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>folio</source>
|
||||||
|
<target>Arkusz</target>
|
||||||
|
<definition>sheet - one drawing of a set</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>fusible</source>
|
||||||
|
<target>Bezpiecznik</target>
|
||||||
|
<definition>fuse</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>grille</source>
|
||||||
|
<target>Siatka</target>
|
||||||
|
<definition>grid</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>interrupteur</source>
|
||||||
|
<target>Wyłącznik</target>
|
||||||
|
<definition>switch</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>maitre</source>
|
||||||
|
<target>Element główny</target>
|
||||||
|
<definition>master - the element a cross-reference points from</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>modele</source>
|
||||||
|
<target>Szablon</target>
|
||||||
|
<definition>template</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>moteur</source>
|
||||||
|
<target>Silnik</target>
|
||||||
|
<definition>motor</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>neutre</source>
|
||||||
|
<target>Neutralny</target>
|
||||||
|
<definition>neutral</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>nomenclature</source>
|
||||||
|
<target>Zestawienie materiałów</target>
|
||||||
|
<definition>parts list / bill of materials</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>numerotation</source>
|
||||||
|
<target>Numeracja</target>
|
||||||
|
<definition>numbering - automatic wire and part numbering</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>phase</source>
|
||||||
|
<target>Faza</target>
|
||||||
|
<definition>phase</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>potentiel</source>
|
||||||
|
<target>Potencjał</target>
|
||||||
|
<definition>potential - conductors electrically joined as one node</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>projet</source>
|
||||||
|
<target>Projekt</target>
|
||||||
|
<definition>project - the .qet file holding the sheets</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>puissance</source>
|
||||||
|
<target>Moc</target>
|
||||||
|
<definition>power</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>relais</source>
|
||||||
|
<target>Przekaźnik</target>
|
||||||
|
<definition>relay</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>renvoi de folio</source>
|
||||||
|
<target>Odnośnik do arkusza</target>
|
||||||
|
<definition>sheet cross-reference</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>repere</source>
|
||||||
|
<target>Oznaczenie</target>
|
||||||
|
<definition>designation - the identifying mark on a part</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>report de folio</source>
|
||||||
|
<target>Odnośnik do arkusza</target>
|
||||||
|
<definition>sheet cross-reference (the arrow symbol)</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>schema</source>
|
||||||
|
<target>Schemat</target>
|
||||||
|
<definition>diagram</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>section</source>
|
||||||
|
<target>Przekrój</target>
|
||||||
|
<definition>cross-section - conductor size in mm2</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>sommaire</source>
|
||||||
|
<target>Spis treści</target>
|
||||||
|
<definition>summary / table of contents</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>tension</source>
|
||||||
|
<target>Napięcie</target>
|
||||||
|
<definition>voltage</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>terre</source>
|
||||||
|
<target>Uziemienie</target>
|
||||||
|
<definition>earth / ground</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>texte</source>
|
||||||
|
<target>Tekst</target>
|
||||||
|
<definition>text</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>transformateur</source>
|
||||||
|
<target>Transformator</target>
|
||||||
|
<definition>transformer</definition>
|
||||||
|
</phrase>
|
||||||
|
</QPH>
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,465 @@
|
|||||||
|
<!DOCTYPE QPH>
|
||||||
|
<QPH sourcelanguage="fr_FR" language="pt_BR">
|
||||||
|
<phrase>
|
||||||
|
<source> Contacts : NO : %1, NC : %2, inverseurs : %3, autres : %4
|
||||||
|
</source>
|
||||||
|
<target>Contatos: NA: %1, NF: %2, reversíveis: %3, outros: %4
|
||||||
|
</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source> Contacts : NO : %1/%2, NC : %3/%4, inverseurs : %5/%6, autres : %7/%8
|
||||||
|
</source>
|
||||||
|
<target>Contatos: NA: %1/%2, NF: %3/%4, reversíveis: %5/%6, outros: %7/%8
|
||||||
|
</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Aperçu</source>
|
||||||
|
<target>Pré-visualização</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Arrondir les coins d'%1</source>
|
||||||
|
<target>Arredondar os cantos de %1</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Borne 1</source>
|
||||||
|
<target>Borne 1</target>
|
||||||
|
<definition>column title</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Borne 2</source>
|
||||||
|
<target>Borne 2</target>
|
||||||
|
<definition>column title</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Catégorie</source>
|
||||||
|
<target>Categoria</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Ce format ne prend pas en charge la transparence : l'image sera enregistrée telle qu'elle était avant l'application de la couleur transparente. Continuer ?</source>
|
||||||
|
<target>Este formato não suporta transparência: a imagem será salva como estava antes da aplicação da cor transparente. Continuar?</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Champ de texte</source>
|
||||||
|
<target>Campo de texto</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Composant 1</source>
|
||||||
|
<target>Componente 1</target>
|
||||||
|
<definition>column title</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Composant 2</source>
|
||||||
|
<target>Componente 2</target>
|
||||||
|
<definition>column title</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Convertir %1 en courbe de Bézier</source>
|
||||||
|
<target>Converter %1 em curva de Bézier</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Convertir en courbe de Bézier</source>
|
||||||
|
<target>Converter em curva de Bézier</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Courant nominal</source>
|
||||||
|
<target>Corrente nominal</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Distance in pixels between the label and the slave cross reference</source>
|
||||||
|
<target>Distância em pixels entre o rótulo e a referência cruzada do escravo</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Distance label - slave :</source>
|
||||||
|
<target>Distância do rótulo - escravo:</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Enregistrer l'image d'origine sous...</source>
|
||||||
|
<target>Salvar a imagem original como...</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Enregistrer l'image sous...</source>
|
||||||
|
<target>Salvar a imagem como...</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Erreur</source>
|
||||||
|
<target>Erro</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Exclure de la nomenclature</source>
|
||||||
|
<target>Excluir da lista de materiais</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Faire pivoter %1</source>
|
||||||
|
<target>Girar %1</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Faire pivoter une image</source>
|
||||||
|
<target>Girar uma imagem</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Fil</source>
|
||||||
|
<target>Fio</target>
|
||||||
|
<definition>column title</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Folio</source>
|
||||||
|
<target>Folha</target>
|
||||||
|
<definition>column title</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Hauteur</source>
|
||||||
|
<target>Altura</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Image BMP (*.bmp)</source>
|
||||||
|
<target>Imagem BMP (*.bmp)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Image JPEG (*.jpg *.jpeg)</source>
|
||||||
|
<target>Imagem JPEG (*.jpg *.jpeg)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Image PNG (*.png)</source>
|
||||||
|
<target>Imagem PNG (*.png)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Image SVG (*.svg)</source>
|
||||||
|
<target>Imagem SVG (*.svg)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Images non incluses dans l'export DXF</source>
|
||||||
|
<target>Imagens não incluídas na exportação DXF</target>
|
||||||
|
<definition>message box title</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Impossible d'enregistrer l'image à cet emplacement.</source>
|
||||||
|
<target>Não foi possível salvar a imagem neste local.</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Impossible d'enregistrer la nomenclature dans %1.
|
||||||
|
%2</source>
|
||||||
|
<target>Não foi possível salvar a lista de materiais em %1.
|
||||||
|
%2</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Impossible de charger l'image.</source>
|
||||||
|
<target>Não foi possível carregar a imagem.</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Incliner %1</source>
|
||||||
|
<target>Inclinar %1</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Incliner une image</source>
|
||||||
|
<target>Inclinar uma imagem</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>La limite fixée pour cet élément maître est atteinte (Limite: %1).
|
||||||
|
|
||||||
|
Voulez-vous tout de même lier ce contact esclave ?</source>
|
||||||
|
<target>O limite definido para este elemento mestre foi atingido (Limite: %1).
|
||||||
|
|
||||||
|
Deseja vincular este contato escravo mesmo assim?</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Largeur</source>
|
||||||
|
<target>Largura</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Le format DXF utilisé ici (AC1006) ne permet pas d'inclure d'image. Les images seront représentées uniquement par un rectangle de contour (position, taille, rotation et inclinaison conservées), sans le contenu de l'image.</source>
|
||||||
|
<target>O formato DXF usado aqui (AC1006) não permite incluir imagens. As imagens serão representadas apenas por um retângulo de contorno (posição, tamanho, rotação e inclinação preservados), sem o conteúdo da imagem.</target>
|
||||||
|
<definition>message box content</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Liste de câblage</source>
|
||||||
|
<target>Lista de cabeamento</target>
|
||||||
|
<definition>window title</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Liste de câblage (base de données)</source>
|
||||||
|
<target>Lista de cabeamento (banco de dados)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>margin: 5px; font-weight: bold;</source>
|
||||||
|
<target>margin: 5px; font-weight: bold;</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Modifier l'angle d'un arc</source>
|
||||||
|
<target>Modificar o ângulo de um arco</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Modifier la courbure d'%1</source>
|
||||||
|
<target>Modificar a curvatura de %1</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Modifier la forme d'%1</source>
|
||||||
|
<target>Modificar a forma de %1</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Modèle</source>
|
||||||
|
<target>Modelo</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Nombre maximum de contacts esclaves définis : non défini
|
||||||
|
</source>
|
||||||
|
<target>Número máximo de contatos escravos definidos: não definido
|
||||||
|
</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Notes</source>
|
||||||
|
<target>Observações</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Redimensionner %1</source>
|
||||||
|
<target>Redimensionar %1</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Redimensionner une image</source>
|
||||||
|
<target>Redimensionar uma imagem</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Réinitialiser</source>
|
||||||
|
<target>Redefinir</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Selectionner une image...</source>
|
||||||
|
<target>Selecionar uma imagem...</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Séparation de potentiel</source>
|
||||||
|
<target>Separação de potencial</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Taille</source>
|
||||||
|
<target>Tamanho</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Tension nominale</source>
|
||||||
|
<target>Tensão nominal</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Tous les fichiers (*)</source>
|
||||||
|
<target>Todos os arquivos (*)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Transparence non conservée</source>
|
||||||
|
<target>Transparência não preservada</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>une image</source>
|
||||||
|
<target>uma imagem</target>
|
||||||
|
<definition>part of a sentence listing the content of a diagram</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Verrouiller la numérotation automatique</source>
|
||||||
|
<target>Bloquear a numeração automática</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Verrouiller la position</source>
|
||||||
|
<target>Bloquear a posição</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Échec de l'enregistrement</source>
|
||||||
|
<target>Falha ao salvar</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>armoire</source>
|
||||||
|
<target>armário</target>
|
||||||
|
<definition>cabinet / enclosure</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>bobine</source>
|
||||||
|
<target>bobina</target>
|
||||||
|
<definition>coil</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>borne</source>
|
||||||
|
<target>borne</target>
|
||||||
|
<definition>terminal - a connection point on a symbol</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>bornier</source>
|
||||||
|
<target>borneira</target>
|
||||||
|
<definition>terminal strip</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>cable</source>
|
||||||
|
<target>cabo</target>
|
||||||
|
<definition>cable</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>calibre</source>
|
||||||
|
<target>calibre</target>
|
||||||
|
<definition>rating - the current rating of a device</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>cartouche</source>
|
||||||
|
<target>bloco de título</target>
|
||||||
|
<definition>title block - the framed information panel</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>collection</source>
|
||||||
|
<target>coleção</target>
|
||||||
|
<definition>collection - the symbol library</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>conducteur</source>
|
||||||
|
<target>condutor</target>
|
||||||
|
<definition>conductor - the drawn wire between terminals</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>contact</source>
|
||||||
|
<target>contato</target>
|
||||||
|
<definition>contact</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>contacteur</source>
|
||||||
|
<target>contator</target>
|
||||||
|
<definition>contactor</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>courant</source>
|
||||||
|
<target>corrente</target>
|
||||||
|
<definition>current</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>disjoncteur</source>
|
||||||
|
<target>disjuntor</target>
|
||||||
|
<definition>circuit breaker</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>dossier</source>
|
||||||
|
<target>pasta</target>
|
||||||
|
<definition>folder</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>element</source>
|
||||||
|
<target>elemento</target>
|
||||||
|
<definition>element - a symbol placed on a sheet</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>esclave</source>
|
||||||
|
<target>escravo</target>
|
||||||
|
<definition>slave - the contact block belonging to a master</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>fusible</source>
|
||||||
|
<target>fusível</target>
|
||||||
|
<definition>fuse</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>grille</source>
|
||||||
|
<target>grade</target>
|
||||||
|
<definition>grid</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>interrupteur</source>
|
||||||
|
<target>interruptor</target>
|
||||||
|
<definition>switch</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>maitre</source>
|
||||||
|
<target>mestre</target>
|
||||||
|
<definition>master - the element a cross-reference points from</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>modele</source>
|
||||||
|
<target>modelo</target>
|
||||||
|
<definition>template</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>moteur</source>
|
||||||
|
<target>motor</target>
|
||||||
|
<definition>motor</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>neutre</source>
|
||||||
|
<target>neutro</target>
|
||||||
|
<definition>neutral</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>nomenclature</source>
|
||||||
|
<target>lista de materiais</target>
|
||||||
|
<definition>parts list / bill of materials</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>numerotation</source>
|
||||||
|
<target>numeração</target>
|
||||||
|
<definition>numbering - automatic wire and part numbering</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>phase</source>
|
||||||
|
<target>fase</target>
|
||||||
|
<definition>phase</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>potentiel</source>
|
||||||
|
<target>potencial</target>
|
||||||
|
<definition>potential - conductors electrically joined as one node</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>projet</source>
|
||||||
|
<target>projeto</target>
|
||||||
|
<definition>project - the .qet file holding the sheets</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>puissance</source>
|
||||||
|
<target>potência</target>
|
||||||
|
<definition>power</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>relais</source>
|
||||||
|
<target>relé</target>
|
||||||
|
<definition>relay</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>renvoi de folio</source>
|
||||||
|
<target>referência de folha</target>
|
||||||
|
<definition>sheet cross-reference</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>repere</source>
|
||||||
|
<target>designação</target>
|
||||||
|
<definition>designation - the identifying mark on a part</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>report de folio</source>
|
||||||
|
<target>remissão de folha</target>
|
||||||
|
<definition>sheet cross-reference (the arrow symbol)</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>schema</source>
|
||||||
|
<target>diagrama</target>
|
||||||
|
<definition>diagram</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>section</source>
|
||||||
|
<target>seção</target>
|
||||||
|
<definition>cross-section - conductor size in mm2</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>sommaire</source>
|
||||||
|
<target>sumário</target>
|
||||||
|
<definition>summary / table of contents</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>tension</source>
|
||||||
|
<target>tensão</target>
|
||||||
|
<definition>voltage</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>terre</source>
|
||||||
|
<target>terra</target>
|
||||||
|
<definition>earth / ground</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>texte</source>
|
||||||
|
<target>texto</target>
|
||||||
|
<definition>text</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>transformateur</source>
|
||||||
|
<target>transformador</target>
|
||||||
|
<definition>transformer</definition>
|
||||||
|
</phrase>
|
||||||
|
</QPH>
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,917 @@
|
|||||||
|
<!DOCTYPE QPH>
|
||||||
|
<QPH sourcelanguage="fr_FR" language="zh">
|
||||||
|
<phrase>
|
||||||
|
<source> Contacts : NO : %1, NC : %2, inverseurs : %3, autres : %4
|
||||||
|
</source>
|
||||||
|
<target>触点:常开:%1,常闭:%2,转换:%3,其他:%4
|
||||||
|
</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source> Contacts : NO : %1/%2, NC : %3/%4, inverseurs : %5/%6, autres : %7/%8
|
||||||
|
</source>
|
||||||
|
<target>触点:常开:%1/%2,常闭:%3/%4,转换:%5/%6,其他:%7/%8
|
||||||
|
</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source> %</source>
|
||||||
|
<target>%</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source> (Ctrl pendant le glissement = position libre, sans accrochage à la grille)</source>
|
||||||
|
<target>(拖动时按 Ctrl = 自由位置,不吸附到网格)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source> -- %1 : mode %2</source>
|
||||||
|
<target>-- %1:%2 模式</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source> ; point rouge : glisser pour repositionner le centre de rotation</source>
|
||||||
|
<target>;红点:拖动以重新定位旋转中心</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source> ; point turquoise : arc</source>
|
||||||
|
<target>;青色点:圆弧</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source> ; un bord : inclinaison</source>
|
||||||
|
<target>;边:倾斜</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source> °</source>
|
||||||
|
<target>°</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source> — Cliquer : mode %1</source>
|
||||||
|
<target>— 单击:%1 模式</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>, Alt = créer des poignées</source>
|
||||||
|
<target>,Alt = 创建控制柄</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>, Alt = détacher en polyligne</source>
|
||||||
|
<target>,Alt = 分离为多段线</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Ajoute une courbe de Bézier sur le folio actuel</source>
|
||||||
|
<target>在当前图纸上添加贝塞尔曲线</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Ajouter un point à une courbe</source>
|
||||||
|
<target>向曲线添加点</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Ajouter une courbe</source>
|
||||||
|
<target>添加曲线</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Angle</source>
|
||||||
|
<target>角度</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Anguleux</source>
|
||||||
|
<target>角点</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Aperçu</source>
|
||||||
|
<target>预览</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Arrondir les coins d'%1</source>
|
||||||
|
<target>将%1的角变圆</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Borne 1</source>
|
||||||
|
<target>端子1</target>
|
||||||
|
<definition>column title</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Borne 2</source>
|
||||||
|
<target>端子2</target>
|
||||||
|
<definition>column title</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Catégorie</source>
|
||||||
|
<target>类别</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Ce format ne prend pas en charge la transparence : l'image sera enregistrée telle qu'elle était avant l'application de la couleur transparente. Continuer ?</source>
|
||||||
|
<target>此格式不支持透明度:图像将按应用透明色之前的状态保存。是否继续?</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Champ de texte</source>
|
||||||
|
<target>文本字段</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Clic : positionner à la taille d'origine. Cliquer-glisser : positionner et redimensionner. Clic droit : pivoter de 90°. Ctrl+molette : ajuster la taille.</source>
|
||||||
|
<target>单击:按原始尺寸放置。单击拖动:放置并调整大小。右键:旋转 90°。Ctrl+滚轮:调整大小。</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Clic gauche : point suivant ; double-clic ou Entrée : terminer ; clic droit : annuler le dernier point</source>
|
||||||
|
<target>左键单击:下一个点;双击或 Enter:结束;右键单击:撤销上一个点</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Clic gauche : positionner le coin opposé (Maj = carré, Ctrl = depuis le centre + position libre, Ctrl+Maj = carré centré) ; clic droit : annuler</source>
|
||||||
|
<target>左键单击:放置对角(Shift = 正方形,Ctrl = 从中心 + 自由位置,Ctrl+Shift = 居中正方形);右键单击:取消</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Clic gauche : positionner le coin opposé (Maj = cercle, Ctrl = depuis le centre + position libre, Ctrl+Maj = cercle centré) ; clic droit : annuler</source>
|
||||||
|
<target>左键单击:放置对角(Shift = 圆形,Ctrl = 从中心 + 自由位置,Ctrl+Shift = 居中圆形);右键单击:取消</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Clic gauche : positionner le point de départ (Ctrl = position libre)</source>
|
||||||
|
<target>左键单击:放置起点(Ctrl = 自由位置)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Clic gauche : positionner le point final (Ctrl = position libre) ; clic droit : annuler</source>
|
||||||
|
<target>左键单击:放置终点(Ctrl = 自由位置);右键单击:取消</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Clic gauche : positionner le premier coin (Ctrl = point central, position libre)</source>
|
||||||
|
<target>左键单击:放置第一个角(Ctrl = 中心点,自由位置)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Clic gauche : positionner le premier point (Ctrl = position libre)</source>
|
||||||
|
<target>左键单击:放置第一个点(Ctrl = 自由位置)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Clic: point anguleux. Cliquer-glisser: point courbe. Clic sur le premier point: fermer. Échap/Entrée: terminer. Clic droit: annuler le dernier point.</source>
|
||||||
|
<target>单击:角点。单击拖动:曲线点。单击第一个点:闭合。Esc/Enter:结束。右键:撤销上一个点。</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Cliquer</source>
|
||||||
|
<target>单击</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Cliquer : mode %1</source>
|
||||||
|
<target>单击:%1 模式</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Cliquez pour choisir une couleur</source>
|
||||||
|
<target>点击选择颜色</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Cliquez sur l'image pour ajouter une couleur. Ajustez la tolérance de chaque couleur avec son curseur, ou cliquez sur × pour la retirer.</source>
|
||||||
|
<target>单击图像以添加颜色。使用滑块调整每种颜色的容差,或单击 × 将其移除。</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Cliquez sur l'image pour choisir une couleur</source>
|
||||||
|
<target>单击图像选择颜色</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Coins arrondis</source>
|
||||||
|
<target>圆角</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Composant 1</source>
|
||||||
|
<target>元件1</target>
|
||||||
|
<definition>column title</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Composant 2</source>
|
||||||
|
<target>元件2</target>
|
||||||
|
<definition>column title</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Convertir %1 en courbe de Bézier</source>
|
||||||
|
<target>将 %1 转换为贝塞尔曲线</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Convertir %1 en polyligne</source>
|
||||||
|
<target>将 %1 转换为多段线</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Convertir en courbe de Bézier</source>
|
||||||
|
<target>转换为贝塞尔曲线</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Convertir en polyligne</source>
|
||||||
|
<target>转换为多段线</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Couleur transparente</source>
|
||||||
|
<target>透明色</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Couleur transparente...</source>
|
||||||
|
<target>透明色...</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Courant nominal</source>
|
||||||
|
<target>额定电流</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Deplacer le centre de rotation</source>
|
||||||
|
<target>移动旋转中心</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Distance in pixels between the label and the slave cross reference</source>
|
||||||
|
<target>标签与从站交叉引用之间的像素距离</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Distance label - slave :</source>
|
||||||
|
<target>标签距离 - 从站:</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Définir une couleur transparente</source>
|
||||||
|
<target>设置透明色</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Déformer une courbe</source>
|
||||||
|
<target>变形曲线</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Déplacer le centre de rotation d'une image</source>
|
||||||
|
<target>移动图像的旋转中心</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Déverrouillé : largeur et hauteur peuvent être modifiées indépendamment. Cliquer pour verrouiller.</source>
|
||||||
|
<target>已解锁:宽度和高度可独立修改。单击锁定。</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Enregistrer l'image d'origine sous...</source>
|
||||||
|
<target>原始图像另存为...</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Enregistrer l'image sous...</source>
|
||||||
|
<target>图像另存为...</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Erreur</source>
|
||||||
|
<target>错误</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Exclure de la nomenclature</source>
|
||||||
|
<target>从物料清单中排除</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Faire pivoter %1</source>
|
||||||
|
<target>旋转 %1</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Faire pivoter une image</source>
|
||||||
|
<target>旋转图像</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Faites glisser les poignées, ou l'intérieur du cadre, pour ajuster la zone à conserver.</source>
|
||||||
|
<target>拖动控制柄或框内区域,调整要保留的区域。</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Fil</source>
|
||||||
|
<target>导线</target>
|
||||||
|
<definition>column title</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Folio</source>
|
||||||
|
<target>图页</target>
|
||||||
|
<definition>column title</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Forme fermée</source>
|
||||||
|
<target>闭合形状</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser %1 : rotation (Maj = 15°)</source>
|
||||||
|
<target>拖动 %1:旋转(Shift = 15°)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser : ajuster l'arc (Ctrl = position libre, Maj = 15°)</source>
|
||||||
|
<target>拖动:调整圆弧(Ctrl = 自由位置,Shift = 15°)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser : arrondir les coins (Ctrl = position libre)</source>
|
||||||
|
<target>拖动:圆角(Ctrl = 自由位置)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser : déformer la courbe (Ctrl = position libre, Alt = briser la tangente)</source>
|
||||||
|
<target>拖动:变形曲线(Ctrl = 自由位置,Alt = 断开切线)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser : déplacer ce point</source>
|
||||||
|
<target>拖动:移动此点</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser : déplacer le centre de rotation</source>
|
||||||
|
<target>拖动:移动旋转中心</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser : déplacer le point (Ctrl = position libre</source>
|
||||||
|
<target>拖动:移动点(Ctrl = 自由位置</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser : inclinaison (Ctrl = position libre, Maj = 15°)</source>
|
||||||
|
<target>拖动:倾斜(Ctrl = 自由位置,Shift = 15°)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser : incliner (Maj = par pas de 15°)</source>
|
||||||
|
<target>拖动:倾斜(Shift = 以 15° 为步长)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser : pivoter (Maj = par pas de 15°)</source>
|
||||||
|
<target>拖动:旋转(Shift = 以 15° 为步长)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser : redimensionner (Ctrl = depuis le centre + position libre, Maj = proportions</source>
|
||||||
|
<target>拖动:调整大小(Ctrl = 从中心 + 自由位置,Shift = 比例</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser : redimensionner (Maj = conserver les proportions, Ctrl = depuis le centre)</source>
|
||||||
|
<target>拖动:调整大小(Shift = 保持比例,Ctrl = 从中心)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser : repositionner le centre de rotation (Ctrl = position libre)</source>
|
||||||
|
<target>拖动:重新定位旋转中心(Ctrl = 自由位置)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser : rotation (Ctrl = position libre, Maj = 15°)</source>
|
||||||
|
<target>拖动:旋转(Ctrl = 自由位置,Shift = 15°)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser le point violet : arrondir les coins</source>
|
||||||
|
<target>拖动紫色点:圆角</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser un coin : pivoter (Maj = par pas de 15°) ; glisser un bord : incliner (Maj = par pas de 15°) ; point rouge : déplacer le centre de rotation</source>
|
||||||
|
<target>拖动角:旋转(Shift = 以 15° 为步长);拖动边:倾斜(Shift = 以 15° 为步长);红点:移动旋转中心</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser un coin/bord : redimensionner (Ctrl = depuis le centre, Maj = conserver les proportions)</source>
|
||||||
|
<target>拖动角/边:调整大小(Ctrl = 从中心,Shift = 保持比例)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser un coin/bord : redimensionner (Ctrl = depuis le centre, Maj = proportions, Alt = détacher en polyligne)</source>
|
||||||
|
<target>拖动角/边:调整大小(Ctrl = 从中心,Shift = 比例,Alt = 分离为多段线)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser un point : le déplacer</source>
|
||||||
|
<target>拖动点:移动它</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser une extrémité : la déplacer</source>
|
||||||
|
<target>拖动端点:移动它</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Glisser une poignée ou la courbe : déformer (Alt = briser la tangente) ; Alt+glisser un point anguleux : créer des poignées ; clic droit : menu du nœud le plus proche</source>
|
||||||
|
<target>拖动控制柄或曲线:变形(Alt = 断开切线);Alt+拖动角点:创建控制柄;右键单击:最近节点菜单</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Géométrie</source>
|
||||||
|
<target>几何</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Hauteur</source>
|
||||||
|
<target>高度</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Image BMP (*.bmp)</source>
|
||||||
|
<target>BMP 图像 (*.bmp)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Image Files (*.png *.jpg *.jpeg *.bmp *.svg)</source>
|
||||||
|
<target>图像文件 (*.png *.jpg *.jpeg *.bmp *.svg)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Image JPEG (*.jpg *.jpeg)</source>
|
||||||
|
<target>JPEG 图像 (*.jpg *.jpeg)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Image PNG (*.png)</source>
|
||||||
|
<target>PNG 图像 (*.png)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Image source</source>
|
||||||
|
<target>源图像</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Image SVG (*.svg)</source>
|
||||||
|
<target>SVG 图像 (*.svg)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Images non incluses dans l'export DXF</source>
|
||||||
|
<target>图像未包含在 DXF 导出中</target>
|
||||||
|
<definition>message box title</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Impossible d'enregistrer l'image à cet emplacement.</source>
|
||||||
|
<target>无法将图像保存到该位置。</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Impossible d'enregistrer la nomenclature dans %1.
|
||||||
|
%2</source>
|
||||||
|
<target>无法将物料清单保存到 %1。
|
||||||
|
%2</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Impossible de charger l'image.</source>
|
||||||
|
<target>无法加载图像。</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Inclinaison X</source>
|
||||||
|
<target>X 倾斜</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Inclinaison Y</source>
|
||||||
|
<target>Y 倾斜</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Incliner %1</source>
|
||||||
|
<target>倾斜 %1</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Incliner une image</source>
|
||||||
|
<target>倾斜图像</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>La limite fixée pour cet élément maître est atteinte (Limite: %1).
|
||||||
|
|
||||||
|
Voulez-vous tout de même lier ce contact esclave ?</source>
|
||||||
|
<target>已达到此主元件的限制(限制:%1)。
|
||||||
|
|
||||||
|
是否仍要链接此从属触点?</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Largeur</source>
|
||||||
|
<target>宽度</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Le format DXF utilisé ici (AC1006) ne permet pas d'inclure d'image. Les images seront représentées uniquement par un rectangle de contour (position, taille, rotation et inclinaison conservées), sans le contenu de l'image.</source>
|
||||||
|
<target>此处使用的 DXF 格式 (AC1006) 无法包含图像。图像将仅以轮廓矩形表示(保留位置、大小、旋转和倾斜),不包含图像内容。</target>
|
||||||
|
<definition>message box content</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Lisse</source>
|
||||||
|
<target>平滑</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Liste de câblage</source>
|
||||||
|
<target>接线列表</target>
|
||||||
|
<definition>window title</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Liste de câblage (base de données)</source>
|
||||||
|
<target>接线列表(数据库)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Longueur</source>
|
||||||
|
<target>长度</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>margin: 5px; font-weight: bold;</source>
|
||||||
|
<target>margin: 5px; font-weight: bold;</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Miroir horizontal</source>
|
||||||
|
<target>水平镜像</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Miroir horizontal d'une image</source>
|
||||||
|
<target>图像水平镜像</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Miroir horizontal de %1</source>
|
||||||
|
<target>%1 的水平镜像</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Miroir impossible : inclinaison trop extrême pour cette forme</source>
|
||||||
|
<target>无法镜像:此形状的倾斜过于极端</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Miroir vertical</source>
|
||||||
|
<target>垂直镜像</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Miroir vertical d'une image</source>
|
||||||
|
<target>图像垂直镜像</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Miroir vertical de %1</source>
|
||||||
|
<target>%1 的垂直镜像</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Modifier l'angle d'un arc</source>
|
||||||
|
<target>修改弧的角度</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Modifier l'angle d'une forme</source>
|
||||||
|
<target>修改形状角度</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Modifier l'angle d'une image</source>
|
||||||
|
<target>修改图像角度</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Modifier l'inclinaison d'une image</source>
|
||||||
|
<target>修改图像倾斜</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Modifier la courbure d'%1</source>
|
||||||
|
<target>修改%1的曲率</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Modifier la forme d'%1</source>
|
||||||
|
<target>修改%1的形状</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Modifier la hauteur d'une image</source>
|
||||||
|
<target>修改图像高度</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Modifier la largeur d'une image</source>
|
||||||
|
<target>修改图像宽度</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Modifier la longueur d'une ligne</source>
|
||||||
|
<target>修改线条长度</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Modifier la taille d'une forme</source>
|
||||||
|
<target>修改形状大小</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Modifier le type d'un nœud</source>
|
||||||
|
<target>修改节点类型</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Modifier une image</source>
|
||||||
|
<target>修改图像</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Modèle</source>
|
||||||
|
<target>型号</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Nombre maximum de contacts esclaves définis : non défini
|
||||||
|
</source>
|
||||||
|
<target>已定义的从属触点最大数量:未定义
|
||||||
|
</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Notes</source>
|
||||||
|
<target>备注</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Nœud le plus proche</source>
|
||||||
|
<target>最近节点</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>pivoter/incliner</source>
|
||||||
|
<target>旋转/倾斜</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Rayon X</source>
|
||||||
|
<target>X半径</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Rayon Y</source>
|
||||||
|
<target>Y半径</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>redimensionner</source>
|
||||||
|
<target>调整大小</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Redimensionner %1</source>
|
||||||
|
<target>调整 %1 大小</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Redimensionner une image</source>
|
||||||
|
<target>调整图像大小</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Remplacer l'image...</source>
|
||||||
|
<target>替换图像...</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Remplacer une image</source>
|
||||||
|
<target>替换图像</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Restaurer les proportions</source>
|
||||||
|
<target>恢复比例</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Restaurer les proportions d'une image</source>
|
||||||
|
<target>恢复图像比例</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Retirer cette couleur</source>
|
||||||
|
<target>移除此颜色</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Revenir à l'image complète, sans rognage</source>
|
||||||
|
<target>恢复为完整图像,不裁剪</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>rgb(%1, %2, %3)</source>
|
||||||
|
<target>rgb(%1, %2, %3)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Rogner l'image</source>
|
||||||
|
<target>裁剪图像</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Rogner une image</source>
|
||||||
|
<target>裁剪图像</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Rogner...</source>
|
||||||
|
<target>裁剪...</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Rotation/Inclinaison</source>
|
||||||
|
<target>旋转/倾斜</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Réinitialiser</source>
|
||||||
|
<target>重置</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Selectionner une image...</source>
|
||||||
|
<target>选择图像...</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Supprimer le nœud le plus proche</source>
|
||||||
|
<target>删除最近节点</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Supprimer un point d'une courbe</source>
|
||||||
|
<target>从曲线删除点</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Symétrique</source>
|
||||||
|
<target>对称</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Séparation de potentiel</source>
|
||||||
|
<target>电位分隔</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Taille</source>
|
||||||
|
<target>大小</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Tension nominale</source>
|
||||||
|
<target>额定电压</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Tolérance pour cette couleur</source>
|
||||||
|
<target>此颜色的容差</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Tous les fichiers (*)</source>
|
||||||
|
<target>所有文件 (*)</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Transformer %1</source>
|
||||||
|
<target>变换 %1</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Transparence non conservée</source>
|
||||||
|
<target>不保留透明度</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>un arc</source>
|
||||||
|
<target>一段弧</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>un coin</source>
|
||||||
|
<target>一个角</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>un point</source>
|
||||||
|
<target>一个点</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>une courbe</source>
|
||||||
|
<target>一条曲线</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>une extrémité</source>
|
||||||
|
<target>一个端点</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>une image</source>
|
||||||
|
<target>一张图像</target>
|
||||||
|
<definition>part of a sentence listing the content of a diagram</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Verrouiller la numérotation automatique</source>
|
||||||
|
<target>锁定自动编号</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Verrouiller la position</source>
|
||||||
|
<target>锁定位置</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Verrouillé : modifier la largeur ou la hauteur ajuste l'autre pour conserver les proportions. Cliquer pour déverrouiller.</source>
|
||||||
|
<target>已锁定:修改宽度或高度会调整另一个以保持比例。单击解锁。</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Échec de l'enregistrement</source>
|
||||||
|
<target>保存失败</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>Édition des nœuds</source>
|
||||||
|
<target>节点编辑</target>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>armoire</source>
|
||||||
|
<target>机柜</target>
|
||||||
|
<definition>cabinet / enclosure</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>bobine</source>
|
||||||
|
<target>线圈</target>
|
||||||
|
<definition>coil</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>borne</source>
|
||||||
|
<target>端子</target>
|
||||||
|
<definition>terminal - a connection point on a symbol</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>bornier</source>
|
||||||
|
<target>端子排</target>
|
||||||
|
<definition>terminal strip</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>cable</source>
|
||||||
|
<target>电缆</target>
|
||||||
|
<definition>cable</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>calibre</source>
|
||||||
|
<target>额定值</target>
|
||||||
|
<definition>rating - the current rating of a device</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>cartouche</source>
|
||||||
|
<target>标题栏</target>
|
||||||
|
<definition>title block - the framed information panel</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>collection</source>
|
||||||
|
<target>符号库</target>
|
||||||
|
<definition>collection - the symbol library</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>conducteur</source>
|
||||||
|
<target>导线</target>
|
||||||
|
<definition>conductor - the drawn wire between terminals</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>contact</source>
|
||||||
|
<target>触点</target>
|
||||||
|
<definition>contact</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>contacteur</source>
|
||||||
|
<target>接触器</target>
|
||||||
|
<definition>contactor</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>courant</source>
|
||||||
|
<target>电流</target>
|
||||||
|
<definition>current</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>disjoncteur</source>
|
||||||
|
<target>断路器</target>
|
||||||
|
<definition>circuit breaker</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>dossier</source>
|
||||||
|
<target>文件夹</target>
|
||||||
|
<definition>folder</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>element</source>
|
||||||
|
<target>元件</target>
|
||||||
|
<definition>element - a symbol placed on a sheet</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>esclave</source>
|
||||||
|
<target>从</target>
|
||||||
|
<definition>slave - the contact block belonging to a master</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>fusible</source>
|
||||||
|
<target>熔断器</target>
|
||||||
|
<definition>fuse</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>grille</source>
|
||||||
|
<target>网格</target>
|
||||||
|
<definition>grid</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>interrupteur</source>
|
||||||
|
<target>开关</target>
|
||||||
|
<definition>switch</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>maitre</source>
|
||||||
|
<target>主</target>
|
||||||
|
<definition>master - the element a cross-reference points from</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>modele</source>
|
||||||
|
<target>模板</target>
|
||||||
|
<definition>template</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>moteur</source>
|
||||||
|
<target>电动机</target>
|
||||||
|
<definition>motor</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>neutre</source>
|
||||||
|
<target>中性线</target>
|
||||||
|
<definition>neutral</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>nomenclature</source>
|
||||||
|
<target>物料清单</target>
|
||||||
|
<definition>parts list / bill of materials</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>numerotation</source>
|
||||||
|
<target>编号</target>
|
||||||
|
<definition>numbering - automatic wire and part numbering</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>phase</source>
|
||||||
|
<target>相</target>
|
||||||
|
<definition>phase</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>potentiel</source>
|
||||||
|
<target>电位</target>
|
||||||
|
<definition>potential - conductors electrically joined as one node</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>projet</source>
|
||||||
|
<target>项目</target>
|
||||||
|
<definition>project - the .qet file holding the sheets</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>puissance</source>
|
||||||
|
<target>功率</target>
|
||||||
|
<definition>power</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>relais</source>
|
||||||
|
<target>继电器</target>
|
||||||
|
<definition>relay</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>renvoi de folio</source>
|
||||||
|
<target>图纸交叉引用</target>
|
||||||
|
<definition>sheet cross-reference</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>repere</source>
|
||||||
|
<target>标识</target>
|
||||||
|
<definition>designation - the identifying mark on a part</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>report de folio</source>
|
||||||
|
<target>图纸交叉引用</target>
|
||||||
|
<definition>sheet cross-reference (the arrow symbol)</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>schema</source>
|
||||||
|
<target>原理图</target>
|
||||||
|
<definition>diagram</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>section</source>
|
||||||
|
<target>截面积</target>
|
||||||
|
<definition>cross-section - conductor size in mm2</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>sommaire</source>
|
||||||
|
<target>目录</target>
|
||||||
|
<definition>summary / table of contents</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>tension</source>
|
||||||
|
<target>电压</target>
|
||||||
|
<definition>voltage</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>terre</source>
|
||||||
|
<target>接地</target>
|
||||||
|
<definition>earth / ground</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>texte</source>
|
||||||
|
<target>文本</target>
|
||||||
|
<definition>text</definition>
|
||||||
|
</phrase>
|
||||||
|
<phrase>
|
||||||
|
<source>transformateur</source>
|
||||||
|
<target>变压器</target>
|
||||||
|
<definition>transformer</definition>
|
||||||
|
</phrase>
|
||||||
|
</QPH>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
#Based on raspberry pi 5 8 Gb Trixie
|
#Based on raspberry pi 5 8 Gb Trixie
|
||||||
#sudo apt install git ssh rsync libqt5svg5-dev qt5-qmake qtbase5-dev libkf5widgetsaddons-dev libkf5coreaddons-dev pkgconf libqt5waylandclient5-dev libqt5waylandcompositor5-dev g++ make
|
#sudo apt install git ssh rsync libqt5svg5-dev qt5-qmake qtbase5-dev libkf5widgetsaddons-dev libkf5coreaddons-dev libsqlite3-dev pkgconf libqt5waylandclient5-dev libqt5waylandcompositor5-dev g++ make
|
||||||
#mkdir -p AppImage/0.100.0/aarch64
|
#mkdir -p AppImage/0.100.0/aarch64
|
||||||
# Get GIT sources
|
# Get GIT sources
|
||||||
#git clone --recursive https://github.com/qelectrotech/qelectrotech-source-mirror.git
|
#git clone --recursive https://github.com/qelectrotech/qelectrotech-source-mirror.git
|
||||||
|
|||||||
@@ -49,6 +49,14 @@ ElementsCollectionModel::ElementsCollectionModel(QObject *parent) :
|
|||||||
*/
|
*/
|
||||||
ElementsCollectionModel::~ElementsCollectionModel()
|
ElementsCollectionModel::~ElementsCollectionModel()
|
||||||
{
|
{
|
||||||
|
// Without cancel(), the wait below runs the whole queued
|
||||||
|
// QtConcurrent::map() to completion, so closing this dialog on a
|
||||||
|
// large collection blocks until every remaining item has been
|
||||||
|
// processed -- a visible hang on the button pressed precisely to
|
||||||
|
// stop the work. cancel() drops the not-yet-started items so the
|
||||||
|
// wait that follows (still needed, so an in-flight item can't
|
||||||
|
// dereference this object after it's gone) is short.
|
||||||
|
m_future.cancel();
|
||||||
m_future.waitForFinished();
|
m_future.waitForFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -431,7 +439,7 @@ void ElementsCollectionModel::addLocation(const ElementsLocation& location)
|
|||||||
collection_name);
|
collection_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ANPASSUNG: Makros und Custom Collection werden hier behandelt!
|
// Macros and Custom Collection are handled here
|
||||||
else if (location.isCustomCollection() || location.isMacrosCollection()) {
|
else if (location.isCustomCollection() || location.isMacrosCollection()) {
|
||||||
QList <ElementCollectionItem *> child_list;
|
QList <ElementCollectionItem *> child_list;
|
||||||
|
|
||||||
@@ -647,7 +655,7 @@ QModelIndex ElementsCollectionModel::indexFromLocation(
|
|||||||
if (eci->type() == FileElementCollectionItem::Type) {
|
if (eci->type() == FileElementCollectionItem::Type) {
|
||||||
if (FileElementCollectionItem *feci = static_cast<FileElementCollectionItem *>(eci)) {
|
if (FileElementCollectionItem *feci = static_cast<FileElementCollectionItem *>(eci)) {
|
||||||
|
|
||||||
// ANPASSUNG: Makro-Prüfung hinzugefügt, damit das Modell den Pfad im Baum findet!
|
// Macro check added so the model finds the path in the tree
|
||||||
if ( (location.isCommonCollection() && feci->isCommonCollection()) ||
|
if ( (location.isCommonCollection() && feci->isCommonCollection()) ||
|
||||||
(location.isCompanyCollection() && feci->isCompanyCollection()) ||
|
(location.isCompanyCollection() && feci->isCompanyCollection()) ||
|
||||||
(location.isMacrosCollection() && feci->isMacrosCollection()) ||
|
(location.isMacrosCollection() && feci->isMacrosCollection()) ||
|
||||||
|
|||||||
@@ -653,9 +653,16 @@ QDomElement ElementsLocation::xml() const
|
|||||||
if (!m_project)
|
if (!m_project)
|
||||||
{
|
{
|
||||||
QFile file (m_file_system_path);
|
QFile file (m_file_system_path);
|
||||||
|
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||||
|
return QDomElement();
|
||||||
|
|
||||||
QDomDocument docu;
|
QDomDocument docu;
|
||||||
if (docu.setContent(&file))
|
if (docu.setContent(&file))
|
||||||
|
{
|
||||||
|
file.close();
|
||||||
return docu.documentElement();
|
return docu.documentElement();
|
||||||
|
}
|
||||||
|
file.close();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ QString FileElementCollectionItem::localName()
|
|||||||
else if (m_path == QETApp::customElementsDirN())
|
else if (m_path == QETApp::customElementsDirN())
|
||||||
setText(QObject::tr("Collection utilisateur"));
|
setText(QObject::tr("Collection utilisateur"));
|
||||||
else if (m_path == macrosPath)
|
else if (m_path == macrosPath)
|
||||||
setText(QObject::tr("Makros"));
|
setText(QObject::tr("Macros"));
|
||||||
else
|
else
|
||||||
setText(QObject::tr("Collection inconnue"));
|
setText(QObject::tr("Collection inconnue"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,10 +46,11 @@ FreeTerminalEditor::FreeTerminalEditor(QETProject *project, QWidget *parent) :
|
|||||||
connect(m_project, &QObject::destroyed, this, &FreeTerminalEditor::reload);
|
connect(m_project, &QObject::destroyed, this, &FreeTerminalEditor::reload);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Disabled the move if the table is currently edited (yellow cell)
|
//Disable the move button while cells are edited (yellow), re-evaluate on every change
|
||||||
connect(m_model, &FreeTerminalModel::dataChanged, this, [=] {
|
connect(m_model, &FreeTerminalModel::dataChanged, this, &FreeTerminalEditor::selectionChanged);
|
||||||
this->setDisabledMove();
|
|
||||||
});
|
connect(ui->m_table_view->selectionModel(), &QItemSelectionModel::selectionChanged,
|
||||||
|
this, &FreeTerminalEditor::selectionChanged);
|
||||||
|
|
||||||
connect(ui->m_table_view, &QAbstractItemView::doubleClicked, this, [=](const QModelIndex &index)
|
connect(ui->m_table_view, &QAbstractItemView::doubleClicked, this, [=](const QModelIndex &index)
|
||||||
{
|
{
|
||||||
@@ -102,7 +103,7 @@ void FreeTerminalEditor::reload()
|
|||||||
QString str(strip->installation() + " " + strip->location() + " " + strip->name());
|
QString str(strip->installation() + " " + strip->location() + " " + strip->name());
|
||||||
ui->m_move_in_cb->addItem(str, strip->uuid());
|
ui->m_move_in_cb->addItem(str, strip->uuid());
|
||||||
}
|
}
|
||||||
setDisabledMove(false);
|
selectionChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,10 +274,19 @@ void FreeTerminalEditor::on_m_move_pb_clicked()
|
|||||||
reload();
|
reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FreeTerminalEditor::selectionChanged()
|
||||||
|
{
|
||||||
|
const bool has_selection = !ui->m_table_view->selectionModel()->selectedIndexes().isEmpty();
|
||||||
|
const bool has_pending = !m_model->modifiedModelRealTerminalData().isEmpty();
|
||||||
|
setDisabledMove(!has_selection || has_pending);
|
||||||
|
}
|
||||||
|
|
||||||
void FreeTerminalEditor::setDisabledMove(bool b)
|
void FreeTerminalEditor::setDisabledMove(bool b)
|
||||||
{
|
{
|
||||||
ui->m_move_label->setDisabled(b);
|
ui->m_move_label->setDisabled(b);
|
||||||
ui->m_move_in_cb->setDisabled(b);
|
ui->m_move_in_cb->setDisabled(b);
|
||||||
ui->m_move_pb->setDisabled(b);
|
ui->m_move_pb->setDisabled(b);
|
||||||
|
ui->m_move_pb->setToolTip(b ? tr("Appliquez ou annulez les modifications en cours avant de déplacer")
|
||||||
|
: tr("Déplacer les bornes sélectionnées vers le bornier choisi"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ bool FreeTerminalModel::setData(const QModelIndex &index, const QVariant &value,
|
|||||||
modified_ = true;
|
modified_ = true;
|
||||||
modified_cell = FUNCTION_CELL;
|
modified_cell = FUNCTION_CELL;
|
||||||
}
|
}
|
||||||
else if (column_ == LED_CELL)
|
else if (column_ == LED_CELL && mrtd.led_ != value.toBool())
|
||||||
{
|
{
|
||||||
mrtd.led_ = value.toBool();
|
mrtd.led_ = value.toBool();
|
||||||
modified_ = true;
|
modified_ = true;
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2006-2026 The QElectroTech Team
|
||||||
|
This file is part of QElectroTech.
|
||||||
|
|
||||||
|
QElectroTech is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
QElectroTech 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 General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "renumberelementscommand.h"
|
||||||
|
|
||||||
|
#include "../qetproject.h"
|
||||||
|
#include "../qetgraphicsitem/element.h"
|
||||||
|
|
||||||
|
RenumberElementsCommand::RenumberElementsCommand(
|
||||||
|
QETProject *project,
|
||||||
|
QVector<ElementChange> changes,
|
||||||
|
QHash<QString, NumerotationContext> old_ctx,
|
||||||
|
QHash<QString, NumerotationContext> new_ctx,
|
||||||
|
const QString &text)
|
||||||
|
: QUndoCommand(text)
|
||||||
|
, project_(project)
|
||||||
|
, changes_(std::move(changes))
|
||||||
|
, old_ctx_(std::move(old_ctx))
|
||||||
|
, new_ctx_(std::move(new_ctx))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenumberElementsCommand::undo()
|
||||||
|
{
|
||||||
|
apply(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenumberElementsCommand::redo()
|
||||||
|
{
|
||||||
|
// QUndoStack calls redo() once immediately after push(); keep standard behaviour.
|
||||||
|
if (first_redo_) {
|
||||||
|
first_redo_ = false;
|
||||||
|
}
|
||||||
|
apply(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenumberElementsCommand::apply(bool use_new)
|
||||||
|
{
|
||||||
|
if (!project_) return;
|
||||||
|
|
||||||
|
// Restore project contexts
|
||||||
|
const auto &ctx = use_new ? new_ctx_ : old_ctx_;
|
||||||
|
for (auto it = ctx.constBegin(); it != ctx.constEnd(); ++it) {
|
||||||
|
project_->addElementAutoNum(it.key(), it.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply per-element changes
|
||||||
|
for (const ElementChange &c : changes_) {
|
||||||
|
if (!c.element) continue;
|
||||||
|
|
||||||
|
const bool frozen = use_new ? c.new_frozen : c.old_frozen;
|
||||||
|
const auto &infos = use_new ? c.new_infos : c.old_infos;
|
||||||
|
const auto &seq = use_new ? c.new_seq : c.old_seq;
|
||||||
|
|
||||||
|
// Temporarily unfreeze so that label/infos update correctly.
|
||||||
|
const bool was_frozen = c.element->isFreezeLabel();
|
||||||
|
if (was_frozen) c.element->freezeLabel(false);
|
||||||
|
|
||||||
|
c.element->rSequenceStruct() = seq;
|
||||||
|
c.element->setElementInformations(infos);
|
||||||
|
c.element->freezeLabel(frozen);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2006-2026 The QElectroTech Team
|
||||||
|
This file is part of QElectroTech.
|
||||||
|
|
||||||
|
QElectroTech is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
QElectroTech 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 General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RENUMBERELEMENTSCOMMAND_H
|
||||||
|
#define RENUMBERELEMENTSCOMMAND_H
|
||||||
|
|
||||||
|
#include <QUndoCommand>
|
||||||
|
#include <QHash>
|
||||||
|
#include <QVector>
|
||||||
|
|
||||||
|
#include "../diagramcontext.h"
|
||||||
|
#include "assignvariables.h" // defines autonum::sequentialNumbers
|
||||||
|
|
||||||
|
class Element;
|
||||||
|
class QETProject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Undoable renumbering of element labels and sequence structs.
|
||||||
|
*/
|
||||||
|
class RenumberElementsCommand final : public QUndoCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct ElementChange
|
||||||
|
{
|
||||||
|
Element *element = nullptr;
|
||||||
|
DiagramContext old_infos;
|
||||||
|
DiagramContext new_infos;
|
||||||
|
autonum::sequentialNumbers old_seq;
|
||||||
|
autonum::sequentialNumbers new_seq;
|
||||||
|
bool old_frozen = false;
|
||||||
|
bool new_frozen = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
RenumberElementsCommand(
|
||||||
|
QETProject *project,
|
||||||
|
QVector<ElementChange> changes,
|
||||||
|
QHash<QString, NumerotationContext> old_ctx,
|
||||||
|
QHash<QString, NumerotationContext> new_ctx,
|
||||||
|
const QString &text);
|
||||||
|
|
||||||
|
void undo() override;
|
||||||
|
void redo() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void apply(bool use_new);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QETProject *project_ = nullptr;
|
||||||
|
QVector<ElementChange> changes_;
|
||||||
|
QHash<QString, NumerotationContext> old_ctx_;
|
||||||
|
QHash<QString, NumerotationContext> new_ctx_;
|
||||||
|
bool first_redo_ = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // RENUMBERELEMENTSCOMMAND_H
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
#include "formulaautonumberingw.h"
|
#include "formulaautonumberingw.h"
|
||||||
#include "numparteditorw.h"
|
#include "numparteditorw.h"
|
||||||
#include "qdebug.h"
|
#include "qdebug.h"
|
||||||
|
#include "renumberelementsdialog.h"
|
||||||
#include "ui_autonumberingmanagementw.h"
|
#include "ui_autonumberingmanagementw.h"
|
||||||
#include "ui_formulaautonumberingw.h"
|
#include "ui_formulaautonumberingw.h"
|
||||||
|
|
||||||
@@ -48,6 +49,8 @@ AutoNumberingManagementW::AutoNumberingManagementW(QETProject *project,
|
|||||||
ui->m_selected_folios_le->setDisabled(true);
|
ui->m_selected_folios_le->setDisabled(true);
|
||||||
ui->m_selected_folios_le->setReadOnly(true);
|
ui->m_selected_folios_le->setReadOnly(true);
|
||||||
ui->m_apply_project_rb->setChecked(true);
|
ui->m_apply_project_rb->setChecked(true);
|
||||||
|
// Enabled only when project is in "Under Development" status and not read-only.
|
||||||
|
ui->m_renumber_elements_pb->setEnabled(ui->m_status_cb->currentIndex() == 0 && project_ && !project_->isReadOnly());
|
||||||
setProjectContext();
|
setProjectContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,6 +90,7 @@ void AutoNumberingManagementW::on_m_status_cb_currentIndexChanged(int index)
|
|||||||
ui->m_both_conductor_rb->setChecked(true);
|
ui->m_both_conductor_rb->setChecked(true);
|
||||||
ui->m_both_element_rb->setChecked(true);
|
ui->m_both_element_rb->setChecked(true);
|
||||||
ui->m_both_folio_rb->setChecked(true);
|
ui->m_both_folio_rb->setChecked(true);
|
||||||
|
ui->m_renumber_elements_pb->setEnabled(true);
|
||||||
}
|
}
|
||||||
//Installing
|
//Installing
|
||||||
else if (index == 1) {
|
else if (index == 1) {
|
||||||
@@ -96,15 +100,31 @@ void AutoNumberingManagementW::on_m_status_cb_currentIndexChanged(int index)
|
|||||||
ui->m_new_conductor_rb->setChecked(true);
|
ui->m_new_conductor_rb->setChecked(true);
|
||||||
ui->m_new_element_rb->setChecked(true);
|
ui->m_new_element_rb->setChecked(true);
|
||||||
ui->m_new_folio_rb->setChecked(true);
|
ui->m_new_folio_rb->setChecked(true);
|
||||||
|
ui->m_renumber_elements_pb->setEnabled(true);
|
||||||
}
|
}
|
||||||
//Built
|
//Built
|
||||||
else if (index == 2) {
|
else if (index == 2) {
|
||||||
ui->m_disable_conductor_rb->setChecked(true);
|
ui->m_disable_conductor_rb->setChecked(true);
|
||||||
ui->m_disable_element_rb->setChecked(true);
|
ui->m_disable_element_rb->setChecked(true);
|
||||||
ui->m_disable_folio_rb->setChecked(true);
|
ui->m_disable_folio_rb->setChecked(true);
|
||||||
|
ui->m_renumber_elements_pb->setEnabled(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AutoNumberingManagementW::on_m_renumber_elements_pb_clicked()
|
||||||
|
{
|
||||||
|
if (!project_ || project_->isReadOnly()) return;
|
||||||
|
// Only allowed during "Under Development"
|
||||||
|
// if (ui->m_status_cb->currentIndex() != 1) return;
|
||||||
|
|
||||||
|
QStringList titles = project_->elementAutoNum().keys();
|
||||||
|
titles.sort(Qt::CaseInsensitive);
|
||||||
|
RenumberElementsDialog dlg(titles, this);
|
||||||
|
if (dlg.exec() != QDialog::Accepted) return;
|
||||||
|
|
||||||
|
project_->renumberElementsBySchemeTitle(dlg.selectedSchemeTitle());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief AutoNumberingManagementW::on_m_apply_folios_rb_clicked
|
@brief AutoNumberingManagementW::on_m_apply_folios_rb_clicked
|
||||||
Set From Folios Combobox
|
Set From Folios Combobox
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ class AutoNumberingManagementW : public QWidget
|
|||||||
void on_m_from_folios_cb_currentIndexChanged(int);
|
void on_m_from_folios_cb_currentIndexChanged(int);
|
||||||
void on_m_to_folios_cb_currentIndexChanged(int);
|
void on_m_to_folios_cb_currentIndexChanged(int);
|
||||||
void on_m_status_cb_currentIndexChanged(int);
|
void on_m_status_cb_currentIndexChanged(int);
|
||||||
|
void on_m_renumber_elements_pb_clicked();
|
||||||
void on_m_apply_folios_rb_clicked();
|
void on_m_apply_folios_rb_clicked();
|
||||||
void on_m_apply_project_rb_clicked();
|
void on_m_apply_project_rb_clicked();
|
||||||
void on_buttonBox_clicked(QAbstractButton *);
|
void on_buttonBox_clicked(QAbstractButton *);
|
||||||
|
|||||||
@@ -305,6 +305,13 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="m_renumber_elements_pb">
|
||||||
|
<property name="text">
|
||||||
|
<string>Renumber element(s)…</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer_2">
|
<spacer name="horizontalSpacer_2">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2006-2026 The QElectroTech Team
|
||||||
|
This file is part of QElectroTech.
|
||||||
|
|
||||||
|
QElectroTech is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
QElectroTech 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 General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "renumberelementsdialog.h"
|
||||||
|
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QDialogButtonBox>
|
||||||
|
#include <QFormLayout>
|
||||||
|
#include <QGroupBox>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QRadioButton>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
RenumberElementsDialog::RenumberElementsDialog(const QStringList &scheme_titles, QWidget *parent)
|
||||||
|
: QDialog(parent)
|
||||||
|
, m_scheme_titles(scheme_titles)
|
||||||
|
{
|
||||||
|
setWindowTitle(tr("Renumber element(s)"));
|
||||||
|
setModal(true);
|
||||||
|
|
||||||
|
auto *vl = new QVBoxLayout(this);
|
||||||
|
|
||||||
|
auto *scope = new QGroupBox(tr("Scope"), this);
|
||||||
|
auto *scope_l = new QVBoxLayout(scope);
|
||||||
|
m_all_rb = new QRadioButton(tr("All schemes"), scope);
|
||||||
|
m_one_rb = new QRadioButton(tr("One scheme"), scope);
|
||||||
|
scope_l->addWidget(m_all_rb);
|
||||||
|
scope_l->addWidget(m_one_rb);
|
||||||
|
vl->addWidget(scope);
|
||||||
|
|
||||||
|
auto *form = new QFormLayout();
|
||||||
|
m_combo = new QComboBox(this);
|
||||||
|
m_combo->addItems(m_scheme_titles);
|
||||||
|
form->addRow(new QLabel(tr("Scheme:"), this), m_combo);
|
||||||
|
vl->addLayout(form);
|
||||||
|
|
||||||
|
m_buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
|
||||||
|
connect(m_buttons, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||||
|
connect(m_buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||||
|
vl->addWidget(m_buttons);
|
||||||
|
|
||||||
|
m_all_rb->setChecked(true);
|
||||||
|
updateUi();
|
||||||
|
|
||||||
|
connect(m_all_rb, &QRadioButton::toggled, this, &RenumberElementsDialog::updateUi);
|
||||||
|
connect(m_one_rb, &QRadioButton::toggled, this, &RenumberElementsDialog::updateUi);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString RenumberElementsDialog::selectedSchemeTitle() const
|
||||||
|
{
|
||||||
|
if (m_all_rb && m_all_rb->isChecked()) return QString();
|
||||||
|
return m_combo ? m_combo->currentText() : QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenumberElementsDialog::updateUi()
|
||||||
|
{
|
||||||
|
const bool one = m_one_rb && m_one_rb->isChecked();
|
||||||
|
if (m_combo) m_combo->setEnabled(one);
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2006-2026 The QElectroTech Team
|
||||||
|
This file is part of QElectroTech.
|
||||||
|
|
||||||
|
QElectroTech is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
QElectroTech 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 General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RENUMBERELEMENTSDIALOG_H
|
||||||
|
#define RENUMBERELEMENTSDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
class QComboBox;
|
||||||
|
class QRadioButton;
|
||||||
|
class QDialogButtonBox;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Simple dialog to pick renumbering scope for elements.
|
||||||
|
*
|
||||||
|
* The user can choose between:
|
||||||
|
* - all element autonumbering schemes
|
||||||
|
* - one selected scheme title
|
||||||
|
*/
|
||||||
|
class RenumberElementsDialog final : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit RenumberElementsDialog(const QStringList &scheme_titles, QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Empty string if "all" is selected, otherwise the chosen scheme title.
|
||||||
|
*/
|
||||||
|
QString selectedSchemeTitle() const;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void updateUi();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QStringList m_scheme_titles;
|
||||||
|
QRadioButton *m_all_rb = nullptr;
|
||||||
|
QRadioButton *m_one_rb = nullptr;
|
||||||
|
QComboBox *m_combo = nullptr;
|
||||||
|
QDialogButtonBox *m_buttons = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // RENUMBERELEMENTSDIALOG_H
|
||||||
@@ -319,10 +319,23 @@ void projectDataBase::addElement(Element *element)
|
|||||||
void projectDataBase::removeElement(Element *element)
|
void projectDataBase::removeElement(Element *element)
|
||||||
{
|
{
|
||||||
m_content_changed = true;
|
m_content_changed = true;
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
m_remove_element_query.bindValue(":uuid", element->uuid().toString());
|
m_remove_element_query.bindValue(":uuid", element->uuid().toString());
|
||||||
if(!m_remove_element_query.exec()) {
|
if (m_remove_element_query.exec()) {
|
||||||
qDebug() << "projectDataBase::removeElement remove error : " << m_remove_element_query.lastError();
|
changed = true;
|
||||||
} else {
|
} else {
|
||||||
|
qDebug() << "projectDataBase::removeElement remove error : " << m_remove_element_query.lastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_remove_element_info_query.bindValue(":uuid", element->uuid().toString());
|
||||||
|
if (m_remove_element_info_query.exec()) {
|
||||||
|
changed = true;
|
||||||
|
} else {
|
||||||
|
qDebug() << "projectDataBase::removeElement remove element_info error : " << m_remove_element_info_query.lastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
emit dataBaseUpdated();
|
emit dataBaseUpdated();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1159,6 +1172,21 @@ void projectDataBase::prepareQuery()
|
|||||||
m_remove_element_query = QSqlQuery(m_data_base);
|
m_remove_element_query = QSqlQuery(m_data_base);
|
||||||
m_remove_element_query.prepare(remove_element);
|
m_remove_element_query.prepare(remove_element);
|
||||||
|
|
||||||
|
//REMOVE ELEMENT INFO
|
||||||
|
//element_info has no ON DELETE CASCADE (foreign keys aren't
|
||||||
|
//enforced by this connection), so removeElement() must clear it
|
||||||
|
//explicitly. Without this, the row is orphaned under the removed
|
||||||
|
//element's uuid, and re-adding an element with that same uuid
|
||||||
|
//later -- undo of this same removal, or a redo replaying it --
|
||||||
|
//hits element_info's PRIMARY KEY constraint on element_uuid: the
|
||||||
|
//element re-add succeeds, but its element_info insert silently
|
||||||
|
//fails and is lost. removeDiagram()'s cascade already clears this
|
||||||
|
//table when a whole folio goes, but that does not run for a
|
||||||
|
//single element removed on its own.
|
||||||
|
QString remove_element_info("DELETE FROM element_info WHERE element_uuid=:uuid");
|
||||||
|
m_remove_element_info_query = QSqlQuery(m_data_base);
|
||||||
|
m_remove_element_info_query.prepare(remove_element_info);
|
||||||
|
|
||||||
//UPDATE ELEMENT INFO
|
//UPDATE ELEMENT INFO
|
||||||
QString update_str("UPDATE element_info SET ");
|
QString update_str("UPDATE element_info SET ");
|
||||||
for (auto string : QETInformation::elementInfoKeys()) {
|
for (auto string : QETInformation::elementInfoKeys()) {
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ class QETProject;
|
|||||||
class Diagram;
|
class Diagram;
|
||||||
class Conductor;
|
class Conductor;
|
||||||
class Terminal;
|
class Terminal;
|
||||||
class sqlite3;
|
struct sqlite3;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief The projectDataBase class
|
@brief The projectDataBase class
|
||||||
@@ -139,6 +139,7 @@ class projectDataBase : public QObject
|
|||||||
QSqlQuery m_insert_elements_query,
|
QSqlQuery m_insert_elements_query,
|
||||||
m_insert_element_info_query,
|
m_insert_element_info_query,
|
||||||
m_remove_element_query,
|
m_remove_element_query,
|
||||||
|
m_remove_element_info_query,
|
||||||
m_update_element_query,
|
m_update_element_query,
|
||||||
m_insert_diagram_query,
|
m_insert_diagram_query,
|
||||||
m_remove_diagram_query,
|
m_remove_diagram_query,
|
||||||
|
|||||||
@@ -77,6 +77,23 @@ void PasteDiagramCommand::redo()
|
|||||||
{
|
{
|
||||||
first_redo = false;
|
first_redo = false;
|
||||||
|
|
||||||
|
//Resolve a linked master/slave pair pasted together (bugtracker
|
||||||
|
//#607) before anything below renews their uuids: at this exact
|
||||||
|
//moment a pasted element's tmp_uuids_link still holds its
|
||||||
|
//source's original partner uuid, which still equals the
|
||||||
|
//not-yet-renewed uuid of that partner's own pasted copy if it
|
||||||
|
//was carried along in the same batch. Scoped to this batch only
|
||||||
|
//(not a project-wide search), so a pair pasted together links to
|
||||||
|
//each other and not to an original element left elsewhere that
|
||||||
|
//happens to still carry that same soon-to-be-replaced uuid. If
|
||||||
|
//only one half of a linked group was pasted, its link entry
|
||||||
|
//simply finds no match here and is dropped -- same "leave it
|
||||||
|
//unlinked" outcome as always.
|
||||||
|
const QList <Element *> elmts_list = content.m_elements;
|
||||||
|
for (Element *e : elmts_list) {
|
||||||
|
e->initLink(elmts_list);
|
||||||
|
}
|
||||||
|
|
||||||
//make new uuid for every pasted conductor, because old uuid are
|
//make new uuid for every pasted conductor, because old uuid are
|
||||||
//the uuid of the copied conductor
|
//the uuid of the copied conductor
|
||||||
const QList <Conductor *> all_pasted_conductors = content.conductors();
|
const QList <Conductor *> all_pasted_conductors = content.conductors();
|
||||||
@@ -85,7 +102,6 @@ void PasteDiagramCommand::redo()
|
|||||||
}
|
}
|
||||||
|
|
||||||
//this is the first paste, we do some actions for the new element
|
//this is the first paste, we do some actions for the new element
|
||||||
const QList <Element *> elmts_list = content.m_elements;
|
|
||||||
for (Element *e : elmts_list)
|
for (Element *e : elmts_list)
|
||||||
{
|
{
|
||||||
//make new uuid, because old uuid are the uuid of the copied element
|
//make new uuid, because old uuid are the uuid of the copied element
|
||||||
|
|||||||
@@ -1477,7 +1477,7 @@ void DiagramView::createTemplateFromSelection()
|
|||||||
|
|
||||||
collection_node.appendChild(collection_elmt);
|
collection_node.appendChild(collection_elmt);
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "Warnung: Konnte XML-Definition für" << old_type << "nicht laden.";
|
qDebug() << "Warning: could not load XML definition for" << old_type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "elementpropertieseditorwidget.h"
|
#include "elementpropertieseditorwidget.h"
|
||||||
|
|
||||||
|
#include "../../qet.h"
|
||||||
#include "../../qetapp.h"
|
#include "../../qetapp.h"
|
||||||
#include "../../qetinformation.h"
|
#include "../../qetinformation.h"
|
||||||
#include "ui_elementpropertieseditorwidget.h"
|
#include "ui_elementpropertieseditorwidget.h"
|
||||||
@@ -185,13 +186,13 @@ void ElementPropertiesEditorWidget::upDateInterface()
|
|||||||
|
|
||||||
const DiagramContext &info = m_data.m_informations;
|
const DiagramContext &info = m_data.m_informations;
|
||||||
ui->m_auto_num_locked_cb->setChecked(
|
ui->m_auto_num_locked_cb->setChecked(
|
||||||
info.value(QStringLiteral("auto_num_locked")).toString() == QLatin1String("true"));
|
QET::infoFlagIsTrue(info.value(QStringLiteral("auto_num_locked")).toString()));
|
||||||
ui->m_potential_isolating_cb->setChecked(
|
ui->m_potential_isolating_cb->setChecked(
|
||||||
info.value(QStringLiteral("potential_isolating")).toString() == QLatin1String("true"));
|
QET::infoFlagIsTrue(info.value(QStringLiteral("potential_isolating")).toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->m_exclude_from_bom_cb->setChecked(
|
ui->m_exclude_from_bom_cb->setChecked(
|
||||||
m_data.m_informations.value(QStringLiteral("exclude_from_bom")).toString() == QLatin1String("true"));
|
QET::infoFlagIsTrue(m_data.m_informations.value(QStringLiteral("exclude_from_bom")).toString()));
|
||||||
|
|
||||||
on_m_base_type_cb_currentIndexChanged(ui->m_base_type_cb->currentIndex());
|
on_m_base_type_cb_currentIndexChanged(ui->m_base_type_cb->currentIndex());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
#include "../../qetapp.h"
|
#include "../../qetapp.h"
|
||||||
#include "../../qetmainwindow.h"
|
#include "../../qetmainwindow.h"
|
||||||
#include "../../recentfiles.h"
|
#include "../../recentfiles.h"
|
||||||
|
#include "../../elementscollectioncache.h"
|
||||||
|
#include "../../factory/elementpicturefactory.h"
|
||||||
#include "../graphicspart/customelementpart.h"
|
#include "../graphicspart/customelementpart.h"
|
||||||
#include "../elementitemeditor.h"
|
#include "../elementitemeditor.h"
|
||||||
#include "../styleeditor.h"
|
#include "../styleeditor.h"
|
||||||
@@ -348,6 +350,24 @@ bool QETElementEditor::toLocation(const ElementsLocation &location)
|
|||||||
tr("Impossible d'enregistrer l'élément", "message box content"));
|
tr("Impossible d'enregistrer l'élément", "message box content"));
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//setXml() just wrote the new drawing to disk, but the preview shown
|
||||||
|
//in the elements panel comes from two caches keyed by path+uuid that
|
||||||
|
//nothing here has told about the change: ElementPictureFactory's
|
||||||
|
//in-memory picture cache and ElementsCollectionCache's on-disk
|
||||||
|
//SQLite cache (see ElementsLocation::icon()). locationWasSaved()
|
||||||
|
//(elementscollectionwidget.cpp) re-reads the icon right after this
|
||||||
|
//call returns, but both caches still hand back the pre-edit pixmap,
|
||||||
|
//so the panel keeps showing the stale preview until the whole
|
||||||
|
//collection is reloaded. Drop and rebuild them here.
|
||||||
|
ElementPictureFactory::instance()->dropCache(location);
|
||||||
|
if (ElementsCollectionCache *cache = QETApp::collectionCache()) {
|
||||||
|
if (cache->fetchData(location)) {
|
||||||
|
cache->cacheName(location.toString(), location.uuid());
|
||||||
|
cache->cachePixmap(location.toString(), location.uuid());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return(true);
|
return(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -674,6 +674,27 @@ void ElementsPanelWidget::duplicateDiagram()
|
|||||||
bool erase_labels = settings.value(
|
bool erase_labels = settings.value(
|
||||||
"diagramcommands/erase-label-on-copy", true).toBool();
|
"diagramcommands/erase-label-on-copy", true).toBool();
|
||||||
|
|
||||||
|
// Resolve a linked pair duplicated together against each other
|
||||||
|
// (bugtracker #607) before the loop below renews their uuids or
|
||||||
|
// clears their pending links: at this exact moment a copy's
|
||||||
|
// tmp_uuids_link still holds its source's original partner
|
||||||
|
// uuid, which still equals the not-yet-renewed uuid of that
|
||||||
|
// partner's own copy if both were duplicated together. Scoped
|
||||||
|
// to this diagram's own copies, not a project-wide search, so
|
||||||
|
// this never links back to the source elements the copies were
|
||||||
|
// made from -- if only one half of a linked pair is here, its
|
||||||
|
// link entry simply finds no match and is dropped, same as
|
||||||
|
// clearPendingLinks() used to do unconditionally for every copy.
|
||||||
|
QList<Element *> new_elements;
|
||||||
|
for (QGraphicsItem *item : new_diagram->items()) {
|
||||||
|
if (Element *elmt = dynamic_cast<Element *>(item)) {
|
||||||
|
new_elements << elmt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Element *elmt : new_elements) {
|
||||||
|
elmt->initLink(new_elements);
|
||||||
|
}
|
||||||
|
|
||||||
for (QGraphicsItem *item : new_diagram->items()) {
|
for (QGraphicsItem *item : new_diagram->items()) {
|
||||||
if (Element *elmt = dynamic_cast<Element *>(item)) {
|
if (Element *elmt = dynamic_cast<Element *>(item)) {
|
||||||
// The XML round-trip kept the source elements' uuids. Give the
|
// The XML round-trip kept the source elements' uuids. Give the
|
||||||
@@ -695,9 +716,9 @@ void ElementsPanelWidget::duplicateDiagram()
|
|||||||
new_diagram->restoreText(elmt);
|
new_diagram->restoreText(elmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear pending links so copies don't link back to
|
// initLink() above already cleared tmp_uuids_link for
|
||||||
// the source elements via stale UUIDs.
|
// every copy, matched or not -- nothing left here that
|
||||||
elmt->clearPendingLinks();
|
// could link back to a stale source uuid.
|
||||||
|
|
||||||
// Clean up copied element data:
|
// Clean up copied element data:
|
||||||
// 1. Slaves always lose label/formula/comment/location
|
// 1. Slaves always lose label/formula/comment/location
|
||||||
|
|||||||
@@ -22,6 +22,8 @@
|
|||||||
#include "logging/eventloopwatchdog.h"
|
#include "logging/eventloopwatchdog.h"
|
||||||
#include "logging/qetlogger.h"
|
#include "logging/qetlogger.h"
|
||||||
#include "machine_info.h"
|
#include "machine_info.h"
|
||||||
|
#include "diagram.h"
|
||||||
|
#include "palettegraphicsview.h"
|
||||||
#include "qet.h"
|
#include "qet.h"
|
||||||
#include "qetapp.h"
|
#include "qetapp.h"
|
||||||
#include "qetmessagebox.h"
|
#include "qetmessagebox.h"
|
||||||
@@ -31,6 +33,7 @@
|
|||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDomImplementation>
|
#include <QDomImplementation>
|
||||||
|
#include <QFont>
|
||||||
|
|
||||||
#include <QStyleFactory>
|
#include <QStyleFactory>
|
||||||
#include <QtConcurrentRun>
|
#include <QtConcurrentRun>
|
||||||
@@ -105,6 +108,19 @@ int main(int argc, char **argv)
|
|||||||
// from Qt 6.12 on; opt in explicitly for older Qt 5/6.
|
// from Qt 6.12 on; opt in explicitly for older Qt 5/6.
|
||||||
QDomImplementation::setInvalidDataPolicy(
|
QDomImplementation::setInvalidDataPolicy(
|
||||||
QDomImplementation::ReturnNullNode);
|
QDomImplementation::ReturnNullNode);
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
// "MS Shell Dlg 2" is not a font but a Windows alias, and many projects
|
||||||
|
// and settings saved on Windows carry it. Qt 5's GDI font backend let
|
||||||
|
// Windows resolve it to Tahoma; Qt 6's DirectWrite backend does not know
|
||||||
|
// the alias and falls back to Arial, so those texts come out heavier on
|
||||||
|
// screen and in exported PDFs (bugtracker #340). Resolve both aliases
|
||||||
|
// the way Windows does. Done before any application object exists so
|
||||||
|
// that the headless export and scripting runs below get it too.
|
||||||
|
QFont::insertSubstitution("MS Shell Dlg 2", "Tahoma");
|
||||||
|
QFont::insertSubstitution("MS Shell Dlg", "Microsoft Sans Serif");
|
||||||
|
#endif
|
||||||
|
|
||||||
//Creation and execution of the application
|
//Creation and execution of the application
|
||||||
//HighDPI
|
//HighDPI
|
||||||
qputenv("QT_ENABLE_HIGHDPI_SCALING", "1");
|
qputenv("QT_ENABLE_HIGHDPI_SCALING", "1");
|
||||||
@@ -144,6 +160,22 @@ int main(int argc, char **argv)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Re-apply the sheet background last picked in the diagram editor, so
|
||||||
|
// every project opened from here on -- existing or new, whichever one
|
||||||
|
// it is -- draws that background instead of the built-in default that
|
||||||
|
// would otherwise force the user to pick it again after each start.
|
||||||
|
//
|
||||||
|
// Done here rather than in main()'s first lines on purpose: the
|
||||||
|
// headless export and scripting runs above return before reaching
|
||||||
|
// this point and must keep rendering on plain white. It also has to
|
||||||
|
// happen before QETApp is constructed below, since that constructor
|
||||||
|
// already loads the projects given on the command line.
|
||||||
|
{
|
||||||
|
const QetSettings::SheetBackground sheet_background = QetSettings::sheetBackground();
|
||||||
|
PaletteGraphicsView::setCustomBackgroundColor(sheet_background.custom);
|
||||||
|
Diagram::background_color = sheet_background.color;
|
||||||
|
}
|
||||||
|
|
||||||
// Resolve the logger's state (log directory, session filename, open
|
// Resolve the logger's state (log directory, session filename, open
|
||||||
// file handle) explicitly here, immediately before installing the
|
// file handle) explicitly here, immediately before installing the
|
||||||
// handler -- not implicitly on whichever thread happens to log
|
// handler -- not implicitly on whichever thread happens to log
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "qeticons.h"
|
#include "qeticons.h"
|
||||||
#include "shortcutmanager.h"
|
#include "shortcutmanager.h"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <QBuffer>
|
#include <QBuffer>
|
||||||
#include <QColorDialog>
|
#include <QColorDialog>
|
||||||
@@ -244,10 +245,33 @@ bool QET::attributeIsAReal(
|
|||||||
bool ok;
|
bool ok;
|
||||||
qreal tmp = e.attribute(nom_attribut).toDouble(&ok);
|
qreal tmp = e.attribute(nom_attribut).toDouble(&ok);
|
||||||
if (!ok) return(false);
|
if (!ok) return(false);
|
||||||
|
// QString::toDouble() sets ok=true for "nan"/"inf"/"-inf" -- these
|
||||||
|
// parse successfully but are not usable coordinates. A non-finite
|
||||||
|
// element/terminal position reaches Conductor::shape() during load
|
||||||
|
// and hangs there at 100% CPU inside QPainterPathStroker::createStroke(),
|
||||||
|
// confirmed with gdb: not a blocked wait, genuine unbounded computation.
|
||||||
|
if (!std::isfinite(tmp)) return(false);
|
||||||
if (reel != nullptr) *reel = tmp;
|
if (reel != nullptr) *reel = tmp;
|
||||||
return(true);
|
return(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief QET::infoFlagIsTrue
|
||||||
|
@see the header comment for why this exists rather than a bare
|
||||||
|
== "true" comparison.
|
||||||
|
@param value the raw elementInformations string to test
|
||||||
|
@return true if @p value, trimmed and case-folded, is one of the
|
||||||
|
truthy spellings this codebase already accepts elsewhere
|
||||||
|
*/
|
||||||
|
bool QET::infoFlagIsTrue(const QString &value)
|
||||||
|
{
|
||||||
|
const QString v = value.trimmed().toLower();
|
||||||
|
return v == QLatin1String("true")
|
||||||
|
|| v == QLatin1String("1")
|
||||||
|
|| v == QLatin1String("yes")
|
||||||
|
|| v == QLatin1String("on");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief QET::ElementsAndConductorsSentence
|
@brief QET::ElementsAndConductorsSentence
|
||||||
Permet de composer rapidement la proposition "x elements et y conducteurs"
|
Permet de composer rapidement la proposition "x elements et y conducteurs"
|
||||||
|
|||||||
@@ -161,6 +161,22 @@ namespace QET {
|
|||||||
bool orthogonalProjection(const QPointF &, const QLineF &, QPointF * = nullptr);
|
bool orthogonalProjection(const QPointF &, const QLineF &, QPointF * = nullptr);
|
||||||
bool attributeIsAnInteger(const QDomElement &, const QString& , int * = nullptr);
|
bool attributeIsAnInteger(const QDomElement &, const QString& , int * = nullptr);
|
||||||
bool attributeIsAReal(const QDomElement &, const QString& , qreal * = nullptr);
|
bool attributeIsAReal(const QDomElement &, const QString& , qreal * = nullptr);
|
||||||
|
/**
|
||||||
|
Whether an elementInformations flag (auto_num_locked,
|
||||||
|
potential_isolating, exclude_from_bom, ...) counts as "on".
|
||||||
|
Case-insensitive and tolerant of surrounding whitespace, and
|
||||||
|
accepts the same set of truthy spellings ("true", "1", "yes",
|
||||||
|
"on") that element_nomenclature_view's SQL predicate for
|
||||||
|
exclude_from_bom already does -- see
|
||||||
|
projectDataBase::createElementNomenclatureView(). These flags
|
||||||
|
are only ever written by this app's own checkboxes as literal
|
||||||
|
"true"/"false" today, but a bare == "true" comparison silently
|
||||||
|
treats anything else -- "True", "TRUE", a trailing space from
|
||||||
|
a hand-edited file, a value some other tool wrote -- as off,
|
||||||
|
with no error and no visible difference from the checkbox
|
||||||
|
being genuinely unticked (discussion #785).
|
||||||
|
*/
|
||||||
|
bool infoFlagIsTrue(const QString &value);
|
||||||
QString ElementsAndConductorsSentence(int elements=0,
|
QString ElementsAndConductorsSentence(int elements=0,
|
||||||
int conductors=0,
|
int conductors=0,
|
||||||
int indi_texts=0,
|
int indi_texts=0,
|
||||||
|
|||||||
+25
-1
@@ -43,6 +43,10 @@
|
|||||||
#include "machine_info.h"
|
#include "machine_info.h"
|
||||||
#include "TerminalStrip/ui/terminalstripeditorwindow.h"
|
#include "TerminalStrip/ui/terminalstripeditorwindow.h"
|
||||||
#include "qetversion.h"
|
#include "qetversion.h"
|
||||||
|
#ifdef QET_SPACEMOUSE_SUPPORT
|
||||||
|
# include "spacemouse/spacemouselistener.h"
|
||||||
|
# include "ui/configpage/spacemouseconfigpage.h"
|
||||||
|
#endif
|
||||||
#include "logging/qetlogger.h"
|
#include "logging/qetlogger.h"
|
||||||
#include "logging/ui/diagnosticsreportdialog.h"
|
#include "logging/ui/diagnosticsreportdialog.h"
|
||||||
|
|
||||||
@@ -164,7 +168,24 @@ QETApp::QETApp() :
|
|||||||
m_splash_screen -> hide();
|
m_splash_screen -> hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
checkBackupFiles();
|
#ifdef QET_SPACEMOUSE_SUPPORT
|
||||||
|
//Always safe to construct: it silently does nothing when spacenavd
|
||||||
|
//isn't running or no device is attached, which is the common case
|
||||||
|
//even in a build with this feature compiled in. See
|
||||||
|
//SpaceMouseListener's class comment.
|
||||||
|
m_space_mouse_listener = new SpaceMouseListener(this);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//Deferred so this constructor returns before the prompts appear.
|
||||||
|
//checkBackupFiles() opens modal dialogs, and main() still has work to
|
||||||
|
//do once we return -- in particular connecting
|
||||||
|
//SingleApplication::receivedMessage to receiveMessage(). While those
|
||||||
|
//prompts were up that connection did not exist yet, so a file handed
|
||||||
|
//to the already-running instance during start-up was accepted by the
|
||||||
|
//socket and then dropped on the floor.
|
||||||
|
QMetaObject::invokeMethod(this, [this]() {
|
||||||
|
checkBackupFiles();
|
||||||
|
}, Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2192,6 +2213,9 @@ void QETApp::configureQET()
|
|||||||
cd.addPage(new ExportConfigPage());
|
cd.addPage(new ExportConfigPage());
|
||||||
cd.addPage(new PrintConfigPage());
|
cd.addPage(new PrintConfigPage());
|
||||||
cd.addPage(new ShortcutsConfigPage());
|
cd.addPage(new ShortcutsConfigPage());
|
||||||
|
#ifdef QET_SPACEMOUSE_SUPPORT
|
||||||
|
cd.addPage(new SpaceMouseConfigPage());
|
||||||
|
#endif
|
||||||
|
|
||||||
// associates the dialog with a possible parent widget
|
// associates the dialog with a possible parent widget
|
||||||
// associe le dialogue a un eventuel widget parent
|
// associe le dialogue a un eventuel widget parent
|
||||||
|
|||||||
@@ -48,6 +48,9 @@ class QETProject;
|
|||||||
class QETTitleBlockTemplateEditor;
|
class QETTitleBlockTemplateEditor;
|
||||||
class QTextOrientationSpinBoxWidget;
|
class QTextOrientationSpinBoxWidget;
|
||||||
class RecentFiles;
|
class RecentFiles;
|
||||||
|
#ifdef QET_SPACEMOUSE_SUPPORT
|
||||||
|
class SpaceMouseListener;
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief The QETApp class
|
@brief The QETApp class
|
||||||
@@ -229,6 +232,13 @@ class QETApp : public QObject
|
|||||||
static TitleBlockTemplatesFilesCollection *m_company_tbt_collection;
|
static TitleBlockTemplatesFilesCollection *m_company_tbt_collection;
|
||||||
static TitleBlockTemplatesFilesCollection *m_custom_tbt_collection;
|
static TitleBlockTemplatesFilesCollection *m_custom_tbt_collection;
|
||||||
static ElementsCollectionCache *collections_cache_;
|
static ElementsCollectionCache *collections_cache_;
|
||||||
|
#ifdef QET_SPACEMOUSE_SUPPORT
|
||||||
|
/// One per application, not per window: a physical 6-DOF device
|
||||||
|
/// is a single ambient input source, and motion is applied to
|
||||||
|
/// whichever DiagramView is currently active. See
|
||||||
|
/// SpaceMouseListener's class comment.
|
||||||
|
SpaceMouseListener *m_space_mouse_listener = nullptr;
|
||||||
|
#endif
|
||||||
static QMap<uint, QETProject *> registered_projects_;
|
static QMap<uint, QETProject *> registered_projects_;
|
||||||
static uint next_project_id;
|
static uint next_project_id;
|
||||||
static RecentFiles *m_projects_recent_files;
|
static RecentFiles *m_projects_recent_files;
|
||||||
|
|||||||
@@ -1856,7 +1856,18 @@ void QETDiagramEditor::selectionGroupTriggered(QAction *action)
|
|||||||
diagram->undoStack().push(c);
|
diagram->undoStack().push(c);
|
||||||
}
|
}
|
||||||
else if (value == "rotate_selected_text")
|
else if (value == "rotate_selected_text")
|
||||||
diagram->undoStack().push(new RotateTextsCommand(diagram));
|
{
|
||||||
|
//Ask for the angle first, then build the command: the command
|
||||||
|
//itself no longer opens a dialog. Guarding on the selection keeps
|
||||||
|
//the previous behaviour of showing no dialog when there is
|
||||||
|
//nothing to rotate.
|
||||||
|
if (RotateTextsCommand::hasSelectedTexts(diagram))
|
||||||
|
{
|
||||||
|
qreal rotation = 0;
|
||||||
|
if (RotateTextsCommand::askRotation(rotation))
|
||||||
|
diagram->undoStack().push(new RotateTextsCommand(diagram, rotation));
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (value == "find_selected_element" && currentElement())
|
else if (value == "find_selected_element" && currentElement())
|
||||||
findElementInPanel(currentElement()->location());
|
findElementInPanel(currentElement()->location());
|
||||||
else if (value == "edit_selected_element")
|
else if (value == "edit_selected_element")
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
#include <QDomElement>
|
#include <QDomElement>
|
||||||
#include <QtCore/qnumeric.h>
|
#include <QtCore/qnumeric.h>
|
||||||
#include <QGraphicsSceneMouseEvent>
|
#include <QGraphicsSceneMouseEvent>
|
||||||
|
#include <QAbstractTextDocumentLayout>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief DynamicElementTextItem::DynamicElementTextItem
|
@brief DynamicElementTextItem::DynamicElementTextItem
|
||||||
@@ -732,19 +733,6 @@ void DynamicElementTextItem::paint(QPainter *painter, const QStyleOptionGraphics
|
|||||||
{
|
{
|
||||||
DiagramTextItem::paint(painter, option, widget);
|
DiagramTextItem::paint(painter, option, widget);
|
||||||
|
|
||||||
//Only ever repositions already-existing sibling items here --
|
|
||||||
//never adds or removes one. paint() runs while QGraphicsScene is
|
|
||||||
//iterating its item list to draw it, and mutating that list mid
|
|
||||||
//-iteration (which addResizeHandles()/removeResizeHandles() do,
|
|
||||||
//through QGraphicsScene::addItem()/removeItem()) crashes. An
|
|
||||||
//earlier version of this fix called them from here and crashed
|
|
||||||
//qelectrotech reproducibly on deselecting a text (SIGABRT); see
|
|
||||||
//refreshResizeHandlesVisibility() for where that now happens
|
|
||||||
//instead -- itemChange(), Qt's own safe hook for exactly this,
|
|
||||||
//already used below for this item's own selection.
|
|
||||||
if (m_left_resize_handle || m_right_resize_handle)
|
|
||||||
updateResizeHandlesPos();
|
|
||||||
|
|
||||||
if (m_frame)
|
if (m_frame)
|
||||||
{
|
{
|
||||||
painter->save();
|
painter->save();
|
||||||
@@ -927,11 +915,17 @@ void DynamicElementTextItem::addResizeHandles()
|
|||||||
|
|
||||||
for (QetGraphicsHandlerItem *handle : {m_left_resize_handle, m_right_resize_handle})
|
for (QetGraphicsHandlerItem *handle : {m_left_resize_handle, m_right_resize_handle})
|
||||||
{
|
{
|
||||||
scene()->addItem(handle);
|
//Children of this text, not free scene items: Qt then carries
|
||||||
|
//them along when the parent element moves, rotates or is
|
||||||
|
//zoomed, and repaints their old and new area in the same
|
||||||
|
//update as this text. Moving free items from paint() instead
|
||||||
|
//left green fragments behind (qelectrotech#1002).
|
||||||
|
handle->setParentItem(this);
|
||||||
handle->setColor(Qt::darkGreen);
|
handle->setColor(Qt::darkGreen);
|
||||||
handle->setZValue(zValue() + 1);
|
|
||||||
handle->installSceneEventFilter(this);
|
handle->installSceneEventFilter(this);
|
||||||
}
|
}
|
||||||
|
m_resize_handles_con = connect(document()->documentLayout(), &QAbstractTextDocumentLayout::documentSizeChanged,
|
||||||
|
this, &DynamicElementTextItem::updateResizeHandlesPos);
|
||||||
|
|
||||||
updateResizeHandlesPos();
|
updateResizeHandlesPos();
|
||||||
}
|
}
|
||||||
@@ -941,6 +935,7 @@ void DynamicElementTextItem::addResizeHandles()
|
|||||||
*/
|
*/
|
||||||
void DynamicElementTextItem::removeResizeHandles()
|
void DynamicElementTextItem::removeResizeHandles()
|
||||||
{
|
{
|
||||||
|
disconnect(m_resize_handles_con);
|
||||||
delete m_left_resize_handle;
|
delete m_left_resize_handle;
|
||||||
delete m_right_resize_handle;
|
delete m_right_resize_handle;
|
||||||
m_left_resize_handle = nullptr;
|
m_left_resize_handle = nullptr;
|
||||||
@@ -973,8 +968,8 @@ void DynamicElementTextItem::updateResizeHandlesPos()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
QRectF br = boundingRect();
|
QRectF br = boundingRect();
|
||||||
m_left_resize_handle->setPos(mapToScene(QPointF(br.left(), br.center().y())));
|
m_left_resize_handle->setPos(br.left(), br.center().y());
|
||||||
m_right_resize_handle->setPos(mapToScene(QPointF(br.right(), br.center().y())));
|
m_right_resize_handle->setPos(br.right(), br.center().y());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -200,6 +200,7 @@ class DynamicElementTextItem : public DiagramTextItem
|
|||||||
qreal m_resize_original_width = -1;
|
qreal m_resize_original_width = -1;
|
||||||
qreal m_resize_baseline_width = -1;
|
qreal m_resize_baseline_width = -1;
|
||||||
qreal m_resize_start_local_x = 0;
|
qreal m_resize_start_local_x = 0;
|
||||||
|
QMetaObject::Connection m_resize_handles_con;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DYNAMICELEMENTTEXTITEM_H
|
#endif // DYNAMICELEMENTTEXTITEM_H
|
||||||
|
|||||||
@@ -39,7 +39,9 @@
|
|||||||
#include "elementtextitemgroup.h"
|
#include "elementtextitemgroup.h"
|
||||||
#include "iostream"
|
#include "iostream"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
#include <QCollator>
|
#include <QCollator>
|
||||||
|
#include <QScreen>
|
||||||
|
|
||||||
static const QString plcTerminalKeys[] = {
|
static const QString plcTerminalKeys[] = {
|
||||||
QETInformation::ELMT_PLC_T1,
|
QETInformation::ELMT_PLC_T1,
|
||||||
@@ -209,6 +211,21 @@ void Element::editProperty()
|
|||||||
//with the "text" tab of ElementPropertiesWidget,
|
//with the "text" tab of ElementPropertiesWidget,
|
||||||
//the ui freeze, until user press escape key
|
//the ui freeze, until user press escape key
|
||||||
dialog.setWindowModality(Qt::WindowModal);
|
dialog.setWindowModality(Qt::WindowModal);
|
||||||
|
|
||||||
|
// A PLC master carries a 6-column IO table: without an explicit
|
||||||
|
// size the dialog falls back to its (cramped) sizeHint, so open it
|
||||||
|
// at three times its natural width instead. The height stays at
|
||||||
|
// the natural one, and the width never exceeds the screen.
|
||||||
|
const ElementData data = elementData();
|
||||||
|
if (data.m_type == ElementData::Master
|
||||||
|
&& data.m_master_type == ElementData::PLC) {
|
||||||
|
const QSize natural = dialog.sizeHint();
|
||||||
|
int width = natural.width() * 3;
|
||||||
|
if (QScreen *screen = QApplication::primaryScreen())
|
||||||
|
width = qMin(width, screen->availableGeometry().width());
|
||||||
|
dialog.resize(width, natural.height());
|
||||||
|
}
|
||||||
|
|
||||||
dialog.exec();
|
dialog.exec();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1369,6 +1386,33 @@ void Element::initLink(QETProject *prj)
|
|||||||
tmp_uuids_link.clear();
|
tmp_uuids_link.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Element::initLink
|
||||||
|
Overload resolving tmp_uuids_link against @p candidates instead of a
|
||||||
|
project-wide ElementProvider search -- see the header comment for
|
||||||
|
why the search has to be scoped this way right after a paste or
|
||||||
|
folio-duplication XML round-trip, before uuids are renewed.
|
||||||
|
@param candidates the elements to search for a link partner in
|
||||||
|
*/
|
||||||
|
void Element::initLink(const QList<Element *> &candidates)
|
||||||
|
{
|
||||||
|
// if nothing to link return now
|
||||||
|
if (tmp_uuids_link.isEmpty()) return;
|
||||||
|
|
||||||
|
for (int i = 0; i < tmp_uuids_link.size(); ++i) {
|
||||||
|
for (Element *elmt : candidates) {
|
||||||
|
if (elmt->uuid() == tmp_uuids_link[i].uuid) {
|
||||||
|
elmt->linkToElement(this);
|
||||||
|
if (tmp_uuids_link[i].group_index >= 0) {
|
||||||
|
m_group_index_map[elmt] = tmp_uuids_link[i].group_index;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tmp_uuids_link.clear();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Element::linkTypeToString
|
* @brief Element::linkTypeToString
|
||||||
* \deprecated use instead ElementData::typeToString
|
* \deprecated use instead ElementData::typeToString
|
||||||
|
|||||||
@@ -207,6 +207,25 @@ class Element : public QetGraphicsItem
|
|||||||
virtual void unlinkAllElements() {}
|
virtual void unlinkAllElements() {}
|
||||||
virtual void unlinkElement(Element *) {}
|
virtual void unlinkElement(Element *) {}
|
||||||
virtual void initLink(QETProject *);
|
virtual void initLink(QETProject *);
|
||||||
|
/**
|
||||||
|
Resolve tmp_uuids_link against a caller-supplied candidate
|
||||||
|
list instead of a project-wide search (bugtracker #607).
|
||||||
|
Used right after an XML round-trip (paste, folio
|
||||||
|
duplication) and before the pasted/duplicated elements'
|
||||||
|
uuids are renewed: at that moment a copy's tmp_uuids_link
|
||||||
|
still holds its source's original partner uuid, which
|
||||||
|
still matches the not-yet-renewed uuid of that partner's
|
||||||
|
own copy if it was carried along in the same batch.
|
||||||
|
Resolving only within @p candidates -- not the whole
|
||||||
|
project -- is what stops a linked pair pasted together
|
||||||
|
from matching an original element left elsewhere that
|
||||||
|
happens to still carry that same soon-to-be-replaced
|
||||||
|
uuid. If only one half of a linked group is in
|
||||||
|
@p candidates, its entry finds no match and is dropped,
|
||||||
|
same as initLink(QETProject *) leaving an unresolvable
|
||||||
|
link unlinked.
|
||||||
|
*/
|
||||||
|
void initLink(const QList<Element *> &candidates);
|
||||||
QList<Element *> linkedElements ();
|
QList<Element *> linkedElements ();
|
||||||
|
|
||||||
int groupIndexForElement(Element *elmt) const;
|
int groupIndexForElement(Element *elmt) const;
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include "../qetgraphicsitem/terminal.h"
|
#include "../qetgraphicsitem/terminal.h"
|
||||||
|
#include "../qet.h"
|
||||||
#include "../qetproject.h"
|
#include "../qetproject.h"
|
||||||
#include "../conductorautonumerotation.h"
|
#include "../conductorautonumerotation.h"
|
||||||
#include "../diagram.h"
|
#include "../diagram.h"
|
||||||
@@ -986,7 +987,7 @@ QList<Terminal *> relatedPotentialTerminal (
|
|||||||
else if (terminal -> parentElement() -> linkType() & Element::Terminale)
|
else if (terminal -> parentElement() -> linkType() & Element::Terminale)
|
||||||
{
|
{
|
||||||
// English: Check if the user activated the potential isolation checkbox for this terminal
|
// English: Check if the user activated the potential isolation checkbox for this terminal
|
||||||
if (terminal->parentElement()->elementInformations().value(QStringLiteral("potential_isolating")).toString() == QLatin1String("true")) {
|
if (QET::infoFlagIsTrue(terminal->parentElement()->elementInformations().value(QStringLiteral("potential_isolating")).toString())) {
|
||||||
// English: Potential is isolated. Return an empty list so it does not propagate to the other side.
|
// English: Potential is isolated. Return an empty list so it does not propagate to the other side.
|
||||||
return QList<Terminal *>();
|
return QList<Terminal *>();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,9 @@
|
|||||||
#include "autoNum/assignvariables.h"
|
#include "autoNum/assignvariables.h"
|
||||||
#include "autoNum/numerotationcontext.h"
|
#include "autoNum/numerotationcontext.h"
|
||||||
#include "autoNum/numerotationcontextcommands.h"
|
#include "autoNum/numerotationcontextcommands.h"
|
||||||
|
#include "autoNum/renumberelementscommand.h"
|
||||||
#include "diagram.h"
|
#include "diagram.h"
|
||||||
|
#include "qetgraphicsitem/element.h"
|
||||||
#include "qetapp.h"
|
#include "qetapp.h"
|
||||||
#include "qetmessagebox.h"
|
#include "qetmessagebox.h"
|
||||||
#include "qetresult.h"
|
#include "qetresult.h"
|
||||||
@@ -40,7 +42,30 @@
|
|||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QtConcurrentRun>
|
#include <QtConcurrentRun>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reset numeric fields of a NumerotationContext so renumbering starts at 1.
|
||||||
|
* Keeps non-numeric parts (string/idfolio/folio/plant/locmach/elementline/elementcolumn/elementprefix) unchanged.
|
||||||
|
*/
|
||||||
|
NumerotationContext resetContextForRenumber(const NumerotationContext &tmpl)
|
||||||
|
{
|
||||||
|
NumerotationContext out = tmpl;
|
||||||
|
for (int i = 0; i < out.size(); ++i) {
|
||||||
|
const QStringList parts = out.itemAt(i);
|
||||||
|
if (parts.isEmpty()) continue;
|
||||||
|
const QString type = parts.at(0);
|
||||||
|
if (out.keyIsNumber(type)) {
|
||||||
|
out.replaceValue(i, QStringLiteral("1"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
#include <QtDebug>
|
#include <QtDebug>
|
||||||
|
#include <algorithm>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
static int BACKUP_INTERVAL = 1200000; //interval in ms of backup = 20min
|
static int BACKUP_INTERVAL = 1200000; //interval in ms of backup = 20min
|
||||||
@@ -132,6 +157,9 @@ QETProject::QETProject(const QString &path, QObject *parent) :
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//The file just read already holds everything a crash could lose, so
|
||||||
|
//there is nothing to back up until the project is changed.
|
||||||
|
m_backup_needed = false;
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,6 +286,19 @@ void QETProject::init()
|
|||||||
m_undo_stack = new QUndoStack(this);
|
m_undo_stack = new QUndoStack(this);
|
||||||
connect(m_undo_stack, &QUndoStack::cleanChanged, this, &QETProject::undoStackChanged);
|
connect(m_undo_stack, &QUndoStack::cleanChanged, this, &QETProject::undoStackChanged);
|
||||||
|
|
||||||
|
//What counts as a change for writeBackup(): the undo stack moving,
|
||||||
|
//setModified(true), and the embedded collections, which can change
|
||||||
|
//without going through either.
|
||||||
|
const auto backup_needed = [this]() { m_backup_needed = true; };
|
||||||
|
connect(m_undo_stack, &QUndoStack::indexChanged, this, backup_needed);
|
||||||
|
connect(&m_titleblocks_collection, &TitleBlockTemplatesCollection::changed, this, backup_needed);
|
||||||
|
connect(&m_titleblocks_collection, &TitleBlockTemplatesCollection::aboutToRemove, this, backup_needed);
|
||||||
|
connect(m_elements_collection, &XmlElementCollection::elementAdded, this, backup_needed);
|
||||||
|
connect(m_elements_collection, &XmlElementCollection::elementChanged, this, backup_needed);
|
||||||
|
connect(m_elements_collection, &XmlElementCollection::elementRemoved, this, backup_needed);
|
||||||
|
connect(m_elements_collection, &XmlElementCollection::directorieAdded, this, backup_needed);
|
||||||
|
connect(m_elements_collection, &XmlElementCollection::directoryRemoved, this, backup_needed);
|
||||||
|
|
||||||
m_save_backup_timer.setInterval(BACKUP_INTERVAL);
|
m_save_backup_timer.setInterval(BACKUP_INTERVAL);
|
||||||
connect(&m_save_backup_timer, &QTimer::timeout, this, &QETProject::writeBackup);
|
connect(&m_save_backup_timer, &QTimer::timeout, this, &QETProject::writeBackup);
|
||||||
m_save_backup_timer.start();
|
m_save_backup_timer.start();
|
||||||
@@ -793,6 +834,109 @@ void QETProject::setCurrrentElementAutonum(QString autoNum) {
|
|||||||
m_current_element_autonum = std::move(autoNum);
|
m_current_element_autonum = std::move(autoNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief QETProject::renumberElementsBySchemeTitle
|
||||||
|
Renumber existing elements by element autonumbering scheme title.
|
||||||
|
|
||||||
|
Elements do not store the scheme title; they store a "formula" (elementInformations["formula"]).
|
||||||
|
This method matches elements to schemes by comparing the stored formula with the formula derived
|
||||||
|
from each scheme's NumerotationContext.
|
||||||
|
|
||||||
|
If scheme_title is empty, all schemes are renumbered. Otherwise only that scheme is renumbered.
|
||||||
|
The operation is undoable.
|
||||||
|
*/
|
||||||
|
void QETProject::renumberElementsBySchemeTitle(const QString &scheme_title)
|
||||||
|
{
|
||||||
|
if (!m_undo_stack) return;
|
||||||
|
if (isReadOnly()) return;
|
||||||
|
|
||||||
|
// Build map: scheme title -> canonical formula
|
||||||
|
QHash<QString, QString> scheme_formula;
|
||||||
|
for (const QString &k : m_element_autonum.keys()) {
|
||||||
|
if (!scheme_title.isEmpty() && k != scheme_title) continue;
|
||||||
|
scheme_formula.insert(k, autonum::numerotationContextToFormula(m_element_autonum.value(k)));
|
||||||
|
}
|
||||||
|
if (scheme_formula.isEmpty()) return;
|
||||||
|
|
||||||
|
// Collect elements per scheme by formula match
|
||||||
|
QHash<QString, QVector<Element*>> by_key;
|
||||||
|
for (Diagram *d : diagrams()) {
|
||||||
|
if (!d) continue;
|
||||||
|
const auto items = d->items();
|
||||||
|
for (QGraphicsItem *it : items) {
|
||||||
|
auto *el = qgraphicsitem_cast<Element*>(it);
|
||||||
|
if (!el) continue;
|
||||||
|
if (el->linkType() == Element::Slave || (el->linkType() & Element::AllReport))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const QString el_formula = el->elementInformations().value(QStringLiteral("formula")).toString();
|
||||||
|
if (el_formula.isEmpty()) continue;
|
||||||
|
|
||||||
|
QString matched_key;
|
||||||
|
for (auto itf = scheme_formula.constBegin(); itf != scheme_formula.constEnd(); ++itf) {
|
||||||
|
if (itf.value() == el_formula) { matched_key = itf.key(); break; }
|
||||||
|
}
|
||||||
|
if (matched_key.isEmpty()) continue;
|
||||||
|
by_key[matched_key].append(el);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (by_key.isEmpty()) return;
|
||||||
|
|
||||||
|
QVector<RenumberElementsCommand::ElementChange> changes;
|
||||||
|
QHash<QString, NumerotationContext> old_ctx;
|
||||||
|
QHash<QString, NumerotationContext> new_ctx;
|
||||||
|
|
||||||
|
for (auto it = by_key.constBegin(); it != by_key.constEnd(); ++it) {
|
||||||
|
old_ctx.insert(it.key(), m_element_autonum.value(it.key()));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto it = by_key.begin(); it != by_key.end(); ++it) {
|
||||||
|
const QString key = it.key();
|
||||||
|
auto &elements = it.value();
|
||||||
|
std::sort(elements.begin(), elements.end(), [](Element *a, Element *b){ return comparPos(a, b); });
|
||||||
|
|
||||||
|
NumerotationContext base_tmpl = m_element_autonum.value(key);
|
||||||
|
NumerotationContext nc = resetContextForRenumber(base_tmpl);
|
||||||
|
NumerotationContextCommands ncc(nc);
|
||||||
|
|
||||||
|
for (Element *el : elements) {
|
||||||
|
RenumberElementsCommand::ElementChange ch;
|
||||||
|
ch.element = el;
|
||||||
|
ch.old_infos = el->elementInformations();
|
||||||
|
ch.old_seq = el->sequenceStruct();
|
||||||
|
ch.old_frozen = el->isFreezeLabel();
|
||||||
|
ch.new_frozen = ch.old_frozen; // preserve frozen state
|
||||||
|
|
||||||
|
const QString formula = ch.old_infos.value(QStringLiteral("formula")).toString();
|
||||||
|
autonum::sequentialNumbers new_seq;
|
||||||
|
new_seq.clear();
|
||||||
|
autonum::setSequential(formula, new_seq, nc, el->diagram(), key);
|
||||||
|
|
||||||
|
DiagramContext new_infos = ch.old_infos;
|
||||||
|
new_infos.addValue(QStringLiteral("label"), autonum::AssignVariables::formulaToLabel(formula, new_seq, el->diagram(), el, nullptr));
|
||||||
|
ch.new_infos = new_infos;
|
||||||
|
ch.new_seq = new_seq;
|
||||||
|
changes.append(ch);
|
||||||
|
|
||||||
|
// advance
|
||||||
|
nc = ncc.next();
|
||||||
|
ncc = NumerotationContextCommands(nc);
|
||||||
|
}
|
||||||
|
|
||||||
|
new_ctx.insert(key, nc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changes.isEmpty()) return;
|
||||||
|
|
||||||
|
auto *cmd = new RenumberElementsCommand(
|
||||||
|
this,
|
||||||
|
changes,
|
||||||
|
old_ctx,
|
||||||
|
new_ctx,
|
||||||
|
scheme_title.isEmpty() ? tr("Renumber elements") : tr("Renumber elements (%1)").arg(scheme_title));
|
||||||
|
m_undo_stack->push(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief QETProject::conductorAutoNumFormula
|
@brief QETProject::conductorAutoNumFormula
|
||||||
@param key : autonum title
|
@param key : autonum title
|
||||||
@@ -1564,6 +1708,9 @@ void QETProject::diagramOrderChanged(int old_index, int new_index) {
|
|||||||
Mark this project as modified and emit the projectModified() signal.
|
Mark this project as modified and emit the projectModified() signal.
|
||||||
*/
|
*/
|
||||||
void QETProject::setModified(bool modified) {
|
void QETProject::setModified(bool modified) {
|
||||||
|
if (modified) {
|
||||||
|
m_backup_needed = true;
|
||||||
|
}
|
||||||
if (m_modified != modified) {
|
if (m_modified != modified) {
|
||||||
m_modified = modified;
|
m_modified = modified;
|
||||||
emit projectModified(this, m_modified);
|
emit projectModified(this, m_modified);
|
||||||
@@ -2146,6 +2293,12 @@ void QETProject::writeBackup()
|
|||||||
//both would write through &m_backup_file on different threads.
|
//both would write through &m_backup_file on different threads.
|
||||||
if (m_backup_future.isRunning())
|
if (m_backup_future.isRunning())
|
||||||
return;
|
return;
|
||||||
|
//toXml() walks the whole project on the GUI thread, which freezes
|
||||||
|
//big projects for seconds (bugtracker #273, #329). A backup of an
|
||||||
|
//unchanged project would be identical to the last one, so skip it.
|
||||||
|
if (!m_backup_needed)
|
||||||
|
return;
|
||||||
|
m_backup_needed = false;
|
||||||
//Capture the document by value (implicitly shared, so cheap): the
|
//Capture the document by value (implicitly shared, so cheap): the
|
||||||
//Qt5-style QtConcurrent::run(function, reference-args) call did not
|
//Qt5-style QtConcurrent::run(function, reference-args) call did not
|
||||||
//survive the Qt6 API change, a lambda behaves identically on both.
|
//survive the Qt6 API change, a lambda behaves identically on both.
|
||||||
|
|||||||
@@ -169,6 +169,20 @@ class QETProject : public QObject
|
|||||||
QString elementCurrentAutoNum() const;
|
QString elementCurrentAutoNum() const;
|
||||||
void setCurrrentElementAutonum(QString autoNum);
|
void setCurrrentElementAutonum(QString autoNum);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Renumber existing elements by element autonumbering scheme.
|
||||||
|
*
|
||||||
|
* Elements do not store the scheme title but they store the corresponding formula.
|
||||||
|
* This operation matches elements to schemes by comparing the stored formula
|
||||||
|
* with the formula derived from the scheme's NumerotationContext.
|
||||||
|
*
|
||||||
|
* If @p scheme_title is empty, all schemes are renumbered.
|
||||||
|
* If @p scheme_title is non-empty, only that scheme is renumbered.
|
||||||
|
*
|
||||||
|
* The operation is undoable.
|
||||||
|
*/
|
||||||
|
void renumberElementsBySchemeTitle(const QString &scheme_title = QString());
|
||||||
|
|
||||||
//Element
|
//Element
|
||||||
void freezeExistentElementLabel(bool freeze, int from, int to);
|
void freezeExistentElementLabel(bool freeze, int from, int to);
|
||||||
void freezeNewElementLabel(bool freeze, int from, int to);
|
void freezeNewElementLabel(bool freeze, int from, int to);
|
||||||
@@ -297,6 +311,8 @@ class QETProject : public QObject
|
|||||||
private:
|
private:
|
||||||
/// When false, writeBackup() is a no-op (set by the headless CLI)
|
/// When false, writeBackup() is a no-op (set by the headless CLI)
|
||||||
static bool m_backup_enabled;
|
static bool m_backup_enabled;
|
||||||
|
/// Something changed since the last backup, see writeBackup()
|
||||||
|
bool m_backup_needed = true;
|
||||||
/// File path this project is saved to
|
/// File path this project is saved to
|
||||||
QString m_file_path;
|
QString m_file_path;
|
||||||
/// Current state of the project
|
/// Current state of the project
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
*/
|
*/
|
||||||
#include "shortcutmanager.h"
|
#include "shortcutmanager.h"
|
||||||
|
|
||||||
|
#include <QAbstractButton>
|
||||||
|
#include <QAction>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
@@ -166,3 +168,32 @@ void ShortcutManager::resetAllToDefaults()
|
|||||||
resetToDefault(id);
|
resetToDefault(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief ShortcutManager::trigger
|
||||||
|
@param id
|
||||||
|
@return see the declaration's doc comment
|
||||||
|
*/
|
||||||
|
bool ShortcutManager::trigger(const QString &id) const
|
||||||
|
{
|
||||||
|
auto it = m_entries.find(id);
|
||||||
|
if (it == m_entries.end()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const QPointer<QObject> &target : qAsConst(it->targets))
|
||||||
|
{
|
||||||
|
if (!target) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (auto *action = qobject_cast<QAction *>(target.data())) {
|
||||||
|
action->trigger();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (auto *button = qobject_cast<QAbstractButton *>(target.data())) {
|
||||||
|
button->click();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|||||||
@@ -71,6 +71,20 @@ class ShortcutManager
|
|||||||
void resetToDefault(const QString &id);
|
void resetToDefault(const QString &id);
|
||||||
void resetAllToDefaults();
|
void resetAllToDefaults();
|
||||||
|
|
||||||
|
/// Activate the first still-alive target registered under \a id
|
||||||
|
/// -- QAction::trigger() or QAbstractButton::click(), whichever
|
||||||
|
/// it turns out to be -- for an input source other than the
|
||||||
|
/// keyboard (e.g. a 3D mouse button) that wants to invoke a
|
||||||
|
/// named action without knowing or caring which of the two it
|
||||||
|
/// is. Deliberately not disambiguated by the currently active
|
||||||
|
/// window when an id has several live targets: a target's
|
||||||
|
/// owning top-level window isn't reliably discoverable from a
|
||||||
|
/// bare QAction. Correct in the overwhelming common case of one
|
||||||
|
/// open editor window; a known simplification in the rarer
|
||||||
|
/// multi-window case, not a guaranteed-correct dispatch.
|
||||||
|
/// @return whether a live target was found and triggered.
|
||||||
|
bool trigger(const QString &id) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ShortcutManager() = default;
|
ShortcutManager() = default;
|
||||||
ShortcutManager(const ShortcutManager &) = delete;
|
ShortcutManager(const ShortcutManager &) = delete;
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2006-2026 The QElectroTech Team
|
||||||
|
This file is part of QElectroTech.
|
||||||
|
|
||||||
|
QElectroTech is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
QElectroTech 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 General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef SPACEMOUSEBACKEND_H
|
||||||
|
#define SPACEMOUSEBACKEND_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief The SpaceMouseBackend class
|
||||||
|
Platform seam for discussion #599's 3D mouse support. A backend owns
|
||||||
|
one platform's connection to the actual 6-DOF device driver -- opening
|
||||||
|
it, pumping whatever event source that platform uses, closing it -- and
|
||||||
|
reports motion through the one signal below. Everything platform-
|
||||||
|
independent (which DiagramView to apply motion to, the pan/zoom
|
||||||
|
primitives to call, the Z-to-zoom-factor mapping) lives in
|
||||||
|
SpaceMouseListener instead, once, so it does not have to be duplicated
|
||||||
|
or re-verified per backend.
|
||||||
|
|
||||||
|
SpnavBackend (Linux, spacenavd/libspnav) is the only implementation so
|
||||||
|
far -- built, linked, and its "no daemon/device present" path actually
|
||||||
|
run in the environment this was written in. A Windows/macOS backend
|
||||||
|
(3Dconnexion's proprietary 3DxWare SDK) would implement this same
|
||||||
|
interface and be selected in SpaceMouseListener's constructor, without
|
||||||
|
changing SpnavBackend or anything downstream of the motion signal.
|
||||||
|
Deliberately not attempted here: this was written on Linux with no
|
||||||
|
3DxWare SDK and no Windows/macOS toolchain available to compile,
|
||||||
|
link, or run a single line of it against, and shipping platform code
|
||||||
|
that has never even built would be a materially different, weaker
|
||||||
|
thing than everything else in this feature.
|
||||||
|
*/
|
||||||
|
class SpaceMouseBackend : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SpaceMouseBackend(QObject *parent = nullptr) : QObject(parent) {}
|
||||||
|
~SpaceMouseBackend() override = default;
|
||||||
|
|
||||||
|
/// True once this backend actually has a live connection to a
|
||||||
|
/// driver/daemon. False is the ordinary case -- no daemon
|
||||||
|
/// running, no device attached -- not an error; see
|
||||||
|
/// SpaceMouseListener's class comment for why that distinction
|
||||||
|
/// matters.
|
||||||
|
virtual bool isAvailable() const = 0;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
/// One raw device sample. dx/dy are the two axes
|
||||||
|
/// SpaceMouseListener maps to horizontal/vertical pan, dz the
|
||||||
|
/// one it maps to zoom. Units and range are whatever the
|
||||||
|
/// backend's own driver reports -- SpaceMouseListener's own
|
||||||
|
/// scale/divisor constants are what turn them into pixels and a
|
||||||
|
/// zoom factor, not this signal.
|
||||||
|
void motion(int dx, int dy, int dz);
|
||||||
|
|
||||||
|
/// One device button was pressed. \a button is whatever index
|
||||||
|
/// the backend's own driver numbers it as -- there is no
|
||||||
|
/// portable numbering across device models, which is exactly
|
||||||
|
/// why the binding from a button to a QET action
|
||||||
|
/// (SpaceMouseButtonMap) is user-configurable rather than
|
||||||
|
/// hardcoded. Emitted on press only; release is not reported,
|
||||||
|
/// since nothing here has a use for it.
|
||||||
|
void buttonPressed(int button);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SPACEMOUSEBACKEND_H
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2006-2026 The QElectroTech Team
|
||||||
|
This file is part of QElectroTech.
|
||||||
|
|
||||||
|
QElectroTech is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
QElectroTech 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 General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include "spacemousebuttonmap.h"
|
||||||
|
|
||||||
|
#include <QSettings>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
const QString SETTINGS_GROUP = QStringLiteral("spacemouse/buttons/");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief SpaceMouseButtonMap::actionId
|
||||||
|
@param button
|
||||||
|
@return see the declaration's doc comment
|
||||||
|
*/
|
||||||
|
QString SpaceMouseButtonMap::actionId(int button)
|
||||||
|
{
|
||||||
|
QSettings settings;
|
||||||
|
return settings.value(SETTINGS_GROUP + QString::number(button)).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief SpaceMouseButtonMap::setActionId
|
||||||
|
@param button
|
||||||
|
@param action_id
|
||||||
|
*/
|
||||||
|
void SpaceMouseButtonMap::setActionId(int button, const QString &action_id)
|
||||||
|
{
|
||||||
|
QSettings settings;
|
||||||
|
const QString key = SETTINGS_GROUP + QString::number(button);
|
||||||
|
if (action_id.isEmpty()) {
|
||||||
|
settings.remove(key);
|
||||||
|
} else {
|
||||||
|
settings.setValue(key, action_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief SpaceMouseButtonMap::allBindings
|
||||||
|
@return see the declaration's doc comment
|
||||||
|
*/
|
||||||
|
QMap<int, QString> SpaceMouseButtonMap::allBindings()
|
||||||
|
{
|
||||||
|
QMap<int, QString> bindings;
|
||||||
|
QSettings settings;
|
||||||
|
settings.beginGroup(QStringLiteral("spacemouse/buttons"));
|
||||||
|
for (const QString &key : settings.childKeys())
|
||||||
|
{
|
||||||
|
bool ok = false;
|
||||||
|
const int button = key.toInt(&ok);
|
||||||
|
if (ok) {
|
||||||
|
bindings.insert(button, settings.value(key).toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
settings.endGroup();
|
||||||
|
return bindings;
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2006-2026 The QElectroTech Team
|
||||||
|
This file is part of QElectroTech.
|
||||||
|
|
||||||
|
QElectroTech is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
QElectroTech 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 General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef SPACEMOUSEBUTTONMAP_H
|
||||||
|
#define SPACEMOUSEBUTTONMAP_H
|
||||||
|
|
||||||
|
#include <QMap>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief The SpaceMouseButtonMap class
|
||||||
|
Persisted mapping from a device button's raw index (backend- and
|
||||||
|
device-specific -- see SpaceMouseBackend::buttonPressed()) to a
|
||||||
|
ShortcutManager action id. Deliberately just a thin QSettings wrapper,
|
||||||
|
the same weight as ShortcutManager::savedSequence(): no caching, reads
|
||||||
|
and writes the setting directly on every call, since this is called at
|
||||||
|
most once per button press, never in a hot loop.
|
||||||
|
|
||||||
|
Unbound by default for every button on every device: nothing is bound
|
||||||
|
until the user opens Configuration > 3D Mouse and binds something --
|
||||||
|
see spacemouseconfigpage.h. A device compiled in and connected but
|
||||||
|
never configured here does nothing on any button press, matching the
|
||||||
|
rest of this feature's "silent until asked for" default.
|
||||||
|
*/
|
||||||
|
class SpaceMouseButtonMap
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// @return the action id bound to \a button, or an empty string
|
||||||
|
/// if nothing is bound to it.
|
||||||
|
static QString actionId(int button);
|
||||||
|
|
||||||
|
/// Bind \a button to \a action_id. An empty \a action_id
|
||||||
|
/// removes the binding (equivalent to it never having been set).
|
||||||
|
static void setActionId(int button, const QString &action_id);
|
||||||
|
|
||||||
|
/// @return every currently bound button, for the configuration
|
||||||
|
/// page to list.
|
||||||
|
static QMap<int, QString> allBindings();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SPACEMOUSEBUTTONMAP_H
|
||||||
@@ -0,0 +1,153 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2006-2026 The QElectroTech Team
|
||||||
|
This file is part of QElectroTech.
|
||||||
|
|
||||||
|
QElectroTech is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
QElectroTech 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 General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include "spacemouselistener.h"
|
||||||
|
|
||||||
|
#include "spacemousebackend.h"
|
||||||
|
#include "spacemousebuttonmap.h"
|
||||||
|
#ifdef QET_SPACEMOUSE_BACKEND_SPNAV
|
||||||
|
# include "spnavbackend.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../diagramview.h"
|
||||||
|
#include "../projectview.h"
|
||||||
|
#include "../qetdiagrameditor.h"
|
||||||
|
#include "../shortcutmanager.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QScrollBar>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
//A device motion delta is an integer on roughly the same order of
|
||||||
|
//magnitude as a QWheelEvent::angleDelta() tick (about +-120 per
|
||||||
|
//detent, more under a hard push/twist -- exact range depends on the
|
||||||
|
//backend and the user's own driver-level sensitivity setting, which
|
||||||
|
//is configured outside QET and out of scope here).
|
||||||
|
//DiagramView::wheelEvent() already turns such a tick into a small
|
||||||
|
//per-event zoom step via zoom(1 + value/1000); reused as a starting
|
||||||
|
//point.
|
||||||
|
//
|
||||||
|
//Neither this divisor nor PAN_SCALE below has been calibrated
|
||||||
|
//against real hardware -- there is none in the environment this was
|
||||||
|
//built in. Both are named constants specifically so that is a
|
||||||
|
//one-line fix once someone with a device tries it.
|
||||||
|
constexpr qreal ZOOM_DIVISOR = 1000.0;
|
||||||
|
constexpr qreal PAN_SCALE = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief SpaceMouseListener::SpaceMouseListener
|
||||||
|
Construct whichever backend is available for this platform and connect
|
||||||
|
its motion() signal. If none is compiled in, or the one that is can't
|
||||||
|
reach a device, isAvailable() simply stays false -- see the class
|
||||||
|
comment.
|
||||||
|
@param parent
|
||||||
|
*/
|
||||||
|
SpaceMouseListener::SpaceMouseListener(QObject *parent) :
|
||||||
|
QObject(parent)
|
||||||
|
{
|
||||||
|
#ifdef QET_SPACEMOUSE_BACKEND_SPNAV
|
||||||
|
m_backend = new SpnavBackend(this);
|
||||||
|
#endif
|
||||||
|
//A future Windows/macOS backend (3Dconnexion's proprietary 3DxWare
|
||||||
|
//SDK) slots in here behind its own QET_SPACEMOUSE_BACKEND_3DXWARE
|
||||||
|
//guard, without changing anything below this constructor.
|
||||||
|
|
||||||
|
if (m_backend) {
|
||||||
|
connect(m_backend, &SpaceMouseBackend::motion,
|
||||||
|
this, &SpaceMouseListener::applyMotion);
|
||||||
|
connect(m_backend, &SpaceMouseBackend::buttonPressed,
|
||||||
|
this, &SpaceMouseListener::applyButton);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief SpaceMouseListener::isAvailable
|
||||||
|
@return whether the platform backend has a live device connection
|
||||||
|
*/
|
||||||
|
bool SpaceMouseListener::isAvailable() const
|
||||||
|
{
|
||||||
|
return m_backend && m_backend->isAvailable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief SpaceMouseListener::zoomFactorForZAxis
|
||||||
|
@param z : raw Z-axis (push/pull) delta from a device motion sample
|
||||||
|
@return the multiplicative factor DiagramView::zoom() expects
|
||||||
|
*/
|
||||||
|
qreal SpaceMouseListener::zoomFactorForZAxis(int z)
|
||||||
|
{
|
||||||
|
return 1.0 + (static_cast<qreal>(z) / ZOOM_DIVISOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief SpaceMouseListener::applyMotion
|
||||||
|
Apply one motion sample to whichever DiagramView is currently active.
|
||||||
|
X/Y translation pans it, Z translation zooms it -- the same two
|
||||||
|
primitives (scrollbars, DiagramView::zoom()) DiagramView::wheelEvent()
|
||||||
|
already drives from a physical wheel, so there is no new navigation
|
||||||
|
logic here, only a new input source feeding the existing one.
|
||||||
|
|
||||||
|
Which of a device's three translation axes is "left/right" vs
|
||||||
|
"forward/back" vs "up/down", and their sign, is a hardware convention
|
||||||
|
this could not be checked against real hardware while writing it -- see
|
||||||
|
the PR description.
|
||||||
|
@param dx
|
||||||
|
@param dy
|
||||||
|
@param dz
|
||||||
|
*/
|
||||||
|
void SpaceMouseListener::applyMotion(int dx, int dy, int dz)
|
||||||
|
{
|
||||||
|
auto *editor = qobject_cast<QETDiagramEditor *>(qApp->activeWindow());
|
||||||
|
if (!editor) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProjectView *project_view = editor->currentProjectView();
|
||||||
|
if (!project_view) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DiagramView *view = project_view->currentDiagram();
|
||||||
|
if (!view) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dx || dy)
|
||||||
|
{
|
||||||
|
view->horizontalScrollBar()->setValue(
|
||||||
|
view->horizontalScrollBar()->value() - qRound(dx * PAN_SCALE));
|
||||||
|
view->verticalScrollBar()->setValue(
|
||||||
|
view->verticalScrollBar()->value() - qRound(dy * PAN_SCALE));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dz) {
|
||||||
|
view->zoom(zoomFactorForZAxis(dz));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief SpaceMouseListener::applyButton
|
||||||
|
@param button
|
||||||
|
*/
|
||||||
|
void SpaceMouseListener::applyButton(int button)
|
||||||
|
{
|
||||||
|
const QString action_id = SpaceMouseButtonMap::actionId(button);
|
||||||
|
if (!action_id.isEmpty()) {
|
||||||
|
ShortcutManager::instance().trigger(action_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2006-2026 The QElectroTech Team
|
||||||
|
This file is part of QElectroTech.
|
||||||
|
|
||||||
|
QElectroTech is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
QElectroTech 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 General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef SPACEMOUSELISTENER_H
|
||||||
|
#define SPACEMOUSELISTENER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class SpaceMouseBackend;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief The SpaceMouseListener class
|
||||||
|
https://github.com/qelectrotech/qelectrotech-source-mirror/discussions/599 :
|
||||||
|
bridges a 3Dconnexion SpaceMouse/SpacePilot 6-DOF device to
|
||||||
|
DiagramView's existing pan/zoom primitives (the same
|
||||||
|
horizontalScrollBar()/verticalScrollBar()/zoom() calls
|
||||||
|
DiagramView::wheelEvent() already uses for a physical wheel), and its
|
||||||
|
buttons to named QET actions via ShortcutManager -- the same registry
|
||||||
|
keyboard shortcuts already use, so a device button can trigger anything
|
||||||
|
in that registry (undo, redo, rotate selection, ...) without QET having
|
||||||
|
a second, device-specific action list.
|
||||||
|
|
||||||
|
Everything here is platform-independent: which DiagramView to apply
|
||||||
|
motion to, the pan/zoom calls, the Z-to-zoom-factor mapping, and button
|
||||||
|
dispatch via SpaceMouseButtonMap + ShortcutManager. Talking to the
|
||||||
|
actual device driver is a SpaceMouseBackend's job (see its class
|
||||||
|
comment) -- this class owns one and applies whatever it reports,
|
||||||
|
without knowing or caring which platform it came from.
|
||||||
|
|
||||||
|
Only compiled in when QET_SPACEMOUSE_SUPPORT is defined. Even then,
|
||||||
|
constructing one is always safe: if no backend is available for this
|
||||||
|
platform, or the one that exists can't reach a driver/daemon (no
|
||||||
|
device attached -- the expected state for the overwhelming majority of
|
||||||
|
users, even of a build with the option on), this silently does nothing
|
||||||
|
rather than failing or nagging the user. There is exactly one of
|
||||||
|
these, owned by QETApp, because a physical 6-DOF device is a single
|
||||||
|
ambient input source for the whole application, not something tied to
|
||||||
|
one window.
|
||||||
|
*/
|
||||||
|
class SpaceMouseListener : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SpaceMouseListener(QObject *parent = nullptr);
|
||||||
|
~SpaceMouseListener() override = default;
|
||||||
|
|
||||||
|
/// True once the platform backend has a live connection to a
|
||||||
|
/// driver/daemon. False is the common case, not an error -- see
|
||||||
|
/// the class comment -- so callers should not warn the user
|
||||||
|
/// when this is false.
|
||||||
|
bool isAvailable() const;
|
||||||
|
|
||||||
|
/// Pure translation from a device Z-axis delta to the
|
||||||
|
/// multiplicative factor DiagramView::zoom() expects. A free
|
||||||
|
/// function so the mapping can be unit-tested without a live
|
||||||
|
/// backend connection or a real device.
|
||||||
|
static qreal zoomFactorForZAxis(int z);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
/// Apply one motion sample -- from whichever backend is in use
|
||||||
|
/// -- to whichever DiagramView is currently active.
|
||||||
|
void applyMotion(int dx, int dy, int dz);
|
||||||
|
|
||||||
|
/// Look up which action id, if any, SpaceMouseButtonMap binds
|
||||||
|
/// \a button to, and trigger it via ShortcutManager. Does
|
||||||
|
/// nothing for an unbound button -- see SpaceMouseButtonMap's
|
||||||
|
/// class comment on the "unbound by default" contract.
|
||||||
|
void applyButton(int button);
|
||||||
|
|
||||||
|
private:
|
||||||
|
SpaceMouseBackend *m_backend = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SPACEMOUSELISTENER_H
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2006-2026 The QElectroTech Team
|
||||||
|
This file is part of QElectroTech.
|
||||||
|
|
||||||
|
QElectroTech is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
QElectroTech 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 General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include "spnavbackend.h"
|
||||||
|
|
||||||
|
#include <QSocketNotifier>
|
||||||
|
|
||||||
|
#include <spnav.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief SpnavBackend::SpnavBackend
|
||||||
|
Try to connect to spacenavd. Failure -- no daemon running, no device
|
||||||
|
attached -- is left silent: it is the expected state for most users and
|
||||||
|
must never surface as an error dialog or a log warning on every
|
||||||
|
ordinary startup.
|
||||||
|
@param parent
|
||||||
|
*/
|
||||||
|
SpnavBackend::SpnavBackend(QObject *parent) :
|
||||||
|
SpaceMouseBackend(parent)
|
||||||
|
{
|
||||||
|
if (spnav_open() == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_available = true;
|
||||||
|
m_notifier = new QSocketNotifier(spnav_fd(), QSocketNotifier::Read, this);
|
||||||
|
connect(m_notifier, &QSocketNotifier::activated,
|
||||||
|
this, &SpnavBackend::readEvents);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief SpnavBackend::~SpnavBackend
|
||||||
|
*/
|
||||||
|
SpnavBackend::~SpnavBackend()
|
||||||
|
{
|
||||||
|
if (m_available) {
|
||||||
|
spnav_close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief SpnavBackend::readEvents
|
||||||
|
Called when the spacenavd socket has data available. Drains every event
|
||||||
|
currently queued -- spnav_poll_event() returns 0 once the queue is
|
||||||
|
empty -- rather than handling just one per activation, so events cannot
|
||||||
|
silently back up if several arrive between two Qt event loop turns.
|
||||||
|
*/
|
||||||
|
void SpnavBackend::readEvents()
|
||||||
|
{
|
||||||
|
spnav_event event;
|
||||||
|
while (spnav_poll_event(&event))
|
||||||
|
{
|
||||||
|
if (event.type == SPNAV_EVENT_MOTION) {
|
||||||
|
//A 6-DOF device also reports rotation (rx, ry, rz); QET's
|
||||||
|
//view has nothing rotation maps to, so those three axes are
|
||||||
|
//read by nothing here.
|
||||||
|
emit motion(event.motion.x, event.motion.y, event.motion.z);
|
||||||
|
}
|
||||||
|
else if (event.type == SPNAV_EVENT_BUTTON && event.button.press) {
|
||||||
|
//Release (press == 0) is not reported -- SpaceMouseListener
|
||||||
|
//triggers a QET action on press, the same way a keyboard
|
||||||
|
//shortcut triggers on key-down, and has no use for release.
|
||||||
|
emit buttonPressed(event.button.bnum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2006-2026 The QElectroTech Team
|
||||||
|
This file is part of QElectroTech.
|
||||||
|
|
||||||
|
QElectroTech is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
QElectroTech 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 General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef SPNAVBACKEND_H
|
||||||
|
#define SPNAVBACKEND_H
|
||||||
|
|
||||||
|
#include "spacemousebackend.h"
|
||||||
|
|
||||||
|
class QSocketNotifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief The SpnavBackend class
|
||||||
|
Linux SpaceMouseBackend, via the spacenavd daemon and libspnav. Only
|
||||||
|
compiled in when QET_SPACEMOUSE_BACKEND_SPNAV is defined (set by
|
||||||
|
cmake/find_spacemouse.cmake once it has actually found libspnav).
|
||||||
|
|
||||||
|
Connecting is always safe even when no daemon is running or no device
|
||||||
|
is attached -- the expected state for the overwhelming majority of
|
||||||
|
users, even of a build with 3D mouse support compiled in -- this
|
||||||
|
silently leaves isAvailable() false rather than failing loudly.
|
||||||
|
*/
|
||||||
|
class SpnavBackend : public SpaceMouseBackend
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SpnavBackend(QObject *parent = nullptr);
|
||||||
|
~SpnavBackend() override;
|
||||||
|
|
||||||
|
bool isAvailable() const override {return m_available;}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
/// Drain and emit every event currently queued on the spacenavd
|
||||||
|
/// socket. Connected to a QSocketNotifier on that socket's fd
|
||||||
|
/// rather than polled on a timer, so this is idle-cost-free
|
||||||
|
/// between events.
|
||||||
|
void readEvents();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_available = false;
|
||||||
|
QSocketNotifier *m_notifier = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SPNAVBACKEND_H
|
||||||
@@ -31,6 +31,7 @@
|
|||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
|
#include <QSet>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
/**
|
/**
|
||||||
@@ -167,11 +168,22 @@ void ConductorColorToolButton::applyColor(const QColor &color)
|
|||||||
}
|
}
|
||||||
|
|
||||||
DiagramContent dc(diagram);
|
DiagramContent dc(diagram);
|
||||||
const auto conductors = dc.conductors(DiagramContent::AnyConductor);
|
const auto selected_conductors = dc.conductors(DiagramContent::AnyConductor);
|
||||||
if (conductors.isEmpty()) {
|
if (selected_conductors.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//A wire drawn across a junction is several Conductor objects
|
||||||
|
//sharing one electrical potential; selecting one segment must
|
||||||
|
//still recolour the whole potential, the way the F2 dialog's
|
||||||
|
//"apply to all" already does.
|
||||||
|
QSet<Conductor *> conductors;
|
||||||
|
for (Conductor *conductor : selected_conductors)
|
||||||
|
{
|
||||||
|
conductors << conductor;
|
||||||
|
conductors += conductor->relatedPotentialConductors();
|
||||||
|
}
|
||||||
|
|
||||||
QUndoCommand *undo = new QUndoCommand(tr("Modifier la couleur de %n conducteur(s)",
|
QUndoCommand *undo = new QUndoCommand(tr("Modifier la couleur de %n conducteur(s)",
|
||||||
"undo caption", conductors.count()));
|
"undo caption", conductors.count()));
|
||||||
int changed = 0;
|
int changed = 0;
|
||||||
|
|||||||
@@ -0,0 +1,223 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2006-2026 The QElectroTech Team
|
||||||
|
This file is part of QElectroTech.
|
||||||
|
|
||||||
|
QElectroTech is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
QElectroTech 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 General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include "spacemouseconfigpage.h"
|
||||||
|
|
||||||
|
#include "../../qeticons.h"
|
||||||
|
#include "../../shortcutmanager.h"
|
||||||
|
#include "../../spacemouse/spacemousebuttonmap.h"
|
||||||
|
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QFrame>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QHeaderView>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include <QTableWidget>
|
||||||
|
#include <QToolButton>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
constexpr int COL_BUTTON = 0;
|
||||||
|
constexpr int COL_ACTION = 1;
|
||||||
|
constexpr int COL_REMOVE = 2;
|
||||||
|
|
||||||
|
//The combo box's first entry: no action bound, i.e. this row does
|
||||||
|
//nothing. Real action ids are never empty (ShortcutManager assigns
|
||||||
|
//them from source, not user input), so an empty string can never
|
||||||
|
//collide with a real one.
|
||||||
|
const QString UNBOUND_LABEL = QObject::tr("(Aucune action)", "spacemouse config: unbound button");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief SpaceMouseConfigPage::SpaceMouseConfigPage
|
||||||
|
@param parent
|
||||||
|
*/
|
||||||
|
SpaceMouseConfigPage::SpaceMouseConfigPage(QWidget *parent) :
|
||||||
|
ConfigPage(parent)
|
||||||
|
{
|
||||||
|
auto *vlayout = new QVBoxLayout();
|
||||||
|
|
||||||
|
QLabel *title_label = new QLabel(this->title());
|
||||||
|
vlayout->addWidget(title_label);
|
||||||
|
|
||||||
|
QFrame *horiz_line = new QFrame();
|
||||||
|
horiz_line->setFrameShape(QFrame::HLine);
|
||||||
|
vlayout->addWidget(horiz_line);
|
||||||
|
|
||||||
|
auto *intro_label = new QLabel(
|
||||||
|
tr("Associez un numéro de bouton de votre souris 3D (SpaceMouse, SpacePilot...) "
|
||||||
|
"à une action de QElectroTech. Le numéro de bouton dépend de votre appareil "
|
||||||
|
"et de son pilote -- reportez-vous à sa documentation, ou essayez successivement "
|
||||||
|
"les valeurs à partir de 0.",
|
||||||
|
"spacemouse config page intro"));
|
||||||
|
intro_label->setWordWrap(true);
|
||||||
|
vlayout->addWidget(intro_label);
|
||||||
|
|
||||||
|
m_table = new QTableWidget(0, 3, this);
|
||||||
|
m_table->setHorizontalHeaderLabels({tr("N° bouton"), tr("Action"), QString()});
|
||||||
|
m_table->horizontalHeader()->setSectionResizeMode(COL_BUTTON, QHeaderView::ResizeToContents);
|
||||||
|
m_table->horizontalHeader()->setSectionResizeMode(COL_ACTION, QHeaderView::Stretch);
|
||||||
|
m_table->horizontalHeader()->setSectionResizeMode(COL_REMOVE, QHeaderView::ResizeToContents);
|
||||||
|
m_table->verticalHeader()->setVisible(false);
|
||||||
|
m_table->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||||
|
m_table->setSelectionMode(QAbstractItemView::NoSelection);
|
||||||
|
vlayout->addWidget(m_table);
|
||||||
|
|
||||||
|
auto *add_button = new QPushButton(QET::Icons::Add, tr("Ajouter une association"), this);
|
||||||
|
connect(add_button, &QPushButton::clicked, this, &SpaceMouseConfigPage::addRow);
|
||||||
|
|
||||||
|
auto *bottom_layout = new QHBoxLayout();
|
||||||
|
bottom_layout->addWidget(add_button);
|
||||||
|
bottom_layout->addStretch();
|
||||||
|
vlayout->addLayout(bottom_layout);
|
||||||
|
|
||||||
|
setLayout(vlayout);
|
||||||
|
|
||||||
|
populateTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
SpaceMouseConfigPage::~SpaceMouseConfigPage()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief SpaceMouseConfigPage::populateTable
|
||||||
|
Fill the table with one row per binding currently persisted in
|
||||||
|
SpaceMouseButtonMap.
|
||||||
|
*/
|
||||||
|
void SpaceMouseConfigPage::populateTable()
|
||||||
|
{
|
||||||
|
const QMap<int, QString> bindings = SpaceMouseButtonMap::allBindings();
|
||||||
|
for (auto it = bindings.constBegin(); it != bindings.constEnd(); ++it) {
|
||||||
|
appendRow(it.key(), it.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief SpaceMouseConfigPage::appendRow
|
||||||
|
Add one row bound to \a button / \a action_id (either or both may be
|
||||||
|
the "unset" value -- 0 and an empty string respectively -- for a fresh
|
||||||
|
row added via the "+" button).
|
||||||
|
@param button
|
||||||
|
@param action_id
|
||||||
|
*/
|
||||||
|
void SpaceMouseConfigPage::appendRow(int button, const QString &action_id)
|
||||||
|
{
|
||||||
|
const int row = m_table->rowCount();
|
||||||
|
m_table->setRowCount(row + 1);
|
||||||
|
|
||||||
|
auto *button_spin = new QSpinBox(m_table);
|
||||||
|
button_spin->setRange(0, 999);
|
||||||
|
button_spin->setValue(button);
|
||||||
|
m_table->setCellWidget(row, COL_BUTTON, button_spin);
|
||||||
|
|
||||||
|
auto *action_combo = new QComboBox(m_table);
|
||||||
|
action_combo->addItem(UNBOUND_LABEL, QString());
|
||||||
|
|
||||||
|
QList<ShortcutManager::ShortcutInfo> shortcuts = ShortcutManager::instance().allShortcuts();
|
||||||
|
std::sort(shortcuts.begin(), shortcuts.end(),
|
||||||
|
[](const ShortcutManager::ShortcutInfo &a, const ShortcutManager::ShortcutInfo &b) {
|
||||||
|
if (a.category != b.category) {
|
||||||
|
return a.category < b.category;
|
||||||
|
}
|
||||||
|
return a.description < b.description;
|
||||||
|
});
|
||||||
|
for (const ShortcutManager::ShortcutInfo &info : shortcuts) {
|
||||||
|
action_combo->addItem(
|
||||||
|
QStringLiteral("%1 — %2").arg(info.category, info.description), info.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
int index_for_current = action_combo->findData(action_id);
|
||||||
|
action_combo->setCurrentIndex(index_for_current >= 0 ? index_for_current : 0);
|
||||||
|
m_table->setCellWidget(row, COL_ACTION, action_combo);
|
||||||
|
|
||||||
|
auto *remove_button = new QToolButton(m_table);
|
||||||
|
remove_button->setIcon(QET::Icons::EditTableDeleteRow);
|
||||||
|
remove_button->setToolTip(tr("Supprimer cette association"));
|
||||||
|
connect(remove_button, &QToolButton::clicked, this, &SpaceMouseConfigPage::removeSelectedRow);
|
||||||
|
m_table->setCellWidget(row, COL_REMOVE, remove_button);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief SpaceMouseConfigPage::addRow
|
||||||
|
Add a fresh, unbound row for the user to fill in.
|
||||||
|
*/
|
||||||
|
void SpaceMouseConfigPage::addRow()
|
||||||
|
{
|
||||||
|
appendRow(0, QString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief SpaceMouseConfigPage::removeSelectedRow
|
||||||
|
Remove whichever row owns the remove button that was clicked. Found by
|
||||||
|
looking the sender up in the button column rather than tracked
|
||||||
|
per-button state, so nothing has to be kept in sync as rows are added
|
||||||
|
and removed around it.
|
||||||
|
*/
|
||||||
|
void SpaceMouseConfigPage::removeSelectedRow()
|
||||||
|
{
|
||||||
|
auto *button = qobject_cast<QToolButton *>(sender());
|
||||||
|
if (!button) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int row = 0; row < m_table->rowCount(); ++row) {
|
||||||
|
if (m_table->cellWidget(row, COL_REMOVE) == button) {
|
||||||
|
m_table->removeRow(row);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief SpaceMouseConfigPage::applyConf
|
||||||
|
Persist exactly what the table currently shows: every previously saved
|
||||||
|
binding is cleared first, then every row still in the table (after any
|
||||||
|
adds/edits/removals) is written back. Simpler and less error-prone than
|
||||||
|
tracking which individual rows changed, and cheap -- this runs once,
|
||||||
|
when the user validates the surrounding ConfigDialog, not on every
|
||||||
|
keystroke.
|
||||||
|
*/
|
||||||
|
void SpaceMouseConfigPage::applyConf()
|
||||||
|
{
|
||||||
|
const QMap<int, QString> previous = SpaceMouseButtonMap::allBindings();
|
||||||
|
for (auto it = previous.constBegin(); it != previous.constEnd(); ++it) {
|
||||||
|
SpaceMouseButtonMap::setActionId(it.key(), QString());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int row = 0; row < m_table->rowCount(); ++row)
|
||||||
|
{
|
||||||
|
auto *button_spin = qobject_cast<QSpinBox *>(m_table->cellWidget(row, COL_BUTTON));
|
||||||
|
auto *action_combo = qobject_cast<QComboBox *>(m_table->cellWidget(row, COL_ACTION));
|
||||||
|
if (!button_spin || !action_combo) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
SpaceMouseButtonMap::setActionId(button_spin->value(), action_combo->currentData().toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SpaceMouseConfigPage::title() const
|
||||||
|
{
|
||||||
|
return tr("Souris 3D", "configuration page title");
|
||||||
|
}
|
||||||
|
|
||||||
|
QIcon SpaceMouseConfigPage::icon() const
|
||||||
|
{
|
||||||
|
return QET::Icons::ConfigureToolbars;
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2006-2026 The QElectroTech Team
|
||||||
|
This file is part of QElectroTech.
|
||||||
|
|
||||||
|
QElectroTech is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
QElectroTech 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 General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef SPACEMOUSECONFIGPAGE_H
|
||||||
|
#define SPACEMOUSECONFIGPAGE_H
|
||||||
|
|
||||||
|
#include "configpage.h"
|
||||||
|
|
||||||
|
class QTableWidget;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief The SpaceMouseConfigPage class
|
||||||
|
Configuration page listing every device-button-to-action binding
|
||||||
|
(SpaceMouseButtonMap), letting the user add, edit and remove them.
|
||||||
|
Modelled directly on ShortcutsConfigPage, one row per binding instead
|
||||||
|
of one row per shortcut, since the two are close cousins: both end in
|
||||||
|
the same place -- ShortcutManager::trigger()/registerAction() -- just
|
||||||
|
from a different input source. Bindings are only persisted (via
|
||||||
|
SpaceMouseButtonMap::setActionId()) when applyConf() runs, i.e. when
|
||||||
|
the user validates the surrounding ConfigDialog.
|
||||||
|
|
||||||
|
Only compiled in, and only added to the Configuration dialog, when
|
||||||
|
QET_SPACEMOUSE_SUPPORT is defined -- see qetapp.cpp.
|
||||||
|
|
||||||
|
Button numbering is intentionally not fixed to any particular device:
|
||||||
|
it is exactly whatever integer SpaceMouseBackend::buttonPressed()
|
||||||
|
reports for the button pressed, which is backend- and device-specific.
|
||||||
|
Rows are added/removed freely rather than the page assuming a button
|
||||||
|
count, since that varies from 2 (SpaceMouse Compact) to over 30
|
||||||
|
(SpacePilot Pro).
|
||||||
|
*/
|
||||||
|
class SpaceMouseConfigPage : public ConfigPage
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SpaceMouseConfigPage(QWidget *parent = nullptr);
|
||||||
|
~SpaceMouseConfigPage() override;
|
||||||
|
|
||||||
|
void applyConf() override;
|
||||||
|
QString title() const override;
|
||||||
|
QIcon icon() const override;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void addRow();
|
||||||
|
void removeSelectedRow();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void populateTable();
|
||||||
|
void appendRow(int button, const QString &action_id);
|
||||||
|
|
||||||
|
QTableWidget *m_table;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SPACEMOUSECONFIGPAGE_H
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
#include "../qetdiagrameditor.h"
|
#include "../qetdiagrameditor.h"
|
||||||
#include "../projectview.h"
|
#include "../projectview.h"
|
||||||
#include "../qetproject.h"
|
#include "../qetproject.h"
|
||||||
|
#include "../utils/qetsettings.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QColorDialog>
|
#include <QColorDialog>
|
||||||
@@ -62,8 +63,28 @@ DiagramBgColorToolButton::DiagramBgColorToolButton(QETDiagramEditor *editor, QWi
|
|||||||
setStatusTip(tr("Choisir la couleur de fond du folio",
|
setStatusTip(tr("Choisir la couleur de fond du folio",
|
||||||
"status bar tip"));
|
"status bar tip"));
|
||||||
|
|
||||||
m_is_system_color = true;
|
//main() already restored the stored choice onto the global
|
||||||
m_current = QApplication::palette().color(QPalette::Base);
|
//Diagram::background_color and PaletteGraphicsView flag; mirror it
|
||||||
|
//here so the button opens on what the editor actually draws, rather
|
||||||
|
//than always claiming "system colour" as it used to.
|
||||||
|
if (PaletteGraphicsView::customBackgroundColor()) {
|
||||||
|
m_is_system_color = false;
|
||||||
|
m_current = Diagram::background_color;
|
||||||
|
} else {
|
||||||
|
m_is_system_color = true;
|
||||||
|
m_current = QApplication::palette().color(QPalette::Base);
|
||||||
|
}
|
||||||
|
for (const QString &name : QetSettings::sheetBackgroundRecentColors())
|
||||||
|
{
|
||||||
|
const QColor c(name);
|
||||||
|
if (c.isValid()) {
|
||||||
|
m_recent.append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (m_recent.size() > MAX_RECENT) {
|
||||||
|
m_recent.removeLast();
|
||||||
|
}
|
||||||
|
|
||||||
setMenu(new QMenu(this));
|
setMenu(new QMenu(this));
|
||||||
rebuildMenu();
|
rebuildMenu();
|
||||||
setSwatch(m_current);
|
setSwatch(m_current);
|
||||||
@@ -123,6 +144,7 @@ void DiagramBgColorToolButton::applyColor(const QColor &color)
|
|||||||
|
|
||||||
PaletteGraphicsView::setCustomBackgroundColor(true);
|
PaletteGraphicsView::setCustomBackgroundColor(true);
|
||||||
Diagram::background_color = color;
|
Diagram::background_color = color;
|
||||||
|
QetSettings::setSheetBackground(QetSettings::SheetBackground{color, true});
|
||||||
|
|
||||||
QETDiagramEditor *editor = m_editor;
|
QETDiagramEditor *editor = m_editor;
|
||||||
if (!editor) {
|
if (!editor) {
|
||||||
@@ -146,6 +168,8 @@ void DiagramBgColorToolButton::applySystemColor()
|
|||||||
|
|
||||||
PaletteGraphicsView::setCustomBackgroundColor(false);
|
PaletteGraphicsView::setCustomBackgroundColor(false);
|
||||||
Diagram::background_color = Qt::white;
|
Diagram::background_color = Qt::white;
|
||||||
|
QetSettings::setSheetBackground(
|
||||||
|
QetSettings::SheetBackground{QColor(Qt::white), false});
|
||||||
|
|
||||||
QETDiagramEditor *editor = m_editor;
|
QETDiagramEditor *editor = m_editor;
|
||||||
if (!editor) {
|
if (!editor) {
|
||||||
@@ -187,6 +211,21 @@ void DiagramBgColorToolButton::rememberRecent(const QColor &color)
|
|||||||
m_recent.removeLast();
|
m_recent.removeLast();
|
||||||
}
|
}
|
||||||
rebuildMenu();
|
rebuildMenu();
|
||||||
|
persistRecent();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief DiagramBgColorToolButton::persistRecent
|
||||||
|
Write the "recently used" colours back to the settings, so they are
|
||||||
|
still there on the next start instead of starting out empty.
|
||||||
|
*/
|
||||||
|
void DiagramBgColorToolButton::persistRecent()
|
||||||
|
{
|
||||||
|
QStringList names;
|
||||||
|
for (const QColor &c : std::as_const(m_recent)) {
|
||||||
|
names << c.name();
|
||||||
|
}
|
||||||
|
QetSettings::setSheetBackgroundRecentColors(names);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ class DiagramBgColorToolButton : public QToolButton
|
|||||||
void applySystemColor();
|
void applySystemColor();
|
||||||
void chooseOtherColor();
|
void chooseOtherColor();
|
||||||
void rememberRecent(const QColor &color);
|
void rememberRecent(const QColor &color);
|
||||||
|
void persistRecent();
|
||||||
void setSwatch(const QColor &color);
|
void setSwatch(const QColor &color);
|
||||||
static QIcon swatchIcon(const QColor &color);
|
static QIcon swatchIcon(const QColor &color);
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include "elementinfowidget.h"
|
#include "elementinfowidget.h"
|
||||||
|
#include "../qet.h"
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include "../diagram.h"
|
#include "../diagram.h"
|
||||||
@@ -366,18 +367,18 @@ void ElementInfoWidget::updateUi()
|
|||||||
// Load the lock status for auto numbering
|
// Load the lock status for auto numbering
|
||||||
if (m_element->elementData().m_type == ElementData::Terminal) {
|
if (m_element->elementData().m_type == ElementData::Terminal) {
|
||||||
QString lock_value = element_info.value(QStringLiteral("auto_num_locked")).toString();
|
QString lock_value = element_info.value(QStringLiteral("auto_num_locked")).toString();
|
||||||
ui->m_auto_num_locked_cb->setChecked(lock_value == QLatin1String("true"));
|
ui->m_auto_num_locked_cb->setChecked(QET::infoFlagIsTrue(lock_value));
|
||||||
|
|
||||||
// English: Load the potential isolating status from the element information mapping
|
// English: Load the potential isolating status from the element information mapping
|
||||||
if (m_potential_isolating_cb) {
|
if (m_potential_isolating_cb) {
|
||||||
QString isolating_value = element_info.value(QStringLiteral("potential_isolating")).toString();
|
QString isolating_value = element_info.value(QStringLiteral("potential_isolating")).toString();
|
||||||
m_potential_isolating_cb->setChecked(isolating_value == QLatin1String("true"));
|
m_potential_isolating_cb->setChecked(QET::infoFlagIsTrue(isolating_value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// English: Load the BOM exclusion status from the element information mapping
|
// English: Load the BOM exclusion status from the element information mapping
|
||||||
if (m_exclude_from_bom_cb) {
|
if (m_exclude_from_bom_cb) {
|
||||||
QString exclude_bom_value = element_info.value(QStringLiteral("exclude_from_bom")).toString();
|
QString exclude_bom_value = element_info.value(QStringLiteral("exclude_from_bom")).toString();
|
||||||
m_exclude_from_bom_cb->setChecked(exclude_bom_value == QLatin1String("true"));
|
m_exclude_from_bom_cb->setChecked(QET::infoFlagIsTrue(exclude_bom_value));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_live_edit) {
|
if (m_live_edit) {
|
||||||
|
|||||||
@@ -539,7 +539,35 @@ void MasterPropertiesWidget::updateUi()
|
|||||||
tr("Type"), tr("Adresse"), tr("Fonction"),
|
tr("Type"), tr("Adresse"), tr("Fonction"),
|
||||||
tr("Commentaire"), tr("Réf. croisée"), tr("Bornes")
|
tr("Commentaire"), tr("Réf. croisée"), tr("Bornes")
|
||||||
});
|
});
|
||||||
m_plc_table->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
|
m_plc_table->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
|
||||||
|
m_plc_table->horizontalHeader()->setSectionsMovable(true);
|
||||||
|
m_plc_table->horizontalHeader()->resizeSection(0, 120);
|
||||||
|
m_plc_table->horizontalHeader()->resizeSection(1, 100);
|
||||||
|
m_plc_table->horizontalHeader()->resizeSection(2, 150);
|
||||||
|
m_plc_table->horizontalHeader()->resizeSection(3, 150);
|
||||||
|
m_plc_table->horizontalHeader()->resizeSection(4, 100);
|
||||||
|
m_plc_table->horizontalHeader()->resizeSection(5, 120);
|
||||||
|
|
||||||
|
// Restore a previously saved column layout, if any
|
||||||
|
auto *plc_hdr = m_plc_table->horizontalHeader();
|
||||||
|
QSettings plc_settings;
|
||||||
|
const QVariant plc_hdr_state = plc_settings.value(
|
||||||
|
QStringLiteral("masterpropertieswidget/plc-table-header-state"));
|
||||||
|
if (!plc_hdr_state.isNull())
|
||||||
|
plc_hdr->restoreState(plc_hdr_state.toByteArray());
|
||||||
|
|
||||||
|
// Persist the column layout whenever the user resizes or moves a column
|
||||||
|
auto save_plc_header_state = [plc_hdr]()
|
||||||
|
{
|
||||||
|
QSettings settings;
|
||||||
|
settings.setValue(QStringLiteral("masterpropertieswidget/plc-table-header-state"),
|
||||||
|
plc_hdr->saveState());
|
||||||
|
};
|
||||||
|
connect(plc_hdr, &QHeaderView::sectionResized,
|
||||||
|
this, save_plc_header_state);
|
||||||
|
connect(plc_hdr, &QHeaderView::sectionMoved,
|
||||||
|
this, save_plc_header_state);
|
||||||
|
|
||||||
m_plc_table->setSelectionBehavior(QAbstractItemView::SelectItems);
|
m_plc_table->setSelectionBehavior(QAbstractItemView::SelectItems);
|
||||||
m_plc_table->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
m_plc_table->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||||
m_plc_table->setMinimumHeight(200);
|
m_plc_table->setMinimumHeight(200);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "terminalnumberingdialog.h"
|
#include "terminalnumberingdialog.h"
|
||||||
#include "ui_terminalnumberingdialog.h"
|
#include "ui_terminalnumberingdialog.h"
|
||||||
|
#include "../qet.h"
|
||||||
#include "../qetproject.h"
|
#include "../qetproject.h"
|
||||||
#include "../diagram.h"
|
#include "../diagram.h"
|
||||||
#include "../qetgraphicsitem/element.h"
|
#include "../qetgraphicsitem/element.h"
|
||||||
@@ -34,7 +35,7 @@ TerminalNumberingDialog::TerminalNumberingDialog(QWidget *parent, QETProject *pr
|
|||||||
if (elmt->elementData().m_type == ElementData::Terminal) {
|
if (elmt->elementData().m_type == ElementData::Terminal) {
|
||||||
// Ignore locked terminals
|
// Ignore locked terminals
|
||||||
DiagramContext info = elmt->elementInformations();
|
DiagramContext info = elmt->elementInformations();
|
||||||
if (info.value(QStringLiteral("auto_num_locked")).toString() == QLatin1String("true")) {
|
if (QET::infoFlagIsTrue(info.value(QStringLiteral("auto_num_locked")).toString())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +159,7 @@ QUndoCommand* TerminalNumberingDialog::getUndoCommand(QETProject *project) const
|
|||||||
DiagramContext info = elmt->elementInformations();
|
DiagramContext info = elmt->elementInformations();
|
||||||
|
|
||||||
// Ignore locked terminals (if the user checked a 'lock' property)
|
// Ignore locked terminals (if the user checked a 'lock' property)
|
||||||
if (info.value(QStringLiteral("auto_num_locked")).toString() == QLatin1String("true")) {
|
if (QET::infoFlagIsTrue(info.value(QStringLiteral("auto_num_locked")).toString())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,15 +25,34 @@
|
|||||||
#include "../qetgraphicsitem/elementtextitemgroup.h"
|
#include "../qetgraphicsitem/elementtextitemgroup.h"
|
||||||
#include "../qtextorientationspinboxwidget.h"
|
#include "../qtextorientationspinboxwidget.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief RotateTextsCommand::hasSelectedTexts
|
||||||
|
@param diagram
|
||||||
|
@return true if @p diagram has at least one selected text or text group.
|
||||||
|
Lets a caller decide whether to ask the user for an angle at all, keeping
|
||||||
|
the previous behaviour where no dialog appeared for an empty selection.
|
||||||
|
*/
|
||||||
|
bool RotateTextsCommand::hasSelectedTexts(Diagram *diagram)
|
||||||
|
{
|
||||||
|
if(!diagram)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
DiagramContent dc(diagram);
|
||||||
|
return (!dc.selectedTexts().isEmpty() || !dc.selectedTextsGroup().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief RotateTextsCommand::RotateTextsCommand
|
@brief RotateTextsCommand::RotateTextsCommand
|
||||||
@param diagram : Apply the rotation to the selected texts and group of texts
|
@param diagram : Apply the rotation to the selected texts and group of texts
|
||||||
of diagram at construction time.
|
of diagram at construction time.
|
||||||
|
@param rotation : the angle to apply, in degrees. Obtain it from
|
||||||
|
askRotation() for interactive use; pass it directly from a test or script.
|
||||||
@param parent : undo parent
|
@param parent : undo parent
|
||||||
*/
|
*/
|
||||||
RotateTextsCommand::RotateTextsCommand(Diagram *diagram, QUndoCommand *parent) :
|
RotateTextsCommand::RotateTextsCommand(Diagram *diagram, qreal rotation, QUndoCommand *parent) :
|
||||||
QUndoCommand(parent),
|
QUndoCommand(parent),
|
||||||
m_diagram(diagram)
|
m_diagram(diagram),
|
||||||
|
m_rotation(rotation)
|
||||||
{
|
{
|
||||||
DiagramContent dc(m_diagram);
|
DiagramContent dc(m_diagram);
|
||||||
QList <DiagramTextItem *> texts_list;
|
QList <DiagramTextItem *> texts_list;
|
||||||
@@ -53,8 +72,6 @@ m_diagram(diagram)
|
|||||||
|
|
||||||
if(texts_list.count() || groups_list.count())
|
if(texts_list.count() || groups_list.count())
|
||||||
{
|
{
|
||||||
openDialog();
|
|
||||||
|
|
||||||
QStringList parts;
|
QStringList parts;
|
||||||
if (texts_list.count())
|
if (texts_list.count())
|
||||||
parts << QObject::tr("%n texte(s)", "", texts_list.count());
|
parts << QObject::tr("%n texte(s)", "", texts_list.count());
|
||||||
@@ -76,6 +93,12 @@ void RotateTextsCommand::undo()
|
|||||||
if(m_diagram)
|
if(m_diagram)
|
||||||
m_diagram.data()->showMe();
|
m_diagram.data()->showMe();
|
||||||
|
|
||||||
|
//Nothing was selected at construction time: there is no animation to
|
||||||
|
//run. QUndoStack::push() calls redo() before it discards an obsolete
|
||||||
|
//command, so this has to be survivable rather than assumed away.
|
||||||
|
if(!m_anim_group)
|
||||||
|
return;
|
||||||
|
|
||||||
m_anim_group->setDirection(QAnimationGroup::Backward);
|
m_anim_group->setDirection(QAnimationGroup::Backward);
|
||||||
m_anim_group->start();
|
m_anim_group->start();
|
||||||
|
|
||||||
@@ -88,6 +111,9 @@ void RotateTextsCommand::redo()
|
|||||||
if(m_diagram)
|
if(m_diagram)
|
||||||
m_diagram.data()->showMe();
|
m_diagram.data()->showMe();
|
||||||
|
|
||||||
|
if(!m_anim_group)
|
||||||
|
return;
|
||||||
|
|
||||||
m_anim_group->setDirection(QAnimationGroup::Forward);
|
m_anim_group->setDirection(QAnimationGroup::Forward);
|
||||||
m_anim_group->start();
|
m_anim_group->start();
|
||||||
|
|
||||||
@@ -95,7 +121,18 @@ void RotateTextsCommand::redo()
|
|||||||
cti->forceRotateByUser(true);
|
cti->forceRotateByUser(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RotateTextsCommand::openDialog()
|
/**
|
||||||
|
@brief RotateTextsCommand::askRotation
|
||||||
|
Ask the user for an orientation.
|
||||||
|
@param rotation : set to the chosen angle when the dialog is accepted,
|
||||||
|
left untouched otherwise.
|
||||||
|
@return true if the user accepted, false if they cancelled.
|
||||||
|
|
||||||
|
Deliberately static and separate from the command: a QUndoCommand that
|
||||||
|
blocks on a modal in its constructor cannot be built by a test, a script,
|
||||||
|
or any headless caller.
|
||||||
|
*/
|
||||||
|
bool RotateTextsCommand::askRotation(qreal &rotation)
|
||||||
{
|
{
|
||||||
//Open the dialog
|
//Open the dialog
|
||||||
QDialog ori_text_dialog;
|
QDialog ori_text_dialog;
|
||||||
@@ -120,10 +157,11 @@ void RotateTextsCommand::openDialog()
|
|||||||
layout_v.addStretch();
|
layout_v.addStretch();
|
||||||
layout_v.addWidget(&buttons);
|
layout_v.addWidget(&buttons);
|
||||||
|
|
||||||
if (ori_text_dialog.exec() == QDialog::Accepted)
|
if (ori_text_dialog.exec() != QDialog::Accepted)
|
||||||
m_rotation = ori_widget->orientation();
|
return false;
|
||||||
else
|
|
||||||
setObsolete(true);
|
rotation = ori_widget->orientation();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RotateTextsCommand::setupAnimation(QObject *target, const QByteArray &propertyName, const QVariant& start, const QVariant& end)
|
void RotateTextsCommand::setupAnimation(QObject *target, const QByteArray &propertyName, const QVariant& start, const QVariant& end)
|
||||||
|
|||||||
@@ -28,19 +28,38 @@ class QParallelAnimationGroup;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
@brief The RotateTextsCommand class
|
@brief The RotateTextsCommand class
|
||||||
Open a dialog for edit the rotation of the current selected texts and texts group in diagram.
|
Apply @p rotation to the currently selected texts and texts group of a
|
||||||
Just instantiate this undo command and push it in a QUndoStack.
|
diagram. Just instantiate this undo command and push it in a QUndoStack.
|
||||||
|
|
||||||
|
This command does not ask the user for anything: obtaining the angle is the
|
||||||
|
caller's job, via the askRotation() helper below. Keeping the dialog out of
|
||||||
|
the constructor is what makes the command usable outside an interactive
|
||||||
|
session — from a test harness, a regression sweep, or a script — and stops
|
||||||
|
a headless caller from blocking forever on a modal nobody can answer.
|
||||||
|
|
||||||
|
Typical interactive use:
|
||||||
|
@code
|
||||||
|
if (RotateTextsCommand::hasSelectedTexts(diagram)) {
|
||||||
|
qreal rotation = 0;
|
||||||
|
if (RotateTextsCommand::askRotation(rotation))
|
||||||
|
diagram->undoStack().push(new RotateTextsCommand(diagram, rotation));
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
*/
|
*/
|
||||||
class RotateTextsCommand : public QUndoCommand
|
class RotateTextsCommand : public QUndoCommand
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RotateTextsCommand(Diagram *diagram, QUndoCommand *parent=nullptr);
|
RotateTextsCommand(Diagram *diagram, qreal rotation, QUndoCommand *parent=nullptr);
|
||||||
|
|
||||||
|
/// @return true if @p diagram has at least one selected text or text group to rotate.
|
||||||
|
static bool hasSelectedTexts(Diagram *diagram);
|
||||||
|
/// Open the orientation dialog. @return true and set @p rotation if accepted, false if cancelled.
|
||||||
|
static bool askRotation(qreal &rotation);
|
||||||
|
|
||||||
void undo() override;
|
void undo() override;
|
||||||
void redo() override;
|
void redo() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void openDialog();
|
|
||||||
void setupAnimation(QObject *target, const QByteArray &propertyName, const QVariant& start, const QVariant& end);
|
void setupAnimation(QObject *target, const QByteArray &propertyName, const QVariant& start, const QVariant& end);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -152,4 +152,67 @@ namespace QetSettings
|
|||||||
QSettings settings;
|
QSettings settings;
|
||||||
settings.setValue("scripting/enabled", enabled);
|
settings.setValue("scripting/enabled", enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief setSheetBackground
|
||||||
|
* Store the sheet background last picked in the diagram editor, so the
|
||||||
|
* next start opens on it for every project, old or new. @sa sheetBackground
|
||||||
|
* @param background
|
||||||
|
*/
|
||||||
|
void setSheetBackground(const SheetBackground &background)
|
||||||
|
{
|
||||||
|
QSettings settings;
|
||||||
|
//HexRgb, not HexArgb, on purpose: Diagram::background_color is
|
||||||
|
//temporarily given an alpha of 0 by the SVG export to make the
|
||||||
|
//background transparent, and that transient value must never end
|
||||||
|
//up here as a stored transparent sheet.
|
||||||
|
settings.setValue(QStringLiteral("diagrameditor/sheet_background_color"),
|
||||||
|
background.color.name(QColor::HexRgb));
|
||||||
|
settings.setValue(QStringLiteral("diagrameditor/sheet_background_custom"),
|
||||||
|
background.custom);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief sheetBackground
|
||||||
|
* @return the sheet background stored by setSheetBackground(), or the
|
||||||
|
* built-in default (white, following the system) when there is none.
|
||||||
|
* @sa setSheetBackground
|
||||||
|
*/
|
||||||
|
SheetBackground sheetBackground()
|
||||||
|
{
|
||||||
|
QSettings settings;
|
||||||
|
SheetBackground background;
|
||||||
|
background.custom = settings.value(
|
||||||
|
QStringLiteral("diagrameditor/sheet_background_custom"),
|
||||||
|
false).toBool();
|
||||||
|
const QColor stored(settings.value(
|
||||||
|
QStringLiteral("diagrameditor/sheet_background_color"),
|
||||||
|
QStringLiteral("#ffffff")).toString());
|
||||||
|
background.color = stored.isValid() ? stored : QColor(Qt::white);
|
||||||
|
return background;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief sheetBackgroundRecentColors
|
||||||
|
* @return the "recently used" sheet background colours, most recent
|
||||||
|
* first. Empty until the user has picked a non-preset colour.
|
||||||
|
* @sa setSheetBackgroundRecentColors
|
||||||
|
*/
|
||||||
|
QStringList sheetBackgroundRecentColors()
|
||||||
|
{
|
||||||
|
QSettings settings;
|
||||||
|
return settings.value(QStringLiteral("diagrameditor/sheet_background_recent")).toStringList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief setSheetBackgroundRecentColors
|
||||||
|
* Store the "recently used" sheet background colours, most recent first.
|
||||||
|
* @sa sheetBackgroundRecentColors
|
||||||
|
* @param colors
|
||||||
|
*/
|
||||||
|
void setSheetBackgroundRecentColors(const QStringList &colors)
|
||||||
|
{
|
||||||
|
QSettings settings;
|
||||||
|
settings.setValue(QStringLiteral("diagrameditor/sheet_background_recent"), colors);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
#define QETSETTINGS_H
|
#define QETSETTINGS_H
|
||||||
|
|
||||||
#include <Qt>
|
#include <Qt>
|
||||||
|
#include <QColor>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*Interface to use QSettings in QElectroTech
|
*Interface to use QSettings in QElectroTech
|
||||||
@@ -36,6 +38,28 @@ namespace QetSettings
|
|||||||
bool scriptingEnabled();
|
bool scriptingEnabled();
|
||||||
void setScriptingEnabled(bool enabled);
|
void setScriptingEnabled(bool enabled);
|
||||||
bool scriptingForcedByEnvironment();
|
bool scriptingForcedByEnvironment();
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief The sheet (folio) background the diagram editors draw.
|
||||||
|
|
||||||
|
Both halves are needed, not just the colour: with custom == false
|
||||||
|
the sheet follows the system ("Couleur systeme") and the views are
|
||||||
|
free to invert the lightness on a dark palette, while the very same
|
||||||
|
#ffffff with custom == true is an explicit "always white" that
|
||||||
|
must not be inverted. Storing only the colour would collapse the
|
||||||
|
two on the next start.
|
||||||
|
*/
|
||||||
|
struct SheetBackground
|
||||||
|
{
|
||||||
|
QColor color;
|
||||||
|
bool custom = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
SheetBackground sheetBackground();
|
||||||
|
void setSheetBackground(const SheetBackground &background);
|
||||||
|
|
||||||
|
QStringList sheetBackgroundRecentColors();
|
||||||
|
void setSheetBackgroundRecentColors(const QStringList &colors);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // QETSETTINGS_H
|
#endif // QETSETTINGS_H
|
||||||
|
|||||||
@@ -170,6 +170,17 @@ add_test(NAME tst_scriptingsetting COMMAND tst_scriptingsetting)
|
|||||||
target_include_directories(tst_scriptingsetting PRIVATE ${QET_DIR}/sources)
|
target_include_directories(tst_scriptingsetting PRIVATE ${QET_DIR}/sources)
|
||||||
target_link_libraries(tst_scriptingsetting PRIVATE Qt::Test Qt::Gui)
|
target_link_libraries(tst_scriptingsetting PRIVATE Qt::Test Qt::Gui)
|
||||||
|
|
||||||
|
# QetSettings::sheetBackground() -- the sheet (folio) background the diagram
|
||||||
|
# editor remembers between runs. Compiles qetsettings.cpp alone for the same
|
||||||
|
# reason as the test above; Qt::Gui because the pair carries a QColor.
|
||||||
|
add_executable(
|
||||||
|
tst_sheetbackgroundsetting
|
||||||
|
tst_sheetbackgroundsetting.cpp
|
||||||
|
${QET_DIR}/sources/utils/qetsettings.cpp)
|
||||||
|
add_test(NAME tst_sheetbackgroundsetting COMMAND tst_sheetbackgroundsetting)
|
||||||
|
target_include_directories(tst_sheetbackgroundsetting PRIVATE ${QET_DIR}/sources)
|
||||||
|
target_link_libraries(tst_sheetbackgroundsetting PRIVATE Qt::Test Qt::Gui)
|
||||||
|
|
||||||
# CrashHandler::formatInt() -- the async-signal-safe decimal formatter the
|
# CrashHandler::formatInt() -- the async-signal-safe decimal formatter the
|
||||||
# signal handler uses for the "Signal: N" line of a crash dump. Compiles
|
# signal handler uses for the "Signal: N" line of a crash dump. Compiles
|
||||||
# crashhandler.cpp and logring.cpp alongside; the handler deliberately
|
# crashhandler.cpp and logring.cpp alongside; the handler deliberately
|
||||||
|
|||||||
@@ -0,0 +1,160 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2006-2026 The QElectroTech Team
|
||||||
|
This file is part of QElectroTech.
|
||||||
|
|
||||||
|
QElectroTech is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
QElectroTech 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 General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
QetSettings::sheetBackground() -- the sheet (folio) background the
|
||||||
|
diagram editor remembers between runs, so the user does not have to
|
||||||
|
pick it again on every start.
|
||||||
|
|
||||||
|
Two properties are pinned here, and both are why this is a pair of
|
||||||
|
values rather than a single colour:
|
||||||
|
|
||||||
|
* The custom flag. "#ffffff" picked explicitly ("always white, never
|
||||||
|
inverted on a dark palette") and "#ffffff" left to follow the
|
||||||
|
system (where the views invert the lightness) are one colour and
|
||||||
|
two behaviours. Storing only the colour would silently turn one
|
||||||
|
into the other on the next start -- which is exactly the reported
|
||||||
|
bug, one step removed.
|
||||||
|
* The alpha being dropped. The SVG export gives
|
||||||
|
Diagram::background_color an alpha of 0 to render a transparent
|
||||||
|
background, and that transient value must not be persisted as a
|
||||||
|
permanently transparent sheet.
|
||||||
|
|
||||||
|
This test owns its own QSettings scope (organization + application
|
||||||
|
name), so it cannot read or write the configuration of whoever runs
|
||||||
|
it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "utils/qetsettings.h"
|
||||||
|
|
||||||
|
#include <QtTest>
|
||||||
|
#include <QSettings>
|
||||||
|
|
||||||
|
class TstSheetBackgroundSetting : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void initTestCase();
|
||||||
|
void init();
|
||||||
|
|
||||||
|
void defaultsToWhiteFollowingTheSystem();
|
||||||
|
void colourAndCustomFlagAreStoredTogether();
|
||||||
|
void sameColourStillDistinguishesTheTwoModes();
|
||||||
|
void alphaIsNotStored();
|
||||||
|
void unreadableColourFallsBackToWhite();
|
||||||
|
void recentColorsDefaultToEmpty();
|
||||||
|
void recentColorsKeepTheirOrder();
|
||||||
|
};
|
||||||
|
|
||||||
|
void TstSheetBackgroundSetting::initTestCase()
|
||||||
|
{
|
||||||
|
// A scope of this test's own: whatever this writes must not land in
|
||||||
|
// the configuration of the account running the suite.
|
||||||
|
QCoreApplication::setOrganizationName(
|
||||||
|
QStringLiteral("QElectroTech-tst_sheetbackgroundsetting"));
|
||||||
|
QCoreApplication::setApplicationName(
|
||||||
|
QStringLiteral("tst_sheetbackgroundsetting"));
|
||||||
|
QSettings settings;
|
||||||
|
settings.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TstSheetBackgroundSetting::init()
|
||||||
|
{
|
||||||
|
QSettings settings;
|
||||||
|
settings.remove(QStringLiteral("diagrameditor/sheet_background_color"));
|
||||||
|
settings.remove(QStringLiteral("diagrameditor/sheet_background_custom"));
|
||||||
|
settings.remove(QStringLiteral("diagrameditor/sheet_background_recent"));
|
||||||
|
settings.sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TstSheetBackgroundSetting::defaultsToWhiteFollowingTheSystem()
|
||||||
|
{
|
||||||
|
// An untouched installation, i.e. every existing one after an upgrade:
|
||||||
|
// white sheet, following the system so the views may still invert it.
|
||||||
|
const auto background = QetSettings::sheetBackground();
|
||||||
|
QVERIFY(background.color.isValid());
|
||||||
|
QCOMPARE(background.color, QColor(Qt::white));
|
||||||
|
QVERIFY(!background.custom);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TstSheetBackgroundSetting::colourAndCustomFlagAreStoredTogether()
|
||||||
|
{
|
||||||
|
QetSettings::setSheetBackground(QetSettings::SheetBackground{QColor("#404040"), true});
|
||||||
|
|
||||||
|
const auto background = QetSettings::sheetBackground();
|
||||||
|
QCOMPARE(background.color, QColor("#404040"));
|
||||||
|
QVERIFY(background.custom);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TstSheetBackgroundSetting::sameColourStillDistinguishesTheTwoModes()
|
||||||
|
{
|
||||||
|
// The reported bug in miniature: white is white either way, yet one
|
||||||
|
// of the two must survive a restart as an explicit choice and the
|
||||||
|
// other as "follow the system".
|
||||||
|
QetSettings::setSheetBackground(QetSettings::SheetBackground{QColor("#ffffff"), true});
|
||||||
|
QVERIFY(QetSettings::sheetBackground().custom);
|
||||||
|
|
||||||
|
QetSettings::setSheetBackground(QetSettings::SheetBackground{QColor("#ffffff"), false});
|
||||||
|
QVERIFY(!QetSettings::sheetBackground().custom);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TstSheetBackgroundSetting::alphaIsNotStored()
|
||||||
|
{
|
||||||
|
// What the SVG export leaves on Diagram::background_color once it has
|
||||||
|
// asked for a transparent background.
|
||||||
|
QColor transparent(QStringLiteral("#12ab34"));
|
||||||
|
transparent.setAlpha(0);
|
||||||
|
QetSettings::setSheetBackground(QetSettings::SheetBackground{transparent, true});
|
||||||
|
|
||||||
|
const auto background = QetSettings::sheetBackground();
|
||||||
|
QCOMPARE(background.color.name(), QStringLiteral("#12ab34"));
|
||||||
|
QCOMPARE(background.color.alpha(), 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TstSheetBackgroundSetting::unreadableColourFallsBackToWhite()
|
||||||
|
{
|
||||||
|
// A hand-edited or truncated settings file must not blank the sheet.
|
||||||
|
QSettings settings;
|
||||||
|
settings.setValue(QStringLiteral("diagrameditor/sheet_background_color"),
|
||||||
|
QStringLiteral("not a colour"));
|
||||||
|
settings.sync();
|
||||||
|
|
||||||
|
const auto background = QetSettings::sheetBackground();
|
||||||
|
QCOMPARE(background.color, QColor(Qt::white));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TstSheetBackgroundSetting::recentColorsDefaultToEmpty()
|
||||||
|
{
|
||||||
|
QVERIFY(QetSettings::sheetBackgroundRecentColors().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
void TstSheetBackgroundSetting::recentColorsKeepTheirOrder()
|
||||||
|
{
|
||||||
|
// Most recent first, as the menu lists them.
|
||||||
|
QetSettings::setSheetBackgroundRecentColors({QStringLiteral("#111111"),
|
||||||
|
QStringLiteral("#222222")});
|
||||||
|
QCOMPARE(QetSettings::sheetBackgroundRecentColors(),
|
||||||
|
QStringList({QStringLiteral("#111111"), QStringLiteral("#222222")}));
|
||||||
|
|
||||||
|
QetSettings::setSheetBackgroundRecentColors(QStringList());
|
||||||
|
QVERIFY(QetSettings::sheetBackgroundRecentColors().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
QTEST_MAIN(TstSheetBackgroundSetting)
|
||||||
|
#include "tst_sheetbackgroundsetting.moc"
|
||||||
Reference in New Issue
Block a user