mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2025-12-17 20:50:34 +01:00
Compare commits
140 Commits
0.9-dev
...
0.9-dev-20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
09c0929040 | ||
|
|
7312d06cc4 | ||
|
|
5c75bc4194 | ||
|
|
760a1f6c43 | ||
|
|
b6cfc8c755 | ||
|
|
820a01cb7d | ||
|
|
bfd7c1ea7c | ||
|
|
b8d9d38d31 | ||
|
|
c05d76c633 | ||
|
|
5a8197b2b3 | ||
|
|
c1169f0e04 | ||
|
|
794af49a3a | ||
|
|
8ef0d0b2f0 | ||
|
|
3729bec350 | ||
|
|
157377e1c1 | ||
|
|
7cb47f3b9e | ||
|
|
9db15f91e7 | ||
|
|
c54ee9b66d | ||
|
|
7a2c62d4d2 | ||
|
|
7f5b446fc9 | ||
|
|
bba1f07f57 | ||
|
|
d32c322e5a | ||
|
|
8960981f09 | ||
|
|
f2f50084e0 | ||
|
|
48be92cde5 | ||
|
|
845431179d | ||
|
|
f6161af258 | ||
|
|
8755a12698 | ||
|
|
a361e16a8e | ||
|
|
0f8f26e177 | ||
|
|
d53bb22509 | ||
|
|
3d25beaea0 | ||
|
|
1a3656f7be | ||
|
|
7de810bac4 | ||
|
|
1b6cf7d5f3 | ||
|
|
6cf79e6e75 | ||
|
|
8fdb9ba21a | ||
|
|
a4adcf4865 | ||
|
|
9300130aaf | ||
|
|
d7dd32ff1a | ||
|
|
564f38396f | ||
|
|
ab5dd39556 | ||
|
|
b12a4525a2 | ||
|
|
e0f2a66f3c | ||
|
|
20f5c3e443 | ||
|
|
ea730a2fa1 | ||
|
|
28d98a1a30 | ||
|
|
a75565e30d | ||
|
|
6ededf94bf | ||
|
|
9ca44f2557 | ||
|
|
9aad769a37 | ||
|
|
1f0f44233e | ||
|
|
5594197aab | ||
|
|
13b6b0c6c9 | ||
|
|
b0e6ad46ac | ||
|
|
b417edaff8 | ||
|
|
301fa629d8 | ||
|
|
44db25e76b | ||
|
|
d5df9703d0 | ||
|
|
11b8ef927b | ||
|
|
83b69253dc | ||
|
|
b96eff00ef | ||
|
|
4051bbd309 | ||
|
|
b181311162 | ||
|
|
1db1800572 | ||
|
|
001e93bc6f | ||
|
|
6e17996d37 | ||
|
|
4c563821e8 | ||
|
|
a4872bf686 | ||
|
|
332d978043 | ||
|
|
755bcf640d | ||
|
|
38a825865c | ||
|
|
5d3710c4b2 | ||
|
|
058824f29a | ||
|
|
4b82c3a0c4 | ||
|
|
ea793125a5 | ||
|
|
153aecbbf3 | ||
|
|
bc88f2ec2e | ||
|
|
6887c543da | ||
|
|
51ed21f9ef | ||
|
|
221773ea8a | ||
|
|
9d4b90da1a | ||
|
|
b021ac3e1f | ||
|
|
faf4235bed | ||
|
|
0a51e22b7d | ||
|
|
632fba5366 | ||
|
|
0ca883f114 | ||
|
|
170d856007 | ||
|
|
0424eb9fba | ||
|
|
8210f06919 | ||
|
|
468618adda | ||
|
|
8141a75738 | ||
|
|
8f201a6e5d | ||
|
|
b8745c0a6b | ||
|
|
7c3bde9118 | ||
|
|
ed8c1dea9d | ||
|
|
28cd389695 | ||
|
|
56bb2a399b | ||
|
|
dc726792d3 | ||
|
|
d8707a4ef2 | ||
|
|
01d6cdb920 | ||
|
|
77710e1cc5 | ||
|
|
1d2c00819d | ||
|
|
eee0469bd7 | ||
|
|
5118037cb5 | ||
|
|
1f53c39290 | ||
|
|
f499507b2d | ||
|
|
b71aec9548 | ||
|
|
c7798e1a80 | ||
|
|
5430692359 | ||
|
|
02b7ead041 | ||
|
|
ea364f9c4e | ||
|
|
f97edad75a | ||
|
|
454b2c8a0f | ||
|
|
b2782bc460 | ||
|
|
059f0eb1b6 | ||
|
|
ce318ac667 | ||
|
|
be2067148e | ||
|
|
444f62a1f8 | ||
|
|
8f85cacb06 | ||
|
|
ffe3d98279 | ||
|
|
dea926e4b4 | ||
|
|
a1779d1a7a | ||
|
|
252106178b | ||
|
|
a00404bc9f | ||
|
|
e2ebb445a8 | ||
|
|
24ec94d73e | ||
|
|
edb42caa16 | ||
|
|
c110acc0ac | ||
|
|
3467c09c1e | ||
|
|
b32a295b0c | ||
|
|
6251862f7a | ||
|
|
793770a72a | ||
|
|
aba16dc936 | ||
|
|
e5b8ba7e22 | ||
|
|
dad32d5897 | ||
|
|
9658a88c18 | ||
|
|
12e301b887 | ||
|
|
f3097fc537 | ||
|
|
73b394527d |
@@ -19,7 +19,7 @@ include(cmake/hoto_update_cmake_message.cmake)
|
||||
cmake_minimum_required(VERSION 3.14...3.19 FATAL_ERROR)
|
||||
|
||||
project(qelectrotech
|
||||
VERSION 0.8.0
|
||||
VERSION 0.9.0
|
||||
DESCRIPTION "QET is a CAD/CAE editor focusing on schematics drawing features."
|
||||
HOMEPAGE_URL "https://qelectrotech.org/"
|
||||
LANGUAGES CXX)
|
||||
@@ -131,3 +131,32 @@ target_include_directories(
|
||||
${QET_DIR}/sources/factory/ui
|
||||
${QET_DIR}/sources/print
|
||||
)
|
||||
|
||||
install(TARGETS ${PROJECT_NAME})
|
||||
if (NOT MINGW)
|
||||
|
||||
install(DIRECTORY ico/breeze-icons/16x16 DESTINATION ${QET_ICONS_PATH})
|
||||
install(DIRECTORY ico/breeze-icons/22x22 DESTINATION ${QET_ICONS_PATH})
|
||||
install(DIRECTORY ico/breeze-icons/32x32 DESTINATION ${QET_ICONS_PATH})
|
||||
install(DIRECTORY ico/breeze-icons/48x48 DESTINATION ${QET_ICONS_PATH})
|
||||
install(DIRECTORY ico/breeze-icons/64x64 DESTINATION ${QET_ICONS_PATH})
|
||||
install(DIRECTORY ico/breeze-icons/128x128 DESTINATION ${QET_ICONS_PATH})
|
||||
install(DIRECTORY ico/breeze-icons/256x256 DESTINATION ${QET_ICONS_PATH})
|
||||
install(DIRECTORY elements DESTINATION share/qelectrotech)
|
||||
install(DIRECTORY examples DESTINATION share/qelectrotech)
|
||||
install(DIRECTORY titleblocks DESTINATION share/qelectrotech)
|
||||
install(FILES LICENSE ELEMENTS.LICENSE CREDIT README ChangeLog DESTINATION share/doc/qelectrotech)
|
||||
install(FILES misc/qelectrotech.desktop DESTINATION share/applications)
|
||||
install(FILES misc/x-qet-element.xml
|
||||
misc/x-qet-project.xml
|
||||
misc/x-qet-titleblock.xml
|
||||
DESTINATION share/mime/application)
|
||||
install(FILES misc/x-qet-element.desktop
|
||||
misc/x-qet-project.desktop
|
||||
misc/x-qet-titleblock.desktop
|
||||
DESTINATION share/mimelnk/application)
|
||||
install(FILES misc/qelectrotech.xml DESTINATION share/mime/packages)
|
||||
install(FILES misc/qelectrotech.appdata.xml DESTINATION ${QET_APPDATA_PATH})
|
||||
install(FILES ${QM_FILES} DESTINATION ${QET_LANG_PATH})
|
||||
|
||||
endif()
|
||||
|
||||
@@ -15,10 +15,10 @@ The main goal of the developers is to provide a libre, easy to use and effective
|
||||
|
||||
### Version
|
||||
|
||||
The current stable version is 0.70 and was released on 2019.07.13.
|
||||
The current stable version is 0.80 and was released on 2021.02.21.
|
||||
Once it has been officialy released, the stable version is always frozen and is no longer developed.
|
||||
|
||||
New functionalities, bug and issue fixings are further made in the development version (currently 0.8), which can also be [downloaded](https://qelectrotech.org/download.html).
|
||||
New functionalities, bug and issue fixings are further made in the development version (currently 0.9), which can also be [downloaded](https://qelectrotech.org/download.html).
|
||||
|
||||
Users who want to test and take benefits from the last software implementations should use the development version. But... use it at your own risk, since things are sometimes broken or only partialy implemented until they are done!
|
||||
|
||||
@@ -33,6 +33,7 @@ Like many other open source softwares, QElectroTech is provided as it is, withou
|
||||
### Development / technical choices
|
||||
|
||||
The development follows the classical way of free and open source software: the source code, written by a community of users, is freely accessible.
|
||||
If you are reading this on Github, be aware that this is an hourly synced mirror. Our real code repository [is located here](https://git.tuxfamily.org/qet/qet.git/).
|
||||
|
||||
Here are the technical choices made for the software development:
|
||||
|
||||
@@ -172,7 +173,7 @@ Nowadays, QET is not only used by many individuals, teachers and students but al
|
||||
If you love QElectroTech, you can help developers to buy new hardware to test
|
||||
and implement new features. Thanks in advance for your generous donations.
|
||||
|
||||
For more information, look at [Paypal](https://www.paypal.com/donate/?token=rqf80cP0Ck1F2jn4Y46G7tIPv9bq7x0crXkwt3GZ6OZYG6ihJYi8lZxmmQ8itsFwMUdd1G&country.x=GB&locale.x=GB)
|
||||
or at [leetchi.com](https://www.leetchi.com/c/qelectroteck)
|
||||
For more information, look at [Paypal](https://www.paypal.com/donate/?token=rqf80cP0Ck1F2jn4Y46G7tIPv9bq7x0crXkwt3GZ6OZYG6ihJYi8lZxmmQ8itsFwMUdd1G&country.x=GB&locale.x=GB)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,12 +1,79 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
If by accident I have forgotten to credit someone in the CHANGELOG, email me and I will fix it.
|
||||
|
||||
__3.2.0__
|
||||
---------
|
||||
|
||||
* Added support for Qt 6 - _Jonas Kvinge_
|
||||
* Fixed warning in `Qt 5.9` with `min`/`max` functions on Windows - _Nick Korotysh_
|
||||
* Fix return value of connectToPrimary() when connect is successful - _Jonas Kvinge_
|
||||
* Fix build issue with MinGW GCC pedantic mode - _Iakov Kirilenko_
|
||||
* Fixed conversion from `int` to `quint32` and Clang Tidy warnings - _Hennadii Chernyshchyk_
|
||||
|
||||
__3.1.5__
|
||||
---------
|
||||
|
||||
* Improved library stability in edge cases and very rapid process initialisation
|
||||
* Fixed Bug where the shared memory block may have been modified without a lock
|
||||
* Fixed Bug causing `instanceStarted()` to not get emitted when a second instance
|
||||
has been started before the primary has initiated it's `QLocalServer`.
|
||||
|
||||
__3.1.4__
|
||||
---------
|
||||
* Officially supporting and build-testing against Qt 5.15
|
||||
* Fixed an MSVC C4996 warning that suggests using `strncpy_s`.
|
||||
|
||||
_Hennadii Chernyshchyk_
|
||||
|
||||
__3.1.3.1__
|
||||
---------
|
||||
* CMake build system improvements
|
||||
* Fixed Clang Tidy warnings
|
||||
|
||||
_Hennadii Chernyshchyk_
|
||||
|
||||
__3.1.3__
|
||||
---------
|
||||
* Improved `CMakeLists.txt`
|
||||
|
||||
_Hennadii Chernyshchyk_
|
||||
|
||||
__3.1.2__
|
||||
---------
|
||||
|
||||
* Fix a crash when exiting an application on Android and iOS
|
||||
|
||||
_Emeric Grange_
|
||||
|
||||
__3.1.1a__
|
||||
----------
|
||||
|
||||
* Added currentUser() method that returns the user the current instance is running as.
|
||||
|
||||
_Leander Schulten_
|
||||
|
||||
__3.1.0a__
|
||||
----------
|
||||
|
||||
* Added primaryUser() method that returns the user the primary instance is running as.
|
||||
|
||||
__3.0.19__
|
||||
----------
|
||||
|
||||
* Fixed code warning for depricated functions in Qt 5.10 related to `QTime` and `qrand()`.
|
||||
|
||||
_Hennadii Chernyshchyk_
|
||||
_Anton Filimonov_
|
||||
_Jonas Kvinge_
|
||||
|
||||
__3.0.18__
|
||||
----------
|
||||
|
||||
* Fallback to standard QApplication class on iOS and Android systems where
|
||||
the library is not supported.
|
||||
|
||||
|
||||
* Added Build CI tests to verify the library builds successfully on Linux, Windows and MacOS across multiple Qt versions.
|
||||
|
||||
_Anton Filimonov_
|
||||
|
||||
@@ -1,43 +1,40 @@
|
||||
cmake_minimum_required(VERSION 3.1.0)
|
||||
cmake_minimum_required(VERSION 3.7.0)
|
||||
|
||||
project(SingleApplication)
|
||||
project(SingleApplication LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
|
||||
# SingleApplication base class
|
||||
set(QAPPLICATION_CLASS QCoreApplication CACHE STRING "Inheritance class for SingleApplication")
|
||||
set_property(CACHE QAPPLICATION_CLASS PROPERTY STRINGS QApplication QGuiApplication QCoreApplication)
|
||||
|
||||
# Libary target
|
||||
add_library(${PROJECT_NAME} STATIC
|
||||
singleapplication.cpp
|
||||
singleapplication_p.cpp
|
||||
)
|
||||
)
|
||||
add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
|
||||
|
||||
if(NOT QT_DEFAULT_MAJOR_VERSION)
|
||||
set(QT_DEFAULT_MAJOR_VERSION 5 CACHE STRING "Qt version to use (5 or 6), defaults to 5")
|
||||
endif()
|
||||
|
||||
# Find dependencies
|
||||
find_package(Qt5Network)
|
||||
if(QAPPLICATION_CLASS STREQUAL QApplication)
|
||||
find_package(Qt5 COMPONENTS Widgets REQUIRED)
|
||||
elseif(QAPPLICATION_CLASS STREQUAL QGuiApplication)
|
||||
find_package(Qt5 COMPONENTS Gui REQUIRED)
|
||||
else()
|
||||
find_package(Qt5 COMPONENTS Core REQUIRED)
|
||||
endif()
|
||||
add_compile_definitions(QAPPLICATION_CLASS=${QAPPLICATION_CLASS})
|
||||
set(QT_COMPONENTS Core Network)
|
||||
set(QT_LIBRARIES Qt${QT_DEFAULT_MAJOR_VERSION}::Core Qt${QT_DEFAULT_MAJOR_VERSION}::Network)
|
||||
|
||||
# Link dependencies
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Network)
|
||||
if(QAPPLICATION_CLASS STREQUAL QApplication)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Widgets)
|
||||
list(APPEND QT_COMPONENTS Widgets)
|
||||
list(APPEND QT_LIBRARIES Qt${QT_DEFAULT_MAJOR_VERSION}::Widgets)
|
||||
elseif(QAPPLICATION_CLASS STREQUAL QGuiApplication)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Gui)
|
||||
list(APPEND QT_COMPONENTS Gui)
|
||||
list(APPEND QT_LIBRARIES Qt${QT_DEFAULT_MAJOR_VERSION}::Gui)
|
||||
else()
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Core)
|
||||
set(QAPPLICATION_CLASS QCoreApplication)
|
||||
endif()
|
||||
|
||||
find_package(Qt${QT_DEFAULT_MAJOR_VERSION} COMPONENTS ${QT_COMPONENTS} REQUIRED)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC ${QT_LIBRARIES})
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE advapi32)
|
||||
endif()
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME} PUBLIC QAPPLICATION_CLASS=${QAPPLICATION_CLASS})
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Itay Grudev 2015 - 2016
|
||||
Copyright (c) Itay Grudev 2015 - 2020
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
SingleApplication
|
||||
=================
|
||||
[](https://github.com/itay-grudev/SingleApplication/actions)
|
||||
|
||||
This is a replacement of the QtSingleApplication for `Qt5`.
|
||||
This is a replacement of the QtSingleApplication for `Qt5` and `Qt6`.
|
||||
|
||||
Keeps the Primary Instance of your Application and kills each subsequent
|
||||
instances. It can (if enabled) spawn secondary (non-related to the primary)
|
||||
@@ -15,18 +16,6 @@ class you specify via the `QAPPLICATION_CLASS` macro (`QCoreApplication` is the
|
||||
default). Further usage is similar to the use of the `Q[Core|Gui]Application`
|
||||
classes.
|
||||
|
||||
The library sets up a `QLocalServer` and a `QSharedMemory` block. The first
|
||||
instance of your Application is your Primary Instance. It would check if the
|
||||
shared memory block exists and if not it will start a `QLocalServer` and listen
|
||||
for connections. Each subsequent instance of your application would check if the
|
||||
shared memory block exists and if it does, it will connect to the QLocalServer
|
||||
to notify the primary instance that a new instance had been started, after which
|
||||
it would terminate with status code `0`. In the Primary Instance
|
||||
`SingleApplication` would emit the `instanceStarted()` signal upon detecting
|
||||
that a new instance had been started.
|
||||
|
||||
The library uses `stdlib` to terminate the program with the `exit()` function.
|
||||
|
||||
You can use the library as if you use any other `QCoreApplication` derived
|
||||
class:
|
||||
|
||||
@@ -43,8 +32,7 @@ int main( int argc, char* argv[] )
|
||||
```
|
||||
|
||||
To include the library files I would recommend that you add it as a git
|
||||
submodule to your project and include it's contents with a `.pri` file. Here is
|
||||
how:
|
||||
submodule to your project. Here is how:
|
||||
|
||||
```bash
|
||||
git submodule add git@github.com:itay-grudev/SingleApplication.git singleapplication
|
||||
@@ -66,13 +54,27 @@ Then include the subdirectory in your `CMakeLists.txt` project file.
|
||||
```cmake
|
||||
set(QAPPLICATION_CLASS QApplication CACHE STRING "Inheritance class for SingleApplication")
|
||||
add_subdirectory(src/third-party/singleapplication)
|
||||
target_link_libraries(${PROJECT_NAME} SingleApplication::SingleApplication)
|
||||
```
|
||||
|
||||
|
||||
The library sets up a `QLocalServer` and a `QSharedMemory` block. The first
|
||||
instance of your Application is your Primary Instance. It would check if the
|
||||
shared memory block exists and if not it will start a `QLocalServer` and listen
|
||||
for connections. Each subsequent instance of your application would check if the
|
||||
shared memory block exists and if it does, it will connect to the QLocalServer
|
||||
to notify the primary instance that a new instance had been started, after which
|
||||
it would terminate with status code `0`. In the Primary Instance
|
||||
`SingleApplication` would emit the `instanceStarted()` signal upon detecting
|
||||
that a new instance had been started.
|
||||
|
||||
The library uses `stdlib` to terminate the program with the `exit()` function.
|
||||
|
||||
Also don't forget to specify which `QCoreApplication` class your app is using if it
|
||||
is not `QCoreApplication` as in examples above.
|
||||
|
||||
The `Instance Started` signal
|
||||
------------------------
|
||||
-----------------------------
|
||||
|
||||
The SingleApplication class implements a `instanceStarted()` signal. You can
|
||||
bind to that signal to raise your application's window when a new instance had
|
||||
@@ -137,13 +139,22 @@ app.isSecondary();
|
||||
*__Note:__ If your Primary Instance is terminated a newly launched instance
|
||||
will replace the Primary one even if the Secondary flag has been set.*
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
There are three examples provided in this repository:
|
||||
|
||||
* Basic example that prevents a secondary instance from starting [`examples/basic`](https://github.com/itay-grudev/SingleApplication/tree/master/examples/basic)
|
||||
* An example of a graphical application raising it's parent window [`examples/calculator`](https://github.com/itay-grudev/SingleApplication/tree/master/examples/calculator)
|
||||
* A console application sending the primary instance it's command line parameters [`examples/sending_arguments`](https://github.com/itay-grudev/SingleApplication/tree/master/examples/sending_arguments)
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
### Members
|
||||
|
||||
```cpp
|
||||
SingleApplication::SingleApplication( int &argc, char *argv[], bool allowSecondary = false, Options options = Mode::User, int timeout = 100 )
|
||||
SingleApplication::SingleApplication( int &argc, char *argv[], bool allowSecondary = false, Options options = Mode::User, int timeout = 100, QString userData = QString() )
|
||||
```
|
||||
|
||||
Depending on whether `allowSecondary` is set, this constructor may terminate
|
||||
@@ -152,7 +163,7 @@ can be specified to set whether the SingleApplication block should work
|
||||
user-wide or system-wide. Additionally the `Mode::SecondaryNotification` may be
|
||||
used to notify the primary instance whenever a secondary instance had been
|
||||
started (disabled by default). `timeout` specifies the maximum time in
|
||||
milliseconds to wait for blocking operations.
|
||||
milliseconds to wait for blocking operations. Setting `userData` provides additional data that will isolate this instance from other instances that do not have the same (or any) user data set.
|
||||
|
||||
*__Note:__ `argc` and `argv` may be changed as Qt removes arguments that it
|
||||
recognizes.*
|
||||
@@ -204,6 +215,22 @@ qint64 SingleApplication::primaryPid()
|
||||
|
||||
Returns the process ID (PID) of the primary instance.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
QString SingleApplication::primaryUser()
|
||||
```
|
||||
|
||||
Returns the username the primary instance is running as.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
QString SingleApplication::currentUser()
|
||||
```
|
||||
|
||||
Returns the username the current instance is running as.
|
||||
|
||||
### Signals
|
||||
|
||||
```cpp
|
||||
|
||||
1
SingleApplication/SingleApplication
Normal file
1
SingleApplication/SingleApplication
Normal file
@@ -0,0 +1 @@
|
||||
#include "singleapplication.h"
|
||||
12
SingleApplication/examples/basic/CMakeLists.txt
Normal file
12
SingleApplication/examples/basic/CMakeLists.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
cmake_minimum_required(VERSION 3.7.0)
|
||||
|
||||
project(basic LANGUAGES CXX)
|
||||
|
||||
# SingleApplication base class
|
||||
set(QAPPLICATION_CLASS QCoreApplication)
|
||||
add_subdirectory(../.. SingleApplication)
|
||||
|
||||
add_executable(basic main.cpp)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} SingleApplication::SingleApplication)
|
||||
|
||||
0
SingleApplication/examples/basic/basic.pro
Normal file → Executable file
0
SingleApplication/examples/basic/basic.pro
Normal file → Executable file
2
SingleApplication/examples/basic/main.cpp
Normal file → Executable file
2
SingleApplication/examples/basic/main.cpp
Normal file → Executable file
@@ -5,5 +5,7 @@ int main(int argc, char *argv[])
|
||||
// Allow secondary instances
|
||||
SingleApplication app( argc, argv );
|
||||
|
||||
qWarning() << "Started a new instance";
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
21
SingleApplication/examples/calculator/CMakeLists.txt
Normal file
21
SingleApplication/examples/calculator/CMakeLists.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
cmake_minimum_required(VERSION 3.7.0)
|
||||
|
||||
project(calculator LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
|
||||
# SingleApplication base class
|
||||
set(QAPPLICATION_CLASS QApplication)
|
||||
add_subdirectory(../.. SingleApplication)
|
||||
|
||||
find_package(Qt${QT_DEFAULT_MAJOR_VERSION} COMPONENTS Core REQUIRED)
|
||||
|
||||
add_executable(${PROJECT_NAME}
|
||||
button.h
|
||||
calculator.h
|
||||
button.cpp
|
||||
calculator.cpp
|
||||
main.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} SingleApplication::SingleApplication)
|
||||
@@ -82,27 +82,27 @@ Calculator::Calculator(QWidget *parent)
|
||||
digitButtons[i] = createButton(QString::number(i), SLOT(digitClicked()));
|
||||
}
|
||||
|
||||
Button *pointButton = createButton(tr("."), SLOT(pointClicked()));
|
||||
Button *changeSignButton = createButton(tr("\302\261"), SLOT(changeSignClicked()));
|
||||
Button *pointButton = createButton(".", SLOT(pointClicked()));
|
||||
Button *changeSignButton = createButton("\302\261", SLOT(changeSignClicked()));
|
||||
|
||||
Button *backspaceButton = createButton(tr("Backspace"), SLOT(backspaceClicked()));
|
||||
Button *clearButton = createButton(tr("Clear"), SLOT(clear()));
|
||||
Button *clearAllButton = createButton(tr("Clear All"), SLOT(clearAll()));
|
||||
Button *backspaceButton = createButton("Backspace", SLOT(backspaceClicked()));
|
||||
Button *clearButton = createButton("Clear", SLOT(clear()));
|
||||
Button *clearAllButton = createButton("Clear All", SLOT(clearAll()));
|
||||
|
||||
Button *clearMemoryButton = createButton(tr("MC"), SLOT(clearMemory()));
|
||||
Button *readMemoryButton = createButton(tr("MR"), SLOT(readMemory()));
|
||||
Button *setMemoryButton = createButton(tr("MS"), SLOT(setMemory()));
|
||||
Button *addToMemoryButton = createButton(tr("M+"), SLOT(addToMemory()));
|
||||
Button *clearMemoryButton = createButton("MC", SLOT(clearMemory()));
|
||||
Button *readMemoryButton = createButton("MR", SLOT(readMemory()));
|
||||
Button *setMemoryButton = createButton("MS", SLOT(setMemory()));
|
||||
Button *addToMemoryButton = createButton("M+", SLOT(addToMemory()));
|
||||
|
||||
Button *divisionButton = createButton(tr("\303\267"), SLOT(multiplicativeOperatorClicked()));
|
||||
Button *timesButton = createButton(tr("\303\227"), SLOT(multiplicativeOperatorClicked()));
|
||||
Button *minusButton = createButton(tr("-"), SLOT(additiveOperatorClicked()));
|
||||
Button *plusButton = createButton(tr("+"), SLOT(additiveOperatorClicked()));
|
||||
Button *divisionButton = createButton("\303\267", SLOT(multiplicativeOperatorClicked()));
|
||||
Button *timesButton = createButton("\303\227", SLOT(multiplicativeOperatorClicked()));
|
||||
Button *minusButton = createButton("-", SLOT(additiveOperatorClicked()));
|
||||
Button *plusButton = createButton("+", SLOT(additiveOperatorClicked()));
|
||||
|
||||
Button *squareRootButton = createButton(tr("Sqrt"), SLOT(unaryOperatorClicked()));
|
||||
Button *powerButton = createButton(tr("x\302\262"), SLOT(unaryOperatorClicked()));
|
||||
Button *reciprocalButton = createButton(tr("1/x"), SLOT(unaryOperatorClicked()));
|
||||
Button *equalButton = createButton(tr("="), SLOT(equalClicked()));
|
||||
Button *squareRootButton = createButton("Sqrt", SLOT(unaryOperatorClicked()));
|
||||
Button *powerButton = createButton("x\302\262", SLOT(unaryOperatorClicked()));
|
||||
Button *reciprocalButton = createButton("1/x", SLOT(unaryOperatorClicked()));
|
||||
Button *equalButton = createButton("=", SLOT(equalClicked()));
|
||||
//! [4]
|
||||
|
||||
//! [5]
|
||||
@@ -140,7 +140,7 @@ Calculator::Calculator(QWidget *parent)
|
||||
mainLayout->addWidget(equalButton, 5, 5);
|
||||
setLayout(mainLayout);
|
||||
|
||||
setWindowTitle(tr("Calculator"));
|
||||
setWindowTitle("Calculator");
|
||||
}
|
||||
//! [6]
|
||||
|
||||
@@ -169,15 +169,15 @@ void Calculator::unaryOperatorClicked()
|
||||
double operand = display->text().toDouble();
|
||||
double result = 0.0;
|
||||
|
||||
if (clickedOperator == tr("Sqrt")) {
|
||||
if (clickedOperator == "Sqrt") {
|
||||
if (operand < 0.0) {
|
||||
abortOperation();
|
||||
return;
|
||||
}
|
||||
result = std::sqrt(operand);
|
||||
} else if (clickedOperator == tr("x\302\262")) {
|
||||
} else if (clickedOperator == "x\302\262") {
|
||||
result = std::pow(operand, 2.0);
|
||||
} else if (clickedOperator == tr("1/x")) {
|
||||
} else if (clickedOperator == "1/x") {
|
||||
if (operand == 0.0) {
|
||||
abortOperation();
|
||||
return;
|
||||
@@ -287,7 +287,7 @@ void Calculator::pointClicked()
|
||||
if (waitingForOperand)
|
||||
display->setText("0");
|
||||
if (!display->text().contains('.'))
|
||||
display->setText(display->text() + tr("."));
|
||||
display->setText(display->text() + ".");
|
||||
waitingForOperand = false;
|
||||
}
|
||||
//! [22]
|
||||
@@ -299,7 +299,7 @@ void Calculator::changeSignClicked()
|
||||
double value = text.toDouble();
|
||||
|
||||
if (value > 0.0) {
|
||||
text.prepend(tr("-"));
|
||||
text.prepend("-");
|
||||
} else if (value < 0.0) {
|
||||
text.remove(0, 1);
|
||||
}
|
||||
@@ -383,20 +383,20 @@ Button *Calculator::createButton(const QString &text, const char *member)
|
||||
void Calculator::abortOperation()
|
||||
{
|
||||
clearAll();
|
||||
display->setText(tr("####"));
|
||||
display->setText("####");
|
||||
}
|
||||
//! [36]
|
||||
|
||||
//! [38]
|
||||
bool Calculator::calculate(double rightOperand, const QString &pendingOperator)
|
||||
{
|
||||
if (pendingOperator == tr("+")) {
|
||||
if (pendingOperator == "+") {
|
||||
sumSoFar += rightOperand;
|
||||
} else if (pendingOperator == tr("-")) {
|
||||
} else if (pendingOperator == "-") {
|
||||
sumSoFar -= rightOperand;
|
||||
} else if (pendingOperator == tr("\303\227")) {
|
||||
} else if (pendingOperator == "\303\227") {
|
||||
factorSoFar *= rightOperand;
|
||||
} else if (pendingOperator == tr("\303\267")) {
|
||||
} else if (pendingOperator == "\303\267") {
|
||||
if (rightOperand == 0.0)
|
||||
return false;
|
||||
factorSoFar /= rightOperand;
|
||||
|
||||
20
SingleApplication/examples/sending_arguments/CMakeLists.txt
Normal file
20
SingleApplication/examples/sending_arguments/CMakeLists.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
cmake_minimum_required(VERSION 3.7.0)
|
||||
|
||||
project(sending_arguments LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
|
||||
# SingleApplication base class
|
||||
set(QAPPLICATION_CLASS QCoreApplication)
|
||||
add_subdirectory(../.. SingleApplication)
|
||||
|
||||
find_package(Qt${QT_DEFAULT_MAJOR_VERSION} COMPONENTS Core REQUIRED)
|
||||
|
||||
add_executable(${PROJECT_NAME}
|
||||
main.cpp
|
||||
messagereceiver.cpp
|
||||
messagereceiver.h
|
||||
main.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} SingleApplication::SingleApplication)
|
||||
3
SingleApplication/examples/sending_arguments/main.cpp
Normal file → Executable file
3
SingleApplication/examples/sending_arguments/main.cpp
Normal file → Executable file
@@ -11,6 +11,9 @@ int main(int argc, char *argv[])
|
||||
// If this is a secondary instance
|
||||
if( app.isSecondary() ) {
|
||||
app.sendMessage( app.arguments().join(' ').toUtf8() );
|
||||
qDebug() << "App already running.";
|
||||
qDebug() << "Primary instance PID: " << app.primaryPid();
|
||||
qDebug() << "Primary instance user: " << app.primaryUser();
|
||||
return 0;
|
||||
} else {
|
||||
QObject::connect(
|
||||
|
||||
0
SingleApplication/examples/sending_arguments/sending_arguments.pro
Normal file → Executable file
0
SingleApplication/examples/sending_arguments/sending_arguments.pro
Normal file → Executable file
@@ -1,6 +1,6 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) Itay Grudev 2015 - 2018
|
||||
// Copyright (c) Itay Grudev 2015 - 2020
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -20,176 +20,255 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include <QtCore/QTime>
|
||||
#include <QtCore/QThread>
|
||||
#include <QtCore/QDateTime>
|
||||
#include <QtCore/QElapsedTimer>
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QSharedMemory>
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) // ### Qt 6: remove
|
||||
#else
|
||||
#if TODO_LIST
|
||||
#pragma message("@TODO remove code for QT 5.10 or later")
|
||||
#endif
|
||||
#include <QRandomGenerator>
|
||||
#endif
|
||||
|
||||
#include "singleapplication.h"
|
||||
#include "singleapplication_p.h"
|
||||
|
||||
/**
|
||||
@brief Constructor. Checks and fires up LocalServer or closes the program
|
||||
if another instance already exists
|
||||
@param argc
|
||||
@param argv
|
||||
@param {bool} allowSecondaryInstances
|
||||
*/
|
||||
SingleApplication::SingleApplication( int &argc, char *argv[], bool allowSecondary, Options options, int timeout )
|
||||
: app_t( argc, argv ), d_ptr( new SingleApplicationPrivate( this ) )
|
||||
* @brief Constructor. Checks and fires up LocalServer or closes the program
|
||||
* if another instance already exists
|
||||
* @param argc
|
||||
* @param argv
|
||||
* @param allowSecondary Whether to enable secondary instance support
|
||||
* @param options Optional flags to toggle specific behaviour
|
||||
* @param timeout Maximum time blocking functions are allowed during app load
|
||||
*/
|
||||
SingleApplication::SingleApplication( int &argc, char *argv[], bool allowSecondary, Options options, int timeout, const QString &userData )
|
||||
: app_t( argc, argv ), d_ptr( new SingleApplicationPrivate( this ) )
|
||||
{
|
||||
Q_D(SingleApplication);
|
||||
Q_D( SingleApplication );
|
||||
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||
// On Android and iOS since the library is not supported fallback to
|
||||
// standard QApplication behaviour by simply returning at this point.
|
||||
qWarning() << "SingleApplication is not supported on Android and iOS systems.";
|
||||
return;
|
||||
// On Android and iOS since the library is not supported fallback to
|
||||
// standard QApplication behaviour by simply returning at this point.
|
||||
qWarning() << "SingleApplication is not supported on Android and iOS systems.";
|
||||
return;
|
||||
#endif
|
||||
|
||||
// Store the current mode of the program
|
||||
d->options = options;
|
||||
// Store the current mode of the program
|
||||
d->options = options;
|
||||
|
||||
// Generating an application ID used for identifying the shared memory
|
||||
// block and QLocalServer
|
||||
d->genBlockServerName();
|
||||
// Add any unique user data
|
||||
if ( ! userData.isEmpty() )
|
||||
d->addAppData( userData );
|
||||
|
||||
// Generating an application ID used for identifying the shared memory
|
||||
// block and QLocalServer
|
||||
d->genBlockServerName();
|
||||
|
||||
// To mitigate QSharedMemory issues with large amount of processes
|
||||
// attempting to attach at the same time
|
||||
SingleApplicationPrivate::randomSleep();
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
// By explicitly attaching it and then deleting it we make sure that the
|
||||
// memory is deleted even after the process has crashed on Unix.
|
||||
d->memory = new QSharedMemory( d->blockServerName );
|
||||
d->memory->attach();
|
||||
delete d->memory;
|
||||
// By explicitly attaching it and then deleting it we make sure that the
|
||||
// memory is deleted even after the process has crashed on Unix.
|
||||
d->memory = new QSharedMemory( d->blockServerName );
|
||||
d->memory->attach();
|
||||
delete d->memory;
|
||||
#endif
|
||||
// Guarantee thread safe behaviour with a shared memory block.
|
||||
d->memory = new QSharedMemory( d->blockServerName );
|
||||
// Guarantee thread safe behaviour with a shared memory block.
|
||||
d->memory = new QSharedMemory( d->blockServerName );
|
||||
|
||||
// Create a shared memory block
|
||||
if( d->memory->create( sizeof( InstancesInfo ) ) ) {
|
||||
// Initialize the shared memory block
|
||||
d->memory->lock();
|
||||
d->initializeMemoryBlock();
|
||||
d->memory->unlock();
|
||||
} else {
|
||||
// Attempt to attach to the memory segment
|
||||
if( ! d->memory->attach() ) {
|
||||
qCritical() << "SingleApplication: Unable to attach to shared memory block.";
|
||||
qCritical() << d->memory->errorString();
|
||||
delete d;
|
||||
::exit( EXIT_FAILURE );
|
||||
}
|
||||
}
|
||||
// Create a shared memory block
|
||||
if( d->memory->create( sizeof( InstancesInfo ) )){
|
||||
// Initialize the shared memory block
|
||||
if( ! d->memory->lock() ){
|
||||
qCritical() << "SingleApplication: Unable to lock memory block after create.";
|
||||
abortSafely();
|
||||
}
|
||||
d->initializeMemoryBlock();
|
||||
} else {
|
||||
if( d->memory->error() == QSharedMemory::AlreadyExists ){
|
||||
// Attempt to attach to the memory segment
|
||||
if( ! d->memory->attach() ){
|
||||
qCritical() << "SingleApplication: Unable to attach to shared memory block.";
|
||||
abortSafely();
|
||||
}
|
||||
if( ! d->memory->lock() ){
|
||||
qCritical() << "SingleApplication: Unable to lock memory block after attach.";
|
||||
abortSafely();
|
||||
}
|
||||
} else {
|
||||
qCritical() << "SingleApplication: Unable to create block.";
|
||||
abortSafely();
|
||||
}
|
||||
}
|
||||
|
||||
InstancesInfo* inst = static_cast<InstancesInfo*>( d->memory->data() );
|
||||
QElapsedTimer time;
|
||||
time.start();
|
||||
auto *inst = static_cast<InstancesInfo*>( d->memory->data() );
|
||||
QElapsedTimer time;
|
||||
time.start();
|
||||
|
||||
// Make sure the shared memory block is initialised and in consistent state
|
||||
while( true ) {
|
||||
d->memory->lock();
|
||||
// Make sure the shared memory block is initialised and in consistent state
|
||||
while( true ){
|
||||
// If the shared memory block's checksum is valid continue
|
||||
if( d->blockChecksum() == inst->checksum ) break;
|
||||
|
||||
if( d->blockChecksum() == inst->checksum ) break;
|
||||
// If more than 5s have elapsed, assume the primary instance crashed and
|
||||
// assume it's position
|
||||
if( time.elapsed() > 5000 ){
|
||||
qWarning() << "SingleApplication: Shared memory block has been in an inconsistent state from more than 5s. Assuming primary instance failure.";
|
||||
d->initializeMemoryBlock();
|
||||
}
|
||||
|
||||
if( time.elapsed() > 5000 ) {
|
||||
qWarning() << "SingleApplication: Shared memory block has been in an inconsistent state from more than 5s. Assuming primary instance failure.";
|
||||
d->initializeMemoryBlock();
|
||||
}
|
||||
// Otherwise wait for a random period and try again. The random sleep here
|
||||
// limits the probability of a collision between two racing apps and
|
||||
// allows the app to initialise faster
|
||||
if( ! d->memory->unlock() ){
|
||||
qDebug() << "SingleApplication: Unable to unlock memory for random wait.";
|
||||
qDebug() << d->memory->errorString();
|
||||
}
|
||||
SingleApplicationPrivate::randomSleep();
|
||||
if( ! d->memory->lock() ){
|
||||
qCritical() << "SingleApplication: Unable to lock memory after random wait.";
|
||||
abortSafely();
|
||||
}
|
||||
}
|
||||
|
||||
d->memory->unlock();
|
||||
if( inst->primary == false ){
|
||||
d->startPrimary();
|
||||
if( ! d->memory->unlock() ){
|
||||
qDebug() << "SingleApplication: Unable to unlock memory after primary start.";
|
||||
qDebug() << d->memory->errorString();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Random sleep here limits the probability of a collision between two racing apps
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) // ### Qt 6: remove
|
||||
qsrand( QDateTime::currentMSecsSinceEpoch() % std::numeric_limits<uint>::max() );
|
||||
QThread::sleep( 8 + static_cast <unsigned long>( static_cast <float>( qrand() ) / RAND_MAX * 10 ) );
|
||||
#else
|
||||
#if TODO_LIST
|
||||
#pragma message("@TODO remove code for QT 5.10 or later")
|
||||
#endif
|
||||
quint32 value = QRandomGenerator::global()->generate();
|
||||
QThread::sleep(8 + static_cast<unsigned long>(value / RAND_MAX * 10));
|
||||
#endif
|
||||
}
|
||||
// Check if another instance can be started
|
||||
if( allowSecondary ){
|
||||
d->startSecondary();
|
||||
if( d->options & Mode::SecondaryNotification ){
|
||||
d->connectToPrimary( timeout, SingleApplicationPrivate::SecondaryInstance );
|
||||
}
|
||||
if( ! d->memory->unlock() ){
|
||||
qDebug() << "SingleApplication: Unable to unlock memory after secondary start.";
|
||||
qDebug() << d->memory->errorString();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if( inst->primary == false) {
|
||||
d->startPrimary();
|
||||
d->memory->unlock();
|
||||
return;
|
||||
}
|
||||
if( ! d->memory->unlock() ){
|
||||
qDebug() << "SingleApplication: Unable to unlock memory at end of execution.";
|
||||
qDebug() << d->memory->errorString();
|
||||
}
|
||||
|
||||
// Check if another instance can be started
|
||||
if( allowSecondary ) {
|
||||
inst->secondary += 1;
|
||||
inst->checksum = d->blockChecksum();
|
||||
d->instanceNumber = inst->secondary;
|
||||
d->startSecondary();
|
||||
if( d->options & Mode::SecondaryNotification ) {
|
||||
d->connectToPrimary( timeout, SingleApplicationPrivate::SecondaryInstance );
|
||||
}
|
||||
d->memory->unlock();
|
||||
return;
|
||||
}
|
||||
d->connectToPrimary( timeout, SingleApplicationPrivate::NewInstance );
|
||||
|
||||
d->memory->unlock();
|
||||
delete d;
|
||||
|
||||
d->connectToPrimary( timeout, SingleApplicationPrivate::NewInstance );
|
||||
::exit( EXIT_SUCCESS );
|
||||
}
|
||||
|
||||
delete d;
|
||||
|
||||
::exit( EXIT_SUCCESS );
|
||||
SingleApplication::~SingleApplication()
|
||||
{
|
||||
Q_D( SingleApplication );
|
||||
delete d;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Destructor
|
||||
*/
|
||||
SingleApplication::~SingleApplication()
|
||||
* Checks if the current application instance is primary.
|
||||
* @return Returns true if the instance is primary, false otherwise.
|
||||
*/
|
||||
bool SingleApplication::isPrimary() const
|
||||
{
|
||||
Q_D(SingleApplication);
|
||||
delete d;
|
||||
Q_D( const SingleApplication );
|
||||
return d->server != nullptr;
|
||||
}
|
||||
|
||||
bool SingleApplication::isPrimary()
|
||||
/**
|
||||
* Checks if the current application instance is secondary.
|
||||
* @return Returns true if the instance is secondary, false otherwise.
|
||||
*/
|
||||
bool SingleApplication::isSecondary() const
|
||||
{
|
||||
Q_D(SingleApplication);
|
||||
return d->server != nullptr;
|
||||
Q_D( const SingleApplication );
|
||||
return d->server == nullptr;
|
||||
}
|
||||
|
||||
bool SingleApplication::isSecondary()
|
||||
/**
|
||||
* Allows you to identify an instance by returning unique consecutive instance
|
||||
* ids. It is reset when the first (primary) instance of your app starts and
|
||||
* only incremented afterwards.
|
||||
* @return Returns a unique instance id.
|
||||
*/
|
||||
quint32 SingleApplication::instanceId() const
|
||||
{
|
||||
Q_D(SingleApplication);
|
||||
return d->server == nullptr;
|
||||
Q_D( const SingleApplication );
|
||||
return d->instanceNumber;
|
||||
}
|
||||
|
||||
quint32 SingleApplication::instanceId()
|
||||
/**
|
||||
* Returns the OS PID (Process Identifier) of the process running the primary
|
||||
* instance. Especially useful when SingleApplication is coupled with OS.
|
||||
* specific APIs.
|
||||
* @return Returns the primary instance PID.
|
||||
*/
|
||||
qint64 SingleApplication::primaryPid() const
|
||||
{
|
||||
Q_D(SingleApplication);
|
||||
return d->instanceNumber;
|
||||
Q_D( const SingleApplication );
|
||||
return d->primaryPid();
|
||||
}
|
||||
|
||||
qint64 SingleApplication::primaryPid()
|
||||
/**
|
||||
* Returns the username the primary instance is running as.
|
||||
* @return Returns the username the primary instance is running as.
|
||||
*/
|
||||
QString SingleApplication::primaryUser() const
|
||||
{
|
||||
Q_D(SingleApplication);
|
||||
return d->primaryPid();
|
||||
Q_D( const SingleApplication );
|
||||
return d->primaryUser();
|
||||
}
|
||||
|
||||
bool SingleApplication::sendMessage( QByteArray message, int timeout )
|
||||
/**
|
||||
* Returns the username the current instance is running as.
|
||||
* @return Returns the username the current instance is running as.
|
||||
*/
|
||||
QString SingleApplication::currentUser() const
|
||||
{
|
||||
Q_D(SingleApplication);
|
||||
|
||||
// Nobody to connect to
|
||||
if( isPrimary() ) return false;
|
||||
|
||||
// Make sure the socket is connected
|
||||
d->connectToPrimary( timeout, SingleApplicationPrivate::Reconnect );
|
||||
|
||||
d->socket->write( message );
|
||||
bool dataWritten = d->socket->waitForBytesWritten( timeout );
|
||||
d->socket->flush();
|
||||
return dataWritten;
|
||||
return SingleApplicationPrivate::getUsername();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends message to the Primary Instance.
|
||||
* @param message The message to send.
|
||||
* @param timeout the maximum timeout in milliseconds for blocking functions.
|
||||
* @return true if the message was sent successfuly, false otherwise.
|
||||
*/
|
||||
bool SingleApplication::sendMessage( const QByteArray &message, int timeout )
|
||||
{
|
||||
Q_D( SingleApplication );
|
||||
|
||||
// Nobody to connect to
|
||||
if( isPrimary() ) return false;
|
||||
|
||||
// Make sure the socket is connected
|
||||
if( ! d->connectToPrimary( timeout, SingleApplicationPrivate::Reconnect ) )
|
||||
return false;
|
||||
|
||||
d->socket->write( message );
|
||||
bool dataWritten = d->socket->waitForBytesWritten( timeout );
|
||||
d->socket->flush();
|
||||
return dataWritten;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up the shared memory block and exits with a failure.
|
||||
* This function halts program execution.
|
||||
*/
|
||||
void SingleApplication::abortSafely()
|
||||
{
|
||||
Q_D( SingleApplication );
|
||||
|
||||
qCritical() << "SingleApplication: " << d->memory->error() << d->memory->errorString();
|
||||
delete d;
|
||||
::exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
QStringList SingleApplication::userData() const
|
||||
{
|
||||
Q_D( const SingleApplication );
|
||||
return d->appData();
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
|
||||
#include <QtCore/QtGlobal>
|
||||
#include <QtNetwork/QLocalSocket>
|
||||
#include <QElapsedTimer>
|
||||
|
||||
#ifndef QAPPLICATION_CLASS
|
||||
#define QAPPLICATION_CLASS QCoreApplication
|
||||
@@ -36,99 +35,118 @@
|
||||
class SingleApplicationPrivate;
|
||||
|
||||
/**
|
||||
@brief The SingleApplication class handles multiple instances of the same
|
||||
Application
|
||||
@see QCoreApplication
|
||||
*/
|
||||
* @brief The SingleApplication class handles multiple instances of the same
|
||||
* Application
|
||||
* @see QCoreApplication
|
||||
*/
|
||||
class SingleApplication : public QAPPLICATION_CLASS
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
typedef QAPPLICATION_CLASS app_t;
|
||||
|
||||
public:
|
||||
/**
|
||||
@brief Mode of operation of SingleApplication.
|
||||
Whether the block should be user-wide or system-wide and whether the
|
||||
primary instance should be notified when a secondary instance had been
|
||||
started.
|
||||
@note Operating system can restrict the shared memory blocks to the same
|
||||
user, in which case the User/System modes will have no effect and the
|
||||
block will be user wide.
|
||||
@enum
|
||||
*/
|
||||
enum Mode {
|
||||
User = 1 << 0,
|
||||
System = 1 << 1,
|
||||
SecondaryNotification = 1 << 2,
|
||||
ExcludeAppVersion = 1 << 3,
|
||||
ExcludeAppPath = 1 << 4
|
||||
};
|
||||
Q_DECLARE_FLAGS(Options, Mode)
|
||||
|
||||
/**
|
||||
@brief Intitializes a SingleApplication instance with argc command line
|
||||
arguments in argv
|
||||
@arg {int &} argc - Number of arguments in argv
|
||||
@arg {const char *[]} argv - Supplied command line arguments
|
||||
@arg {bool} allowSecondary - Whether to start the instance as secondary
|
||||
if there is already a primary instance.
|
||||
@arg {Mode} mode - Whether for the SingleApplication block to be applied
|
||||
User wide or System wide.
|
||||
@arg {int} timeout - Timeout to wait in milliseconds.
|
||||
@note argc and argv may be changed as Qt removes arguments that it
|
||||
recognizes
|
||||
@note Mode::SecondaryNotification only works if set on both the primary
|
||||
instance and the secondary instance.
|
||||
@note The timeout is just a hint for the maximum time of blocking
|
||||
operations. It does not guarantee that the SingleApplication
|
||||
initialisation will be completed in given time, though is a good hint.
|
||||
Usually 4*timeout would be the worst case (fail) scenario.
|
||||
@see See the corresponding QAPPLICATION_CLASS constructor for reference
|
||||
*/
|
||||
explicit SingleApplication( int &argc, char *argv[], bool allowSecondary = false, Options options = Mode::User, int timeout = 1000 );
|
||||
~SingleApplication();
|
||||
|
||||
/**
|
||||
@brief Returns if the instance is the primary instance
|
||||
@returns {bool}
|
||||
*/
|
||||
bool isPrimary();
|
||||
|
||||
/**
|
||||
@brief Returns if the instance is a secondary instance
|
||||
@returns {bool}
|
||||
*/
|
||||
bool isSecondary();
|
||||
|
||||
/**
|
||||
@brief Returns a unique identifier for the current instance
|
||||
@returns {qint32}
|
||||
*/
|
||||
quint32 instanceId();
|
||||
|
||||
/**
|
||||
@brief Returns the process ID (PID) of the primary instance
|
||||
@returns {qint64}
|
||||
*/
|
||||
qint64 primaryPid();
|
||||
|
||||
/**
|
||||
@brief Sends a message to the primary instance. Returns true on success.
|
||||
@param {int} timeout - Timeout for connecting
|
||||
@returns {bool}
|
||||
@note sendMessage() will return false if invoked from the primary
|
||||
instance.
|
||||
*/
|
||||
bool sendMessage( QByteArray message, int timeout = 100 );
|
||||
|
||||
Q_SIGNALS:
|
||||
void instanceStarted();
|
||||
void receivedMessage( quint32 instanceId, QByteArray message );
|
||||
|
||||
private:
|
||||
SingleApplicationPrivate *d_ptr;
|
||||
Q_DECLARE_PRIVATE(SingleApplication)
|
||||
Q_OBJECT
|
||||
|
||||
using app_t = QAPPLICATION_CLASS;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Mode of operation of SingleApplication.
|
||||
* Whether the block should be user-wide or system-wide and whether the
|
||||
* primary instance should be notified when a secondary instance had been
|
||||
* started.
|
||||
* @note Operating system can restrict the shared memory blocks to the same
|
||||
* user, in which case the User/System modes will have no effect and the
|
||||
* block will be user wide.
|
||||
* @enum
|
||||
*/
|
||||
enum Mode {
|
||||
User = 1 << 0,
|
||||
System = 1 << 1,
|
||||
SecondaryNotification = 1 << 2,
|
||||
ExcludeAppVersion = 1 << 3,
|
||||
ExcludeAppPath = 1 << 4
|
||||
};
|
||||
Q_DECLARE_FLAGS(Options, Mode)
|
||||
|
||||
/**
|
||||
* @brief Intitializes a SingleApplication instance with argc command line
|
||||
* arguments in argv
|
||||
* @arg {int &} argc - Number of arguments in argv
|
||||
* @arg {const char *[]} argv - Supplied command line arguments
|
||||
* @arg {bool} allowSecondary - Whether to start the instance as secondary
|
||||
* if there is already a primary instance.
|
||||
* @arg {Mode} mode - Whether for the SingleApplication block to be applied
|
||||
* User wide or System wide.
|
||||
* @arg {int} timeout - Timeout to wait in milliseconds.
|
||||
* @note argc and argv may be changed as Qt removes arguments that it
|
||||
* recognizes
|
||||
* @note Mode::SecondaryNotification only works if set on both the primary
|
||||
* instance and the secondary instance.
|
||||
* @note The timeout is just a hint for the maximum time of blocking
|
||||
* operations. It does not guarantee that the SingleApplication
|
||||
* initialisation will be completed in given time, though is a good hint.
|
||||
* Usually 4*timeout would be the worst case (fail) scenario.
|
||||
* @see See the corresponding QAPPLICATION_CLASS constructor for reference
|
||||
*/
|
||||
explicit SingleApplication( int &argc, char *argv[], bool allowSecondary = false, Options options = Mode::User, int timeout = 1000, const QString &userData = {} );
|
||||
~SingleApplication() override;
|
||||
|
||||
/**
|
||||
* @brief Returns if the instance is the primary instance
|
||||
* @returns {bool}
|
||||
*/
|
||||
bool isPrimary() const;
|
||||
|
||||
/**
|
||||
* @brief Returns if the instance is a secondary instance
|
||||
* @returns {bool}
|
||||
*/
|
||||
bool isSecondary() const;
|
||||
|
||||
/**
|
||||
* @brief Returns a unique identifier for the current instance
|
||||
* @returns {qint32}
|
||||
*/
|
||||
quint32 instanceId() const;
|
||||
|
||||
/**
|
||||
* @brief Returns the process ID (PID) of the primary instance
|
||||
* @returns {qint64}
|
||||
*/
|
||||
qint64 primaryPid() const;
|
||||
|
||||
/**
|
||||
* @brief Returns the username of the user running the primary instance
|
||||
* @returns {QString}
|
||||
*/
|
||||
QString primaryUser() const;
|
||||
|
||||
/**
|
||||
* @brief Returns the username of the current user
|
||||
* @returns {QString}
|
||||
*/
|
||||
QString currentUser() const;
|
||||
|
||||
/**
|
||||
* @brief Sends a message to the primary instance. Returns true on success.
|
||||
* @param {int} timeout - Timeout for connecting
|
||||
* @returns {bool}
|
||||
* @note sendMessage() will return false if invoked from the primary
|
||||
* instance.
|
||||
*/
|
||||
bool sendMessage( const QByteArray &message, int timeout = 100 );
|
||||
|
||||
/**
|
||||
* @brief Get the set user data.
|
||||
* @returns {QStringList}
|
||||
*/
|
||||
QStringList userData() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void instanceStarted();
|
||||
void receivedMessage( quint32 instanceId, QByteArray message );
|
||||
|
||||
private:
|
||||
SingleApplicationPrivate *d_ptr;
|
||||
Q_DECLARE_PRIVATE(SingleApplication)
|
||||
void abortSafely();
|
||||
};
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(SingleApplication::Options)
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
QT += core network
|
||||
CONFIG += c++17
|
||||
CONFIG += c++11
|
||||
|
||||
HEADERS += $$PWD/singleapplication.h \
|
||||
HEADERS += $$PWD/SingleApplication \
|
||||
$$PWD/singleapplication.h \
|
||||
$$PWD/singleapplication_p.h
|
||||
SOURCES += $$PWD/singleapplication.cpp \
|
||||
$$PWD/singleapplication_p.cpp
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) Itay Grudev 2015 - 2018
|
||||
// Copyright (c) Itay Grudev 2015 - 2020
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -33,412 +33,454 @@
|
||||
#include <cstddef>
|
||||
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QThread>
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QDataStream>
|
||||
#include <QtCore/QElapsedTimer>
|
||||
#include <QtCore/QCryptographicHash>
|
||||
#include <QtNetwork/QLocalServer>
|
||||
#include <QtNetwork/QLocalSocket>
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
|
||||
#include <QtCore/QRandomGenerator>
|
||||
#else
|
||||
#include <QtCore/QDateTime>
|
||||
#endif
|
||||
|
||||
#include "singleapplication.h"
|
||||
#include "singleapplication_p.h"
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include <windows.h>
|
||||
#include <lmcons.h>
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX 1
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <lmcons.h>
|
||||
#endif
|
||||
|
||||
SingleApplicationPrivate::SingleApplicationPrivate( SingleApplication *q_ptr )
|
||||
: q_ptr( q_ptr )
|
||||
: q_ptr( q_ptr )
|
||||
{
|
||||
server = nullptr;
|
||||
socket = nullptr;
|
||||
memory = nullptr;
|
||||
instanceNumber = -1;
|
||||
server = nullptr;
|
||||
socket = nullptr;
|
||||
memory = nullptr;
|
||||
instanceNumber = 0;
|
||||
}
|
||||
|
||||
SingleApplicationPrivate::~SingleApplicationPrivate()
|
||||
{
|
||||
if( socket != nullptr ) {
|
||||
socket->close();
|
||||
delete socket;
|
||||
}
|
||||
if( socket != nullptr ){
|
||||
socket->close();
|
||||
delete socket;
|
||||
}
|
||||
|
||||
memory->lock();
|
||||
InstancesInfo* inst = static_cast<InstancesInfo*>(memory->data());
|
||||
if( server != nullptr ) {
|
||||
server->close();
|
||||
delete server;
|
||||
inst->primary = false;
|
||||
inst->primaryPid = -1;
|
||||
inst->checksum = blockChecksum();
|
||||
}
|
||||
memory->unlock();
|
||||
if( memory != nullptr ){
|
||||
memory->lock();
|
||||
auto *inst = static_cast<InstancesInfo*>(memory->data());
|
||||
if( server != nullptr ){
|
||||
server->close();
|
||||
delete server;
|
||||
inst->primary = false;
|
||||
inst->primaryPid = -1;
|
||||
inst->primaryUser[0] = '\0';
|
||||
inst->checksum = blockChecksum();
|
||||
}
|
||||
memory->unlock();
|
||||
|
||||
delete memory;
|
||||
delete memory;
|
||||
}
|
||||
}
|
||||
|
||||
QString SingleApplicationPrivate::getUsername()
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
wchar_t username[UNLEN + 1];
|
||||
// Specifies size of the buffer on input
|
||||
DWORD usernameLength = UNLEN + 1;
|
||||
if( GetUserNameW( username, &usernameLength ) )
|
||||
return QString::fromWCharArray( username );
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
|
||||
return QString::fromLocal8Bit( qgetenv( "USERNAME" ) );
|
||||
#else
|
||||
return qEnvironmentVariable( "USERNAME" );
|
||||
#endif
|
||||
#endif
|
||||
#ifdef Q_OS_UNIX
|
||||
QString username;
|
||||
uid_t uid = geteuid();
|
||||
struct passwd *pw = getpwuid( uid );
|
||||
if( pw )
|
||||
username = QString::fromLocal8Bit( pw->pw_name );
|
||||
if ( username.isEmpty() ){
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
|
||||
username = QString::fromLocal8Bit( qgetenv( "USER" ) );
|
||||
#else
|
||||
username = qEnvironmentVariable( "USER" );
|
||||
#endif
|
||||
}
|
||||
return username;
|
||||
#endif
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::genBlockServerName()
|
||||
{
|
||||
QCryptographicHash appData( QCryptographicHash::Sha256 );
|
||||
appData.addData( "SingleApplication", 17 );
|
||||
appData.addData( SingleApplication::app_t::applicationName().toUtf8() );
|
||||
appData.addData( SingleApplication::app_t::organizationName().toUtf8() );
|
||||
appData.addData( SingleApplication::app_t::organizationDomain().toUtf8() );
|
||||
QCryptographicHash appData( QCryptographicHash::Sha256 );
|
||||
appData.addData( "SingleApplication", 17 );
|
||||
appData.addData( SingleApplication::app_t::applicationName().toUtf8() );
|
||||
appData.addData( SingleApplication::app_t::organizationName().toUtf8() );
|
||||
appData.addData( SingleApplication::app_t::organizationDomain().toUtf8() );
|
||||
|
||||
if( ! (options & SingleApplication::Mode::ExcludeAppVersion) ) {
|
||||
appData.addData( SingleApplication::app_t::applicationVersion().toUtf8() );
|
||||
}
|
||||
if ( ! appDataList.isEmpty() )
|
||||
appData.addData( appDataList.join( "" ).toUtf8() );
|
||||
|
||||
if( ! (options & SingleApplication::Mode::ExcludeAppPath) ) {
|
||||
if( ! (options & SingleApplication::Mode::ExcludeAppVersion) ){
|
||||
appData.addData( SingleApplication::app_t::applicationVersion().toUtf8() );
|
||||
}
|
||||
|
||||
if( ! (options & SingleApplication::Mode::ExcludeAppPath) ){
|
||||
#ifdef Q_OS_WIN
|
||||
appData.addData( SingleApplication::app_t::applicationFilePath().toLower().toUtf8() );
|
||||
appData.addData( SingleApplication::app_t::applicationFilePath().toLower().toUtf8() );
|
||||
#else
|
||||
appData.addData( SingleApplication::app_t::applicationFilePath().toUtf8() );
|
||||
appData.addData( SingleApplication::app_t::applicationFilePath().toUtf8() );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// User level block requires a user specific data in the hash
|
||||
if( options & SingleApplication::Mode::User ) {
|
||||
#ifdef Q_OS_WIN
|
||||
wchar_t username [ UNLEN + 1 ];
|
||||
// Specifies size of the buffer on input
|
||||
DWORD usernameLength = UNLEN + 1;
|
||||
if( GetUserNameW( username, &usernameLength ) ) {
|
||||
appData.addData( QString::fromWCharArray(username).toUtf8() );
|
||||
} else {
|
||||
appData.addData( qgetenv("USERNAME") );
|
||||
}
|
||||
#endif
|
||||
#ifdef Q_OS_UNIX
|
||||
QByteArray username;
|
||||
uid_t uid = geteuid();
|
||||
struct passwd *pw = getpwuid(uid);
|
||||
if( pw ) {
|
||||
username = pw->pw_name;
|
||||
}
|
||||
if( username.isEmpty() ) {
|
||||
username = qgetenv("USER");
|
||||
}
|
||||
appData.addData(username);
|
||||
#endif
|
||||
}
|
||||
// User level block requires a user specific data in the hash
|
||||
if( options & SingleApplication::Mode::User ){
|
||||
appData.addData( getUsername().toUtf8() );
|
||||
}
|
||||
|
||||
// Replace the backslash in RFC 2045 Base64 [a-zA-Z0-9+/=] to comply with
|
||||
// server naming requirements.
|
||||
blockServerName = appData.result().toBase64().replace("/", "_");
|
||||
// Replace the backslash in RFC 2045 Base64 [a-zA-Z0-9+/=] to comply with
|
||||
// server naming requirements.
|
||||
blockServerName = appData.result().toBase64().replace("/", "_");
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::initializeMemoryBlock()
|
||||
void SingleApplicationPrivate::initializeMemoryBlock() const
|
||||
{
|
||||
InstancesInfo* inst = static_cast<InstancesInfo*>( memory->data() );
|
||||
inst->primary = false;
|
||||
inst->secondary = 0;
|
||||
inst->primaryPid = -1;
|
||||
inst->checksum = blockChecksum();
|
||||
auto *inst = static_cast<InstancesInfo*>( memory->data() );
|
||||
inst->primary = false;
|
||||
inst->secondary = 0;
|
||||
inst->primaryPid = -1;
|
||||
inst->primaryUser[0] = '\0';
|
||||
inst->checksum = blockChecksum();
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::startPrimary()
|
||||
{
|
||||
Q_Q(SingleApplication);
|
||||
// Reset the number of connections
|
||||
auto *inst = static_cast <InstancesInfo*>( memory->data() );
|
||||
|
||||
// Successful creation means that no main process exists
|
||||
// So we start a QLocalServer to listen for connections
|
||||
QLocalServer::removeServer( blockServerName );
|
||||
server = new QLocalServer();
|
||||
inst->primary = true;
|
||||
inst->primaryPid = QCoreApplication::applicationPid();
|
||||
qstrncpy( inst->primaryUser, getUsername().toUtf8().data(), sizeof(inst->primaryUser) );
|
||||
inst->checksum = blockChecksum();
|
||||
instanceNumber = 0;
|
||||
// Successful creation means that no main process exists
|
||||
// So we start a QLocalServer to listen for connections
|
||||
QLocalServer::removeServer( blockServerName );
|
||||
server = new QLocalServer();
|
||||
|
||||
// Restrict access to the socket according to the
|
||||
// SingleApplication::Mode::User flag on User level or no restrictions
|
||||
if( options & SingleApplication::Mode::User ) {
|
||||
server->setSocketOptions( QLocalServer::UserAccessOption );
|
||||
} else {
|
||||
server->setSocketOptions( QLocalServer::WorldAccessOption );
|
||||
}
|
||||
// Restrict access to the socket according to the
|
||||
// SingleApplication::Mode::User flag on User level or no restrictions
|
||||
if( options & SingleApplication::Mode::User ){
|
||||
server->setSocketOptions( QLocalServer::UserAccessOption );
|
||||
} else {
|
||||
server->setSocketOptions( QLocalServer::WorldAccessOption );
|
||||
}
|
||||
|
||||
server->listen( blockServerName );
|
||||
QObject::connect(
|
||||
server,
|
||||
&QLocalServer::newConnection,
|
||||
this,
|
||||
&SingleApplicationPrivate::slotConnectionEstablished
|
||||
);
|
||||
|
||||
// Reset the number of connections
|
||||
InstancesInfo* inst = static_cast <InstancesInfo*>( memory->data() );
|
||||
|
||||
inst->primary = true;
|
||||
inst->primaryPid = q->applicationPid();
|
||||
inst->checksum = blockChecksum();
|
||||
|
||||
instanceNumber = 0;
|
||||
server->listen( blockServerName );
|
||||
QObject::connect(
|
||||
server,
|
||||
&QLocalServer::newConnection,
|
||||
this,
|
||||
&SingleApplicationPrivate::slotConnectionEstablished
|
||||
);
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::startSecondary()
|
||||
{
|
||||
auto *inst = static_cast <InstancesInfo*>( memory->data() );
|
||||
|
||||
inst->secondary += 1;
|
||||
inst->checksum = blockChecksum();
|
||||
instanceNumber = inst->secondary;
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::connectToPrimary( int msecs, ConnectionType connectionType )
|
||||
bool SingleApplicationPrivate::connectToPrimary( int msecs, ConnectionType connectionType )
|
||||
{
|
||||
// Connect to the Local Server of the Primary Instance if not already
|
||||
// connected.
|
||||
if( socket == nullptr ) {
|
||||
socket = new QLocalSocket();
|
||||
}
|
||||
QElapsedTimer time;
|
||||
time.start();
|
||||
|
||||
// If already connected - we are done;
|
||||
if( socket->state() == QLocalSocket::ConnectedState )
|
||||
return;
|
||||
// Connect to the Local Server of the Primary Instance if not already
|
||||
// connected.
|
||||
if( socket == nullptr ){
|
||||
socket = new QLocalSocket();
|
||||
}
|
||||
|
||||
// If not connect
|
||||
if( socket->state() == QLocalSocket::UnconnectedState ||
|
||||
socket->state() == QLocalSocket::ClosingState ) {
|
||||
socket->connectToServer( blockServerName );
|
||||
}
|
||||
if( socket->state() == QLocalSocket::ConnectedState ) return true;
|
||||
|
||||
// Wait for being connected
|
||||
if( socket->state() == QLocalSocket::ConnectingState ) {
|
||||
socket->waitForConnected( msecs );
|
||||
}
|
||||
if( socket->state() != QLocalSocket::ConnectedState ){
|
||||
|
||||
// Initialisation message according to the SingleApplication protocol
|
||||
if( socket->state() == QLocalSocket::ConnectedState ) {
|
||||
// Notify the parent that a new instance had been started;
|
||||
QByteArray initMsg;
|
||||
QDataStream writeStream(&initMsg, QIODevice::WriteOnly);
|
||||
while( true ){
|
||||
randomSleep();
|
||||
|
||||
if( socket->state() != QLocalSocket::ConnectingState )
|
||||
socket->connectToServer( blockServerName );
|
||||
|
||||
if( socket->state() == QLocalSocket::ConnectingState ){
|
||||
socket->waitForConnected( static_cast<int>(msecs - time.elapsed()) );
|
||||
}
|
||||
|
||||
// If connected break out of the loop
|
||||
if( socket->state() == QLocalSocket::ConnectedState ) break;
|
||||
|
||||
// If elapsed time since start is longer than the method timeout return
|
||||
if( time.elapsed() >= msecs ) return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialisation message according to the SingleApplication protocol
|
||||
QByteArray initMsg;
|
||||
QDataStream writeStream(&initMsg, QIODevice::WriteOnly);
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
|
||||
writeStream.setVersion(QDataStream::Qt_5_6);
|
||||
writeStream.setVersion(QDataStream::Qt_5_6);
|
||||
#endif
|
||||
|
||||
writeStream << blockServerName.toLatin1();
|
||||
writeStream << static_cast<quint8>(connectionType);
|
||||
writeStream << instanceNumber;
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) // ### Qt 6: remove
|
||||
quint16 checksum =
|
||||
qChecksum(
|
||||
initMsg.constData(),
|
||||
static_cast<quint32>(initMsg.length()));
|
||||
writeStream << blockServerName.toLatin1();
|
||||
writeStream << static_cast<quint8>(connectionType);
|
||||
writeStream << instanceNumber;
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
quint16 checksum = qChecksum(QByteArray(initMsg, static_cast<quint32>(initMsg.length())));
|
||||
#else
|
||||
#if TODO_LIST
|
||||
#pragma message("@TODO remove code for QT 6 or later")
|
||||
quint16 checksum = qChecksum(initMsg.constData(), static_cast<quint32>(initMsg.length()));
|
||||
#endif
|
||||
quint16 checksum =
|
||||
qChecksum(
|
||||
QByteArrayView(
|
||||
initMsg.constData(),
|
||||
static_cast<quint32>(initMsg.length())));
|
||||
#endif
|
||||
writeStream << checksum;
|
||||
writeStream << checksum;
|
||||
|
||||
// The header indicates the message length that follows
|
||||
QByteArray header;
|
||||
QDataStream headerStream(&header, QIODevice::WriteOnly);
|
||||
// The header indicates the message length that follows
|
||||
QByteArray header;
|
||||
QDataStream headerStream(&header, QIODevice::WriteOnly);
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
|
||||
headerStream.setVersion(QDataStream::Qt_5_6);
|
||||
headerStream.setVersion(QDataStream::Qt_5_6);
|
||||
#endif
|
||||
headerStream << static_cast <quint64>( initMsg.length() );
|
||||
headerStream << static_cast <quint64>( initMsg.length() );
|
||||
|
||||
socket->write( header );
|
||||
socket->write( initMsg );
|
||||
socket->flush();
|
||||
socket->waitForBytesWritten( msecs );
|
||||
}
|
||||
socket->write( header );
|
||||
socket->write( initMsg );
|
||||
bool result = socket->waitForBytesWritten( static_cast<int>(msecs - time.elapsed()) );
|
||||
socket->flush();
|
||||
return result;
|
||||
}
|
||||
|
||||
quint16 SingleApplicationPrivate::blockChecksum()
|
||||
quint16 SingleApplicationPrivate::blockChecksum() const
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) // ### Qt 6: remove
|
||||
return qChecksum(
|
||||
static_cast <const char *>( memory->data() ),
|
||||
offsetof( InstancesInfo, checksum )
|
||||
);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
quint16 checksum = qChecksum(QByteArray(static_cast<const char*>(memory->constData()), offsetof(InstancesInfo, checksum)));
|
||||
#else
|
||||
#if TODO_LIST
|
||||
#pragma message("@TODO remove code for QT 6 or later")
|
||||
#endif
|
||||
return qChecksum(
|
||||
QByteArrayView(
|
||||
static_cast <const char *>( memory->data() ),
|
||||
offsetof( InstancesInfo, checksum )));
|
||||
|
||||
quint16 checksum = qChecksum(static_cast<const char*>(memory->constData()), offsetof(InstancesInfo, checksum));
|
||||
#endif
|
||||
return checksum;
|
||||
}
|
||||
|
||||
qint64 SingleApplicationPrivate::primaryPid()
|
||||
qint64 SingleApplicationPrivate::primaryPid() const
|
||||
{
|
||||
qint64 pid;
|
||||
qint64 pid;
|
||||
|
||||
memory->lock();
|
||||
InstancesInfo* inst = static_cast<InstancesInfo*>( memory->data() );
|
||||
pid = inst->primaryPid;
|
||||
memory->unlock();
|
||||
memory->lock();
|
||||
auto *inst = static_cast<InstancesInfo*>( memory->data() );
|
||||
pid = inst->primaryPid;
|
||||
memory->unlock();
|
||||
|
||||
return pid;
|
||||
return pid;
|
||||
}
|
||||
|
||||
QString SingleApplicationPrivate::primaryUser() const
|
||||
{
|
||||
QByteArray username;
|
||||
|
||||
memory->lock();
|
||||
auto *inst = static_cast<InstancesInfo*>( memory->data() );
|
||||
username = inst->primaryUser;
|
||||
memory->unlock();
|
||||
|
||||
return QString::fromUtf8( username );
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Executed when a connection has been made to the LocalServer
|
||||
*/
|
||||
* @brief Executed when a connection has been made to the LocalServer
|
||||
*/
|
||||
void SingleApplicationPrivate::slotConnectionEstablished()
|
||||
{
|
||||
QLocalSocket *nextConnSocket = server->nextPendingConnection();
|
||||
connectionMap.insert(nextConnSocket, ConnectionInfo());
|
||||
QLocalSocket *nextConnSocket = server->nextPendingConnection();
|
||||
connectionMap.insert(nextConnSocket, ConnectionInfo());
|
||||
|
||||
QObject::connect(nextConnSocket, &QLocalSocket::aboutToClose,
|
||||
[nextConnSocket, this]() {
|
||||
auto &info = connectionMap[nextConnSocket];
|
||||
Q_EMIT this->slotClientConnectionClosed( nextConnSocket, info.instanceId );
|
||||
}
|
||||
);
|
||||
QObject::connect(nextConnSocket, &QLocalSocket::aboutToClose,
|
||||
[nextConnSocket, this](){
|
||||
auto &info = connectionMap[nextConnSocket];
|
||||
Q_EMIT this->slotClientConnectionClosed( nextConnSocket, info.instanceId );
|
||||
}
|
||||
);
|
||||
|
||||
QObject::connect(nextConnSocket, &QLocalSocket::disconnected,
|
||||
[nextConnSocket, this](){
|
||||
connectionMap.remove(nextConnSocket);
|
||||
nextConnSocket->deleteLater();
|
||||
}
|
||||
);
|
||||
QObject::connect(nextConnSocket, &QLocalSocket::disconnected, nextConnSocket, &QLocalSocket::deleteLater);
|
||||
|
||||
QObject::connect(nextConnSocket, &QLocalSocket::readyRead,
|
||||
[nextConnSocket, this]() {
|
||||
auto &info = connectionMap[nextConnSocket];
|
||||
switch(info.stage) {
|
||||
case StageHeader:
|
||||
readInitMessageHeader(nextConnSocket);
|
||||
break;
|
||||
case StageBody:
|
||||
readInitMessageBody(nextConnSocket);
|
||||
break;
|
||||
case StageConnected:
|
||||
Q_EMIT this->slotDataAvailable( nextConnSocket, info.instanceId );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
}
|
||||
);
|
||||
QObject::connect(nextConnSocket, &QLocalSocket::destroyed,
|
||||
[nextConnSocket, this](){
|
||||
connectionMap.remove(nextConnSocket);
|
||||
}
|
||||
);
|
||||
|
||||
QObject::connect(nextConnSocket, &QLocalSocket::readyRead,
|
||||
[nextConnSocket, this](){
|
||||
auto &info = connectionMap[nextConnSocket];
|
||||
switch(info.stage){
|
||||
case StageHeader:
|
||||
readInitMessageHeader(nextConnSocket);
|
||||
break;
|
||||
case StageBody:
|
||||
readInitMessageBody(nextConnSocket);
|
||||
break;
|
||||
case StageConnected:
|
||||
Q_EMIT this->slotDataAvailable( nextConnSocket, info.instanceId );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::readInitMessageHeader( QLocalSocket *sock )
|
||||
{
|
||||
if (!connectionMap.contains( sock )) {
|
||||
return;
|
||||
}
|
||||
if (!connectionMap.contains( sock )){
|
||||
return;
|
||||
}
|
||||
|
||||
if( sock->bytesAvailable() < ( qint64 )sizeof( quint64 ) ) {
|
||||
return;
|
||||
}
|
||||
if( sock->bytesAvailable() < ( qint64 )sizeof( quint64 ) ){
|
||||
return;
|
||||
}
|
||||
|
||||
QDataStream headerStream( sock );
|
||||
QDataStream headerStream( sock );
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
|
||||
headerStream.setVersion( QDataStream::Qt_5_6 );
|
||||
headerStream.setVersion( QDataStream::Qt_5_6 );
|
||||
#endif
|
||||
|
||||
// Read the header to know the message length
|
||||
quint64 msgLen = 0;
|
||||
headerStream >> msgLen;
|
||||
ConnectionInfo &info = connectionMap[sock];
|
||||
info.stage = StageBody;
|
||||
info.msgLen = msgLen;
|
||||
// Read the header to know the message length
|
||||
quint64 msgLen = 0;
|
||||
headerStream >> msgLen;
|
||||
ConnectionInfo &info = connectionMap[sock];
|
||||
info.stage = StageBody;
|
||||
info.msgLen = msgLen;
|
||||
|
||||
if ( sock->bytesAvailable() >= (qint64) msgLen ) {
|
||||
readInitMessageBody( sock );
|
||||
}
|
||||
if ( sock->bytesAvailable() >= (qint64) msgLen ){
|
||||
readInitMessageBody( sock );
|
||||
}
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::readInitMessageBody( QLocalSocket *sock )
|
||||
{
|
||||
Q_Q(SingleApplication);
|
||||
Q_Q(SingleApplication);
|
||||
|
||||
if (!connectionMap.contains( sock )) {
|
||||
return;
|
||||
}
|
||||
if (!connectionMap.contains( sock )){
|
||||
return;
|
||||
}
|
||||
|
||||
ConnectionInfo &info = connectionMap[sock];
|
||||
if( sock->bytesAvailable() < ( qint64 )info.msgLen ) {
|
||||
return;
|
||||
}
|
||||
ConnectionInfo &info = connectionMap[sock];
|
||||
if( sock->bytesAvailable() < ( qint64 )info.msgLen ){
|
||||
return;
|
||||
}
|
||||
|
||||
// Read the message body
|
||||
QByteArray msgBytes = sock->read(info.msgLen);
|
||||
QDataStream readStream(msgBytes);
|
||||
// Read the message body
|
||||
QByteArray msgBytes = sock->read(info.msgLen);
|
||||
QDataStream readStream(msgBytes);
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
|
||||
readStream.setVersion( QDataStream::Qt_5_6 );
|
||||
readStream.setVersion( QDataStream::Qt_5_6 );
|
||||
#endif
|
||||
|
||||
// server name
|
||||
QByteArray latin1Name;
|
||||
readStream >> latin1Name;
|
||||
// server name
|
||||
QByteArray latin1Name;
|
||||
readStream >> latin1Name;
|
||||
|
||||
// connection type
|
||||
ConnectionType connectionType = InvalidConnection;
|
||||
quint8 connTypeVal = InvalidConnection;
|
||||
readStream >> connTypeVal;
|
||||
connectionType = static_cast <ConnectionType>( connTypeVal );
|
||||
// connection type
|
||||
ConnectionType connectionType = InvalidConnection;
|
||||
quint8 connTypeVal = InvalidConnection;
|
||||
readStream >> connTypeVal;
|
||||
connectionType = static_cast <ConnectionType>( connTypeVal );
|
||||
|
||||
// instance id
|
||||
quint32 instanceId = 0;
|
||||
readStream >> instanceId;
|
||||
// instance id
|
||||
quint32 instanceId = 0;
|
||||
readStream >> instanceId;
|
||||
|
||||
// checksum
|
||||
quint16 msgChecksum = 0;
|
||||
readStream >> msgChecksum;
|
||||
// checksum
|
||||
quint16 msgChecksum = 0;
|
||||
readStream >> msgChecksum;
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) // ### Qt 6: remove
|
||||
const quint16 actualChecksum =
|
||||
qChecksum(
|
||||
msgBytes.constData(),
|
||||
static_cast<quint32>( msgBytes.length() - sizeof( quint16 ) ) );
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
const quint16 actualChecksum = qChecksum(QByteArray(msgBytes, static_cast<quint32>(msgBytes.length() - sizeof(quint16))));
|
||||
#else
|
||||
#if TODO_LIST
|
||||
#pragma message("@TODO remove code for QT 6 or later")
|
||||
const quint16 actualChecksum = qChecksum(msgBytes.constData(), static_cast<quint32>(msgBytes.length() - sizeof(quint16)));
|
||||
#endif
|
||||
const quint16 actualChecksum =
|
||||
qChecksum(
|
||||
QByteArrayView(
|
||||
msgBytes.constData(),
|
||||
static_cast<quint32>(msgBytes.length() - sizeof(quint16))));
|
||||
#endif
|
||||
bool isValid = readStream.status() == QDataStream::Ok &&
|
||||
QLatin1String(latin1Name) == blockServerName &&
|
||||
msgChecksum == actualChecksum;
|
||||
|
||||
if( !isValid ) {
|
||||
sock->close();
|
||||
return;
|
||||
}
|
||||
bool isValid = readStream.status() == QDataStream::Ok &&
|
||||
QLatin1String(latin1Name) == blockServerName &&
|
||||
msgChecksum == actualChecksum;
|
||||
|
||||
info.instanceId = instanceId;
|
||||
info.stage = StageConnected;
|
||||
if( !isValid ){
|
||||
sock->close();
|
||||
return;
|
||||
}
|
||||
|
||||
if( connectionType == NewInstance ||
|
||||
( connectionType == SecondaryInstance &&
|
||||
options & SingleApplication::Mode::SecondaryNotification ) )
|
||||
{
|
||||
Q_EMIT q->instanceStarted();
|
||||
}
|
||||
info.instanceId = instanceId;
|
||||
info.stage = StageConnected;
|
||||
|
||||
if (sock->bytesAvailable() > 0) {
|
||||
Q_EMIT this->slotDataAvailable( sock, instanceId );
|
||||
}
|
||||
if( connectionType == NewInstance ||
|
||||
( connectionType == SecondaryInstance &&
|
||||
options & SingleApplication::Mode::SecondaryNotification ) )
|
||||
{
|
||||
Q_EMIT q->instanceStarted();
|
||||
}
|
||||
|
||||
if (sock->bytesAvailable() > 0){
|
||||
Q_EMIT this->slotDataAvailable( sock, instanceId );
|
||||
}
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::slotDataAvailable( QLocalSocket *dataSocket, quint32 instanceId )
|
||||
{
|
||||
Q_Q(SingleApplication);
|
||||
Q_EMIT q->receivedMessage( instanceId, dataSocket->readAll() );
|
||||
Q_Q(SingleApplication);
|
||||
Q_EMIT q->receivedMessage( instanceId, dataSocket->readAll() );
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::slotClientConnectionClosed( QLocalSocket *closedSocket, quint32 instanceId )
|
||||
{
|
||||
if( closedSocket->bytesAvailable() > 0 )
|
||||
Q_EMIT slotDataAvailable( closedSocket, instanceId );
|
||||
if( closedSocket->bytesAvailable() > 0 )
|
||||
Q_EMIT slotDataAvailable( closedSocket, instanceId );
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::randomSleep()
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK( 5, 10, 0 )
|
||||
QThread::msleep( QRandomGenerator::global()->bounded( 8u, 18u ));
|
||||
#else
|
||||
qsrand( QDateTime::currentMSecsSinceEpoch() % std::numeric_limits<uint>::max() );
|
||||
QThread::msleep( 8 + static_cast <unsigned long>( static_cast <float>( qrand() ) / RAND_MAX * 10 ));
|
||||
#endif
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::addAppData(const QString &data)
|
||||
{
|
||||
appDataList.push_back(data);
|
||||
}
|
||||
|
||||
QStringList SingleApplicationPrivate::appData() const
|
||||
{
|
||||
return appDataList;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) Itay Grudev 2015 - 2016
|
||||
// Copyright (c) Itay Grudev 2015 - 2020
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -38,62 +38,67 @@
|
||||
#include "singleapplication.h"
|
||||
|
||||
struct InstancesInfo {
|
||||
bool primary;
|
||||
quint32 secondary;
|
||||
qint64 primaryPid;
|
||||
quint16 checksum;
|
||||
bool primary;
|
||||
quint32 secondary;
|
||||
qint64 primaryPid;
|
||||
char primaryUser[128];
|
||||
quint16 checksum; // Must be the last field
|
||||
};
|
||||
|
||||
struct ConnectionInfo {
|
||||
explicit ConnectionInfo() :
|
||||
msgLen(0), instanceId(0), stage(0) {}
|
||||
qint64 msgLen;
|
||||
quint32 instanceId;
|
||||
quint8 stage;
|
||||
qint64 msgLen = 0;
|
||||
quint32 instanceId = 0;
|
||||
quint8 stage = 0;
|
||||
};
|
||||
|
||||
class SingleApplicationPrivate : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum ConnectionType : quint8 {
|
||||
InvalidConnection = 0,
|
||||
NewInstance = 1,
|
||||
SecondaryInstance = 2,
|
||||
Reconnect = 3
|
||||
};
|
||||
enum ConnectionStage : quint8 {
|
||||
StageHeader = 0,
|
||||
StageBody = 1,
|
||||
StageConnected = 2,
|
||||
};
|
||||
Q_DECLARE_PUBLIC(SingleApplication)
|
||||
|
||||
SingleApplicationPrivate( SingleApplication *q_ptr );
|
||||
~SingleApplicationPrivate();
|
||||
|
||||
void genBlockServerName();
|
||||
void initializeMemoryBlock();
|
||||
void startPrimary();
|
||||
void startSecondary();
|
||||
void connectToPrimary(int msecs, ConnectionType connectionType );
|
||||
quint16 blockChecksum();
|
||||
qint64 primaryPid();
|
||||
void readInitMessageHeader(QLocalSocket *socket);
|
||||
void readInitMessageBody(QLocalSocket *socket);
|
||||
|
||||
SingleApplication *q_ptr;
|
||||
QSharedMemory *memory;
|
||||
QLocalSocket *socket;
|
||||
QLocalServer *server;
|
||||
quint32 instanceNumber;
|
||||
QString blockServerName;
|
||||
SingleApplication::Options options;
|
||||
QMap<QLocalSocket*, ConnectionInfo> connectionMap;
|
||||
|
||||
public Q_SLOTS:
|
||||
void slotConnectionEstablished();
|
||||
void slotDataAvailable( QLocalSocket*, quint32 );
|
||||
void slotClientConnectionClosed( QLocalSocket*, quint32 );
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum ConnectionType : quint8 {
|
||||
InvalidConnection = 0,
|
||||
NewInstance = 1,
|
||||
SecondaryInstance = 2,
|
||||
Reconnect = 3
|
||||
};
|
||||
enum ConnectionStage : quint8 {
|
||||
StageHeader = 0,
|
||||
StageBody = 1,
|
||||
StageConnected = 2,
|
||||
};
|
||||
Q_DECLARE_PUBLIC(SingleApplication)
|
||||
|
||||
SingleApplicationPrivate( SingleApplication *q_ptr );
|
||||
~SingleApplicationPrivate() override;
|
||||
|
||||
static QString getUsername();
|
||||
void genBlockServerName();
|
||||
void initializeMemoryBlock() const;
|
||||
void startPrimary();
|
||||
void startSecondary();
|
||||
bool connectToPrimary( int msecs, ConnectionType connectionType );
|
||||
quint16 blockChecksum() const;
|
||||
qint64 primaryPid() const;
|
||||
QString primaryUser() const;
|
||||
void readInitMessageHeader(QLocalSocket *socket);
|
||||
void readInitMessageBody(QLocalSocket *socket);
|
||||
static void randomSleep();
|
||||
void addAppData(const QString &data);
|
||||
QStringList appData() const;
|
||||
|
||||
SingleApplication *q_ptr;
|
||||
QSharedMemory *memory;
|
||||
QLocalSocket *socket;
|
||||
QLocalServer *server;
|
||||
quint32 instanceNumber;
|
||||
QString blockServerName;
|
||||
SingleApplication::Options options;
|
||||
QMap<QLocalSocket*, ConnectionInfo> connectionMap;
|
||||
QStringList appDataList;
|
||||
|
||||
public Q_SLOTS:
|
||||
void slotConnectionEstablished();
|
||||
void slotDataAvailable( QLocalSocket*, quint32 );
|
||||
void slotClientConnectionClosed( QLocalSocket*, quint32 );
|
||||
};
|
||||
|
||||
#endif // SINGLEAPPLICATION_P_H
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "org.qelectrotech.QElectroTech",
|
||||
"runtime": "org.kde.Platform",
|
||||
"runtime-version": "5.14",
|
||||
"runtime-version": "5.15",
|
||||
"sdk": "org.kde.Sdk",
|
||||
"command": "qelectrotech",
|
||||
"rename-desktop-file": "qelectrotech.desktop",
|
||||
@@ -10,17 +10,61 @@
|
||||
"copy-icon": true,
|
||||
"finish-args": [
|
||||
"--socket=wayland",
|
||||
"--socket=x11",
|
||||
"--socket=fallback-x11",
|
||||
"--device=dri",
|
||||
"--share=ipc",
|
||||
"--filesystem=host"
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"name": "tkinter",
|
||||
"buildsystem": "simple",
|
||||
"build-commands": [
|
||||
"pip3 install --prefix=${FLATPAK_DEST} ."
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/iwalton3/tkinter-standalone",
|
||||
"commit": "2301112d142ebaf7532b25600c77d1a2edc9ef04"
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"name": "tcl",
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://sourceforge.net/projects/tcl/files/Tcl/8.6.11/tcl8.6.11-src.tar.gz",
|
||||
"sha256": "8c0486668586672c5693d7d95817cb05a18c5ecca2f40e2836b9578064088258"
|
||||
}
|
||||
],
|
||||
"subdir": "unix",
|
||||
"post-install": [
|
||||
"chmod +w ${FLATPAK_DEST}/lib/libtcl8.6.so"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "tk",
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://sourceforge.net/projects/tcl/files/Tcl/8.6.11/tk8.6.11-src.tar.gz",
|
||||
"sha256": "5228a8187a7f70fa0791ef0f975270f068ba9557f57456f51eb02d9d4ea31282"
|
||||
}
|
||||
],
|
||||
"subdir": "unix",
|
||||
"post-install": [
|
||||
"chmod +w ${FLATPAK_DEST}/lib/libtk8.6.so"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "qelectrotech",
|
||||
"buildsystem": "qmake",
|
||||
"post-install": [
|
||||
"mv /app/share/mime/packages/qelectrotech.xml /app/share/mime/packages/org.qelectrotech.QElectroTech.xml"
|
||||
"mv ${FLATPAK_DEST}/share/mime/packages/qelectrotech.xml ${FLATPAK_DEST}/share/mime/packages/org.qelectrotech.QElectroTech.xml"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
@@ -32,6 +76,50 @@
|
||||
"path": "patches/0001-build-Fix-the-installation-paths.patch"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "python3.6.0",
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://www.python.org/ftp/python/3.6.0/Python-3.6.0.tar.xz",
|
||||
"sha256": "b0c5f904f685e32d9232f7bdcbece9819a892929063b6e385414ad2dd6a23622"
|
||||
}
|
||||
],
|
||||
"config-opts": ["--enable-shared"],
|
||||
"post-install": [
|
||||
"chmod +w ${FLATPAK_DEST}/lib/libpython3.6m.so.1.0",
|
||||
"chmod +w ${FLATPAK_DEST}/lib/libpython3.so"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "python3-qet-tb-generator",
|
||||
"buildsystem": "simple",
|
||||
"build-commands": [
|
||||
"pip3 install --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} qet-tb-generator"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/9e/c3/aaad3309a5f2ca08e2fa0ab01123bb6fafb15a92854bff88042039192a67/qet_tb_generator-1.1.7.tar.gz",
|
||||
"sha256": "f626ab7bf4d9091fc85f63d33136585e611272b347499b448ece4e33cc04eeed"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DXFtoQET-2020-1",
|
||||
"buildsystem": "qmake",
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/qelectrotech/DXFtoQET-2020.git",
|
||||
"commit": "01fbb2afe0fe66782cb1d1f901c73616c7d5299d"
|
||||
}
|
||||
],
|
||||
"post-install": [
|
||||
"mkdir -p ${FLATPAK_DEST}/bin",
|
||||
"cp DXFtoQET ${FLATPAK_DEST}/bin/"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -39,10 +39,12 @@ if(${QET_LANG_PATH} STRGREATER "")
|
||||
message("QET_LANG_PATH " ${INSTALL_PREFIX}${QET_LANG_PATH})
|
||||
add_definitions(-DQET_LANG_PATH=${INSTALL_PREFIX}${QET_LANG_PATH})
|
||||
endif()
|
||||
if (NOT MINGW)
|
||||
if(${QET_EXAMPLES_PATH} STRGREATER "")
|
||||
message("QET_EXAMPLES_PATH " ${INSTALL_PREFIX}${QET_EXAMPLES_PATH})
|
||||
add_definitions(-DQET_EXAMPLES_PATH=${INSTALL_PREFIX}${QET_EXAMPLES_PATH})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
message("QET_LICENSE_PATH " ${QET_LICENSE_PATH})
|
||||
message("QET_MIME_XML_PATH " ${QET_MIME_XML_PATH})
|
||||
|
||||
@@ -19,9 +19,9 @@ message(" - fetch_kdeaddons")
|
||||
if(DEFINED BUILD_WITH_KF5)
|
||||
Include(FetchContent)
|
||||
|
||||
set(BUILD_KF5_YES "YES")
|
||||
option(BUILD_KF5 "Build KF5 libraries, use system ones otherwise" YES)
|
||||
|
||||
if(DEFINED BUILD_KF5_YES)
|
||||
if(BUILD_KF5)
|
||||
|
||||
if(NOT DEFINED KF5_GIT_TAG)
|
||||
#https://qelectrotech.org/forum/viewtopic.php?pid=13924#p13924
|
||||
|
||||
@@ -18,9 +18,16 @@ message(" - fetch_pugixml")
|
||||
|
||||
Include(FetchContent)
|
||||
|
||||
FetchContent_Declare(
|
||||
pugixml
|
||||
GIT_REPOSITORY https://github.com/zeux/pugixml.git
|
||||
GIT_TAG v1.11.1)
|
||||
option(BUILD_PUGIXML "Build pugixml library, use system one otherwise" YES)
|
||||
|
||||
FetchContent_MakeAvailable(pugixml)
|
||||
if(BUILD_PUGIXML)
|
||||
|
||||
FetchContent_Declare(
|
||||
pugixml
|
||||
GIT_REPOSITORY https://github.com/zeux/pugixml.git
|
||||
GIT_TAG v1.11.4)
|
||||
|
||||
FetchContent_MakeAvailable(pugixml)
|
||||
else()
|
||||
find_package(pugixml REQUIRED)
|
||||
endif()
|
||||
|
||||
@@ -26,6 +26,6 @@ Include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
SingleApplication
|
||||
GIT_REPOSITORY https://github.com/itay-grudev/SingleApplication.git
|
||||
GIT_TAG v3.1.5)
|
||||
GIT_TAG v3.2.0)
|
||||
|
||||
FetchContent_MakeAvailable(SingleApplication)
|
||||
|
||||
@@ -28,9 +28,6 @@ if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
|
||||
# This strips terminating newline in the variable
|
||||
string(REGEX REPLACE "\n$" "" GIT_COMMIT_SHA "${GIT_COMMIT_SHA}")
|
||||
|
||||
# This adds to definitions => .cpp
|
||||
add_definitions(-DGIT_COMMIT_SHA="${GIT_COMMIT_SHA}")
|
||||
|
||||
if(NOT GIT_COMMIT_RESULT EQUAL "0")
|
||||
message(
|
||||
FATAL_ERROR
|
||||
@@ -39,3 +36,6 @@ if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
|
||||
", please check")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# This adds to definitions => .cpp
|
||||
add_definitions(-DGIT_COMMIT_SHA="${GIT_COMMIT_SHA}")
|
||||
|
||||
@@ -52,6 +52,8 @@ set(QET_RES_FILES
|
||||
${QET_DIR}/sources/editor/ui/lineeditor.ui
|
||||
${QET_DIR}/sources/editor/ui/polygoneditor.ui
|
||||
${QET_DIR}/sources/editor/ui/rectangleeditor.ui
|
||||
${QET_DIR}/sources/editor/ui/qetelementeditor.ui
|
||||
${QET_DIR}/sources/editor/ui/terminaleditor.ui
|
||||
${QET_DIR}/sources/ElementsCollection/ui/renamedialog.ui
|
||||
${QET_DIR}/sources/factory/ui/addtabledialog.ui
|
||||
${QET_DIR}/sources/NameList/ui/namelistdialog.ui
|
||||
@@ -260,12 +262,8 @@ set(QET_SRC_FILES
|
||||
${QET_DIR}/sources/editor/elementscene.h
|
||||
${QET_DIR}/sources/editor/elementview.cpp
|
||||
${QET_DIR}/sources/editor/elementview.h
|
||||
${QET_DIR}/sources/editor/qetelementeditor.cpp
|
||||
${QET_DIR}/sources/editor/qetelementeditor.h
|
||||
${QET_DIR}/sources/editor/styleeditor.cpp
|
||||
${QET_DIR}/sources/editor/styleeditor.h
|
||||
${QET_DIR}/sources/editor/terminaleditor.cpp
|
||||
${QET_DIR}/sources/editor/terminaleditor.h
|
||||
|
||||
${QET_DIR}/sources/editor/esevent/eseventaddarc.cpp
|
||||
${QET_DIR}/sources/editor/esevent/eseventaddarc.h
|
||||
@@ -320,8 +318,12 @@ set(QET_SRC_FILES
|
||||
${QET_DIR}/sources/editor/ui/polygoneditor.h
|
||||
${QET_DIR}/sources/editor/ui/rectangleeditor.cpp
|
||||
${QET_DIR}/sources/editor/ui/rectangleeditor.h
|
||||
${QET_DIR}/sources/editor/ui/terminaleditor.cpp
|
||||
${QET_DIR}/sources/editor/ui/terminaleditor.h
|
||||
${QET_DIR}/sources/editor/ui/texteditor.cpp
|
||||
${QET_DIR}/sources/editor/ui/texteditor.h
|
||||
${QET_DIR}/sources/editor/ui/qetelementeditor.h
|
||||
${QET_DIR}/sources/editor/ui/qetelementeditor.cpp
|
||||
|
||||
${QET_DIR}/sources/editor/UndoCommand/pastepartscommand.cpp
|
||||
${QET_DIR}/sources/editor/UndoCommand/pastepartscommand.h
|
||||
@@ -371,6 +373,8 @@ set(QET_SRC_FILES
|
||||
${QET_DIR}/sources/print/projectprintwindow.cpp
|
||||
${QET_DIR}/sources/print/projectprintwindow.h
|
||||
|
||||
${QET_DIR}/sources/properties/elementdata.cpp
|
||||
${QET_DIR}/sources/properties/elementdata.h
|
||||
${QET_DIR}/sources/properties/propertiesinterface.cpp
|
||||
${QET_DIR}/sources/properties/propertiesinterface.h
|
||||
${QET_DIR}/sources/properties/reportproperties.cpp
|
||||
@@ -379,6 +383,8 @@ set(QET_SRC_FILES
|
||||
${QET_DIR}/sources/properties/terminaldata.h
|
||||
${QET_DIR}/sources/properties/xrefproperties.cpp
|
||||
${QET_DIR}/sources/properties/xrefproperties.h
|
||||
${QET_DIR}/sources/properties/userproperties.cpp
|
||||
${QET_DIR}/sources/properties/userproperties.h
|
||||
|
||||
${QET_DIR}/sources/PropertiesEditor/propertieseditordialog.h
|
||||
${QET_DIR}/sources/PropertiesEditor/propertieseditordockwidget.cpp
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<name lang="hu">Beérkező hivatkozás</name>
|
||||
<name lang="nl">Referentie Vorig</name>
|
||||
</names>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<polygon x2="-1" y2="4" y4="-4" x1="-1" x3="9" y3="0" closed="false" style="line-style:normal;line-weight:normal;filling:black;color:black" y1="-4" x4="-1" antialias="true"/>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<name lang="ru">Следующая страница</name>
|
||||
<name lang="cs">Další list</name>
|
||||
</names>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<polygon y3="0" y2="4" x4="-9" x3="2" x1="-9" x2="-9" y4="-4" style="line-style:normal;line-weight:normal;filling:black;color:black" y1="-4" closed="false" antialias="true"/>
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
<elementInformation name="plant" show="1"></elementInformation>
|
||||
<elementInformation name="label" show="1"></elementInformation>
|
||||
</elementInformations>
|
||||
<informations>titus
|
||||
<informations>titus
|
||||
titus0818@yahoo.com</informations>
|
||||
<description>
|
||||
<line y1="-16" x1="0" style="line-style:normal;line-weight:hight;filling:none;color:black" end2="none" y2="13" length2="1.5" length1="1.5" x2="0" end1="none" antialias="false"/>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<name lang="ru">Однополюсный + нейтраль</name>
|
||||
<name lang="hu">F + N</name>
|
||||
</names>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<input x="-5" y="-25.45" tagg="label" size="9" rotate="true" text="_"/>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<name lang="ru">Трёхполюсный</name>
|
||||
<name lang="hu">3F</name>
|
||||
</names>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<input x="-2" y="-34.45" tagg="label" size="9" rotate="true" text="_"/>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<name lang="ru">Трёхполюсный + нейтраль</name>
|
||||
<name lang="hu">3F + N</name>
|
||||
</names>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<input x="-7" y="-44.45" tagg="label" size="9" rotate="true" text="_"/>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<name lang="ru">Фаза</name>
|
||||
<name lang="hu">F</name>
|
||||
</names>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<input x="-6" y="-14.45" tagg="label" size="9" rotate="true" text="_"/>
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
<elementInformation name="plant" show="1"></elementInformation>
|
||||
<elementInformation name="label" show="1"></elementInformation>
|
||||
</elementInformations>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<dynamic_text uuid="{0af57a27-1887-4576-8b51-200ca996e582}" Halignment="AlignLeft" frame="false" x="2" Valignment="AlignTop" text_from="ElementInfo" y="-22.5" font="Sans Serif,9,-1,5,50,0,0,0,0,0" z="1" rotation="0" text_width="-1">
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<name lang="cs">Kabel 3G</name>
|
||||
<name lang="hu">Kábel 2 + PE</name>
|
||||
</names>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<text x="12" y="9" size="4" text="2"/>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<name lang="cs">Kabel 4G</name>
|
||||
<name lang="hu">Kábel 3 + PE</name>
|
||||
</names>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<line length1="1.5" length2="1.5" antialias="true" end1="none" end2="none" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="7.95" x1="-12.05" y2="11.95" x2="-8.05"/>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<name lang="cs">Kabel 3G</name>
|
||||
<name lang="hu">Kábel 2 + PE</name>
|
||||
</names>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<line length1="1.5" length2="1.5" antialias="true" end1="none" end2="none" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="7.95" x1="17.95" y2="11.95" x2="21.95"/>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<name lang="cs">Kabel 4G</name>
|
||||
<name lang="hu">Kábel 3 + PE</name>
|
||||
</names>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<line length1="1.5" length2="1.5" antialias="true" end1="none" end2="none" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="7.95" x1="-33.05" y2="11.95" x2="-29.05"/>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<name lang="cs">Kabel 5G</name>
|
||||
<name lang="hu">Kábel 4 + N + PE</name>
|
||||
</names>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<line end1="none" x1="-42.05" y1="7.95" x2="-38.05" length1="1.5" y2="11.95" antialias="true" end2="none" length2="1.5" style="line-style:normal;line-weight:normal;filling:none;color:black"/>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<name lang="cs">Kabel 3G</name>
|
||||
<name lang="hu">Kábel 2 + PE</name>
|
||||
</names>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<line end1="none" x1="-23.05" y1="7.95" x2="-19.05" length1="1.5" y2="11.95" antialias="true" end2="none" length2="1.5" style="line-style:normal;line-weight:normal;filling:none;color:black"/>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<name lang="hu">Kábel 2 + PE</name>
|
||||
</names>
|
||||
<elementInformations/>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<line x2="1.95" end1="none" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="-2.05" length2="1.5" antialias="true" y2="1.95" end2="none" x1="-2.05" length1="1.5"/>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<name lang="fr">Cable 3 phases+terre</name>
|
||||
<name lang="hu">Kábel 3 + PE</name>
|
||||
</names>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<line x1="-2.05" y1="-2.05" end1="none" style="line-style:normal;line-weight:normal;filling:none;color:black" end2="none" length1="1.5" length2="1.5" x2="1.95" y2="1.95" antialias="true"/>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<name lang="fr">Cable 6 phases+terre</name>
|
||||
<name lang="hu">Kábel 6 + PE</name>
|
||||
</names>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<input size="4" tagg="none" rotate="true" x="38" y="-4" text="6"/>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<name lang="es">Sección 1 conductor</name>
|
||||
<name lang="hu">1 ér keresztmetszet</name>
|
||||
</names>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<line antialias="false" length1="1.5" x2="9.91885" end2="none" x1="-10.8483" end1="none" y2="0" length2="1.5" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="0"/>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<name lang="es">Sección 2 conductores</name>
|
||||
<name lang="hu">2 ér keresztmetszet</name>
|
||||
</names>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<line antialias="true" length1="1.5" x2="41.95" end2="none" x1="37.95" end1="none" y2="1.95" length2="1.5" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="-2.05"/>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<name lang="es">Sección 2 conductores</name>
|
||||
<name lang="hu">2 ér keresztmetszet</name>
|
||||
</names>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<line antialias="true" length1="1.5" x2="21.95" end2="none" x1="17.95" end1="none" y2="1.95" length2="1.5" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="-2.05"/>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<name lang="es">Sección 3 conductores</name>
|
||||
<name lang="hu">3 ér keresztmetszet</name>
|
||||
</names>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<line antialias="true" length1="1.5" x2="41.95" end2="none" x1="37.95" end1="none" y2="1.95" length2="1.5" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="-2.05"/>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<kindInformations>
|
||||
<kindInformation name="type" show="1">protection</kindInformation>
|
||||
</kindInformations>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<polygon antialias="true" style="line-style:normal;line-weight:normal;filling:none;color:black" closed="false" y1="-10" x1="-15" y2="10" x2="-10" y3="20" x3="-10"/>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<kindInformations>
|
||||
<kindInformation name="type" show="1">protection</kindInformation>
|
||||
</kindInformations>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<polygon antialias="true" style="line-style:normal;line-weight:normal;filling:none;color:black" closed="false" y1="-10" x1="25" y2="10" x2="30" y3="20" x3="30"/>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<kindInformations>
|
||||
<kindInformation name="type" show="1">protection</kindInformation>
|
||||
</kindInformations>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<line length1="1.5" length2="1.5" antialias="false" end1="none" end2="none" style="line-style:dashed;line-weight:thin;filling:none;color:black" y1="0" x1="-33" y2="0" x2="-26"/>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<kindInformations>
|
||||
<kindInformation name="type" show="1">protection</kindInformation>
|
||||
</kindInformations>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<polygon antialias="true" style="line-style:normal;line-weight:normal;filling:none;color:black" closed="false" y1="-10" x1="-15" y2="10" x2="-10" y3="20" x3="-10"/>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<definition hotspot_y="52" version="0.51" hotspot_x="56" link_type="simple" width="70" type="element" height="100">
|
||||
<definition hotspot_y="52" version="0.51" hotspot_x="56" link_type="master" width="70" type="element" height="100">
|
||||
<uuid uuid="{2d6c186b-0578-4682-90c9-f77843432e9f}"/>
|
||||
<names>
|
||||
<name lang="cs">Motorový spouštěč 1P+N</name>
|
||||
@@ -12,6 +12,9 @@
|
||||
<name lang="ar">قاطع مغناطيسي-حراري GV</name>
|
||||
<name lang="hu">Motorvédő kapcsoló 1 pólusú GV</name>
|
||||
</names>
|
||||
<kindInformations>
|
||||
<kindInformation name="type" show="1">protection</kindInformation>
|
||||
</kindInformations>
|
||||
<informations></informations>
|
||||
<description>
|
||||
<polygon x1="0" y1="14" x5="0" y4="4" y5="4" x6="0" y7="-25" x2="0" y6="-6" y2="10" y3="10" x7="-7" antialias="true" x3="5" closed="false" x4="5" style="line-style:normal;line-weight:normal;filling:none;color:black"/>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<definition hotspot_y="52" width="70" version="0.51" type="element" height="100" hotspot_x="56" link_type="simple">
|
||||
<definition hotspot_y="52" width="70" version="0.51" type="element" height="100" hotspot_x="56" link_type="master">
|
||||
<uuid uuid="{ec5fa3cd-6769-4a35-aaa9-6bc5ba4fc779}"/>
|
||||
<names>
|
||||
<name lang="fr">Disjoncteur Magnéto-thermique GV 2P</name>
|
||||
@@ -8,6 +8,9 @@
|
||||
<name lang="cs">Motorový spouštěč 2P</name>
|
||||
<name lang="hu">Motorvédő kapcsoló 2 pólusú GV</name>
|
||||
</names>
|
||||
<kindInformations>
|
||||
<kindInformation name="type" show="1">protection</kindInformation>
|
||||
</kindInformations>
|
||||
<informations></informations>
|
||||
<description>
|
||||
<polygon y2="10" x3="-15" y4="4" x2="-20" y3="10" x5="-20" style="line-style:normal;line-weight:normal;filling:none;color:black" x1="-20" x4="-15" closed="false" y1="14" y6="-6" x7="-27" y5="4" antialias="true" y7="-25" x6="-20"/>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<definition hotspot_y="52" version="0.51" hotspot_x="56" link_type="simple" width="110" type="element" height="100">
|
||||
<definition hotspot_y="52" version="0.51" hotspot_x="56" link_type="master" width="110" type="element" height="100">
|
||||
<uuid uuid="{2424a938-847f-447f-a4ad-d9b6ef730fd9}"/>
|
||||
<names>
|
||||
<name lang="de">Motorschutzschalter</name>
|
||||
@@ -12,6 +12,9 @@
|
||||
<name lang="ar">قاطع مغناطيسي-حراري GV</name>
|
||||
<name lang="hu">Motorvédő kapcsoló 3F + N pólusú</name>
|
||||
</names>
|
||||
<kindInformations>
|
||||
<kindInformation name="type" show="1">protection</kindInformation>
|
||||
</kindInformations>
|
||||
<informations></informations>
|
||||
<description>
|
||||
<line end1="none" x1="40" y1="39" x2="40" length1="1.5" y2="28" antialias="false" end2="none" length2="1.5" style="line-style:normal;line-weight:normal;filling:none;color:black"/>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<definition hotspot_y="50" width="110" version="0.51" type="element" height="100" hotspot_x="56" link_type="simple">
|
||||
<definition hotspot_y="50" width="110" version="0.51" type="element" height="100" hotspot_x="56" link_type="master">
|
||||
<uuid uuid="{686e19c6-6bce-4ced-8c01-2d7f58a78386}"/>
|
||||
<names>
|
||||
<name lang="el">Θερμομαγνητικό</name>
|
||||
@@ -12,6 +12,9 @@
|
||||
<name lang="de">Motorschutzschalter</name>
|
||||
<name lang="hu">Motorvédő kapcsoló 4 pólusú GV</name>
|
||||
</names>
|
||||
<kindInformations>
|
||||
<kindInformation name="type" show="1">protection</kindInformation>
|
||||
</kindInformations>
|
||||
<informations></informations>
|
||||
<description>
|
||||
<line y2="28" end1="none" length2="1.5" x2="40" style="line-style:normal;line-weight:normal;filling:none;color:black" x1="40" length1="1.5" y1="39" end2="none" antialias="false"/>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<definition type="element" link_type="simple" hotspot_x="31" hotspot_y="4" version="0.5" width="90" height="70">
|
||||
<definition type="element" link_type="master" hotspot_x="31" hotspot_y="4" version="0.5" width="90" height="70">
|
||||
<uuid uuid="{98ADF831-42F0-4EDE-9267-6733EEBEAF62}"/><names>
|
||||
<name lang="en">Motor circuit breaker</name>
|
||||
<name lang="es">Disyuntor termico magnetico 3P mando manual con auto retorno y boton de desenclave</name>
|
||||
@@ -10,6 +10,9 @@
|
||||
<name lang="pl">Wyłącznik silnikowy</name>
|
||||
<name lang="hu">Motorvédő kapcsoló 3 pólusú</name>
|
||||
</names>
|
||||
<kindInformations>
|
||||
<kindInformation name="type" show="1">protection</kindInformation>
|
||||
</kindInformations>
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<definition type="element" link_type="simple" hotspot_x="33" hotspot_y="5" version="0.5" width="110" height="70">
|
||||
<definition type="element" link_type="master" hotspot_x="33" hotspot_y="5" version="0.5" width="110" height="70">
|
||||
<uuid uuid="{C33FE39E-B2EE-4EC0-BC3F-4EB76E9BCEA0}"/><names>
|
||||
<name lang="en">Motor circuit breaker with neutral</name>
|
||||
<name lang="es">Disyuntor termico magnetico 3P+N mando manual con auto retorno y boton de desenclave</name>
|
||||
@@ -10,6 +10,9 @@
|
||||
<name lang="pl">Wyłącznik silnikowy</name>
|
||||
<name lang="hu">Motorvédő kapcsoló 3F + N pólusú</name>
|
||||
</names>
|
||||
<kindInformations>
|
||||
<kindInformation name="type" show="1">protection</kindInformation>
|
||||
</kindInformations>
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<definition hotspot_y="50" version="0.51" hotspot_x="56" link_type="simple" width="70" type="element" height="110">
|
||||
<definition hotspot_y="50" version="0.51" hotspot_x="56" link_type="master" width="70" type="element" height="110">
|
||||
<uuid uuid="{68830151-5901-40f6-b94d-dc68b85165a2}"/>
|
||||
<names>
|
||||
<name lang="fr">Disjoncteur differentiel 1P+N</name>
|
||||
@@ -8,6 +8,9 @@
|
||||
<name lang="cs">Jističochránič 2P</name>
|
||||
<name lang="hu">Differenciál-védőkapcsoló 1P+N termikus és zárlatvédelemmel</name>
|
||||
</names>
|
||||
<kindInformations>
|
||||
<kindInformation name="type" show="1">protection</kindInformation>
|
||||
</kindInformations>
|
||||
<informations></informations>
|
||||
<description>
|
||||
<line end1="none" x1="-29.6203" y1="28" x2="10" length1="1.5" y2="28" antialias="false" end2="none" length2="1.5" style="line-style:normal;line-weight:normal;filling:none;color:black"/>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<definition hotspot_y="50" version="0.51" hotspot_x="56" link_type="simple" width="110" type="element" height="110">
|
||||
<definition hotspot_y="50" version="0.51" hotspot_x="56" link_type="master" width="110" type="element" height="110">
|
||||
<uuid uuid="{3fa48846-98c0-43e1-8a96-330d4dc11ceb}"/>
|
||||
<names>
|
||||
<name lang="cs">Jističochránič 3P+N</name>
|
||||
@@ -12,6 +12,9 @@
|
||||
<name lang="ar">قاطع مغناطيسي-حراري GV</name>
|
||||
<name lang="hu">Differenciál-védőkapcsoló 3P+N termikus és zárlatvédelemmel</name>
|
||||
</names>
|
||||
<kindInformations>
|
||||
<kindInformation name="type" show="1">protection</kindInformation>
|
||||
</kindInformations>
|
||||
<informations></informations>
|
||||
<description>
|
||||
<line end1="none" x1="-29.6203" y1="28" x2="49.5887" length1="1.5" y2="28" antialias="false" end2="none" length2="1.5" style="line-style:normal;line-weight:normal;filling:none;color:black"/>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<definition hotspot_y="50" version="0.51" hotspot_x="56" link_type="simple" width="70" type="element" height="110">
|
||||
<definition hotspot_y="50" version="0.51" hotspot_x="56" link_type="master" width="70" type="element" height="110">
|
||||
<uuid uuid="{20f65431-6f1f-4e09-9c73-68a1431c40a1}"/>
|
||||
<names>
|
||||
<name lang="fr">Disjoncteur differentiel 2P</name>
|
||||
@@ -8,6 +8,9 @@
|
||||
<name lang="cs">Jističochránič 2P</name>
|
||||
<name lang="hu">Differenciál-védőkapcsoló 2P termikus és zárlatvédelemmel</name>
|
||||
</names>
|
||||
<kindInformations>
|
||||
<kindInformation name="type" show="1">protection</kindInformation>
|
||||
</kindInformations>
|
||||
<informations></informations>
|
||||
<description>
|
||||
<polygon x1="-20" y1="14" x5="-20" y4="4" y5="4" x6="-20" y7="-25" x2="-20" y6="-6" y2="10" y3="10" x7="-27" antialias="true" x3="-15" closed="false" x4="-15" style="line-style:normal;line-weight:normal;filling:none;color:black"/>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<definition hotspot_y="50" version="0.51" hotspot_x="56" link_type="simple" width="90" type="element" height="110">
|
||||
<definition hotspot_y="50" version="0.51" hotspot_x="56" link_type="master" width="90" type="element" height="110">
|
||||
<uuid uuid="{1e746e43-1906-4ea0-99a6-261e3c862dba}"/>
|
||||
<names>
|
||||
<name lang="cs">Jističochránič 3P</name>
|
||||
@@ -12,6 +12,9 @@
|
||||
<name lang="ar">قاطع مغناطيسي-حراري GV</name>
|
||||
<name lang="hu">Differenciál-védőkapcsoló 3P termikus és zárlatvédelemmel</name>
|
||||
</names>
|
||||
<kindInformations>
|
||||
<kindInformation name="type" show="1">protection</kindInformation>
|
||||
</kindInformations>
|
||||
<informations></informations>
|
||||
<description>
|
||||
<text text="I>" size="9" y="25" x="-24"/>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<definition hotspot_y="50" version="0.51" hotspot_x="56" link_type="simple" width="110" type="element" height="110">
|
||||
<definition hotspot_y="50" version="0.51" hotspot_x="56" link_type="master" width="110" type="element" height="110">
|
||||
<uuid uuid="{fee3faef-5f4a-4a0b-bf0e-b6e93d9f9425}"/>
|
||||
<names>
|
||||
<name lang="de">Motorschutzschalter</name>
|
||||
@@ -12,6 +12,9 @@
|
||||
<name lang="ar">قاطع مغناطيسي-حراري GV</name>
|
||||
<name lang="hu">Differenciál-védőkapcsoló 4P termikus és zárlatvédelemmel</name>
|
||||
</names>
|
||||
<kindInformations>
|
||||
<kindInformation name="type" show="1">protection</kindInformation>
|
||||
</kindInformations>
|
||||
<informations></informations>
|
||||
<description>
|
||||
<polygon x1="-20" y1="14" x5="-20" y4="4" y5="4" x6="-20" y7="-25" x2="-20" y6="-6" y2="10" y3="10" x7="-27" antialias="true" x3="-15" closed="false" x4="-15" style="line-style:normal;line-weight:normal;filling:none;color:black"/>
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
<name lang="pt">Descarregador de faísca</name>
|
||||
<name lang="fr">Éclateur</name>
|
||||
<name lang="nl">Vonkbrug</name>
|
||||
<name lang="hu">Szikraköz</name>
|
||||
</names>
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
<name lang="cs">Varistor</name>
|
||||
<name lang="it">Varistore Metal-oxide</name>
|
||||
<name lang="nl">Varistor Metal-oxide</name>
|
||||
<name lang="hu">Fém-oxid varisztor</name>
|
||||
</names>
|
||||
<kindInformations>
|
||||
<kindInformation name="type" show="1">protection</kindInformation>
|
||||
|
||||
@@ -10,10 +10,11 @@
|
||||
<name lang="el">Προστασία από υπέρταση</name>
|
||||
<name lang="fr">Parafoudre</name>
|
||||
<name lang="en">Surge protection</name>
|
||||
<name lang="hu">Túlfeszültség védő</name>
|
||||
<name lang="es">Protección contra descargas 2</name>
|
||||
</names>
|
||||
<elementInformations/>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<dynamic_text z="1" text_from="ElementInfo" rotation="0" text_width="-1" Valignment="AlignTop" frame="false" x="18" font="Sans Serif,9,-1,5,50,0,0,0,0,0" y="-15.45" uuid="{daef117a-d243-49f7-b089-6a8ffe076f69}" Halignment="AlignLeft">
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<uuid uuid="{5FC5912D-A466-4E02-8051-7F08868D3FB5}"/><names>
|
||||
<name lang="de">Blitzschutz</name>
|
||||
<name lang="en">Surge protector</name>
|
||||
<name lang="hu">Túlfeszültség védő</name>
|
||||
<name lang="es">Protección contra descargas</name>
|
||||
<name lang="it">Scaricatore</name>
|
||||
<name lang="fr">Parafoudre</name>
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<name lang="pl">Ogranicznik przepięć</name>
|
||||
<name lang="ar">حامي من الصواعق</name>
|
||||
<name lang="en">Surge protection</name>
|
||||
<name lang="hu">Túlfeszültség védő</name>
|
||||
</names>
|
||||
<elementInformations>
|
||||
<elementInformation show="1" name="unity"></elementInformation>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
<name lang="cs">Bleskojistka, ochrana proti přepětí</name>
|
||||
<name lang="fr">Parafoudre</name>
|
||||
<name lang="en">Surge protector</name>
|
||||
<name lang="hu">Túlfeszültség védő</name>
|
||||
<name lang="es">Protección contra descargas</name>
|
||||
</names>
|
||||
<elementInformations>
|
||||
|
||||
@@ -11,5 +11,6 @@
|
||||
<name lang="el">Προστασία από υπέρταση</name>
|
||||
<name lang="nl">Overspanningsbeveiliging</name>
|
||||
<name lang="da">Overspændingsbeskyttelse</name>
|
||||
<name lang="hu">Túlfeszültség védelem</name>
|
||||
</names>
|
||||
</qet-directory>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
<name lang="pl">Odgromnik gazowyładowczy dwuelektrodowy</name>
|
||||
<name lang="cs">Plynová bleskojistka</name>
|
||||
<name lang="nl">gasontladingsbuis</name>
|
||||
<name lang="hu">Védőgázas szimetrikus kisülőcső</name>
|
||||
</names>
|
||||
<kindInformations>
|
||||
<kindInformation name="type" show="1">protection</kindInformation>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
<name lang="pl">Odgromnik gazowyładowczy trójelektrodowy</name>
|
||||
<name lang="cs">Dvojitá plynová bleskojistka</name>
|
||||
<name lang="nl">Symmetrische gasontlading buis</name>
|
||||
<name lang="hu">Védőgázas kisülőcső</name>
|
||||
</names>
|
||||
<kindInformations>
|
||||
<kindInformation name="type" show="1">protection</kindInformation>
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<name lang="es">Bobina</name>
|
||||
<name lang="cs">Cívka relé</name>
|
||||
<name lang="nl">Spoel</name>
|
||||
<name lang="hu">Tekercs</name>
|
||||
<name lang="be">Relais spoel (algemeen)</name>
|
||||
</names>
|
||||
<kindInformations>
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
<name lang="cs">Bistabilní remanentní relé</name>
|
||||
<name lang="nl">spoel remanent</name>
|
||||
<name lang="be">Spoel KA remanent</name>
|
||||
<name lang="hu">Tekercs</name>
|
||||
</names>
|
||||
<kindInformations>
|
||||
<kindInformation name="type" show="1">coil</kindInformation>
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<name lang="es">Bobina KA con enclavamiento mecánico</name>
|
||||
<name lang="cs">Mechanické blokovací relé</name>
|
||||
<name lang="nl">spoel met vergrendeling</name>
|
||||
<name lang="hu">Tekercs</name>
|
||||
<name lang="be">Spoel KA met mechanische vergrendeling</name>
|
||||
</names>
|
||||
<kindInformations>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
<name lang="cs">Relé se zpožděným zapnutím a vypnutím</name>
|
||||
<name lang="de">Relais ansprech- und rückfallverzögert</name>
|
||||
<name lang="it">Bobina di relè ritardato</name>
|
||||
<name lang="hu">Tekercs be/ki késleltetéssel</name>
|
||||
<name lang="el">Πηνίο χρονικού, καθυστέρηση ενεργοποίησης-απενεργοποίησης</name>
|
||||
<name lang="ar">ملف مُؤقت مع تأخير الإستجابة و تأخير الإعتاق</name>
|
||||
<name lang="pl">Cewka przekaźnika działającego ze zwłoką przy wzbudzeniu i odwzbudzeniu</name>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<uuid uuid="{7E996B1F-B537-44D9-A3E9-DB5F30487400}"/><names>
|
||||
<name lang="be">Spoel met uitschakel vertraging</name>
|
||||
<name lang="en">Coil with off delay</name>
|
||||
<name lang="hu">Tekercs ki késleltetéssel</name>
|
||||
<name lang="fr">Bobine tempo repos</name>
|
||||
<name lang="ru">Обмотка</name>
|
||||
<name lang="es">Bobina de reposo temporizado</name>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<uuid uuid="{14D69713-ADDE-4ACD-8654-50E3E60B61F7}"/><names>
|
||||
<name lang="be">Spoel met inschakel vertraging</name>
|
||||
<name lang="en">Coil with on delay</name>
|
||||
<name lang="hu">Tekercs be késleltetéssel</name>
|
||||
<name lang="fr">Bobine tempo travail</name>
|
||||
<name lang="ru">Обмотка</name>
|
||||
<name lang="es">Bobina de trabajo temporizado</name>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
<name lang="pl">Przekaźnik prądu przemiennego</name>
|
||||
<name lang="cs">Cívka relé pro AC napájení</name>
|
||||
<name lang="es">Relé de CA</name>
|
||||
<name lang="hu">Tekercs AC</name>
|
||||
<name lang="nl">Relais voor wisselspanning</name>
|
||||
<name lang="be">Relais AC (wisselspanning)</name>
|
||||
</names>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
<name lang="cs">Cívka relé pro DC napájení</name>
|
||||
<name lang="de">Spule mit Gleichstrombetätigung</name>
|
||||
<name lang="it">Relè DC</name>
|
||||
<name lang="hu">Tekercs DC</name>
|
||||
<name lang="el">Πηνίο συνεχούς</name>
|
||||
<name lang="pl">Przekaźnik prądu przemiennego</name>
|
||||
</names>
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
<name lang="cs">Elektronické relé</name>
|
||||
<name lang="nl">relais electronisch</name>
|
||||
<name lang="es">Relé electrónico</name>
|
||||
<name lang="be">Electronisch relais</name>
|
||||
<name lang="be">Electronisch relais</name>
|
||||
<name lang="hu">Tranzisztoros működtetés</name>
|
||||
</names>
|
||||
<kindInformations>
|
||||
<kindInformation name="type" show="1">coil</kindInformation>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<name lang="es">Contacto relé térmico (NA)</name>
|
||||
<name lang="cs">Kontakt (NO) tepelného jističe</name>
|
||||
</names>
|
||||
<informations>Author: The QElectroTech team







|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<line length1="1.5" length2="1.5" antialias="false" end1="none" end2="none" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="3" x1="-12.6286" y2="3" x2="-16.1714"/>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<name lang="es">Contacto relé térmico (NC)</name>
|
||||
<name lang="cs">Kontakt (NC) tepelného jističe</name>
|
||||
</names>
|
||||
<informations>Author: The QElectroTech team







|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<line length1="1.5" length2="1.5" antialias="false" end1="none" end2="none" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="0" x1="-7.67895" y2="0" x2="-10.9053"/>
|
||||
|
||||
@@ -13,5 +13,6 @@
|
||||
<name lang="cs">Relé, stykače a kontakty</name>
|
||||
<name lang="da">Relæer, kontaktorer og kontakter</name>
|
||||
<name lang="ja">継電器、接触器、接点</name>
|
||||
<name lang="hu">Relék, kontaktorok és érintkezők</name>
|
||||
</names>
|
||||
</qet-directory>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<name lang="cs">Jednofázový autotransformátor</name>
|
||||
<name lang="nl">enkelfase autotransformator</name>
|
||||
</names>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<line length1="1.5" length2="1.5" antialias="false" end1="none" end2="none" style="line-style:normal;line-weight:normal;filling:none;color:black" y1="-20" x1="8" y2="-35" x2="8"/>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<name lang="cs">Třífázový autotransformátor</name>
|
||||
<name lang="nl">driefase autotransformator</name>
|
||||
</names>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<input x="20" y="17.6667" size="5" text="___V"/>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<name lang="cs">Třífázový autotransformátor + neutrál</name>
|
||||
<name lang="nl">driefase autotransformator + Nul</name>
|
||||
</names>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<input x="20" y="17.6667" size="5" text="___V"/>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<name lang="cs">Třífázový transformátor</name>
|
||||
<name lang="nl">Driefase transformator</name>
|
||||
</names>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<text x="-16" y="-31.6667" size="4" text="A1"/>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<name lang="cs">Třífázový transformátor + neutrál</name>
|
||||
<name lang="nl">driefase transformator + Nul</name>
|
||||
</names>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<polygon x4="-12" antialias="false" style="line-style:normal;line-weight:normal;filling:none;color:black" closed="false" y1="35" x1="-34" y2="30" x2="-34" y3="19" x3="-27" y4="19"/>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<name lang="es">Lámpara azul</name>
|
||||
<name lang="cs">Kontrolka</name>
|
||||
</names>
|
||||
<informations>Author: The QElectroTech team





|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<ellipse width="14.5169" x="-7.5012" y="-6.95514" antialias="true" height="13.3034" style="line-style:normal;line-weight:normal;filling:blue;color:black"/>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<name lang="es">Lámpara roja</name>
|
||||
<name lang="cs">Kontrolka</name>
|
||||
</names>
|
||||
<informations>Author: The QElectroTech team





|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<polygon style="line-style:normal;line-weight:normal;filling:red;color:red" x1="-6.61784" x2="-8.37626" x3="-8.37626" x4="-7.49705" antialias="false" x5="-4.85942" x6="-0.463379" x7="3.05345" x8="5.69108" x9="7.4495" y1="-5.31158" y10="-0.849266" y2="-2.3367" y11="-3.82414" y3="0.638173" y4="3.61305" y12="-6.0553" y5="5.84421" x10="7.4495" y13="-6.79902" y6="7.33165" x11="6.57029" y14="-6.79902" y7="6.58793" x12="4.81187" y15="-5.31158" y8="4.35677" x13="1.29504" y9="2.12561" x14="-3.10101" x15="-6.61784"/>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<name lang="ca">Lum verda</name>
|
||||
<name lang="cs">Kontrolka</name>
|
||||
</names>
|
||||
<informations>Author: The QElectroTech team





|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<ellipse width="14.5169" x="-7.5012" y="-6.95514" antialias="true" height="13.3034" style="line-style:normal;line-weight:normal;filling:green;color:black"/>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<name lang="pl">Głośnik</name>
|
||||
<name lang="nl">Luidspreker</name>
|
||||
</names>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<input y="1.55" text="_" x="14" rotate="true" size="9" tagg="label"/>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<kindInformations>
|
||||
<kindInformation show="1" name="type">commutator</kindInformation>
|
||||
</kindInformations>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<line y1="0" length1="1.5" y2="0" antialias="false" x1="-5" end1="none" style="line-style:dashed;line-weight:thin;filling:none;color:black" length2="1.5" end2="none" x2="7"/>
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
<definition hotspot_y="24" type="element" link_type="simple" height="50" width="60" orientation="dyyy" version="0.80" hotspot_x="28">
|
||||
<uuid uuid="{4f9e99c4-8b9f-4727-837a-c145a41669dc}"/>
|
||||
<names>
|
||||
<name lang="de">Fußschalter 2-polig Schliesser/Öffner</name>
|
||||
<name lang="en">Foot Switch (NO/NC)</name>
|
||||
<name lang="pl">Łącznik wielozestykowy napędzany nogą</name>
|
||||
<name lang="it">Comando a pedale (NO/NC)</name>
|
||||
<name lang="ar">مفتاح بدوّاسة (NO/NC)</name>
|
||||
<name lang="el">Ποδοδιακόπτης, ανοικτή και κλειστή επαφή</name>
|
||||
<name lang="cs">Pedálový spínač (NO/NC)</name>
|
||||
<name lang="es">Paro de emergencia con pedal (NA/NC)</name>
|
||||
<name lang="fr">Interrupteur à pedale (NO/NC)</name>
|
||||
<name lang="nl">Voetschakelaar (NO/NC)</name>
|
||||
</names>
|
||||
<elementInformations/>
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<line x2="-15" length1="1.5" y1="-9" y2="-9" length2="1.5" antialias="false" end1="none" end2="none" x1="-22" style="line-style:normal;line-weight:normal;filling:none;color:black"/>
|
||||
<dynamic_text font="Sans Serif,5,-1,5,50,0,0,0,0,0" uuid="{6e15cbca-5884-432a-b376-0eeeaf93807b}" frame="false" Valignment="AlignTop" z="4" Halignment="AlignLeft" x="-25" rotation="0" text_width="-1" text_from="ElementInfo" y="-23">
|
||||
<text></text>
|
||||
</dynamic_text>
|
||||
<dynamic_text font="Sans Serif,5,-1,5,50,0,0,0,0,0" uuid="{fec82be4-22c7-47c0-9f88-03e4aa98453b}" frame="false" Valignment="AlignTop" z="5" Halignment="AlignLeft" x="-24" rotation="0" text_width="-1" text_from="ElementInfo" y="9">
|
||||
<text></text>
|
||||
</dynamic_text>
|
||||
<polygon x2="-22" x3="-16" y1="20" y2="10" antialias="true" y3="-10" closed="false" x1="-22" style="line-style:normal;line-weight:normal;filling:none;color:black"/>
|
||||
<line x2="28" length1="1.5" y1="0" y2="0" length2="1.5" antialias="false" end1="none" end2="none" x1="-23" style="line-style:dashed;line-weight:thin;filling:none;color:black"/>
|
||||
<line x2="-22" length1="1.5" y1="-20" y2="-9" length2="1.5" antialias="false" end1="none" end2="none" x1="-22" style="line-style:normal;line-weight:normal;filling:none;color:black"/>
|
||||
<polygon x2="25" x3="19" y1="20" y2="10" antialias="true" y3="-10" closed="false" x1="25" style="line-style:normal;line-weight:normal;filling:none;color:black"/>
|
||||
<line x2="25" length1="1.5" y1="-20" y2="-9" length2="1.5" antialias="false" end1="none" end2="none" x1="25" style="line-style:normal;line-weight:normal;filling:none;color:black"/>
|
||||
<dynamic_text font="Sans Serif,9,-1,5,50,0,0,0,0,0" uuid="{710338b0-9eaa-4d59-83d7-04c5d943f372}" frame="false" Valignment="AlignTop" z="12" Halignment="AlignLeft" x="-16" rotation="0" text_width="-1" text_from="ElementInfo" y="-7.8334">
|
||||
<text></text>
|
||||
<info_name>label</info_name>
|
||||
</dynamic_text>
|
||||
<terminal uuid="{d0344bb5-2bee-4b7e-a546-3d1e93cc6c6e}" name="" x="-22" orientation="n" y="-20"/>
|
||||
<terminal uuid="{e5ce146b-8ee7-4911-8b16-3df6e5db95f7}" name="" x="25" orientation="s" y="20"/>
|
||||
<terminal uuid="{cb1c6234-2e2b-4182-a41e-0bd903308857}" name="" x="25" orientation="n" y="-20"/>
|
||||
<terminal uuid="{4c78277d-8476-4fb2-9ca3-49c4e85e6dd3}" name="" x="-22" orientation="s" y="20"/>
|
||||
</description>
|
||||
</definition>
|
||||
@@ -14,7 +14,7 @@
|
||||
<kindInformations>
|
||||
<kindInformation show="1" name="type">commutator</kindInformation>
|
||||
</kindInformations>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<polygon style="line-style:normal;line-weight:normal;filling:none;color:black" antialias="true" y3="-10" y2="10" closed="false" x2="30" x3="24" x1="30" y1="20"/>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<kindInformations>
|
||||
<kindInformation show="1" name="type">commutator</kindInformation>
|
||||
</kindInformations>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<polygon y1="20" y3="-10" x3="36" antialias="true" x2="30" y2="10" x1="30" closed="false" style="line-style:normal;line-weight:normal;filling:none;color:black"/>
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
<definition hotspot_x="34" type="element" version="0.90" link_type="simple" width="190" height="60" hotspot_y="30">
|
||||
<uuid uuid="{1493c806-dd66-4b97-8f60-7fe6805d7364}"/>
|
||||
<names>
|
||||
<name lang="fr">Commutateur à 3 positions A/0/M </name>
|
||||
</names>
|
||||
<elementInformations>
|
||||
<elementInformation name="designation" show="1"></elementInformation>
|
||||
<elementInformation name="unity" show="1"></elementInformation>
|
||||
<elementInformation name="manufacturer_reference" show="1"></elementInformation>
|
||||
<elementInformation name="supplier" show="1"></elementInformation>
|
||||
<elementInformation name="label" show="1"></elementInformation>
|
||||
<elementInformation name="description" show="1"></elementInformation>
|
||||
<elementInformation name="manufacturer" show="1"></elementInformation>
|
||||
<elementInformation name="quantity" show="1"></elementInformation>
|
||||
<elementInformation name="comment" show="1"></elementInformation>
|
||||
<elementInformation name="plant" show="1"></elementInformation>
|
||||
<elementInformation name="machine_manufacturer_reference" show="1"></elementInformation>
|
||||
</elementInformations>
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<text x="-22" color="#000000" text="0" y="-6" font="Sans Serif,2,-1,5,50,0,0,0,0,0" rotation="0"/>
|
||||
<polygon x3="150" x1="145" y1="-10" y2="10" style="line-style:normal;line-weight:normal;filling:none;color:black" y3="20" closed="false" antialias="true" x2="150"/>
|
||||
<text x="-19" color="#000000" text="I" y="-6" font="Sans Serif,2,-1,5,50,0,0,0,0,0" rotation="0"/>
|
||||
<line end1="none" length1="1.5" x1="150" y1="-20" y2="-10" style="line-style:normal;line-weight:normal;filling:none;color:black" end2="none" length2="1.5" antialias="false" x2="150"/>
|
||||
<polygon x3="50" x1="45" y1="-10" y2="10" style="line-style:normal;line-weight:normal;filling:none;color:black" y3="20" closed="false" antialias="true" x2="50"/>
|
||||
<text x="-10" color="#000000" text="III" y="-6" font="Sans Serif,2,-1,5,50,0,0,0,0,0" rotation="0"/>
|
||||
<polygon x3="100" x1="95" y1="-10" y2="10" style="line-style:normal;line-weight:normal;filling:none;color:black" y3="20" closed="false" antialias="true" x2="100"/>
|
||||
<line end1="none" length1="1.5" x1="50" y1="-20" y2="-10" style="line-style:normal;line-weight:normal;filling:none;color:black" end2="none" length2="1.5" antialias="false" x2="50"/>
|
||||
<line end1="none" length1="1.5" x1="100" y1="-20" y2="-10" style="line-style:normal;line-weight:normal;filling:none;color:black" end2="none" length2="1.5" antialias="false" x2="100"/>
|
||||
<line end1="none" length1="1.5" x1="-15" y1="5" y2="-5" style="line-style:dashed;line-weight:thin;filling:none;color:black" end2="none" length2="1.5" antialias="false" x2="-9"/>
|
||||
<line end1="none" length1="1.5" x1="-21" y1="-5" y2="5" style="line-style:dashed;line-weight:thin;filling:none;color:black" end2="none" length2="1.5" antialias="false" x2="-15"/>
|
||||
<line end1="none" length1="1.5" x1="147" y1="0" y2="0" style="line-style:dashed;line-weight:thin;filling:none;color:black" end2="none" length2="1.5" antialias="false" x2="-23.0136"/>
|
||||
<text x="-14" color="#000000" text="II" y="-6" font="Sans Serif,2,-1,5,50,0,0,0,0,0" rotation="0"/>
|
||||
<dynamic_text x="160" text_width="-1" y="-10" Valignment="AlignTop" font="Sans Serif,9,-1,5,50,0,0,0,0,0" text_from="ElementInfo" z="13" rotation="0" frame="false" uuid="{f223e627-8712-4f6f-9c88-ec96bed2375e}" Halignment="AlignLeft">
|
||||
<text></text>
|
||||
<info_name>label</info_name>
|
||||
</dynamic_text>
|
||||
<polygon x3="-27" x1="-24" y1="-5" y2="-5" style="line-style:normal;line-weight:thin;filling:none;color:black" x4="-30" y4="5" y3="5" closed="false" antialias="false" x2="-27"/>
|
||||
<polygon x3="0" x1="-5" y1="-10" y2="10" style="line-style:normal;line-weight:normal;filling:none;color:black" y3="20" closed="false" antialias="true" x2="0"/>
|
||||
<line end1="none" length1="1.5" x1="0" y1="-20" y2="-10" style="line-style:normal;line-weight:normal;filling:none;color:black" end2="none" length2="1.5" antialias="false" x2="0"/>
|
||||
<line end1="none" length1="1.5" x1="-15" y1="5" y2="-6" style="line-style:normal;line-weight:thin;filling:none;color:black" end2="none" length2="1.5" antialias="false" x2="-18"/>
|
||||
<line end1="none" length1="1.5" x1="-13" y1="-6" y2="5" style="line-style:normal;line-weight:thin;filling:none;color:black" end2="none" length2="1.5" antialias="false" x2="-15"/>
|
||||
<terminal x="0" name="" orientation="s" type="Generic" y="21" uuid="{80d55e51-fb45-4e4b-9321-113e221eb3fb}"/>
|
||||
<terminal x="150" name="" orientation="s" type="Generic" y="21" uuid="{35246de8-5510-4491-ac36-9f168d0f2c67}"/>
|
||||
<terminal x="100" name="" orientation="s" type="Generic" y="21" uuid="{276a6a53-a111-4c37-bd44-62a391f3790d}"/>
|
||||
<terminal x="0" name="" orientation="n" type="Generic" y="-21" uuid="{98679cb1-c7aa-472f-8fba-2176b61cdb84}"/>
|
||||
<terminal x="50" name="" orientation="s" type="Generic" y="21" uuid="{e8f43154-6943-4015-b5cf-d7cff3a3bf59}"/>
|
||||
<terminal x="150" name="" orientation="n" type="Generic" y="-22" uuid="{b7eafdd7-085a-4b99-961c-5518e9f89a89}"/>
|
||||
<terminal x="50" name="" orientation="n" type="Generic" y="-21" uuid="{73d98523-0345-48f2-a752-89d6f99646c0}"/>
|
||||
<terminal x="100" name="" orientation="n" type="Generic" y="-21" uuid="{ecb47209-ebde-4018-9bfb-234a6719c1ab}"/>
|
||||
</description>
|
||||
</definition>
|
||||
@@ -11,7 +11,7 @@
|
||||
<name lang="es">Interruptor de 3 posiciones</name>
|
||||
</names>
|
||||
<elementInformations/>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<line end1="none" x1="47" x2="23" end2="none" length1="1.5" length2="1.5" antialias="false" y1="0" style="line-style:dashed;line-weight:thin;filling:none;color:black" y2="0"/>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<kindInformations>
|
||||
<kindInformation name="type" show="1">commutator</kindInformation>
|
||||
</kindInformations>
|
||||
<informations>Author: The QElectroTech team
|
||||
<informations>Author: The QElectroTech team
|
||||
License: see http://qelectrotech.org/wiki/doc/elements_license</informations>
|
||||
<description>
|
||||
<line x2="7" y2="-3" length1="1.5" style="line-style:dashed;line-weight:thin;filling:none;color:black" end1="none" x1="3" end2="none" length2="1.5" antialias="true" y1="3"/>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user