Compare commits
69 Commits
221e0bc8c2
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 911f169b5e | |||
| 884e8e903e | |||
|
|
0b54793b08 | ||
|
|
b05180f575 | ||
|
|
c3e5092845 | ||
|
|
60706e5e52 | ||
|
|
b9f515950a | ||
| 075aadc665 | |||
| 5db2677d76 | |||
| b40f3cbd14 | |||
|
|
842129931f | ||
| 43508cd698 | |||
| 0389f98ba6 | |||
| c8a088173f | |||
|
|
2192910e8e | ||
|
|
f99c96a855 | ||
| 3410583931 | |||
|
|
0ea9ce2e0f | ||
|
|
afe8588cd3 | ||
|
|
7993247027 | ||
|
|
5a71884cfb | ||
| 1bb800f1e7 | |||
|
|
7647b01d62 | ||
| 37fcc5e888 | |||
|
|
ab4abd214e | ||
| 07c235afa2 | |||
|
|
4f44c588fa | ||
|
|
0d802fcec3 | ||
|
|
8639529bbe | ||
| 4309d2231e | |||
| 093b90fab6 | |||
| 6aec85418a | |||
| c6c058279a | |||
| 291695bcb9 | |||
|
|
95dd9d18e6 | ||
| beae1c1b3d | |||
|
|
c0ce6a81e3 | ||
| 9b1a1233f9 | |||
| 5c919e4d55 | |||
| 25e752e83b | |||
| 9c35c9ea42 | |||
| 6232b560b5 | |||
| d3c62335b1 | |||
| 7780657d82 | |||
| aa4b2a1b84 | |||
| cb553cf928 | |||
| dc3669f513 | |||
| 9f0382965f | |||
| 653aa49a7b | |||
| 2547ed6e1c | |||
| c81c38f780 | |||
| 1fc551d7d1 | |||
| 53b4d6e041 | |||
| 95765226e9 | |||
| d6da7aac9a | |||
| 6b03797600 | |||
|
|
f19a33cc5f | ||
| c40f288aaa | |||
| 23695bc7ef | |||
|
|
3bdc491830 | ||
| 7d43b0a694 | |||
| 407e2e41ed | |||
| 398d50c45c | |||
| 4dd278dbf7 | |||
| be44a70a57 | |||
| a325cc3826 | |||
| 6f5b8d8df6 | |||
| 50c82bca43 | |||
| a8a947ff0b |
48
.gitignore
vendored
48
.gitignore
vendored
@@ -1,22 +1,26 @@
|
|||||||
BionxControl.pro.user
|
BionxControl.pro.user
|
||||||
build/
|
build/
|
||||||
bcvalue.cpp.autosave
|
bcvalue.cpp.autosave
|
||||||
.qtcreator/BionxControl.pro.user
|
.qtcreator/BionxControl.pro.user
|
||||||
.user
|
.user
|
||||||
|
|
||||||
# Objektdateien ignorieren
|
# Objektdateien ignorieren
|
||||||
*.o
|
*.o
|
||||||
|
|
||||||
.qtc_clangd/
|
.qtc_clangd/
|
||||||
|
|
||||||
# Von Qt generierte MOC-Dateien (Meta-Object Compiler) ignorieren
|
# Von Qt generierte MOC-Dateien (Meta-Object Compiler) ignorieren
|
||||||
moc_*
|
moc_*
|
||||||
|
|
||||||
# Von Qt generierte Ressourcen-Dateien ignorieren
|
# Von Qt generierte Ressourcen-Dateien ignorieren
|
||||||
qrc_*
|
qrc_*
|
||||||
|
|
||||||
BionxControl
|
BionxControl
|
||||||
Makefile
|
Makefile
|
||||||
ui_*
|
ui_*
|
||||||
|
|
||||||
.qmake.stash
|
.qmake.stash
|
||||||
|
.vs/
|
||||||
|
debug/
|
||||||
|
release/
|
||||||
|
BionxControl.qtvscr
|
||||||
|
|||||||
226
.qtcreator/BionxControl.pro.user.23a63a0
Normal file
226
.qtcreator/BionxControl.pro.user.23a63a0
Normal file
@@ -0,0 +1,226 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE QtCreatorProject>
|
||||||
|
<!-- Written by QtCreator 19.0.0, 2026-04-01T10:25:51. -->
|
||||||
|
<qtcreator>
|
||||||
|
<data>
|
||||||
|
<variable>EnvironmentId</variable>
|
||||||
|
<value type="QByteArray">{23a63a0b-7f48-446f-a5f4-d5b7f38a6fae}</value>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.ActiveTarget</variable>
|
||||||
|
<value type="qlonglong">0</value>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.EditorSettings</variable>
|
||||||
|
<valuemap type="QVariantMap">
|
||||||
|
<value type="bool" key="EditorConfiguration.AutoDetect">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
|
||||||
|
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
|
||||||
|
<value type="QString" key="language">Cpp</value>
|
||||||
|
<valuemap type="QVariantMap" key="value">
|
||||||
|
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
|
||||||
|
</valuemap>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
|
||||||
|
<value type="QString" key="language">QmlJS</value>
|
||||||
|
<valuemap type="QVariantMap" key="value">
|
||||||
|
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
|
||||||
|
</valuemap>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="EditorConfiguration.CodeStyle.Count">2</value>
|
||||||
|
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
|
||||||
|
<value type="int" key="EditorConfiguration.IndentSize">4</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
|
||||||
|
<value type="int" key="EditorConfiguration.LineEndingBehavior">0</value>
|
||||||
|
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
|
||||||
|
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
|
||||||
|
<value type="int" key="EditorConfiguration.PreferAfterWhitespaceComments">0</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.PreferSingleLineComments">false</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
|
||||||
|
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">2</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
|
||||||
|
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
|
||||||
|
<value type="int" key="EditorConfiguration.TabSize">8</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.UseIndenter">false</value>
|
||||||
|
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.addFinalNewLine">false</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
|
||||||
|
<value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.tintMarginArea">true</value>
|
||||||
|
</valuemap>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.PluginSettings</variable>
|
||||||
|
<valuemap type="QVariantMap">
|
||||||
|
<valuemap type="QVariantMap" key="AutoTest.ActiveFrameworks">
|
||||||
|
<value type="bool" key="AutoTest.Framework.Boost">true</value>
|
||||||
|
<value type="bool" key="AutoTest.Framework.CTest">false</value>
|
||||||
|
<value type="bool" key="AutoTest.Framework.Catch">true</value>
|
||||||
|
<value type="bool" key="AutoTest.Framework.GTest">true</value>
|
||||||
|
<value type="bool" key="AutoTest.Framework.QtQuickTest">true</value>
|
||||||
|
<value type="bool" key="AutoTest.Framework.QtTest">true</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="bool" key="AutoTest.ApplyFilter">false</value>
|
||||||
|
<valuemap type="QVariantMap" key="AutoTest.CheckStates"/>
|
||||||
|
<valuelist type="QVariantList" key="AutoTest.PathFilters"/>
|
||||||
|
<value type="int" key="AutoTest.RunAfterBuild">0</value>
|
||||||
|
<value type="bool" key="AutoTest.UseGlobal">true</value>
|
||||||
|
<valuemap type="QVariantMap" key="ClangTools">
|
||||||
|
<value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value>
|
||||||
|
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
|
||||||
|
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value>
|
||||||
|
<value type="int" key="ClangTools.ParallelJobs">8</value>
|
||||||
|
<value type="bool" key="ClangTools.PreferConfigFile">true</value>
|
||||||
|
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
|
||||||
|
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
|
||||||
|
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
|
||||||
|
<value type="bool" key="ClangTools.UseGlobalSettings">true</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="RcSync">0</value>
|
||||||
|
</valuemap>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.Target.0</variable>
|
||||||
|
<valuemap type="QVariantMap">
|
||||||
|
<value type="QString" key="DeviceType">Desktop</value>
|
||||||
|
<value type="bool" key="HasPerBcDcs">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{fad1a024-ac8c-47cf-928f-6229932645bf}</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||||
|
<value type="int" key="EnableQmlDebugging">0</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">./build/%{Asciify:%{Kit:FileSystemName}-%{BuildConfig:Name}}</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">build/Desktop-Debug</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
||||||
|
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
||||||
|
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||||
|
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||||
|
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
|
||||||
|
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||||
|
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||||
|
<valuelist type="QVariantList" key="Analyzer.Valgrind.SuppressionFiles"/>
|
||||||
|
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
||||||
|
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||||
|
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||||
|
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
||||||
|
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph dwarf,4096 -F 250</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">/mnt/c/projects/BionxControl/BionxControl.pro</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.UniqueId"></value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||||
|
<value type="QString" key="RunConfiguration.WorkingDirectory.default">%{RunConfig:Executable:Path}</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
||||||
|
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||||
|
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||||
|
<valuelist type="QVariantList" key="Analyzer.Valgrind.SuppressionFiles"/>
|
||||||
|
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
||||||
|
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||||
|
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||||
|
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
||||||
|
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph dwarf,4096 -F 250</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">/mnt/c/projects/BionxControl/BionxControl.pro</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.UniqueId"></value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||||
|
<value type="QString" key="RunConfiguration.WorkingDirectory.default">%{RunConfig:Executable:Path}</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
||||||
|
</valuemap>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.TargetCount</variable>
|
||||||
|
<value type="qlonglong">1</value>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>Version</variable>
|
||||||
|
<value type="int">22</value>
|
||||||
|
</data>
|
||||||
|
</qtcreator>
|
||||||
860
.qtcreator/BionxControl.pro.user.628da39
Normal file
860
.qtcreator/BionxControl.pro.user.628da39
Normal file
@@ -0,0 +1,860 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE QtCreatorProject>
|
||||||
|
<!-- Written by QtCreator 19.0.0, 2026-03-30T17:25:48. -->
|
||||||
|
<qtcreator>
|
||||||
|
<data>
|
||||||
|
<variable>EnvironmentId</variable>
|
||||||
|
<value type="QByteArray">{628da395-74db-4105-8489-c4b4db698d13}</value>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.ActiveTarget</variable>
|
||||||
|
<value type="qlonglong">0</value>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.EditorSettings</variable>
|
||||||
|
<valuemap type="QVariantMap">
|
||||||
|
<value type="bool" key="EditorConfiguration.AutoDetect">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
|
||||||
|
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
|
||||||
|
<value type="QString" key="language">Cpp</value>
|
||||||
|
<valuemap type="QVariantMap" key="value">
|
||||||
|
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
|
||||||
|
</valuemap>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
|
||||||
|
<value type="QString" key="language">QmlJS</value>
|
||||||
|
<valuemap type="QVariantMap" key="value">
|
||||||
|
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
|
||||||
|
</valuemap>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="EditorConfiguration.CodeStyle.Count">2</value>
|
||||||
|
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
|
||||||
|
<value type="int" key="EditorConfiguration.IndentSize">4</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
|
||||||
|
<value type="int" key="EditorConfiguration.LineEndingBehavior">0</value>
|
||||||
|
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
|
||||||
|
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
|
||||||
|
<value type="int" key="EditorConfiguration.PreferAfterWhitespaceComments">0</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.PreferSingleLineComments">false</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
|
||||||
|
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">2</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
|
||||||
|
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
|
||||||
|
<value type="int" key="EditorConfiguration.TabSize">8</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.UseIndenter">false</value>
|
||||||
|
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
|
||||||
|
<value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.tintMarginArea">true</value>
|
||||||
|
</valuemap>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.PluginSettings</variable>
|
||||||
|
<valuemap type="QVariantMap">
|
||||||
|
<valuemap type="QVariantMap" key="AutoTest.ActiveFrameworks">
|
||||||
|
<value type="bool" key="AutoTest.Framework.Boost">true</value>
|
||||||
|
<value type="bool" key="AutoTest.Framework.CTest">false</value>
|
||||||
|
<value type="bool" key="AutoTest.Framework.Catch">true</value>
|
||||||
|
<value type="bool" key="AutoTest.Framework.GTest">true</value>
|
||||||
|
<value type="bool" key="AutoTest.Framework.QtQuickTest">true</value>
|
||||||
|
<value type="bool" key="AutoTest.Framework.QtTest">true</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="bool" key="AutoTest.ApplyFilter">false</value>
|
||||||
|
<valuemap type="QVariantMap" key="AutoTest.CheckStates"/>
|
||||||
|
<valuelist type="QVariantList" key="AutoTest.PathFilters"/>
|
||||||
|
<value type="int" key="AutoTest.RunAfterBuild">0</value>
|
||||||
|
<value type="bool" key="AutoTest.UseGlobal">true</value>
|
||||||
|
<valuemap type="QVariantMap" key="ClangTools">
|
||||||
|
<value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value>
|
||||||
|
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
|
||||||
|
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value>
|
||||||
|
<value type="int" key="ClangTools.ParallelJobs">8</value>
|
||||||
|
<value type="bool" key="ClangTools.PreferConfigFile">true</value>
|
||||||
|
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
|
||||||
|
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
|
||||||
|
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
|
||||||
|
<value type="bool" key="ClangTools.UseGlobalSettings">true</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="RcSync">0</value>
|
||||||
|
</valuemap>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.Target.0</variable>
|
||||||
|
<valuemap type="QVariantMap">
|
||||||
|
<value type="QString" key="DeviceType">Desktop</value>
|
||||||
|
<value type="bool" key="HasPerBcDcs">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 6.11.0 MinGW 64-bit</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 6.11.0 MinGW 64-bit</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt6.6110.win64_mingw_kit</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||||
|
<value type="int" key="EnableQmlDebugging">0</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">C:\projects\BionxControl\build\Desktop_Qt_6_11_0_MinGW_64_bit-Debug</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">C:/projects/BionxControl/build/Desktop_Qt_6_11_0_MinGW_64_bit-Debug</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
||||||
|
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
||||||
|
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||||
|
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||||
|
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
|
||||||
|
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||||
|
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||||
|
<valuelist type="QVariantList" key="Analyzer.Valgrind.SuppressionFiles"/>
|
||||||
|
<value type="QList<int>" key="Analyzer.Valgrind.VisibleErrorKinds"></value>
|
||||||
|
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
||||||
|
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||||
|
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||||
|
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
||||||
|
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph "dwarf,4096" -F 250</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">C:/projects/BionxControl/BionxControl.pro</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.UniqueId"></value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||||
|
<value type="QString" key="RunConfiguration.WorkingDirectory.default">%{RunConfig:Executable:Path}</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
||||||
|
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||||
|
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||||
|
<valuelist type="QVariantList" key="Analyzer.Valgrind.SuppressionFiles"/>
|
||||||
|
<value type="QList<int>" key="Analyzer.Valgrind.VisibleErrorKinds"></value>
|
||||||
|
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
||||||
|
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||||
|
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||||
|
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
||||||
|
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph "dwarf,4096" -F 250</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">C:/projects/BionxControl/BionxControl.pro</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.UniqueId"></value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||||
|
<value type="QString" key="RunConfiguration.WorkingDirectory.default">%{RunConfig:Executable:Path}</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
||||||
|
</valuemap>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.Target.1</variable>
|
||||||
|
<valuemap type="QVariantMap">
|
||||||
|
<value type="QString" key="DeviceType">Desktop</value>
|
||||||
|
<value type="bool" key="HasPerBcDcs">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 6.11.0 MSVC2022 64bit</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 6.11.0 MSVC2022 64bit</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt6.6110.win64_msvc2022_64_kit</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||||
|
<value type="int" key="EnableQmlDebugging">0</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">C:\projects\BionxControl\build\Desktop_Qt_6_11_0_MSVC2022_64bit-Debug</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">C:/projects/BionxControl/build/Desktop_Qt_6_11_0_MSVC2022_64bit-Debug</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
||||||
|
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
||||||
|
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||||
|
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||||
|
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
|
||||||
|
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||||
|
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||||
|
<valuelist type="QVariantList" key="Analyzer.Valgrind.SuppressionFiles"/>
|
||||||
|
<value type="QList<int>" key="Analyzer.Valgrind.VisibleErrorKinds"></value>
|
||||||
|
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
||||||
|
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||||
|
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||||
|
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
||||||
|
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph "dwarf,4096" -F 250</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">C:/projects/BionxControl/BionxControl.pro</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.UniqueId"></value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||||
|
<value type="QString" key="RunConfiguration.WorkingDirectory.default">%{RunConfig:Executable:Path}</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
||||||
|
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||||
|
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||||
|
<valuelist type="QVariantList" key="Analyzer.Valgrind.SuppressionFiles"/>
|
||||||
|
<value type="QList<int>" key="Analyzer.Valgrind.VisibleErrorKinds"></value>
|
||||||
|
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
||||||
|
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||||
|
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||||
|
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
||||||
|
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph "dwarf,4096" -F 250</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">C:/projects/BionxControl/BionxControl.pro</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.UniqueId"></value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||||
|
<value type="QString" key="RunConfiguration.WorkingDirectory.default">%{RunConfig:Executable:Path}</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
||||||
|
</valuemap>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.Target.2</variable>
|
||||||
|
<valuemap type="QVariantMap">
|
||||||
|
<value type="QString" key="DeviceType">Desktop</value>
|
||||||
|
<value type="bool" key="HasPerBcDcs">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 6.11.0 llvm-mingw 64-bit</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 6.11.0 llvm-mingw 64-bit</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt6.6110.win64_llvm_mingw_kit</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||||
|
<value type="int" key="EnableQmlDebugging">0</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">C:\projects\BionxControl\build\Desktop_Qt_6_11_0_llvm_mingw_64_bit-Debug</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">C:/projects/BionxControl/build/Desktop_Qt_6_11_0_llvm_mingw_64_bit-Debug</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
||||||
|
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
||||||
|
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||||
|
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||||
|
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
|
||||||
|
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||||
|
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||||
|
<valuelist type="QVariantList" key="Analyzer.Valgrind.SuppressionFiles"/>
|
||||||
|
<value type="QList<int>" key="Analyzer.Valgrind.VisibleErrorKinds"></value>
|
||||||
|
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
||||||
|
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||||
|
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||||
|
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
||||||
|
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph "dwarf,4096" -F 250</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
|
||||||
|
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.UniqueId"></value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||||
|
<value type="QString" key="RunConfiguration.WorkingDirectory.default">%{RunConfig:Executable:Path}</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
||||||
|
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||||
|
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||||
|
<valuelist type="QVariantList" key="Analyzer.Valgrind.SuppressionFiles"/>
|
||||||
|
<value type="QList<int>" key="Analyzer.Valgrind.VisibleErrorKinds"></value>
|
||||||
|
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
||||||
|
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||||
|
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||||
|
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
||||||
|
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph "dwarf,4096" -F 250</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
|
||||||
|
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.UniqueId"></value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||||
|
<value type="QString" key="RunConfiguration.WorkingDirectory.default">%{RunConfig:Executable:Path}</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
||||||
|
</valuemap>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.Target.3</variable>
|
||||||
|
<valuemap type="QVariantMap">
|
||||||
|
<value type="QString" key="DeviceType">Desktop</value>
|
||||||
|
<value type="bool" key="HasPerBcDcs">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 6.10.1 MinGW 64-bit</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 6.10.1 MinGW 64-bit</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt6.6101.win64_mingw_kit</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||||
|
<value type="int" key="EnableQmlDebugging">0</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">C:\projects\BionxControl\build\Desktop_Qt_6_10_1_MinGW_64_bit-Debug</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">C:/projects/BionxControl/build/Desktop_Qt_6_10_1_MinGW_64_bit-Debug</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
||||||
|
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
||||||
|
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||||
|
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||||
|
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
|
||||||
|
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||||
|
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="QList<int>" key="Analyzer.Valgrind.VisibleErrorKinds"></value>
|
||||||
|
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
||||||
|
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||||
|
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||||
|
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
||||||
|
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph "dwarf,4096" -F 250</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">C:/projects/BionxControl/BionxControl.pro</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.UniqueId"></value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||||
|
<value type="QString" key="RunConfiguration.WorkingDirectory.default">%{RunConfig:Executable:Path}</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
||||||
|
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||||
|
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="QList<int>" key="Analyzer.Valgrind.VisibleErrorKinds"></value>
|
||||||
|
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
||||||
|
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||||
|
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||||
|
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
||||||
|
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph "dwarf,4096" -F 250</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">C:/projects/BionxControl/BionxControl.pro</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.UniqueId"></value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||||
|
<value type="QString" key="RunConfiguration.WorkingDirectory.default">%{RunConfig:Executable:Path}</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
||||||
|
</valuemap>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.Target.4</variable>
|
||||||
|
<valuemap type="QVariantMap">
|
||||||
|
<value type="QString" key="DeviceType">Desktop</value>
|
||||||
|
<value type="bool" key="HasPerBcDcs">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 6.10.1 llvm-mingw 64-bit</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 6.10.1 llvm-mingw 64-bit</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt6.6101.win64_llvm_mingw_kit</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||||
|
<value type="int" key="EnableQmlDebugging">0</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">C:\projects\BionxControl\build\Desktop_Qt_6_10_1_llvm_mingw_64_bit-Debug</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">C:/projects/BionxControl/build/Desktop_Qt_6_10_1_llvm_mingw_64_bit-Debug</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
||||||
|
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
||||||
|
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||||
|
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||||
|
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
|
||||||
|
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||||
|
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="QList<int>" key="Analyzer.Valgrind.VisibleErrorKinds"></value>
|
||||||
|
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
||||||
|
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||||
|
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||||
|
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
||||||
|
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph "dwarf,4096" -F 250</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">C:/projects/BionxControl/BionxControl.pro</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.UniqueId"></value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||||
|
<value type="QString" key="RunConfiguration.WorkingDirectory.default">%{RunConfig:Executable:Path}</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
||||||
|
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||||
|
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="QList<int>" key="Analyzer.Valgrind.VisibleErrorKinds"></value>
|
||||||
|
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
||||||
|
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||||
|
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||||
|
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
||||||
|
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph "dwarf,4096" -F 250</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">C:/projects/BionxControl/BionxControl.pro</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.UniqueId"></value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||||
|
<value type="QString" key="RunConfiguration.WorkingDirectory.default">%{RunConfig:Executable:Path}</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
||||||
|
</valuemap>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.Target.5</variable>
|
||||||
|
<valuemap type="QVariantMap">
|
||||||
|
<value type="QString" key="DeviceType">Desktop</value>
|
||||||
|
<value type="bool" key="HasPerBcDcs">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 6.10.1 MSVC2022 64bit</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 6.10.1 MSVC2022 64bit</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt6.6101.win64_msvc2022_64_kit</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||||
|
<value type="int" key="EnableQmlDebugging">0</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">C:\projects\BionxControl\build\Desktop_Qt_6_10_1_MSVC2022_64bit-Debug</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">C:/projects/BionxControl/build/Desktop_Qt_6_10_1_MSVC2022_64bit-Debug</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
||||||
|
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
||||||
|
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||||
|
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||||
|
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
|
||||||
|
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||||
|
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="QList<int>" key="Analyzer.Valgrind.VisibleErrorKinds"></value>
|
||||||
|
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
||||||
|
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||||
|
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||||
|
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
||||||
|
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph "dwarf,4096" -F 250</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">C:/projects/BionxControl/BionxControl.pro</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.UniqueId"></value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||||
|
<value type="QString" key="RunConfiguration.WorkingDirectory.default">%{RunConfig:Executable:Path}</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
||||||
|
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||||
|
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="QList<int>" key="Analyzer.Valgrind.VisibleErrorKinds"></value>
|
||||||
|
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
||||||
|
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||||
|
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||||
|
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
||||||
|
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph "dwarf,4096" -F 250</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">C:/projects/BionxControl/BionxControl.pro</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.UniqueId"></value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||||
|
<value type="QString" key="RunConfiguration.WorkingDirectory.default">%{RunConfig:Executable:Path}</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
||||||
|
</valuemap>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.TargetCount</variable>
|
||||||
|
<value type="qlonglong">6</value>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>Version</variable>
|
||||||
|
<value type="int">22</value>
|
||||||
|
</data>
|
||||||
|
</qtcreator>
|
||||||
@@ -1,60 +1,31 @@
|
|||||||
QT += core gui svg
|
QT += core gui svg widgets
|
||||||
|
|
||||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
|
||||||
|
|
||||||
CONFIG += c++23
|
CONFIG += c++23
|
||||||
|
|
||||||
QMAKE_CXXFLAGS += -std=c++23
|
|
||||||
|
|
||||||
# You can make your code fail to compile if it uses deprecated APIs.
|
# You can make your code fail to compile if it uses deprecated APIs.
|
||||||
# In order to do so, uncomment the following line.
|
# In order to do so, uncomment the following line.
|
||||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||||
|
|
||||||
INCLUDEPATH += . libwin
|
INCLUDEPATH += . libwin
|
||||||
|
|
||||||
linux:contains(QT_ARCH, arm.*)
|
|
||||||
{
|
|
||||||
message("Konfiguration für Raspberry Pi (ARM) erkannt.")
|
|
||||||
|
|
||||||
# 1. Header-Dateien (z.B. für bcm2835.h oder eigene Treiber)
|
|
||||||
#INCLUDEPATH += /usr/local/include \
|
|
||||||
# /home/pi/my_custom_drivers/include
|
|
||||||
|
|
||||||
# not used at the moment
|
|
||||||
# 2. Bibliotheken linken
|
|
||||||
# -L sagt dem Linker WO er suchen soll
|
|
||||||
# -l sagt dem Linker WAS er nehmen soll (z.B. libwiringPi.so -> -lwiringPi)
|
|
||||||
#LIBS += -L/usr/lib \
|
|
||||||
# -lmhstcan
|
|
||||||
|
|
||||||
|
|
||||||
# Optional: Spezielle Compiler-Flags für den Pi (Optimierung)
|
|
||||||
#QMAKE_CXXFLAGS += -O3
|
|
||||||
}
|
|
||||||
|
|
||||||
li
|
|
||||||
|
|
||||||
windows
|
|
||||||
{
|
|
||||||
#LIBS += -L$$PWD/can_api -lmhstcan -lAdvapi32
|
|
||||||
}
|
|
||||||
|
|
||||||
# You can make your code fail to compile if it uses deprecated APIs.
|
# You can make your code fail to compile if it uses deprecated APIs.
|
||||||
# In order to do so, uncomment the following line.
|
# In order to do so, uncomment the following line.
|
||||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
aalegacy.cpp \
|
|
||||||
bc.cpp \
|
bc.cpp \
|
||||||
bcanimateddelegate.cpp \
|
bcdelightpmwidget.cpp \
|
||||||
bcdeviceview.cpp \
|
bcdeviceview.cpp \
|
||||||
bcdriver.cpp \
|
bcdriver.cpp \
|
||||||
|
bcdriverstatewidget.cpp \
|
||||||
bcdrivertinycan.cpp \
|
bcdrivertinycan.cpp \
|
||||||
bcguihelpers.cpp \
|
bcthemebutton.cpp \
|
||||||
bcsliderstyle.cpp \
|
bctoggleswitch.cpp \
|
||||||
bctransmitter.cpp \
|
bctransmitter.cpp \
|
||||||
bcvalue.cpp \
|
bcvalue.cpp \
|
||||||
|
bcvaluedelegate.cpp \
|
||||||
bcvaluemodel.cpp \
|
bcvaluemodel.cpp \
|
||||||
|
bcvalueslider.cpp \
|
||||||
bcxmlloader.cpp \
|
bcxmlloader.cpp \
|
||||||
libwin/can_drv_win.c \
|
libwin/can_drv_win.c \
|
||||||
libwin/mhs_can_drv.c \
|
libwin/mhs_can_drv.c \
|
||||||
@@ -63,20 +34,24 @@ SOURCES += \
|
|||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
bc.h \
|
bc.h \
|
||||||
bcanimateddelegate.h \
|
bcdelightpmwidget.h \
|
||||||
bcdeviceview.h \
|
bcdeviceview.h \
|
||||||
bcdriver.h \
|
bcdriver.h \
|
||||||
|
bcdriverstatewidget.h \
|
||||||
bcdrivertinycan.h \
|
bcdrivertinycan.h \
|
||||||
bcguihelpers.h \
|
|
||||||
bcmainwindow.h \
|
bcmainwindow.h \
|
||||||
bcsliderstyle.h \
|
bcthemebutton.h \
|
||||||
|
bctoggleswitch.h \
|
||||||
bctransmitter.h \
|
bctransmitter.h \
|
||||||
bcvalue.h \
|
bcvalue.h \
|
||||||
|
bcvaluedelegate.h \
|
||||||
bcvaluemodel.h \
|
bcvaluemodel.h \
|
||||||
|
bcvalueslider.h \
|
||||||
bcxmlloader.h
|
bcxmlloader.h
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
bcmainwindow.ui
|
bcmainwindow.ui \
|
||||||
|
bcvalueslider.ui
|
||||||
|
|
||||||
# Default rules for deployment.
|
# Default rules for deployment.
|
||||||
qnx: target.path = /tmp/$${TARGET}/bin
|
qnx: target.path = /tmp/$${TARGET}/bin
|
||||||
|
|||||||
6
BionxControl.slnx
Normal file
6
BionxControl.slnx
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<Solution>
|
||||||
|
<Configurations>
|
||||||
|
<Platform Name="x64" />
|
||||||
|
</Configurations>
|
||||||
|
<Project Path="BionxControl.vcxproj" Id="84c4d2da-be54-3c31-bef9-6bccdd5c3277" />
|
||||||
|
</Solution>
|
||||||
293
BionxControl.vcxproj
Normal file
293
BionxControl.vcxproj
Normal file
@@ -0,0 +1,293 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{84C4D2DA-BE54-3C31-BEF9-6BCCDD5C3277}</ProjectGuid>
|
||||||
|
<RootNamespace>BionxControl</RootNamespace>
|
||||||
|
<Keyword>QtVS_v304</Keyword>
|
||||||
|
<QtMsBuild Condition="'$(QtMsBuild)'=='' OR !Exists('$(QtMsBuild)\qt.targets')">$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<PlatformToolset>v145</PlatformToolset>
|
||||||
|
<OutputDirectory>release\</OutputDirectory>
|
||||||
|
<ATLMinimizesCRunTimeLibraryUsage>false</ATLMinimizesCRunTimeLibraryUsage>
|
||||||
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<IntermediateDirectory>release\</IntermediateDirectory>
|
||||||
|
<PrimaryOutput>BionxControl</PrimaryOutput>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<PlatformToolset>v145</PlatformToolset>
|
||||||
|
<OutputDirectory>debug\</OutputDirectory>
|
||||||
|
<ATLMinimizesCRunTimeLibraryUsage>false</ATLMinimizesCRunTimeLibraryUsage>
|
||||||
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<IntermediateDirectory>debug\</IntermediateDirectory>
|
||||||
|
<PrimaryOutput>BionxControl</PrimaryOutput>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<Import Project="$(QtMsBuild)\qt_defaults.props" Condition="Exists('$(QtMsBuild)\qt_defaults.props')" />
|
||||||
|
<PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<QtInstall>msvc2022x64Qt6</QtInstall>
|
||||||
|
<QtModules>core;gui;widgets;svg</QtModules>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<QtInstall>msvc2022x64Qt6</QtInstall>
|
||||||
|
<QtModules>core;gui;widgets;svg</QtModules>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Target Name="QtMsBuildNotFound" BeforeTargets="CustomBuild;ClCompile" Condition="!Exists('$(QtMsBuild)\qt.targets') OR !Exists('$(QtMsBuild)\Qt.props')">
|
||||||
|
<Message Importance="High" Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
|
||||||
|
</Target>
|
||||||
|
<ImportGroup Label="ExtensionSettings" />
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
|
||||||
|
<Import Project="$(QtMsBuild)\Qt.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
|
||||||
|
<Import Project="$(QtMsBuild)\Qt.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">release\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">release\</IntDir>
|
||||||
|
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">BionxControl</TargetName>
|
||||||
|
<IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</IgnoreImportLibrary>
|
||||||
|
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">debug\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">debug\</IntDir>
|
||||||
|
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">BionxControl</TargetName>
|
||||||
|
<IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</IgnoreImportLibrary>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalIncludeDirectories>GeneratedFiles\$(ConfigurationName);GeneratedFiles;.;libwin;..\..\Qt\6.11.0\msvc2022_64\include;..\..\Qt\6.11.0\msvc2022_64\include\QtSvg;..\..\Qt\6.11.0\msvc2022_64\include\QtWidgets;..\..\Qt\6.11.0\msvc2022_64\include\QtGui;..\..\Qt\6.11.0\msvc2022_64\include\QtCore;release;/include;..\..\Qt\6.11.0\msvc2022_64\mkspecs\win32-msvc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -permissive- -Zc:__cplusplus -Zc:externConstexpr -utf-8 -w34100 -w34189 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<AssemblerListingLocation>release\</AssemblerListingLocation>
|
||||||
|
<BrowseInformation>false</BrowseInformation>
|
||||||
|
<DebugInformationFormat>None</DebugInformationFormat>
|
||||||
|
<DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||||
|
<ExceptionHandling>Sync</ExceptionHandling>
|
||||||
|
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||||
|
<ObjectFileName>release\</ObjectFileName>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;QT_NO_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<PreprocessToFile>false</PreprocessToFile>
|
||||||
|
<ProgramDataBaseFileName>
|
||||||
|
</ProgramDataBaseFileName>
|
||||||
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
|
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||||
|
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||||
|
<UseFullPaths>false</UseFullPaths>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>C:\Qt\6.11.0\msvc2022_64\lib\Qt6EntryPoint.lib;shell32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<AdditionalOptions>"/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<DataExecutionPrevention>true</DataExecutionPrevention>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||||
|
<IgnoreImportLibrary>true</IgnoreImportLibrary>
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<OutputFile>$(OutDir)\BionxControl.exe</OutputFile>
|
||||||
|
<RandomizedBaseAddress>true</RandomizedBaseAddress>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||||
|
</Link>
|
||||||
|
<Midl>
|
||||||
|
<DefaultCharType>Unsigned</DefaultCharType>
|
||||||
|
<EnableErrorChecks>None</EnableErrorChecks>
|
||||||
|
<WarningLevel>0</WarningLevel>
|
||||||
|
</Midl>
|
||||||
|
<ResourceCompile>
|
||||||
|
<PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;QT_NO_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
</ResourceCompile>
|
||||||
|
<QtMoc>
|
||||||
|
<CompilerFlavor>msvc</CompilerFlavor>
|
||||||
|
<Include>C:/projects/BionxControl/$(Configuration)/moc_predefs.h</Include>
|
||||||
|
<ExecutionDescription>Moc'ing %(Identity)...</ExecutionDescription>
|
||||||
|
<DynamicSource>output</DynamicSource>
|
||||||
|
<QtMocDir>$(Configuration)</QtMocDir>
|
||||||
|
<QtMocFileName>moc_%(Filename).cpp</QtMocFileName>
|
||||||
|
</QtMoc>
|
||||||
|
<QtRcc>
|
||||||
|
<InitFuncName>bionxcontrol</InitFuncName>
|
||||||
|
<Compression>default</Compression>
|
||||||
|
<NoZstd>true</NoZstd>
|
||||||
|
<ExecutionDescription>Rcc'ing %(Identity)...</ExecutionDescription>
|
||||||
|
<QtRccDir>$(Configuration)</QtRccDir>
|
||||||
|
<QtRccFileName>qrc_%(Filename).cpp</QtRccFileName>
|
||||||
|
</QtRcc>
|
||||||
|
<QtUic>
|
||||||
|
<ExecutionDescription>Uic'ing %(Identity)...</ExecutionDescription>
|
||||||
|
<QtUicDir>$(ProjectDir)</QtUicDir>
|
||||||
|
<QtUicFileName>ui_%(Filename).h</QtUicFileName>
|
||||||
|
</QtUic>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalIncludeDirectories>GeneratedFiles\$(ConfigurationName);GeneratedFiles;.;libwin;..\..\Qt\6.11.0\msvc2022_64\include;..\..\Qt\6.11.0\msvc2022_64\include\QtSvg;..\..\Qt\6.11.0\msvc2022_64\include\QtWidgets;..\..\Qt\6.11.0\msvc2022_64\include\QtGui;..\..\Qt\6.11.0\msvc2022_64\include\QtCore;debug;/include;..\..\Qt\6.11.0\msvc2022_64\mkspecs\win32-msvc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -permissive- -Zc:__cplusplus -Zc:externConstexpr -utf-8 -w34100 -w34189 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<AssemblerListingLocation>debug\</AssemblerListingLocation>
|
||||||
|
<BrowseInformation>false</BrowseInformation>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||||
|
<ExceptionHandling>Sync</ExceptionHandling>
|
||||||
|
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||||
|
<ObjectFileName>debug\</ObjectFileName>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<PreprocessToFile>false</PreprocessToFile>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||||
|
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||||
|
<UseFullPaths>false</UseFullPaths>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>C:\Qt\6.11.0\msvc2022_64\lib\Qt6EntryPointd.lib;shell32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<AdditionalOptions>"/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<DataExecutionPrevention>true</DataExecutionPrevention>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<IgnoreImportLibrary>true</IgnoreImportLibrary>
|
||||||
|
<OutputFile>$(OutDir)\BionxControl.exe</OutputFile>
|
||||||
|
<RandomizedBaseAddress>true</RandomizedBaseAddress>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||||
|
</Link>
|
||||||
|
<Midl>
|
||||||
|
<DefaultCharType>Unsigned</DefaultCharType>
|
||||||
|
<EnableErrorChecks>None</EnableErrorChecks>
|
||||||
|
<WarningLevel>0</WarningLevel>
|
||||||
|
</Midl>
|
||||||
|
<ResourceCompile>
|
||||||
|
<PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
</ResourceCompile>
|
||||||
|
<QtMoc>
|
||||||
|
<CompilerFlavor>msvc</CompilerFlavor>
|
||||||
|
<Include>C:/projects/BionxControl/$(Configuration)/moc_predefs.h</Include>
|
||||||
|
<ExecutionDescription>Moc'ing %(Identity)...</ExecutionDescription>
|
||||||
|
<DynamicSource>output</DynamicSource>
|
||||||
|
<QtMocDir>$(Configuration)</QtMocDir>
|
||||||
|
<QtMocFileName>moc_%(Filename).cpp</QtMocFileName>
|
||||||
|
</QtMoc>
|
||||||
|
<QtRcc>
|
||||||
|
<InitFuncName>bionxcontrol</InitFuncName>
|
||||||
|
<Compression>default</Compression>
|
||||||
|
<NoZstd>true</NoZstd>
|
||||||
|
<ExecutionDescription>Rcc'ing %(Identity)...</ExecutionDescription>
|
||||||
|
<QtRccDir>$(Configuration)</QtRccDir>
|
||||||
|
<QtRccFileName>qrc_%(Filename).cpp</QtRccFileName>
|
||||||
|
</QtRcc>
|
||||||
|
<QtUic>
|
||||||
|
<ExecutionDescription>Uic'ing %(Identity)...</ExecutionDescription>
|
||||||
|
<QtUicDir>$(ProjectDir)</QtUicDir>
|
||||||
|
<QtUicFileName>ui_%(Filename).h</QtUicFileName>
|
||||||
|
</QtUic>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="bc.cpp" />
|
||||||
|
<ClCompile Include="bcdelightpmwidget.cpp" />
|
||||||
|
<ClCompile Include="bcdeviceview.cpp" />
|
||||||
|
<ClCompile Include="bcdriver.cpp" />
|
||||||
|
<ClCompile Include="bcdriverstatewidget.cpp" />
|
||||||
|
<ClCompile Include="bcdrivertinycan.cpp" />
|
||||||
|
<ClCompile Include="bcmainwindow.cpp" />
|
||||||
|
<ClCompile Include="bcthemeswitchbutton.cpp" />
|
||||||
|
<ClCompile Include="bctoggleswitch.cpp" />
|
||||||
|
<ClCompile Include="bctransmitter.cpp" />
|
||||||
|
<ClCompile Include="bcvalue.cpp" />
|
||||||
|
<ClCompile Include="bcvaluedelegate.cpp" />
|
||||||
|
<ClCompile Include="bcvaluemodel.cpp" />
|
||||||
|
<ClCompile Include="bcvalueslider.cpp" />
|
||||||
|
<ClCompile Include="bcxmlloader.cpp" />
|
||||||
|
<ClCompile Include="libwin\can_drv_win.c" />
|
||||||
|
<ClCompile Include="main.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<QtMoc Include="bc.h" />
|
||||||
|
<QtMoc Include="bcdelightpmwidget.h" />
|
||||||
|
<QtMoc Include="bcdeviceview.h" />
|
||||||
|
<QtMoc Include="bcdriver.h" />
|
||||||
|
<QtMoc Include="bcdriverstatewidget.h" />
|
||||||
|
<ClInclude Include="bcdrivertinycan.h" />
|
||||||
|
<QtMoc Include="bcmainwindow.h" />
|
||||||
|
<QtMoc Include="bcthemeswitchbutton.h" />
|
||||||
|
<QtMoc Include="bctoggleswitch.h" />
|
||||||
|
<QtMoc Include="bctransmitter.h" />
|
||||||
|
<QtMoc Include="bcvalue.h" />
|
||||||
|
<QtMoc Include="bcvaluedelegate.h" />
|
||||||
|
<QtMoc Include="bcvaluemodel.h" />
|
||||||
|
<QtMoc Include="bcvalueslider.h" />
|
||||||
|
<QtMoc Include="bcxmlloader.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<CustomBuild Include="debug\moc_predefs.h.cbt">
|
||||||
|
<FileType>Document</FileType>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\Qt\6.11.0\msvc2022_64\mkspecs\features\data\dummy.cpp;%(AdditionalInputs)</AdditionalInputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">cl -BxC:\Qt\6.11.0\msvc2022_64\bin\qmake.exe -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -permissive- -Zc:__cplusplus -Zc:externConstexpr -Zi -MDd -std:c++latest -utf-8 -W3 -w34100 -w34189 -w44456 -w44457 -w44458 -wd4577 -wd4467 -E ..\..\Qt\6.11.0\msvc2022_64\mkspecs\features\data\dummy.cpp 2>NUL >$(IntDir)\moc_predefs.h</Command>
|
||||||
|
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Generate moc_predefs.h</Message>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)\moc_predefs.h;%(Outputs)</Outputs>
|
||||||
|
</CustomBuild>
|
||||||
|
<CustomBuild Include="release\moc_predefs.h.cbt">
|
||||||
|
<FileType>Document</FileType>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\Qt\6.11.0\msvc2022_64\mkspecs\features\data\dummy.cpp;%(AdditionalInputs)</AdditionalInputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">cl -BxC:\Qt\6.11.0\msvc2022_64\bin\qmake.exe -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -permissive- -Zc:__cplusplus -Zc:externConstexpr -O2 -MD -std:c++latest -utf-8 -W3 -w34100 -w34189 -w44456 -w44457 -w44458 -wd4577 -wd4467 -E ..\..\Qt\6.11.0\msvc2022_64\mkspecs\features\data\dummy.cpp 2>NUL >$(IntDir)\moc_predefs.h</Command>
|
||||||
|
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Generate moc_predefs.h</Message>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)\moc_predefs.h;%(Outputs)</Outputs>
|
||||||
|
</CustomBuild>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<QtUic Include="bcmainwindow.ui" />
|
||||||
|
<QtUic Include="bcvalueslider.ui" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="resources\bc_dark.qss" />
|
||||||
|
<None Include="resources\bc_light.qss" />
|
||||||
|
<None Include="resources\bikeinfo.xml" />
|
||||||
|
<None Include="resources\bionx_akku.png" />
|
||||||
|
<None Include="resources\bionx_console.png" />
|
||||||
|
<None Include="resources\bionx_motor.png" />
|
||||||
|
<QtRcc Include="bionxcontrol.qrc" />
|
||||||
|
<None Include="resources\connect.png" />
|
||||||
|
<None Include="resources\exit.png" />
|
||||||
|
<None Include="resources\exit_red.png" />
|
||||||
|
<None Include="resources\smile\face-angel.png" />
|
||||||
|
<None Include="resources\smile\face-angry.png" />
|
||||||
|
<None Include="resources\smile\face-cool.png" />
|
||||||
|
<None Include="resources\smile\face-crying.png" />
|
||||||
|
<None Include="resources\smile\face-embarrassed.png" />
|
||||||
|
<None Include="resources\smile\face-glasses.png" />
|
||||||
|
<None Include="resources\smile\face-kiss.png" />
|
||||||
|
<None Include="resources\smile\face-laugh.png" />
|
||||||
|
<None Include="resources\smile\face-monkey.png" />
|
||||||
|
<None Include="resources\smile\face-plain.png" />
|
||||||
|
<None Include="resources\smile\face-raspberry.png" />
|
||||||
|
<None Include="resources\smile\face-sad.png" />
|
||||||
|
<None Include="resources\smile\face-sick.png" />
|
||||||
|
<None Include="resources\smile\face-smile-big.png" />
|
||||||
|
<None Include="resources\smile\face-smile.png" />
|
||||||
|
<None Include="resources\smile\face-smirk.png" />
|
||||||
|
<None Include="resources\smile\face-surprise.png" />
|
||||||
|
<None Include="resources\sync.png" />
|
||||||
|
<None Include="resources\sync_green.png" />
|
||||||
|
<None Include="resources\sync_yellow.png" />
|
||||||
|
<None Include="resources\update.png" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<Import Project="$(QtMsBuild)\qt.targets" Condition="Exists('$(QtMsBuild)\qt.targets')" />
|
||||||
|
<ImportGroup Label="ExtensionTargets" />
|
||||||
|
</Project>
|
||||||
260
BionxControl.vcxproj.filters
Normal file
260
BionxControl.vcxproj.filters
Normal file
@@ -0,0 +1,260 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Form Files">
|
||||||
|
<UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
|
||||||
|
<Extensions>ui</Extensions>
|
||||||
|
<ParseFiles>false</ParseFiles>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Form Files">
|
||||||
|
<UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
|
||||||
|
<Extensions>ui</Extensions>
|
||||||
|
<ParseFiles>false</ParseFiles>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Generated Files">
|
||||||
|
<UniqueIdentifier>{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cxx;moc;h;def;odl;idl;res;</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Generated Files">
|
||||||
|
<UniqueIdentifier>{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cxx;moc;h;def;odl;idl;res;</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resource Files">
|
||||||
|
<UniqueIdentifier>{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}</UniqueIdentifier>
|
||||||
|
<Extensions>qrc;*</Extensions>
|
||||||
|
<ParseFiles>false</ParseFiles>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resource Files">
|
||||||
|
<UniqueIdentifier>{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}</UniqueIdentifier>
|
||||||
|
<Extensions>qrc;*</Extensions>
|
||||||
|
<ParseFiles>false</ParseFiles>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Source Files">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Source Files">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="bc.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="bcdelightpmwidget.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="bcdeviceview.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="bcdriver.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="bcdriverstatewidget.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="bcdrivertinycan.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="bcmainwindow.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="bcthemeswitchbutton.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="bctoggleswitch.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="bctransmitter.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="bcvalue.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="bcvaluedelegate.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="bcvaluemodel.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="bcvalueslider.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="bcxmlloader.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="libwin\can_drv_win.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="main.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<QtMoc Include="bc.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</QtMoc>
|
||||||
|
<QtMoc Include="bcdelightpmwidget.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</QtMoc>
|
||||||
|
<QtMoc Include="bcdeviceview.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</QtMoc>
|
||||||
|
<QtMoc Include="bcdriver.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</QtMoc>
|
||||||
|
<QtMoc Include="bcdriverstatewidget.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</QtMoc>
|
||||||
|
<ClInclude Include="bcdrivertinycan.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<QtMoc Include="bcmainwindow.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</QtMoc>
|
||||||
|
<QtMoc Include="bcthemeswitchbutton.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</QtMoc>
|
||||||
|
<QtMoc Include="bctoggleswitch.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</QtMoc>
|
||||||
|
<QtMoc Include="bctransmitter.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</QtMoc>
|
||||||
|
<QtMoc Include="bcvalue.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</QtMoc>
|
||||||
|
<QtMoc Include="bcvaluedelegate.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</QtMoc>
|
||||||
|
<QtMoc Include="bcvaluemodel.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</QtMoc>
|
||||||
|
<QtMoc Include="bcvalueslider.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</QtMoc>
|
||||||
|
<QtMoc Include="bcxmlloader.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</QtMoc>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<CustomBuild Include="debug\moc_predefs.h.cbt">
|
||||||
|
<Filter>Generated Files</Filter>
|
||||||
|
</CustomBuild>
|
||||||
|
<CustomBuild Include="release\moc_predefs.h.cbt">
|
||||||
|
<Filter>Generated Files</Filter>
|
||||||
|
</CustomBuild>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<QtUic Include="bcmainwindow.ui">
|
||||||
|
<Filter>Form Files</Filter>
|
||||||
|
</QtUic>
|
||||||
|
<QtUic Include="bcvalueslider.ui">
|
||||||
|
<Filter>Form Files</Filter>
|
||||||
|
</QtUic>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="resources\bc_dark.qss">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\bc_light.qss">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\bikeinfo.xml">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\bionx_akku.png">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\bionx_console.png">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\bionx_motor.png">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
<QtRcc Include="bionxcontrol.qrc">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</QtRcc>
|
||||||
|
<None Include="resources\connect.png">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\exit.png">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\exit_red.png">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\smile\face-angel.png">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\smile\face-angry.png">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\smile\face-cool.png">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\smile\face-crying.png">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\smile\face-embarrassed.png">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\smile\face-glasses.png">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\smile\face-kiss.png">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\smile\face-laugh.png">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\smile\face-monkey.png">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\smile\face-plain.png">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\smile\face-raspberry.png">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\smile\face-sad.png">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\smile\face-sick.png">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\smile\face-smile-big.png">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\smile\face-smile.png">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\smile\face-smirk.png">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\smile\face-surprise.png">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\sync.png">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\sync_green.png">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\sync_yellow.png">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\update.png">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
21
BionxControl.vcxproj.user
Normal file
21
BionxControl.vcxproj.user
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<LocalDebuggerEnvironment>PATH=C:\Qt\6.11.0\msvc2022_64\bin;%PATH%
|
||||||
|
$(LocalDebuggerEnvironment)</LocalDebuggerEnvironment>
|
||||||
|
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<LocalDebuggerEnvironment>PATH=C:\Qt\6.11.0\msvc2022_64\bin;%PATH%
|
||||||
|
$(LocalDebuggerEnvironment)</LocalDebuggerEnvironment>
|
||||||
|
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<QtTouchProperty>
|
||||||
|
</QtTouchProperty>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<QtTouchProperty>
|
||||||
|
</QtTouchProperty>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
137
CMakeLists.txt
Normal file
137
CMakeLists.txt
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
project(BionxControl VERSION 1.0 LANGUAGES C CXX)
|
||||||
|
# --- C++23 aktivieren ---
|
||||||
|
set(CMAKE_CXX_STANDARD 23)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
# set(CMAKE_CXX_EXTENSIONS OFF) # Optional: Auf OFF setzen, wenn du reines C++23 statt GNU++23 erzwingen willst
|
||||||
|
|
||||||
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
|
set(CMAKE_AUTOUIC ON)
|
||||||
|
|
||||||
|
find_package(Qt6 REQUIRED COMPONENTS Gui Svg Widgets)
|
||||||
|
|
||||||
|
qt_standard_project_setup()
|
||||||
|
|
||||||
|
qt_add_executable(BionxControl WIN32 MACOSX_BUNDLE
|
||||||
|
bc.cpp bc.h
|
||||||
|
bcdelightpmwidget.cpp bcdelightpmwidget.h
|
||||||
|
bcdeviceview.cpp bcdeviceview.h
|
||||||
|
bcdriver.cpp bcdriver.h
|
||||||
|
bcdriverstatewidget.cpp bcdriverstatewidget.h
|
||||||
|
bcdrivertinycan.cpp bcdrivertinycan.h
|
||||||
|
bcmainwindow.cpp bcmainwindow.h bcmainwindow.ui
|
||||||
|
bcthemebutton.cpp bcthemebutton.h
|
||||||
|
bctoggleswitch.cpp bctoggleswitch.h
|
||||||
|
bctransmitter.cpp bctransmitter.h
|
||||||
|
bcvalue.cpp bcvalue.h
|
||||||
|
bcvaluedelegate.cpp bcvaluedelegate.h
|
||||||
|
bcvaluemodel.cpp bcvaluemodel.h
|
||||||
|
bcvalueslider.cpp bcvalueslider.h bcvalueslider.ui
|
||||||
|
bcxmlloader.cpp bcxmlloader.h
|
||||||
|
main.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
# Plattformspezifische CAN-Treiber einbinden
|
||||||
|
if(WIN32)
|
||||||
|
target_sources(BionxControl PRIVATE libwin/can_drv_win.c)
|
||||||
|
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||||
|
target_sources(BionxControl PRIVATE libwin/mhs_can_drv.c)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_include_directories(BionxControl PRIVATE
|
||||||
|
.
|
||||||
|
libwin
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(BionxControl PRIVATE
|
||||||
|
Qt::Core
|
||||||
|
Qt::Gui
|
||||||
|
Qt::Svg
|
||||||
|
Qt::Widgets
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Resources:
|
||||||
|
set_source_files_properties("resources/bc_dark.qss"
|
||||||
|
PROPERTIES QT_RESOURCE_ALIAS "bc_dark.qss"
|
||||||
|
)
|
||||||
|
set_source_files_properties("resources/bc_light.qss"
|
||||||
|
PROPERTIES QT_RESOURCE_ALIAS "bc_light.qss"
|
||||||
|
)
|
||||||
|
set_source_files_properties("resources/bikeinfo.xml"
|
||||||
|
PROPERTIES QT_RESOURCE_ALIAS "bikeinfo.xml"
|
||||||
|
)
|
||||||
|
set_source_files_properties("resources/bionx_akku.png"
|
||||||
|
PROPERTIES QT_RESOURCE_ALIAS "bionx_akku.png"
|
||||||
|
)
|
||||||
|
set_source_files_properties("resources/bionx_console.png"
|
||||||
|
PROPERTIES QT_RESOURCE_ALIAS "bionx_console.png"
|
||||||
|
)
|
||||||
|
set_source_files_properties("resources/bionx_motor.png"
|
||||||
|
PROPERTIES QT_RESOURCE_ALIAS "bionx_motor.png"
|
||||||
|
)
|
||||||
|
set_source_files_properties("resources/connect.png"
|
||||||
|
PROPERTIES QT_RESOURCE_ALIAS "connect.png"
|
||||||
|
)
|
||||||
|
set_source_files_properties("resources/exit.png"
|
||||||
|
PROPERTIES QT_RESOURCE_ALIAS "exit.png"
|
||||||
|
)
|
||||||
|
set_source_files_properties("resources/exit_red.png"
|
||||||
|
PROPERTIES QT_RESOURCE_ALIAS "exit_red.png"
|
||||||
|
)
|
||||||
|
set_source_files_properties("resources/sync.png"
|
||||||
|
PROPERTIES QT_RESOURCE_ALIAS "sync.png"
|
||||||
|
)
|
||||||
|
set_source_files_properties("resources/sync_green.png"
|
||||||
|
PROPERTIES QT_RESOURCE_ALIAS "sync_green.png"
|
||||||
|
)
|
||||||
|
set_source_files_properties("resources/sync_yellow.png"
|
||||||
|
PROPERTIES QT_RESOURCE_ALIAS "sync_yellow.png"
|
||||||
|
)
|
||||||
|
set_source_files_properties("resources/update.png"
|
||||||
|
PROPERTIES QT_RESOURCE_ALIAS "update.png"
|
||||||
|
)
|
||||||
|
set(bionxcontrol_resource_files
|
||||||
|
"resources/bc_dark.qss"
|
||||||
|
"resources/bc_light.qss"
|
||||||
|
"resources/bikeinfo.xml"
|
||||||
|
"resources/bionx_akku.png"
|
||||||
|
"resources/bionx_console.png"
|
||||||
|
"resources/bionx_motor.png"
|
||||||
|
"resources/connect.png"
|
||||||
|
"resources/exit.png"
|
||||||
|
"resources/exit_red.png"
|
||||||
|
"resources/smile/face-angel.png"
|
||||||
|
"resources/smile/face-angry.png"
|
||||||
|
"resources/smile/face-cool.png"
|
||||||
|
"resources/smile/face-crying.png"
|
||||||
|
"resources/smile/face-embarrassed.png"
|
||||||
|
"resources/smile/face-glasses.png"
|
||||||
|
"resources/smile/face-kiss.png"
|
||||||
|
"resources/smile/face-laugh.png"
|
||||||
|
"resources/smile/face-monkey.png"
|
||||||
|
"resources/smile/face-plain.png"
|
||||||
|
"resources/smile/face-raspberry.png"
|
||||||
|
"resources/smile/face-sad.png"
|
||||||
|
"resources/smile/face-sick.png"
|
||||||
|
"resources/smile/face-smile-big.png"
|
||||||
|
"resources/smile/face-smile.png"
|
||||||
|
"resources/smile/face-smirk.png"
|
||||||
|
"resources/smile/face-surprise.png"
|
||||||
|
"resources/sync.png"
|
||||||
|
"resources/sync_green.png"
|
||||||
|
"resources/sync_yellow.png"
|
||||||
|
"resources/update.png"
|
||||||
|
)
|
||||||
|
|
||||||
|
qt_add_resources(BionxControl "bionxcontrol"
|
||||||
|
PREFIX
|
||||||
|
"/"
|
||||||
|
FILES
|
||||||
|
${bionxcontrol_resource_files}
|
||||||
|
)
|
||||||
|
|
||||||
|
install(TARGETS BionxControl
|
||||||
|
BUNDLE DESTINATION .
|
||||||
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
|
)
|
||||||
36
Dockerfile
Normal file
36
Dockerfile
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
# Wir nutzen Debian Trixie als Basis für das aktuelle Raspberry Pi OS
|
||||||
|
FROM debian:trixie
|
||||||
|
|
||||||
|
# Verhindert interaktive Prompts während der Installation
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
# 1. Multiarch für armhf aktivieren
|
||||||
|
RUN dpkg --add-architecture armhf && \
|
||||||
|
apt-get update && \
|
||||||
|
apt-get upgrade -y
|
||||||
|
|
||||||
|
# 2. Host-Build-Tools und Cross-Compiler für 32-Bit installieren
|
||||||
|
RUN apt-get install -y \
|
||||||
|
build-essential \
|
||||||
|
crossbuild-essential-armhf \
|
||||||
|
cmake \
|
||||||
|
ninja-build \
|
||||||
|
git \
|
||||||
|
pkg-config
|
||||||
|
|
||||||
|
# 3. Qt6 für den HOST installieren (für moc, uic, etc.)
|
||||||
|
RUN apt-get install -y \
|
||||||
|
qt6-base-dev \
|
||||||
|
qt6-tools-dev-tools \
|
||||||
|
qt6-svg-dev
|
||||||
|
|
||||||
|
# 4. Qt6 Bibliotheken für das TARGET (armhf) installieren
|
||||||
|
RUN apt-get install -y \
|
||||||
|
qt6-base-dev:armhf \
|
||||||
|
libglvnd-dev:armhf \
|
||||||
|
qt6-svg-dev:armhf
|
||||||
|
|
||||||
|
# Aufräumen
|
||||||
|
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
WORKDIR /workspace
|
||||||
744
aalegacy.cpp
744
aalegacy.cpp
@@ -1,744 +0,0 @@
|
|||||||
/* BigXionFlasher.c */
|
|
||||||
/* ====================================================================
|
|
||||||
* Copyright (c) 2011-2013 by Thomas König <info@bigxionflasher.org>.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
*
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in
|
|
||||||
* the documentation and/or other materials provided with the
|
|
||||||
* distribution.
|
|
||||||
*
|
|
||||||
* 3. All advertising materials mentioning features or use of this
|
|
||||||
* software must display the following acknowledgment:
|
|
||||||
* "This product includes software developed by the
|
|
||||||
* BigXionFlasher Project. (http://www.bigxionflasher.org/)"
|
|
||||||
*
|
|
||||||
* 4. The name "BigXionFlasher" must not be used to
|
|
||||||
* endorse or promote products derived from this software without
|
|
||||||
* prior written permission. For written permission, please contact
|
|
||||||
* info@bigxionflasher.org.
|
|
||||||
*
|
|
||||||
* 5. Products derived from this software may not be called "BigXionFlasher"
|
|
||||||
* nor may "BigXionFlasher" appear in their names without prior written
|
|
||||||
* permission of the BigXionFlasher Project.
|
|
||||||
*
|
|
||||||
* 6. Redistributions of any form whatsoever must retain the following
|
|
||||||
* acknowledgment:
|
|
||||||
* "This product includes software developed by the
|
|
||||||
* BigXionFlasher Project. (http://www.bigxionflasher.org/)"
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE BigXionFlasher PROJECT ``AS IS'' AND ANY
|
|
||||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE BigXionFlasher PROJECT OR
|
|
||||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
|
||||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
* ====================================================================
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <time.h>
|
|
||||||
#ifdef __WIN32__
|
|
||||||
#include <conio.h>
|
|
||||||
#define DEVICE_OPEN NULL
|
|
||||||
#define TREIBER_NAME "mhstcan.dll"
|
|
||||||
#define _NL "\n\r"
|
|
||||||
#define _DEGREE_SIGN "o"
|
|
||||||
#else
|
|
||||||
#define DEVICE_OPEN NULL
|
|
||||||
#define TREIBER_NAME "libmhstcan.so"
|
|
||||||
#define _NL "\n"
|
|
||||||
#define _DEGREE_SIGN "°"
|
|
||||||
#endif
|
|
||||||
#include "can_drv.h"
|
|
||||||
|
|
||||||
#define __DOSTR(v) #v
|
|
||||||
#define __STR(v) __DOSTR(v)
|
|
||||||
|
|
||||||
#define __BXF_VERSION__ "V 0.2.4 rev. 97"
|
|
||||||
|
|
||||||
#define UNLIMITED_SPEED_VALUE 70 /* Km/h */
|
|
||||||
#define UNLIMITED_MIN_SPEED_VALUE 30 /* Km/h */
|
|
||||||
#define MAX_THROTTLE_SPEED_VALUE 70 /* Km/h */
|
|
||||||
|
|
||||||
//#include "registers.h"
|
|
||||||
|
|
||||||
#define TIMEOUT_VALUE 80
|
|
||||||
#define TIMEOUT_US 10000 // 10ms
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define BATTERY_REF_HW 1
|
|
||||||
#define BATTERY_REF_SW 1
|
|
||||||
#define BATTERY_SN_PN_HI 1
|
|
||||||
#define BATTERY_SN_PN_LO 1
|
|
||||||
#define BATTERY_SN_ITEM_HI 1
|
|
||||||
#define BATTERY_SN_ITEM_LO 1
|
|
||||||
#define BATTERY_STATUS_VBATT_HI 1
|
|
||||||
#define BATTERY_STATUS_VBATT_LO 1
|
|
||||||
#define BATTERY_STATUS_LEVEL 1
|
|
||||||
#define BATTERY_STATS_VBATTMAX 1
|
|
||||||
#define BATTERY_STATS_VBATTMIN 1
|
|
||||||
#define BATTERY_STATS_VBATTMEA 1
|
|
||||||
#define BATTERY_STATS_VBATTMEAN 1
|
|
||||||
#define BATTERY_STATS_RESET_HI 1
|
|
||||||
#define BATTERY_STATS_RESET_LO 1
|
|
||||||
#define BATTERY_STSTS_GGJSRCALIB 1
|
|
||||||
|
|
||||||
#define BATTERY_STSTS_VCTRLSHORTS 1
|
|
||||||
#define BATTERY_STATS_LMD_HI 1
|
|
||||||
#define BATTERY_STATS_LMD_LO 1
|
|
||||||
#define BATTERY_CONFIG_CELLCAPACITY_HI 1
|
|
||||||
#define BATTERY_CONFIG_CELLCAPACITY_LO 1
|
|
||||||
|
|
||||||
#define BATTERY_STATS_CHARGETIMEWORST_HI 1
|
|
||||||
#define BATTERY_STATS_CHARGETIMEWORST_LO 1
|
|
||||||
#define BATTERY_STATS_CHARGETIMEMEAN_HI 1
|
|
||||||
#define BATTERY_STATS_CHARGETIMEMEAN_LO 1
|
|
||||||
#define BATTERY_STATS_BATTCYCLES_HI 1
|
|
||||||
#define BATTERY_STATS_BATTCYCLES_LO 1
|
|
||||||
#define BATTERY_STATS_BATTFULLCYCLES_HI 1
|
|
||||||
#define BATTERY_STATS_BATTFULLCYCLES_LO 1
|
|
||||||
#define BATTERY_STATS_POWERCYCLES_HI 1
|
|
||||||
#define BATTERY_STATS_POWERCYCLES_LO 1
|
|
||||||
|
|
||||||
#define BATTERY_STATS_TBATTMAX 1
|
|
||||||
#define BATTERY_STATS_TBATTMIN 1
|
|
||||||
#define MOTOR_REF_HW 1
|
|
||||||
#define MOTOR_REF_SW 1
|
|
||||||
#define MOTOR_REALTIME_TEMP 1
|
|
||||||
#define MOTOR_SN_PN_HI 1
|
|
||||||
#define MOTOR_SN_PN_LO 1
|
|
||||||
#define MOTOR_SN_ITEM_HI 1
|
|
||||||
#define MOTOR_SN_ITEM_LO 1
|
|
||||||
|
|
||||||
#define CONSOLE_STATUS_SLAVE 1
|
|
||||||
#define BATTERY_CONFIG_SHUTDOWN 1
|
|
||||||
|
|
||||||
#define CONSOLE_ASSIST_MAXSPEEDFLAG 1
|
|
||||||
#define CONSOLE_ASSIST_MAXSPEED_HI 1
|
|
||||||
#define CONSOLE_ASSIST_MAXSPEED_LO 1
|
|
||||||
#define MOTOR_PROTECT_UNLOCK 1
|
|
||||||
#define MOTOR_PROTECT_UNLOCK_KEY 1
|
|
||||||
#define MOTOR_ASSIST_MAXSPEED 1
|
|
||||||
#define CONSOLE_GEOMETRY_CIRC_HI 1
|
|
||||||
#define CONSOLE_GEOMETRY_CIRC_LO1
|
|
||||||
|
|
||||||
#define CONSOLE_GEOMETRY_CIRC_LO 1
|
|
||||||
#define MOTOR_GEOMETRY_CIRC_HI1
|
|
||||||
#define MOTOR_GEOMETRY_CIRC_HI 1
|
|
||||||
#define MOTOR_GEOMETRY_CIRC_LO 1
|
|
||||||
#define CONSOLE_ASSIST_MINSPEEDFLAG 1
|
|
||||||
#define CONSOLE_ASSIST_MINSPEED 1
|
|
||||||
|
|
||||||
#define CONSOLE_THROTTLE_MAXSPEEDFLAG 1
|
|
||||||
#define CONSOLE_THROTTLE_MAXSPEED_HI 1
|
|
||||||
#define CONSOLE_THROTTLE_MAXSPEED_LO 1
|
|
||||||
|
|
||||||
#define BATTERY_CONFIG_PACKSERIAL 1
|
|
||||||
#define BATTERY_CELLMON_BALANCERENABLED 1
|
|
||||||
#define BATTERY_CONFIG_PACKPARALLEL 1
|
|
||||||
#define BATTERY_CELLMON_CHANNELADDR 1
|
|
||||||
#define BATTERY_CELLMON_CHANNELDATA_HI 1
|
|
||||||
|
|
||||||
#define BATTERY_STATUS_PACKTEMPERATURE1 1
|
|
||||||
|
|
||||||
#define BATTERY_CELLMON_CHANNELDATA_LO 1
|
|
||||||
|
|
||||||
#define CONSOLE_REF_HW 1
|
|
||||||
#define CONSOLE_REF_SW 1
|
|
||||||
#define CONSOLE_ASSIST_INITLEVEL 1
|
|
||||||
#define CONSOLE_SN_PN_HI 1
|
|
||||||
#define CONSOLE_SN_PN_LO 1
|
|
||||||
#define CONSOLE_SN_ITEM_HI 1
|
|
||||||
#define CONSOLE_SN_ITEM_LO 1
|
|
||||||
#define CONSOLE_ASSIST_MOUNTAINCAP 1
|
|
||||||
#define CONSOLE_STATS_BCValueTypeWord_1 1
|
|
||||||
#define CONSOLE_STATS_BCValueTypeWord_2 1
|
|
||||||
#define CONSOLE_STATS_BCValueTypeWord_3 1
|
|
||||||
|
|
||||||
#define CONSOLE_STATS_BCValueTypeWord_4 1
|
|
||||||
|
|
||||||
#define doSleep(x) usleep(x*1000)
|
|
||||||
|
|
||||||
int gAssistInitLevel = -1, gPrintSystemSettings = 0, gSkipShutdown = 0, gPowerOff = 0, gConsoleSetSlaveMode = 1, gNoSerialNumbers = 0, gSetMountainCap = -1, gSetWheelCircumference = 0;
|
|
||||||
double gSetSpeedLimit = -1, gSetMinSpeedLimit = -1, gSetThrottleSpeedLimit = -1;
|
|
||||||
|
|
||||||
#define CONSOLE 1
|
|
||||||
#define MOTOR 2
|
|
||||||
#define BATTERY 3
|
|
||||||
#define BIB 4
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
char *getNodeName(unsigned char id)
|
|
||||||
{
|
|
||||||
if (id == CONSOLE)
|
|
||||||
return "console";
|
|
||||||
else if (id == BATTERY)
|
|
||||||
return "battery";
|
|
||||||
else if (id == MOTOR)
|
|
||||||
return "motor";
|
|
||||||
else if (id == BIB)
|
|
||||||
return "bib";
|
|
||||||
else
|
|
||||||
return "UNKNOWN";
|
|
||||||
}
|
|
||||||
|
|
||||||
void setValue(unsigned char receipient, unsigned char reg, unsigned char value)
|
|
||||||
{
|
|
||||||
struct TCanMsg msg;
|
|
||||||
int timeout = TIMEOUT_VALUE;
|
|
||||||
|
|
||||||
msg.MsgFlags = 0L;
|
|
||||||
msg.Id = receipient;
|
|
||||||
msg.MsgLen = 4;
|
|
||||||
msg.MsgData[0] = 0x00;
|
|
||||||
msg.MsgData[1] = reg;
|
|
||||||
msg.MsgData[2] = 0x00;
|
|
||||||
msg.MsgData[3] = value;
|
|
||||||
|
|
||||||
CanTransmit(0, &msg, 1);
|
|
||||||
|
|
||||||
while(timeout-- && CanTransmitGetCount(0))
|
|
||||||
usleep(TIMEOUT_US);
|
|
||||||
|
|
||||||
if (timeout == -1)
|
|
||||||
printf("error: could not send value to %s" _NL, getNodeName(receipient));
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int getValue(unsigned char receipient, unsigned char reg)
|
|
||||||
{
|
|
||||||
struct TCanMsg msg;
|
|
||||||
int err, retry = 20;
|
|
||||||
int timeout = TIMEOUT_VALUE;
|
|
||||||
|
|
||||||
msg.MsgFlags = 0L;
|
|
||||||
msg.Id = receipient;
|
|
||||||
msg.MsgLen = 2;
|
|
||||||
msg.MsgData[0] = 0x00;
|
|
||||||
msg.MsgData[1] = reg;
|
|
||||||
|
|
||||||
CanTransmit(0, &msg, 1);
|
|
||||||
|
|
||||||
while(timeout-- && CanTransmitGetCount(0))
|
|
||||||
usleep(TIMEOUT_US);
|
|
||||||
|
|
||||||
if (timeout == -1)
|
|
||||||
printf("error: could not send value to node %s" _NL, getNodeName(receipient));
|
|
||||||
|
|
||||||
retry:
|
|
||||||
|
|
||||||
timeout = TIMEOUT_VALUE;
|
|
||||||
while(timeout-- && !CanReceiveGetCount(0))
|
|
||||||
usleep(TIMEOUT_US);
|
|
||||||
|
|
||||||
if (timeout == -1)
|
|
||||||
{
|
|
||||||
printf("error: no response from node %s" _NL, getNodeName(receipient));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((err = CanReceive(0, &msg, 1)) > 0)
|
|
||||||
{
|
|
||||||
if (--retry && (msg.Id != BIB || msg.MsgLen != 4 || msg.MsgData[1] != reg))
|
|
||||||
goto retry;
|
|
||||||
|
|
||||||
if (!retry)
|
|
||||||
{
|
|
||||||
printf("error: no response from node %s to %s" _NL, getNodeName(receipient), getNodeName(BIB));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (unsigned int) msg.MsgData[3];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("Error: %d" _NL, err);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void setSpeedLimit(double speed)
|
|
||||||
{
|
|
||||||
int limit = (speed != 0);
|
|
||||||
|
|
||||||
if (!speed)
|
|
||||||
speed = UNLIMITED_SPEED_VALUE;
|
|
||||||
setValue(CONSOLE, CONSOLE_ASSIST_MAXSPEEDFLAG, limit);
|
|
||||||
setValue(CONSOLE, CONSOLE_ASSIST_MAXSPEED_HI, ((int)(speed * 10)) >> 8);
|
|
||||||
setValue(CONSOLE, CONSOLE_ASSIST_MAXSPEED_LO, ((int)(speed * 10)) & 0xff);
|
|
||||||
setValue(MOTOR, MOTOR_PROTECT_UNLOCK, MOTOR_PROTECT_UNLOCK_KEY);
|
|
||||||
setValue(MOTOR, MOTOR_ASSIST_MAXSPEED, (int)speed);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void setWheelCircumference(unsigned short circumference)
|
|
||||||
{
|
|
||||||
if (!circumference)
|
|
||||||
return;
|
|
||||||
|
|
||||||
setValue(CONSOLE, CONSOLE_GEOMETRY_CIRC_HI, (int) (circumference >> 8));
|
|
||||||
setValue(CONSOLE, CONSOLE_GEOMETRY_CIRC_LO, (int) (circumference & 0xff));
|
|
||||||
setValue(MOTOR, MOTOR_PROTECT_UNLOCK, MOTOR_PROTECT_UNLOCK_KEY);
|
|
||||||
setValue(MOTOR, MOTOR_GEOMETRY_CIRC_HI, (int) (circumference >> 8));
|
|
||||||
setValue(MOTOR, MOTOR_GEOMETRY_CIRC_LO, (int) (circumference & 0xff));
|
|
||||||
}
|
|
||||||
|
|
||||||
void setMinSpeedLimit(double speed)
|
|
||||||
{
|
|
||||||
char limit = (speed != 0);
|
|
||||||
|
|
||||||
setValue(CONSOLE, CONSOLE_ASSIST_MINSPEEDFLAG, limit);
|
|
||||||
setValue(CONSOLE, CONSOLE_ASSIST_MINSPEED, (int)(speed * 10));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void setThrottleSpeedLimit(double speed)
|
|
||||||
{
|
|
||||||
int limit = (speed != 0);
|
|
||||||
|
|
||||||
if (!speed)
|
|
||||||
speed = MAX_THROTTLE_SPEED_VALUE;
|
|
||||||
|
|
||||||
setValue(CONSOLE, CONSOLE_THROTTLE_MAXSPEEDFLAG, limit);
|
|
||||||
setValue(CONSOLE, CONSOLE_THROTTLE_MAXSPEED_HI, ((int)(speed * 10)) >> 8);
|
|
||||||
setValue(CONSOLE, CONSOLE_THROTTLE_MAXSPEED_LO, ((int)(speed * 10)) & 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
void printBatteryStats()
|
|
||||||
{
|
|
||||||
int channel = 1, packSerial, packParallel;
|
|
||||||
|
|
||||||
printf( " balancer enabled ...: %s" _NL _NL, (getValue(BATTERY, BATTERY_CELLMON_BALANCERENABLED != 0) ? "yes" : "no"));
|
|
||||||
|
|
||||||
packSerial = getValue(BATTERY, BATTERY_CONFIG_PACKSERIAL);
|
|
||||||
packParallel = getValue(BATTERY, BATTERY_CONFIG_PACKPARALLEL);
|
|
||||||
|
|
||||||
packSerial = (packSerial > 20) ? 0 : packSerial;
|
|
||||||
packParallel = (packParallel > 20) ? 0 : packParallel;
|
|
||||||
|
|
||||||
for (;channel <= packSerial; channel++) {
|
|
||||||
setValue(BATTERY, BATTERY_CELLMON_CHANNELADDR, (int)0x80 + channel);
|
|
||||||
printf(" voltage cell #%02d ...: %.3fV" _NL, channel,
|
|
||||||
((getValue(BATTERY, BATTERY_CELLMON_CHANNELDATA_HI) << 8) + getValue(BATTERY,BATTERY_CELLMON_CHANNELDATA_LO)) * 0.001);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (channel = 0 ; channel < packParallel ; channel ++)
|
|
||||||
printf(" temperature pack #%02d: %d" _DEGREE_SIGN "C" _NL, channel + 1,
|
|
||||||
getValue(BATTERY, BATTERY_STATUS_PACKTEMPERATURE1 + channel));
|
|
||||||
|
|
||||||
printf(_NL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void printChargeStats() {
|
|
||||||
int channel = 1, totalChagres = 0, c;
|
|
||||||
|
|
||||||
for (channel = 1 ; channel <= 10; channel++) {
|
|
||||||
setValue(BATTERY, 0xf6, channel);
|
|
||||||
c = (getValue(BATTERY, 0xf7) << 8) + getValue(BATTERY,0xf8);
|
|
||||||
totalChagres += c;
|
|
||||||
printf(" charge level @ %03d%% : %04d" _NL, channel*10, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf(" total # of charges .: %04d" _NL _NL, totalChagres);
|
|
||||||
}
|
|
||||||
|
|
||||||
double getVoltageValue(unsigned char in, unsigned char reg)
|
|
||||||
{
|
|
||||||
return (getValue(BATTERY, reg) + 20.8333) * 0.416667;
|
|
||||||
}
|
|
||||||
|
|
||||||
void usage(void) {
|
|
||||||
printf( "usage:" _NL
|
|
||||||
" -l <speedLimit> .......... set the speed limit to <speedLimit> (1 - " __STR(UNLIMITED_SPEED_VALUE) "), 0 = remove the limit" _NL );
|
|
||||||
}
|
|
||||||
|
|
||||||
int parseOptions(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int oc;
|
|
||||||
char odef[] = "l:t:m:sa:pnxio:c:h?";
|
|
||||||
|
|
||||||
while((oc = getopt(argc,argv,odef)) != -1) {
|
|
||||||
switch(oc) {
|
|
||||||
case 'p':
|
|
||||||
gPowerOff = 1;
|
|
||||||
break;
|
|
||||||
case 'x':
|
|
||||||
gSkipShutdown = 1;
|
|
||||||
break;
|
|
||||||
case 'l':
|
|
||||||
gSetSpeedLimit = atof(optarg);
|
|
||||||
if (gSetSpeedLimit > UNLIMITED_SPEED_VALUE || gSetSpeedLimit < 0) {
|
|
||||||
printf("error: speed limit %.2f is out of range. exiting..." _NL, gSetSpeedLimit);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
gSetThrottleSpeedLimit = atof(optarg);
|
|
||||||
if (gSetThrottleSpeedLimit > MAX_THROTTLE_SPEED_VALUE || gSetThrottleSpeedLimit < 0) {
|
|
||||||
printf("error: throttle speed limit %.2f is out of range. exiting..." _NL, gSetThrottleSpeedLimit);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'm':
|
|
||||||
gSetMinSpeedLimit = atof(optarg);
|
|
||||||
if (gSetMinSpeedLimit > UNLIMITED_MIN_SPEED_VALUE || gSetMinSpeedLimit < 0) {
|
|
||||||
printf("error: min speed limit %.2f is out of range. exiting..." _NL, gSetMinSpeedLimit);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'a':
|
|
||||||
gAssistInitLevel = atoi(optarg);
|
|
||||||
if (gAssistInitLevel > 4 || gAssistInitLevel < 0) {
|
|
||||||
printf("error: initial assist level %d is out of range. exiting..." _NL, gAssistInitLevel);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'o':
|
|
||||||
gSetMountainCap = atoi(optarg);
|
|
||||||
if (gSetMountainCap > 100 || gSetMountainCap < 0) {
|
|
||||||
printf("error: mountain cap level %d is out of range. exiting..." _NL, gSetMountainCap);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
gSetWheelCircumference = atoi(optarg);
|
|
||||||
if (gSetWheelCircumference > 3000 || gSetWheelCircumference < 1000) {
|
|
||||||
printf("error: wheel circumference %d is out of range. exiting..." _NL, gSetWheelCircumference);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'n':
|
|
||||||
gConsoleSetSlaveMode = 0;
|
|
||||||
break;
|
|
||||||
case 'i':
|
|
||||||
gNoSerialNumbers = 1;
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
gPrintSystemSettings = 1;
|
|
||||||
break;
|
|
||||||
case 'h':
|
|
||||||
case '?':
|
|
||||||
default:
|
|
||||||
usage();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void printSystemSettings()
|
|
||||||
{
|
|
||||||
int hwVersion, swVersion, wheelCirc;
|
|
||||||
char *sl;
|
|
||||||
double speedLimit = 0;
|
|
||||||
|
|
||||||
printf(_NL _NL);
|
|
||||||
|
|
||||||
hwVersion = getValue(CONSOLE, CONSOLE_REF_HW);
|
|
||||||
|
|
||||||
if (hwVersion == 0)
|
|
||||||
printf("Console not responding" _NL _NL);
|
|
||||||
else {
|
|
||||||
swVersion = getValue(CONSOLE, CONSOLE_REF_SW);
|
|
||||||
printf( "Console information:" _NL
|
|
||||||
" hardware version ........: %02d" _NL
|
|
||||||
" software version ........: %02d" _NL
|
|
||||||
" assistance level ........: %d" _NL,
|
|
||||||
hwVersion, swVersion,
|
|
||||||
getValue(CONSOLE, CONSOLE_ASSIST_INITLEVEL)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!gNoSerialNumbers)
|
|
||||||
printf( " part number .............: %05d" _NL
|
|
||||||
" item number .............: %05d" _NL _NL,
|
|
||||||
((getValue(CONSOLE, CONSOLE_SN_PN_HI) << 8) + getValue(CONSOLE, CONSOLE_SN_PN_LO)),
|
|
||||||
((getValue(CONSOLE, CONSOLE_SN_ITEM_HI) << 8) + getValue(CONSOLE, CONSOLE_SN_ITEM_LO))
|
|
||||||
);
|
|
||||||
|
|
||||||
/* ASSIST speed limit */
|
|
||||||
sl = getValue(CONSOLE, CONSOLE_ASSIST_MAXSPEEDFLAG) == 0 ? (char*)"no" : (char*)"yes";
|
|
||||||
speedLimit = ((getValue(CONSOLE, CONSOLE_ASSIST_MAXSPEED_HI) << 8) + getValue(CONSOLE, CONSOLE_ASSIST_MAXSPEED_LO)) / (double)10;
|
|
||||||
printf( " max limit enabled .......: %s" _NL
|
|
||||||
" speed limit .............: %0.2f Km/h" _NL _NL, sl, speedLimit);
|
|
||||||
|
|
||||||
/* MIN speed limit */
|
|
||||||
sl = getValue(CONSOLE, CONSOLE_ASSIST_MINSPEEDFLAG) == 0 ? (char*)"no" : (char*)"yes";
|
|
||||||
speedLimit = (getValue(CONSOLE, CONSOLE_ASSIST_MINSPEED)) / (double)10;
|
|
||||||
printf( " min limit enabled .......: %s" _NL
|
|
||||||
" min speed limit .........: %0.2f Km/h" _NL _NL, sl, speedLimit);
|
|
||||||
|
|
||||||
/* THROTTLE speed limit */
|
|
||||||
sl = getValue(CONSOLE, CONSOLE_THROTTLE_MAXSPEEDFLAG) == 0 ? (char*)"no" : (char*)"yes";
|
|
||||||
speedLimit = ((getValue(CONSOLE, CONSOLE_THROTTLE_MAXSPEED_HI) << 8) + getValue(CONSOLE, CONSOLE_THROTTLE_MAXSPEED_LO)) / (double)10;
|
|
||||||
printf( " throttle limit enabled ..: %s" _NL
|
|
||||||
" throttle speed limit ....: %0.2f Km/h" _NL _NL, sl, speedLimit);
|
|
||||||
|
|
||||||
/* WHEEL CIRCUMFERENCE */
|
|
||||||
wheelCirc = (getValue(CONSOLE, CONSOLE_GEOMETRY_CIRC_HI) << 8) + getValue(CONSOLE, CONSOLE_GEOMETRY_CIRC_LO);
|
|
||||||
printf( " wheel circumference .....: %d mm" _NL _NL, wheelCirc);
|
|
||||||
|
|
||||||
if (swVersion >= 59)
|
|
||||||
printf(
|
|
||||||
" mountain cap ............: %0.2f%%" _NL,
|
|
||||||
(getValue(CONSOLE, CONSOLE_ASSIST_MOUNTAINCAP) * 1.5625));
|
|
||||||
|
|
||||||
printf( " odo .....................: %0.2f Km" _NL _NL,
|
|
||||||
((getValue(CONSOLE, CONSOLE_STATS_BCValueTypeWord_1) << 24) +
|
|
||||||
(getValue(CONSOLE, CONSOLE_STATS_BCValueTypeWord_2) << 16) +
|
|
||||||
(getValue(CONSOLE, CONSOLE_STATS_BCValueTypeWord_3) << 8) +
|
|
||||||
(getValue(CONSOLE, CONSOLE_STATS_BCValueTypeWord_4))) / (double)10
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
hwVersion = getValue(BATTERY, BATTERY_REF_HW);
|
|
||||||
if (hwVersion == 0)
|
|
||||||
printf("Battery not responding" _NL _NL);
|
|
||||||
else {
|
|
||||||
printf( "Battery information:" _NL
|
|
||||||
" hardware version ........: %02d" _NL
|
|
||||||
" software version ........: %02d" _NL,
|
|
||||||
hwVersion, getValue(BATTERY, BATTERY_REF_SW)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!gNoSerialNumbers)
|
|
||||||
printf( " part number .............: %05d" _NL
|
|
||||||
" item number .............: %05d" _NL,
|
|
||||||
((getValue(BATTERY, BATTERY_SN_PN_HI) << 8) + getValue(BATTERY, BATTERY_SN_PN_LO)),
|
|
||||||
((getValue(BATTERY, BATTERY_SN_ITEM_HI) << 8) + getValue(BATTERY, BATTERY_SN_ITEM_LO))
|
|
||||||
);
|
|
||||||
|
|
||||||
printf( " voltage .................: %0.2fV" _NL
|
|
||||||
" battery level ...........: %0.2f%%" _NL
|
|
||||||
" maximum voltage .........: %0.2f%%" _NL
|
|
||||||
" minimum voltage .........: %0.2f%%" _NL
|
|
||||||
" mean voltage ............: %0.2f%%" _NL
|
|
||||||
" resets ..................: %0d" _NL
|
|
||||||
" ggjrCalib ...............: %0d" _NL
|
|
||||||
" vctrlShorts .............: %0d" _NL
|
|
||||||
" lmd .....................: %0.2fAh" _NL
|
|
||||||
" cell capacity ...........: %0.2fAh" _NL _NL,
|
|
||||||
((getValue(BATTERY, BATTERY_STATUS_VBATT_HI) << 8) + getValue(BATTERY, BATTERY_STATUS_VBATT_LO)) * 0.001,
|
|
||||||
(getValue(BATTERY, BATTERY_STATUS_LEVEL) * 6.6667),
|
|
||||||
getVoltageValue(BATTERY, BATTERY_STATS_VBATTMAX),
|
|
||||||
getVoltageValue(BATTERY, BATTERY_STATS_VBATTMIN),
|
|
||||||
getVoltageValue(BATTERY, BATTERY_STATS_VBATTMEAN),
|
|
||||||
(getValue(BATTERY, BATTERY_STATS_RESET_HI) << 8) + getValue(BATTERY, BATTERY_STATS_RESET_LO),
|
|
||||||
getValue(BATTERY, BATTERY_STSTS_GGJSRCALIB),
|
|
||||||
getValue(BATTERY, BATTERY_STSTS_VCTRLSHORTS),
|
|
||||||
((getValue(BATTERY, BATTERY_STATS_LMD_HI) << 8) + getValue(BATTERY, BATTERY_STATS_LMD_LO)) * 0.002142,
|
|
||||||
((getValue(BATTERY, BATTERY_CONFIG_CELLCAPACITY_HI) << 8) + getValue(BATTERY, BATTERY_CONFIG_CELLCAPACITY_LO)) * 0.001
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
printf( " charge time worst .......: %0d" _NL
|
|
||||||
" charge time mean ........: %0d" _NL
|
|
||||||
" charge cycles ...........: %0d" _NL
|
|
||||||
" full charge cycles ......: %0d" _NL
|
|
||||||
" power cycles ............: %0d" _NL
|
|
||||||
" battery temp max ........: %0d" _NL
|
|
||||||
" battery temp min ........: %0d" _NL _NL,
|
|
||||||
(getValue(BATTERY, BATTERY_STATS_CHARGETIMEWORST_HI) << 8) + getValue(BATTERY, BATTERY_STATS_CHARGETIMEWORST_LO),
|
|
||||||
(getValue(BATTERY, BATTERY_STATS_CHARGETIMEMEAN_HI) << 8) + getValue(BATTERY, BATTERY_STATS_CHARGETIMEMEAN_LO),
|
|
||||||
(getValue(BATTERY, BATTERY_STATS_BATTCYCLES_HI) << 8) + getValue(BATTERY, BATTERY_STATS_BATTCYCLES_LO),
|
|
||||||
(getValue(BATTERY, BATTERY_STATS_BATTFULLCYCLES_HI) << 8) + getValue(BATTERY, BATTERY_STATS_BATTFULLCYCLES_LO),
|
|
||||||
(getValue(BATTERY, BATTERY_STATS_POWERCYCLES_HI) << 8) + getValue(BATTERY, BATTERY_STATS_POWERCYCLES_HI),
|
|
||||||
getValue(BATTERY, BATTERY_STATS_TBATTMAX),
|
|
||||||
getValue(BATTERY, BATTERY_STATS_TBATTMIN)
|
|
||||||
);
|
|
||||||
|
|
||||||
printChargeStats();
|
|
||||||
|
|
||||||
if (hwVersion >= 60)
|
|
||||||
printBatteryStats();
|
|
||||||
else
|
|
||||||
printf(" no battery details supported by battery hardware #%d" _NL _NL, hwVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
hwVersion = getValue(MOTOR, MOTOR_REF_HW);
|
|
||||||
if (hwVersion == 0)
|
|
||||||
printf("Motor not responding" _NL _NL);
|
|
||||||
else {
|
|
||||||
printf( "Motor information:" _NL
|
|
||||||
" hardware version ........: %02d" _NL
|
|
||||||
" software version ........: %02d" _NL
|
|
||||||
//" temperature .............: %02d" _DEGREE_SIGN "C"_NL
|
|
||||||
" speed limit .............: %02d Km/h" _NL,
|
|
||||||
hwVersion, getValue(MOTOR, MOTOR_REF_SW),
|
|
||||||
getValue(MOTOR, MOTOR_REALTIME_TEMP),
|
|
||||||
getValue(MOTOR, MOTOR_ASSIST_MAXSPEED)
|
|
||||||
);
|
|
||||||
|
|
||||||
wheelCirc = (getValue(MOTOR, MOTOR_GEOMETRY_CIRC_HI) << 8) + getValue(MOTOR, MOTOR_GEOMETRY_CIRC_LO);
|
|
||||||
printf( " wheel circumference .....: %d mm" _NL _NL, wheelCirc);
|
|
||||||
|
|
||||||
if (!gNoSerialNumbers)
|
|
||||||
printf( " part number .............: %05d" _NL
|
|
||||||
" item number .............: %05d" _NL _NL,
|
|
||||||
((getValue(MOTOR, MOTOR_SN_PN_HI) << 8) + getValue(MOTOR, MOTOR_SN_PN_LO)),
|
|
||||||
((getValue(MOTOR, MOTOR_SN_ITEM_HI) << 8) + getValue(MOTOR, MOTOR_SN_ITEM_LO))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int xmain(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int err, doShutdown = 0, consoleInSlaveMode = 0;
|
|
||||||
struct TDeviceStatus status;
|
|
||||||
|
|
||||||
printf("BigXionFlasher USB " __BXF_VERSION__ _NL " (c) 2011-2013 by Thomas Koenig <info@bigxionflasher.org> - www.bigxionflasher.org" _NL);
|
|
||||||
|
|
||||||
if ((err=parseOptions(argc, argv) < 0))
|
|
||||||
exit(1);
|
|
||||||
|
|
||||||
if ((err = LoadDriver(TREIBER_NAME)) < 0) {
|
|
||||||
printf("LoadDriver error: %d" _NL, err);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((err = CanInitDriver(NULL)) < 0) {
|
|
||||||
printf("CanInitDriver error: %d" _NL, err);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((err = CanDeviceOpen(0, DEVICE_OPEN)) < 0) {
|
|
||||||
printf("CanDeviceOpen error: %d" _NL, err);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
CanSetSpeed(0, CAN_125K_BIT);
|
|
||||||
CanSetMode(0, OP_CAN_START, CAN_CMD_ALL_CLEAR);
|
|
||||||
CanGetDeviceStatus(0, &status);
|
|
||||||
|
|
||||||
if (status.DrvStatus >= DRV_STATUS_CAN_OPEN)
|
|
||||||
{
|
|
||||||
if (status.CanStatus == CAN_STATUS_BUS_OFF)
|
|
||||||
{
|
|
||||||
printf("CAN Status BusOff" _NL);
|
|
||||||
CanSetMode(0, OP_CAN_RESET, CAN_CMD_NONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("error: could not open device" _NL);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
consoleInSlaveMode = getValue(CONSOLE, CONSOLE_STATUS_SLAVE);
|
|
||||||
|
|
||||||
if (consoleInSlaveMode)
|
|
||||||
{
|
|
||||||
printf("console already in salve mode. good!" _NL _NL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (gConsoleSetSlaveMode)
|
|
||||||
{
|
|
||||||
int retry = 20;
|
|
||||||
|
|
||||||
printf("putting console in salve mode ... ");
|
|
||||||
do {
|
|
||||||
setValue(CONSOLE, CONSOLE_STATUS_SLAVE, 1);
|
|
||||||
consoleInSlaveMode = getValue(CONSOLE, CONSOLE_STATUS_SLAVE);
|
|
||||||
usleep(200000);
|
|
||||||
} while(retry-- && !consoleInSlaveMode);
|
|
||||||
|
|
||||||
doSleep(500); // give the console some time to settle
|
|
||||||
printf("%s" _NL _NL, consoleInSlaveMode ? "done" : "failed");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("console not in slave mode" _NL _NL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gAssistInitLevel != -1)
|
|
||||||
{
|
|
||||||
printf("setting initial assistance level to %d" _NL, gAssistInitLevel);
|
|
||||||
setValue(CONSOLE, CONSOLE_ASSIST_INITLEVEL, gAssistInitLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gSetSpeedLimit > 0)
|
|
||||||
{
|
|
||||||
printf("set speed limit to %0.2f km/h" _NL, gSetSpeedLimit);
|
|
||||||
setSpeedLimit(gSetSpeedLimit);
|
|
||||||
doShutdown = 1;
|
|
||||||
} else if (gSetSpeedLimit == 0) {
|
|
||||||
printf("disable speed limit, drive carefully" _NL);
|
|
||||||
setSpeedLimit(0);
|
|
||||||
doShutdown = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gSetMinSpeedLimit > 0) {
|
|
||||||
printf("set minimal speed limit to %0.2f km/h" _NL, gSetMinSpeedLimit);
|
|
||||||
setMinSpeedLimit(gSetMinSpeedLimit);
|
|
||||||
doShutdown = 1;
|
|
||||||
} else if (gSetMinSpeedLimit == 0) {
|
|
||||||
printf("disable minimal speed limit, drive carefully" _NL);
|
|
||||||
setMinSpeedLimit(0);
|
|
||||||
doShutdown = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gSetThrottleSpeedLimit > 0) {
|
|
||||||
printf("set throttle speed limit to %0.2f km/h" _NL, gSetThrottleSpeedLimit);
|
|
||||||
setThrottleSpeedLimit(gSetThrottleSpeedLimit);
|
|
||||||
doShutdown = 1;
|
|
||||||
} else if (gSetThrottleSpeedLimit == 0) {
|
|
||||||
printf("disable throttle speed limit, drive carefully" _NL);
|
|
||||||
setThrottleSpeedLimit(0);
|
|
||||||
doShutdown = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gSetMountainCap > 0) {
|
|
||||||
printf("set mountain cap level to %0.2f%%" _NL, ((int)gSetMountainCap / 1.5625) * 1.5625);
|
|
||||||
setValue(CONSOLE, CONSOLE_ASSIST_MOUNTAINCAP, gSetMountainCap / 1.5625);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gSetWheelCircumference > 0) {
|
|
||||||
printf("set wheel circumference to %d" _NL, gSetWheelCircumference);
|
|
||||||
setWheelCircumference(gSetWheelCircumference);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gPrintSystemSettings)
|
|
||||||
printSystemSettings();
|
|
||||||
|
|
||||||
if ((doShutdown && !gSkipShutdown) || gPowerOff) {
|
|
||||||
doSleep(1000);
|
|
||||||
printf("shutting down system." _NL);
|
|
||||||
setValue(BATTERY, BATTERY_CONFIG_SHUTDOWN, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
CanDownDriver();
|
|
||||||
UnloadDriver();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
error:
|
|
||||||
CanDownDriver();
|
|
||||||
UnloadDriver();
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
25
armhf-toolchain.cmake
Normal file
25
armhf-toolchain.cmake
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# Name des Zielsystems
|
||||||
|
set(CMAKE_SYSTEM_NAME Linux)
|
||||||
|
set(CMAKE_SYSTEM_PROCESSOR arm)
|
||||||
|
|
||||||
|
# Die Cross-Compiler aus dem Debian-Paket für 32-Bit (armhf)
|
||||||
|
set(CMAKE_C_COMPILER /usr/bin/arm-linux-gnueabihf-gcc)
|
||||||
|
set(CMAKE_CXX_COMPILER /usr/bin/arm-linux-gnueabihf-g++)
|
||||||
|
|
||||||
|
# Wo das System nach Bibliotheken und Headern suchen soll (Sysroot)
|
||||||
|
set(CMAKE_SYSROOT /)
|
||||||
|
|
||||||
|
# Pfade für pkg-config anpassen, damit es die armhf .pc Dateien findet
|
||||||
|
set(ENV{PKG_CONFIG_DIR} "")
|
||||||
|
set(ENV{PKG_CONFIG_LIBDIR} "/usr/lib/arm-linux-gnueabihf/pkgconfig:/usr/share/pkgconfig")
|
||||||
|
set(ENV{PKG_CONFIG_SYSROOT_DIR} ${CMAKE_SYSROOT})
|
||||||
|
|
||||||
|
# Suchverhalten für find_package(), find_library() etc.
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # Programme (wie moc) auf dem Host suchen
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) # Libs nur im Target (armhf) suchen
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) # Header nur im Target (armhf) suchen
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) # CMake-Pakete nur im Target suchen
|
||||||
|
|
||||||
|
# *** WICHTIG FÜR QT6 ***
|
||||||
|
# Sagt Qt, wo es die Host-Tools für das Code-Generieren findet
|
||||||
|
set(QT_HOST_PATH "/usr")
|
||||||
78
bc.h
78
bc.h
@@ -36,9 +36,39 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QObject> // Nötig für Q_GADGET/Q_ENUM Makros
|
#include <QObject> // Nötig für Q_GADGET/Q_ENUM Makros
|
||||||
|
#include <QTime>
|
||||||
|
|
||||||
//uint8_t;
|
//uint8_t;
|
||||||
|
|
||||||
|
#define BCTimeStamp QTime::currentTime().toString("hh:mm:ss.zzz: ")
|
||||||
|
|
||||||
|
using namespace Qt::Literals::StringLiterals; // Für _L1
|
||||||
|
|
||||||
|
namespace BCTags
|
||||||
|
{
|
||||||
|
inline constexpr auto Bike = "Bike"_L1;
|
||||||
|
inline constexpr auto Device = "Device"_L1;
|
||||||
|
inline constexpr auto ID = "ID"_L1;
|
||||||
|
inline constexpr auto Label = "Label"_L1;
|
||||||
|
inline constexpr auto UnitLabel = "UnitLabel"_L1;
|
||||||
|
inline constexpr auto IsWord = "IsWord"_L1;
|
||||||
|
inline constexpr auto ReadOnly = "ReadOnly"_L1;
|
||||||
|
inline constexpr auto Default = "Default"_L1;
|
||||||
|
|
||||||
|
inline constexpr auto Current = "Current"_L1;
|
||||||
|
inline constexpr auto Enabled = "Enabled"_L1;
|
||||||
|
inline constexpr auto ValueType = "ValueType"_L1;
|
||||||
|
inline constexpr auto Min = "Min"_L1;
|
||||||
|
inline constexpr auto Max = "Max"_L1;
|
||||||
|
inline constexpr auto Factor = "Factor"_L1;
|
||||||
|
|
||||||
|
inline constexpr auto Yes = "Yes"_L1;
|
||||||
|
inline constexpr auto No = "No"_L1;
|
||||||
|
|
||||||
|
inline constexpr auto Host = "bionxcontrol"_L1;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Simple exception class
|
* @brief Simple exception class
|
||||||
@@ -73,15 +103,6 @@ namespace bc
|
|||||||
[[maybe_unused]] constexpr static double NORMALIZED_VOLTAGE_OFFSET = 20.8333;
|
[[maybe_unused]] constexpr static double NORMALIZED_VOLTAGE_OFFSET = 20.8333;
|
||||||
[[maybe_unused]] constexpr static double NORMALIZED_VOLTAGE_FAKTOR = 0.416667;
|
[[maybe_unused]] constexpr static double NORMALIZED_VOLTAGE_FAKTOR = 0.416667;
|
||||||
|
|
||||||
// misc
|
|
||||||
//#define cbc::Version "CanBusControl 0.0.01 / 02.07.2022"
|
|
||||||
[[maybe_unused]] constexpr static const char* Version = "BionxControl 0.1.00 / 08.11.2022 © 2022 chris@sourceworx.org";
|
|
||||||
|
|
||||||
[[maybe_unused]] constexpr static const char* OrgName = "source::worx";
|
|
||||||
[[maybe_unused]] constexpr static const char* DomainName = "sourceworx.org";
|
|
||||||
[[maybe_unused]] constexpr static const char* AppName = "BionxControl";
|
|
||||||
|
|
||||||
|
|
||||||
// timer
|
// timer
|
||||||
void delay_seconds( uint32_t );
|
void delay_seconds( uint32_t );
|
||||||
void delay_millis( uint32_t );
|
void delay_millis( uint32_t );
|
||||||
@@ -91,27 +112,6 @@ namespace bc
|
|||||||
QString formatInt( int count, int len );
|
QString formatInt( int count, int len );
|
||||||
} // namespace bc
|
} // namespace bc
|
||||||
|
|
||||||
// abbreviations:
|
|
||||||
// SOC = State Of Charge
|
|
||||||
// LMD = Last Measured Discharge
|
|
||||||
// NIP = ?
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
Needed ?
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
template <typename E>
|
|
||||||
constexpr auto to_u(E e) noexcept {
|
|
||||||
return static_cast<std::underlying_type_t<E>>(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// constants.h
|
|
||||||
#pragma once
|
|
||||||
#include <QLatin1StringView>
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct BC
|
struct BC
|
||||||
{
|
{
|
||||||
@@ -766,23 +766,5 @@ public:
|
|||||||
Q_ENUM(ID)
|
Q_ENUM(ID)
|
||||||
};
|
};
|
||||||
|
|
||||||
using namespace Qt::Literals::StringLiterals; // Für _L1
|
|
||||||
|
|
||||||
namespace BCTags
|
|
||||||
{
|
|
||||||
inline constexpr auto Device = "Device"_L1;
|
|
||||||
inline constexpr auto ID = "ID"_L1;
|
|
||||||
inline constexpr auto Label = "Label"_L1;
|
|
||||||
inline constexpr auto UnitLabel = "UnitLabel"_L1;
|
|
||||||
inline constexpr auto IsWord = "IsWord"_L1;
|
|
||||||
inline constexpr auto Default = "Default"_L1;
|
|
||||||
|
|
||||||
inline constexpr auto Current = "Current"_L1;
|
|
||||||
inline constexpr auto Enabled = "Enabled"_L1;
|
|
||||||
inline constexpr auto ValueType = "ValueType"_L1;
|
|
||||||
inline constexpr auto Min = "Min"_L1;
|
|
||||||
inline constexpr auto Max = "Max"_L1;
|
|
||||||
inline constexpr auto Factor = "Factor"_L1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // BC_H
|
#endif // BC_H
|
||||||
|
|||||||
@@ -1,358 +0,0 @@
|
|||||||
/***************************************************************************
|
|
||||||
|
|
||||||
BionxControl
|
|
||||||
© 2025 -2026 christoph holzheuer
|
|
||||||
christoph.holzheuer@gmail.com
|
|
||||||
|
|
||||||
Using:
|
|
||||||
|
|
||||||
mhs_can_drv.c
|
|
||||||
© 2011 - 2023 by MHS-Elektronik GmbH & Co. KG, Germany
|
|
||||||
Klaus Demlehner, klaus@mhs-elektronik.de
|
|
||||||
@see www.mhs-elektronik.de
|
|
||||||
|
|
||||||
Based on Bionx data type descriptions from:
|
|
||||||
|
|
||||||
BigXionFlasher USB V 0.2.4 rev. 97
|
|
||||||
© 2011-2013 by Thomas Koenig <info@bigxionflasher.org>
|
|
||||||
@see www.bigxionflasher.org
|
|
||||||
|
|
||||||
Bionx Bike Info
|
|
||||||
© 2018 Thorsten Schmidt (tschmidt@ts-soft.de)
|
|
||||||
@see www.ts-soft.de
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
@see https://github.com/bikemike/bionx-bikeinfo
|
|
||||||
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
#include <QSlider>
|
|
||||||
#include <QLabel>
|
|
||||||
#include <QHBoxLayout>
|
|
||||||
#include <QWidget>
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QPainter>
|
|
||||||
#include <QTimer>
|
|
||||||
#include <QTableView>
|
|
||||||
|
|
||||||
#include <QVariantAnimation>
|
|
||||||
#include <QPropertyAnimation>
|
|
||||||
#include <QPainter>
|
|
||||||
|
|
||||||
#include "bcanimateddelegate.h"
|
|
||||||
|
|
||||||
|
|
||||||
BCAnimatedDelegate::BCAnimatedDelegate(const BCValueList& valueList, QTableView* view)
|
|
||||||
: QStyledItemDelegate{view}, _valueList{valueList}, _view{view}
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
QString BCAnimatedDelegate::displayText(const QVariant& dataValue, const QLocale& locale) const
|
|
||||||
{
|
|
||||||
// Wir prüfen, ob im Variant unser Struct steckt
|
|
||||||
if (dataValue.canConvert<const BCValue&>())
|
|
||||||
{
|
|
||||||
const BCValue& bc = dataValue.value<const BCValue/>();
|
|
||||||
//qDebug() << " --- YES: " << bc.label;
|
|
||||||
// Hier bauen wir den String zusammen, den man sieht,
|
|
||||||
// wenn KEIN Editor offen ist.
|
|
||||||
// Format: "Label: Wert Einheit"
|
|
||||||
return QString("%1: %2 %3").arg(bc.label, bc.visibleValue, "mmX");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
qDebug() << " --- Nö!";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback für normale Strings/Zahlen
|
|
||||||
return QStyledItemDelegate::displayText(dataValue, locale);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
QWidget *BCAnimatedDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex& index) const
|
|
||||||
{
|
|
||||||
QVariant rawData = index.data(Qt::EditRole);
|
|
||||||
//if (!rawData.canConvert<BCValue*>())
|
|
||||||
return QStyledItemDelegate::createEditor(parent, option, index);
|
|
||||||
/*
|
|
||||||
const BCValue& bc = *rawData.value<BCValue*>();
|
|
||||||
|
|
||||||
// Nur bei Integern den Slider-Editor bauen
|
|
||||||
if (bc.value.typeId() == QMetaType::Int)
|
|
||||||
{
|
|
||||||
QWidget *container = new QWidget(parent);
|
|
||||||
container->setAutoFillBackground(true);
|
|
||||||
|
|
||||||
QHBoxLayout *layout = new QHBoxLayout(container);
|
|
||||||
layout->setContentsMargins(4, 0, 4, 0);
|
|
||||||
layout->setSpacing(10);
|
|
||||||
|
|
||||||
// Linkes Label (Name)
|
|
||||||
QLabel *lblName = new QLabel(bc.label, container);
|
|
||||||
lblName->setFixedWidth(80);
|
|
||||||
|
|
||||||
// Slider
|
|
||||||
QSlider *slider = new QSlider(Qt::Horizontal, container);
|
|
||||||
slider->setRange(0, 100);
|
|
||||||
slider->setObjectName("slider");
|
|
||||||
|
|
||||||
// Rechtes Label (Vorschau Wert + Einheit)
|
|
||||||
QLabel *lblUnit = new QLabel(container);
|
|
||||||
lblUnit->setFixedWidth(60);
|
|
||||||
lblUnit->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
|
||||||
lblUnit->setObjectName("lblUnit");
|
|
||||||
|
|
||||||
layout->addWidget(lblName);
|
|
||||||
layout->addWidget(slider);
|
|
||||||
layout->addWidget(lblUnit);
|
|
||||||
|
|
||||||
// Live-Update des Labels im Editor (aber noch kein Speichern im Model)
|
|
||||||
connect(slider, &QSlider::valueChanged, this, [=](int val){
|
|
||||||
lblUnit->setText(QString("%1 %2").arg(val).arg("mm2"));
|
|
||||||
});
|
|
||||||
|
|
||||||
return container;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return QStyledItemDelegate::createEditor(parent, option, index);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void BCAnimatedDelegate::setEditorData(QWidget *editor, const QModelIndex& index) const
|
|
||||||
{
|
|
||||||
// Daten vom Model in den Editor laden
|
|
||||||
const BCValue& bc = *index.data(Qt::EditRole).value<BCValue*>();
|
|
||||||
|
|
||||||
QSlider *slider = editor->findChild<QSlider*>("slider");
|
|
||||||
QLabel *lblUnit = editor->findChild<QLabel*>("lblUnit");
|
|
||||||
|
|
||||||
if (slider && lblUnit) {
|
|
||||||
bool olDriverState = slider->blockSignals(true);
|
|
||||||
slider->setValue(bc.visibleValue.toInt());
|
|
||||||
slider->blockSignals(olDriverState);
|
|
||||||
|
|
||||||
lblUnit->setText(QString("%1 %2").arg(bc.visibleValue.toInt()).arg( "mm3"));
|
|
||||||
} else {
|
|
||||||
QStyledItemDelegate::setEditorData(editor, index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BCAnimatedDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex& index) const
|
|
||||||
{
|
|
||||||
// Daten vom Editor zurück ins Model speichern (Beim Schließen)
|
|
||||||
QSlider *slider = editor->findChild<QSlider*>("slider");
|
|
||||||
|
|
||||||
if (slider) {
|
|
||||||
int value = slider->value();
|
|
||||||
model->setData(index, value, Qt::EditRole);
|
|
||||||
} else {
|
|
||||||
QStyledItemDelegate::setModelData(editor, model, index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BCAnimatedDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex& index) const
|
|
||||||
{
|
|
||||||
// __fix!
|
|
||||||
editor->setGeometry(option.rect);
|
|
||||||
}
|
|
||||||
|
|
||||||
QSize BCAnimatedDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex& index) const
|
|
||||||
{
|
|
||||||
return QStyledItemDelegate::sizeHint(option,index);
|
|
||||||
/*
|
|
||||||
QStyleOptionViewItem opt = option;
|
|
||||||
initStyleOption(&opt, index);
|
|
||||||
opt.text = formatDisplayString(index);
|
|
||||||
|
|
||||||
QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
|
|
||||||
return style->sizeFromContents(QStyle::CT_ItemViewItem, &opt, QSize(), opt.widget);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void BCAnimatedDelegate::paint(QPainter *painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
|
||||||
{
|
|
||||||
|
|
||||||
// Standard-Zeichnen (Text, Hintergrund, Selection) durchführen
|
|
||||||
QStyledItemDelegate::paint(painter, option, index);
|
|
||||||
|
|
||||||
int row = index.row();
|
|
||||||
int col = index.column();
|
|
||||||
|
|
||||||
switch (col)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
|
|
||||||
if( m_rowOpacities.contains(row))
|
|
||||||
paintHighlightRow(painter,option,index);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
|
|
||||||
if( row>-1 && row <= _valueList.size() )
|
|
||||||
paintSliderIndicator(painter,option,index);
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void BCAnimatedDelegate::paintHighlightRow(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
|
||||||
{
|
|
||||||
painter->save();
|
|
||||||
painter->setRenderHint(QPainter::Antialiasing);
|
|
||||||
int row = index.row();
|
|
||||||
qreal opacity = m_rowOpacities.value(row);
|
|
||||||
painter->setOpacity(opacity);
|
|
||||||
// Margin von 4px
|
|
||||||
QRect itemRect = option.rect.adjusted(3, 3, -3, -3);
|
|
||||||
|
|
||||||
// Border (2px solid #2196F3)
|
|
||||||
QPen borderPen( Qt::red, 1);
|
|
||||||
painter->setPen(borderPen);
|
|
||||||
painter->setBrush(Qt::NoBrush);
|
|
||||||
painter->drawRoundedRect(itemRect, 2, 2);
|
|
||||||
|
|
||||||
painter->restore();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void BCAnimatedDelegate::paintSliderIndicator(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
|
||||||
{
|
|
||||||
|
|
||||||
const BCValue& valueX = *(_valueList[ index.row()].get());
|
|
||||||
int value = 50;index.model()->data(index, Qt::DisplayRole).toInt();
|
|
||||||
|
|
||||||
// Hintergrund
|
|
||||||
if (option.state & QStyle::State_Selected)
|
|
||||||
{
|
|
||||||
painter->fillRect(option.rect, option.palette.highlight());
|
|
||||||
}
|
|
||||||
else if (index.row() % 2 == 1)
|
|
||||||
{
|
|
||||||
painter->fillRect(option.rect, QColor(0xFAFAFA));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
painter->fillRect(option.rect, Qt::white);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Text und kleiner Slider-Indikator zeichnen
|
|
||||||
painter->save();
|
|
||||||
painter->setRenderHint(QPainter::Antialiasing);
|
|
||||||
|
|
||||||
//QRect textRect = option.rect.adjusted(8, 0, -120, 0);
|
|
||||||
|
|
||||||
QRect barRect = option.rect.adjusted
|
|
||||||
(
|
|
||||||
8,
|
|
||||||
option.rect.height() / 2 - 2,
|
|
||||||
-8,
|
|
||||||
-option.rect.height() / 2 + 2
|
|
||||||
);
|
|
||||||
|
|
||||||
//QRect barRect = option.rect;
|
|
||||||
// Text
|
|
||||||
//painter->setPen(option.state & QStyle::State_Selected ? option.palette.highlightedText().color() : Qt::black);
|
|
||||||
//painter->drawText(textRect, Qt::AlignVCenter | Qt::AlignLeft,
|
|
||||||
// QString::number(value));
|
|
||||||
|
|
||||||
// Mini Progress Bar
|
|
||||||
painter->setPen(Qt::NoPen);
|
|
||||||
painter->setBrush(QColor(0xE0E0E0));
|
|
||||||
painter->drawRoundedRect(barRect, 2, 2);
|
|
||||||
|
|
||||||
QRect fillRect = barRect;
|
|
||||||
fillRect.setWidth(barRect.width() * value / 100);
|
|
||||||
painter->setBrush(QColor(0x0078D4));
|
|
||||||
painter->drawRoundedRect(fillRect, 2, 2);
|
|
||||||
|
|
||||||
painter->restore();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void BCAnimatedDelegate::onHighlightRow(int row)
|
|
||||||
{
|
|
||||||
// Alte Animation für diese Zeile stoppen falls vorhanden
|
|
||||||
if (m_rowAnimations.contains(row))
|
|
||||||
{
|
|
||||||
m_rowAnimations[row]->stop();
|
|
||||||
m_rowAnimations[row]->deleteLater();
|
|
||||||
}
|
|
||||||
|
|
||||||
// QVariantAnimation ist flexibler als QPropertyAnimation
|
|
||||||
auto* anim = new QVariantAnimation(this);
|
|
||||||
anim->setDuration(800);
|
|
||||||
anim->setStartValue(0.0);
|
|
||||||
anim->setEndValue(1.0);
|
|
||||||
|
|
||||||
// Custom Easing für Fade-in/out Effekt
|
|
||||||
anim->setEasingCurve(QEasingCurve::OutQuad);
|
|
||||||
|
|
||||||
connect(anim, &QVariantAnimation::valueChanged, this, [this, row](const QVariant& value)
|
|
||||||
{
|
|
||||||
qreal progress = value.toReal();
|
|
||||||
qreal opacity;
|
|
||||||
|
|
||||||
// Schnelles Fade-in (20%), langsames Fade-out (80%)
|
|
||||||
if (progress < 0.2) {
|
|
||||||
opacity = progress * 5.0; // 0->1 in 20%
|
|
||||||
} else {
|
|
||||||
opacity = 1.0 - ((progress - 0.2) / 0.8); // 1->0 in 80%
|
|
||||||
}
|
|
||||||
|
|
||||||
m_rowOpacities[row] = opacity;
|
|
||||||
updateRow(row);
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(anim, &QVariantAnimation::finished, this, [this, row, anim]()
|
|
||||||
{
|
|
||||||
m_rowOpacities.remove(row);
|
|
||||||
m_rowAnimations.remove(row);
|
|
||||||
updateRow(row);
|
|
||||||
anim->deleteLater();
|
|
||||||
});
|
|
||||||
|
|
||||||
m_rowAnimations[row] = anim;
|
|
||||||
anim->start(QAbstractAnimation::DeleteWhenStopped);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Optional: alle Highlights sofort clearen
|
|
||||||
void BCAnimatedDelegate::clearAllHighlights()
|
|
||||||
{
|
|
||||||
for(auto* anim : std::as_const(m_rowAnimations))
|
|
||||||
{
|
|
||||||
anim->stop();
|
|
||||||
anim->deleteLater();
|
|
||||||
}
|
|
||||||
m_rowAnimations.clear();
|
|
||||||
m_rowOpacities.clear();
|
|
||||||
|
|
||||||
if (_view)
|
|
||||||
{
|
|
||||||
_view->viewport()->update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BCAnimatedDelegate::updateRow(int row)
|
|
||||||
{
|
|
||||||
if (_view && _view->model() && row >= 0)
|
|
||||||
{
|
|
||||||
QModelIndex idx = _view->model()->index(row,1);
|
|
||||||
QRect rect = _view->visualRect(idx);
|
|
||||||
if (!rect.isEmpty()) {
|
|
||||||
_view->viewport()->update(rect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
216
bcdelightpmwidget.cpp
Normal file
216
bcdelightpmwidget.cpp
Normal file
@@ -0,0 +1,216 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
BionxControl
|
||||||
|
© 2025 -2026 christoph holzheuer
|
||||||
|
christoph.holzheuer@gmail.com
|
||||||
|
|
||||||
|
Using:
|
||||||
|
|
||||||
|
mhs_can_drv.c
|
||||||
|
© 2011 - 2023 by MHS-Elektronik GmbH & Co. KG, Germany
|
||||||
|
Klaus Demlehner, klaus@mhs-elektronik.de
|
||||||
|
@see www.mhs-elektronik.de
|
||||||
|
|
||||||
|
Based on Bionx data type descriptions from:
|
||||||
|
|
||||||
|
BigXionFlasher USB V 0.2.4 rev. 97
|
||||||
|
© 2011-2013 by Thomas Koenig <info@bigxionflasher.org>
|
||||||
|
@see www.bigxionflasher.org
|
||||||
|
|
||||||
|
Bionx Bike Info
|
||||||
|
© 2018 Thorsten Schmidt (tschmidt@ts-soft.de)
|
||||||
|
@see www.ts-soft.de
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
@see https://github.com/bikemike/bionx-bikeinfo
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include <QPropertyAnimation>
|
||||||
|
#include <QSequentialAnimationGroup>
|
||||||
|
#include <QParallelAnimationGroup>
|
||||||
|
#include <QRandomGenerator>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QGraphicsOpacityEffect>
|
||||||
|
#include <QPainterPath>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QIcon>
|
||||||
|
#include <QDirIterator>
|
||||||
|
#include <QPushButton>
|
||||||
|
|
||||||
|
#include <bcdelightpmwidget.h>
|
||||||
|
|
||||||
|
|
||||||
|
BCDelightPMWidget::BCDelightPMWidget(QWidget *parent)
|
||||||
|
: QObject(parent), _playGround{parent}
|
||||||
|
{
|
||||||
|
loadWidgetsFromResources();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Die Methode zum automatischen Einlesen
|
||||||
|
void BCDelightPMWidget::loadWidgetsFromResources()
|
||||||
|
{
|
||||||
|
|
||||||
|
QString resourcePath = ":/resources/smile";
|
||||||
|
|
||||||
|
QDirIterator it(resourcePath, QDir::Files);
|
||||||
|
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
QString fullPath = it.next();
|
||||||
|
// Eine Zufallsfarbe für den Button-Hintergrund generieren
|
||||||
|
QStringList colors = {"#ff5555", "#50fa7b", "#8be9fd", "#ffb86c"};
|
||||||
|
|
||||||
|
// Ihre Funktion aufrufen und den Pfad übergeben
|
||||||
|
createFlyingWidget(fullPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void BCDelightPMWidget::createFlyingWidget(const QString& iconPath)
|
||||||
|
{
|
||||||
|
// 1. Button als Kind des Playground erstellen
|
||||||
|
QPushButton *btn = new QPushButton(_playGround);
|
||||||
|
|
||||||
|
// 2. Das Icon laden und setzen
|
||||||
|
QPixmap pixmap(iconPath);
|
||||||
|
QIcon icon(pixmap);
|
||||||
|
btn->setIcon(icon);
|
||||||
|
|
||||||
|
// 3. WICHTIG: Icon-Größe und Button-Größe synchronisieren
|
||||||
|
// Damit das Bild den Button voll ausfüllt
|
||||||
|
QSize size(128, 128);
|
||||||
|
btn->setFixedSize(size); // Die Klick-Fläche
|
||||||
|
btn->setIconSize(size); // Das Bild darin
|
||||||
|
|
||||||
|
// 4. Stylesheet: Alle Standard-Rahmen und Hintergründe entfernen
|
||||||
|
// "border: none" entfernt den 3D-Rahmen
|
||||||
|
// "background: transparent" macht den Rest unsichtbar
|
||||||
|
btn->setStyleSheet(
|
||||||
|
"QPushButton {"
|
||||||
|
" border: none;"
|
||||||
|
" background-color: transparent;"
|
||||||
|
" outline: none;" /* Entfernt den Fokus-Rahmen beim Klicken */
|
||||||
|
"}"
|
||||||
|
// Optional: Kleiner visueller Effekt beim Drücken (Bild bewegt sich leicht)
|
||||||
|
"QPushButton:pressed {"
|
||||||
|
" padding-top: 4px;"
|
||||||
|
" padding-left: 4px;"
|
||||||
|
"}"
|
||||||
|
);
|
||||||
|
|
||||||
|
btn->show();
|
||||||
|
|
||||||
|
QGraphicsOpacityEffect *opacityEff = new QGraphicsOpacityEffect(btn);
|
||||||
|
opacityEff->setOpacity(1.0);
|
||||||
|
btn->setGraphicsEffect(opacityEff);
|
||||||
|
// --------------------------------------
|
||||||
|
|
||||||
|
btn->show();
|
||||||
|
|
||||||
|
btn->move(50 + _flyingWidgets.size() * 60, 50);
|
||||||
|
_flyingWidgets.append(btn);
|
||||||
|
|
||||||
|
btn->move(_playGround->width()/2, _playGround->height()/2);
|
||||||
|
opacityEff->setOpacity(0.0);
|
||||||
|
|
||||||
|
}
|
||||||
|
void BCDelightPMWidget::onStartChaos()
|
||||||
|
{
|
||||||
|
// Master-Gruppe, damit alle Widgets gleichzeitig starten
|
||||||
|
QParallelAnimationGroup *masterGroup = new QParallelAnimationGroup(this);
|
||||||
|
|
||||||
|
// Gemeinsamer Startpunkt berechnen (Mitte des Playgrounds)
|
||||||
|
// Wir ziehen die halbe Größe eines Widgets (ca. 25px) ab, damit sie wirklich zentriert sind
|
||||||
|
int centerX = (_playGround->width() / 2) - 25;
|
||||||
|
int centerY = (_playGround->height() / 2) - 25;
|
||||||
|
QPoint startPoint(centerX, centerY);
|
||||||
|
|
||||||
|
for (QWidget *widget : std::as_const(_flyingWidgets))
|
||||||
|
{
|
||||||
|
|
||||||
|
QParallelAnimationGroup *widgetGroup = new QParallelAnimationGroup(masterGroup);
|
||||||
|
|
||||||
|
// ---------------------------------------------------------
|
||||||
|
// 1. Die Bogen-Animation (QVariantAnimation statt QPropertyAnimation)
|
||||||
|
// ---------------------------------------------------------
|
||||||
|
|
||||||
|
// ZIELE UND STÜTZPUNKTE BERECHNEN
|
||||||
|
int maxX = _playGround->width() - widget->width();
|
||||||
|
int maxY = _playGround->height() - widget->height();
|
||||||
|
QPoint endPoint(
|
||||||
|
QRandomGenerator::global()->bounded(qMax(0, maxX)),
|
||||||
|
QRandomGenerator::global()->bounded(qMax(0, maxY))
|
||||||
|
);
|
||||||
|
|
||||||
|
// Der Kontrollpunkt bestimmt die Kurve.
|
||||||
|
// Für eine Rakete muss er viel HÖHER liegen als Start und Ziel.
|
||||||
|
// Wir nehmen die Mitte zwischen Start/Ziel und gehen 300px nach oben (Y minus).
|
||||||
|
int controlX = (startPoint.x() + endPoint.x()) / 2;
|
||||||
|
int controlY = qMin(startPoint.y(), endPoint.y()) - 300;
|
||||||
|
|
||||||
|
// Pfad erstellen (Quadratische Bézierkurve)
|
||||||
|
QPainterPath path;
|
||||||
|
path.moveTo(startPoint);
|
||||||
|
// quadTo(Kontrollpunkt, Endpunkt)
|
||||||
|
path.quadTo(controlX, controlY, endPoint.x(), endPoint.y());
|
||||||
|
|
||||||
|
// Die Animation treibt den Fortschritt von 0.0 bis 1.0
|
||||||
|
QVariantAnimation *animCurve = new QVariantAnimation();
|
||||||
|
int duration = 2600 + QRandomGenerator::global()->bounded(800);
|
||||||
|
animCurve->setDuration(duration);
|
||||||
|
animCurve->setStartValue(0.0);
|
||||||
|
animCurve->setEndValue(1.0);
|
||||||
|
|
||||||
|
// Für ballistische Flugbahnen ist 'OutQuad' oder 'OutSine' realistisch
|
||||||
|
// (Schneller Start, oben langsamer, unten wieder schneller - physikalisch komplex,
|
||||||
|
// aber OutQuad sieht gut aus für "Wurf")
|
||||||
|
animCurve->setEasingCurve(QEasingCurve::OutQuad);
|
||||||
|
|
||||||
|
// WICHTIG: Lambda, um bei jedem Schritt die Position zu setzen
|
||||||
|
// Wir müssen 'widget' und 'path' in das Lambda capturen (by value für path ist ok)
|
||||||
|
connect(animCurve, &QVariantAnimation::valueChanged, [widget, path](const QVariant &val){
|
||||||
|
qreal progress = val.toReal();
|
||||||
|
|
||||||
|
// Magie: Berechne den Punkt auf der Kurve bei 'progress' Prozent
|
||||||
|
QPointF currentPos = path.pointAtPercent(progress);
|
||||||
|
|
||||||
|
widget->move(currentPos.toPoint());
|
||||||
|
});
|
||||||
|
|
||||||
|
widgetGroup->addAnimation(animCurve);
|
||||||
|
|
||||||
|
// ---------------------------------------------------------
|
||||||
|
// 2. Fade-Out (Bleibt fast gleich)
|
||||||
|
// ---------------------------------------------------------
|
||||||
|
QGraphicsOpacityEffect *eff = qobject_cast<QGraphicsOpacityEffect*>(widget->graphicsEffect());
|
||||||
|
if (eff) {
|
||||||
|
QPropertyAnimation *animFade = new QPropertyAnimation(eff, "opacity");
|
||||||
|
animFade->setDuration(duration);
|
||||||
|
animFade->setStartValue(1.0);
|
||||||
|
animFade->setEndValue(0.0);
|
||||||
|
// Erst am Ende ausblenden (ExpoCurve), damit man den Flugbogen sieht
|
||||||
|
animFade->setEasingCurve(QEasingCurve::InExpo);
|
||||||
|
widgetGroup->addAnimation(animFade);
|
||||||
|
}
|
||||||
|
|
||||||
|
masterGroup->addAnimation(widgetGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Speicher aufräumen, wenn alles vorbei ist
|
||||||
|
// Hinweis: Die Widgets bleiben danach unsichtbar (Opacity 0), existieren aber noch.
|
||||||
|
connect(masterGroup, &QAbstractAnimation::finished, masterGroup, &QObject::deleteLater);
|
||||||
|
|
||||||
|
masterGroup->start();
|
||||||
|
}
|
||||||
65
bcdelightpmwidget.h
Normal file
65
bcdelightpmwidget.h
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
BionxControl
|
||||||
|
© 2025 -2026 christoph holzheuer
|
||||||
|
christoph.holzheuer@gmail.com
|
||||||
|
|
||||||
|
Using:
|
||||||
|
|
||||||
|
mhs_can_drv.c
|
||||||
|
© 2011 - 2023 by MHS-Elektronik GmbH & Co. KG, Germany
|
||||||
|
Klaus Demlehner, klaus@mhs-elektronik.de
|
||||||
|
@see www.mhs-elektronik.de
|
||||||
|
|
||||||
|
Based on Bionx data type descriptions from:
|
||||||
|
|
||||||
|
BigXionFlasher USB V 0.2.4 rev. 97
|
||||||
|
© 2011-2013 by Thomas Koenig <info@bigxionflasher.org>
|
||||||
|
@see www.bigxionflasher.org
|
||||||
|
|
||||||
|
Bionx Bike Info
|
||||||
|
© 2018 Thorsten Schmidt (tschmidt@ts-soft.de)
|
||||||
|
@see www.ts-soft.de
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
@see https://github.com/bikemike/bionx-bikeinfo
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef BC_DELIGHTPMWIDGET_H
|
||||||
|
#define BC_DELIGHTPMWIDGET_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The BCDelightPMWidget class : Demonstration Graphischer
|
||||||
|
* Effekte für unseren Produktmanager Simon.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class BCDelightPMWidget : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
BCDelightPMWidget( QWidget* parent );
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void onStartChaos();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void loadWidgetsFromResources();
|
||||||
|
void createFlyingWidget(const QString& iconPath);
|
||||||
|
|
||||||
|
QWidget* _playGround{};
|
||||||
|
// Liste der Widgets, die wir bewegen
|
||||||
|
QList<QWidget*> _flyingWidgets;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // BC_DELIGHTPMWIDGET_H
|
||||||
@@ -27,13 +27,13 @@
|
|||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
@see https://github.com/bikemike/bionx-bikeinfo
|
@see https://github.com/bikemike/bionx-bikeinfo
|
||||||
|
|
||||||
***************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
|
|
||||||
#include <bcdeviceview.h>
|
#include <bcdeviceview.h>
|
||||||
#include <bcanimateddelegate.h>
|
#include <bcvaluedelegate.h>
|
||||||
|
|
||||||
BCDeviceView::BCDeviceView(QWidget *parent)
|
BCDeviceView::BCDeviceView(QWidget *parent)
|
||||||
: QTableView(parent)
|
: QTableView(parent)
|
||||||
@@ -44,18 +44,26 @@ BCDeviceView::BCDeviceView(QWidget *parent)
|
|||||||
//horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
//horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||||
|
|
||||||
// __fix! ziemlich wildes ge-pointere, hier
|
// __fix! ziemlich wildes ge-pointere, hier
|
||||||
_itemDelegate = new BCAnimatedDelegate( _valueModel.getValueList(), this);
|
_itemDelegate = new BCValueDelegate( _valueModel.getValueList(), this);
|
||||||
setItemDelegate( _itemDelegate );
|
setItemDelegateForColumn( 1, _itemDelegate );
|
||||||
|
setStyleSheet("padding-left: 8px;");
|
||||||
|
|
||||||
|
// Verbindet den einfachen Klick direkt mit dem Editier-Befehl
|
||||||
|
connect(this, &QAbstractItemView::clicked, this, [this](const QModelIndex &index) {
|
||||||
|
edit(index);
|
||||||
|
});
|
||||||
|
|
||||||
|
setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void BCDeviceView::setDeviceID( BCDevice::ID deviceID )
|
void BCDeviceView::setDeviceID( BCDevice::ID deviceID )
|
||||||
{
|
{
|
||||||
_devideID = deviceID;
|
_devideID = deviceID;
|
||||||
}
|
}
|
||||||
|
|
||||||
BCDevice::ID BCDeviceView::getDeviceID() const
|
BCDevice::ID BCDeviceView::deviceID() const
|
||||||
{
|
{
|
||||||
return _devideID;
|
return _devideID;
|
||||||
}
|
}
|
||||||
@@ -65,21 +73,47 @@ BCDevice::ID BCDeviceView::getDeviceID() const
|
|||||||
* @brief Gibt eine Referenz auf der ValueList zurück.
|
* @brief Gibt eine Referenz auf der ValueList zurück.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const BCValueList& BCDeviceView::getValueListX()
|
const BCValueList& BCDeviceView::getValueList()
|
||||||
{
|
{
|
||||||
return _valueModel.getValueList();
|
return _valueModel.getValueList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Flag, ob diese View schonmal angezeigt wurde.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool BCDeviceView::firstExpose()
|
||||||
|
{
|
||||||
|
bool stored = _firstExpose;
|
||||||
|
_firstExpose = false;
|
||||||
|
return stored;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SLOT, der aufgerufen wird, wenn die ValueList vom XML-Lader fertig geladen wurde.
|
* @brief SLOT, der aufgerufen wird, wenn die ValueList vom XML-Lader fertig geladen wurde.
|
||||||
* Die DeviceView nimmt die ValueList dann in Besitz.
|
* Die DeviceView nimmt die ValueList dann in Besitz.
|
||||||
*/
|
*/
|
||||||
void BCDeviceView::onValueListReady( BCDevice::ID deviceID, BCValueList valueList )
|
void BCDeviceView::onValueListReady( BCDevice::ID deviceID, BCValueList valueList )
|
||||||
{
|
{
|
||||||
qDebug() << " --- onValueListReady: " << deviceID << ": " << valueList.size();
|
|
||||||
if(_devideID == deviceID)
|
if(_devideID == deviceID)
|
||||||
|
{
|
||||||
_valueModel.takeValueList( valueList );
|
_valueModel.takeValueList( valueList );
|
||||||
|
/*
|
||||||
|
const BCValueList& list = _valueModel.getValueList();
|
||||||
|
int rows = _valueModel.rowCount();
|
||||||
|
for (int r = 0; r < rows; ++r)
|
||||||
|
{
|
||||||
|
BCValuePtr bcValue = list[r];
|
||||||
|
if( !bcValue->isReadOnly() )
|
||||||
|
{
|
||||||
|
QModelIndex index = _valueModel.index(r, 1);
|
||||||
|
openPersistentEditor(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
} // if id
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -87,12 +121,16 @@ void BCDeviceView::onValueListReady( BCDevice::ID deviceID, BCValueList valueLis
|
|||||||
* @brief SLOT, der aufgerufen wird, wenn ein Value geändert wurde. Gibt dem ItemDelegate Bescheid.
|
* @brief SLOT, der aufgerufen wird, wenn ein Value geändert wurde. Gibt dem ItemDelegate Bescheid.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void BCDeviceView::onValueUpdated(int index, BCValue::State state, const QString& newVisibleValue )
|
void BCDeviceView::updateValue(int index,BCValue::Flags newState, uint32_t rawValue )
|
||||||
{
|
{
|
||||||
_valueModel.onValueUpdated( index, state, newVisibleValue);
|
_valueModel.updateValue( index, newState, rawValue );
|
||||||
_itemDelegate->onHighlightRow( index );
|
_itemDelegate->onHighlightRow( index );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Die Spalte mit dem Label soll immer bei 60% der Gesamtbreite liegen.
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
|
|
||||||
void BCDeviceView::resizeEvent(QResizeEvent *event)
|
void BCDeviceView::resizeEvent(QResizeEvent *event)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,15 +30,15 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef BCDEVICEVIEW_H
|
#ifndef BC_DEVICEVIEW_H
|
||||||
#define BCDEVICEVIEW_H
|
#define BC_DEVICEVIEW_H
|
||||||
|
|
||||||
#include <QTableView>
|
#include <QTableView>
|
||||||
|
|
||||||
#include <bcvaluemodel.h>
|
#include <bcvaluemodel.h>
|
||||||
|
|
||||||
|
|
||||||
class BCAnimatedDelegate;
|
class BCValueDelegate;
|
||||||
|
|
||||||
class BCDeviceView : public QTableView
|
class BCDeviceView : public QTableView
|
||||||
{
|
{
|
||||||
@@ -48,28 +48,28 @@ public:
|
|||||||
|
|
||||||
explicit BCDeviceView(QWidget *parent = nullptr);
|
explicit BCDeviceView(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
|
||||||
void setDeviceID( BCDevice::ID deviceID );
|
void setDeviceID( BCDevice::ID deviceID );
|
||||||
BCDevice::ID getDeviceID() const;
|
BCDevice::ID deviceID() const;
|
||||||
|
|
||||||
const BCValueList& getValueListX();
|
const BCValueList& getValueList();
|
||||||
//BCValueModel &getValueModel();
|
|
||||||
|
|
||||||
bool hasContent();
|
bool firstExpose();
|
||||||
|
void updateValue(int index, BCValue::Flags newState, uint32_t rawValue );
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void onValueListReady( BCDevice::ID deviceID, BCValueList valueList );
|
void onValueListReady( BCDevice::ID deviceID, BCValueList valueList );
|
||||||
void onValueUpdated( int index, BCValue::State state, const QString& newVisibleValue="" );
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void resizeEvent(QResizeEvent *event) override;
|
void resizeEvent(QResizeEvent *event) override;
|
||||||
|
|
||||||
BCDevice::ID _devideID{BCDevice::ID::Invalid};
|
bool _firstExpose{true};
|
||||||
BCValueModel _valueModel;
|
BCDevice::ID _devideID{BCDevice::ID::Invalid};
|
||||||
BCAnimatedDelegate* _itemDelegate{};
|
BCValueModel _valueModel;
|
||||||
|
BCValueDelegate* _itemDelegate{};
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BCDEVICEVIEW_H
|
#endif // BC_DEVICEVIEW_H
|
||||||
|
|||||||
@@ -74,7 +74,9 @@ TransmitResult BCDriverDummy::readRawByte( uint32_t deviceID, uint8_t registerID
|
|||||||
{
|
{
|
||||||
Q_UNUSED(deviceID)
|
Q_UNUSED(deviceID)
|
||||||
Q_UNUSED(registerID)
|
Q_UNUSED(registerID)
|
||||||
qDebug() << " --- Dummy: readRawByte:DriverState: " << getDriverState();
|
// Tätigkeit simulieren
|
||||||
|
//bc::delay_millis(200);
|
||||||
|
bc::delay_millis(50);
|
||||||
uint8_t myRandomByte = static_cast<uint8_t>(QRandomGenerator::global()->bounded(256));
|
uint8_t myRandomByte = static_cast<uint8_t>(QRandomGenerator::global()->bounded(256));
|
||||||
return myRandomByte;
|
return myRandomByte;
|
||||||
}
|
}
|
||||||
@@ -88,7 +90,7 @@ TransmitResult BCDriverDummy::writeRawByte( uint32_t deviceID, uint8_t registerI
|
|||||||
{
|
{
|
||||||
Q_UNUSED(deviceID)
|
Q_UNUSED(deviceID)
|
||||||
Q_UNUSED(registerID)
|
Q_UNUSED(registerID)
|
||||||
qDebug() << " --- BCDriverTinyCan writeRawValue: " << value;
|
Q_UNUSED(value)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,8 +30,8 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef BCDRIVER_H
|
#ifndef BC_DRIVER_H
|
||||||
#define BCDRIVER_H
|
#define BC_DRIVER_H
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <expected>
|
#include <expected>
|
||||||
@@ -119,4 +119,4 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BCDRIVER_H
|
#endif // BC_DRIVER_H
|
||||||
|
|||||||
122
bcdriverstatewidget.cpp
Normal file
122
bcdriverstatewidget.cpp
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
BionxControl
|
||||||
|
© 2025 -2026 christoph holzheuer
|
||||||
|
christoph.holzheuer@gmail.com
|
||||||
|
|
||||||
|
Using:
|
||||||
|
|
||||||
|
mhs_can_drv.c
|
||||||
|
© 2011 - 2023 by MHS-Elektronik GmbH & Co. KG, Germany
|
||||||
|
Klaus Demlehner, klaus@mhs-elektronik.de
|
||||||
|
@see www.mhs-elektronik.de
|
||||||
|
|
||||||
|
Based on Bionx data type descriptions from:
|
||||||
|
|
||||||
|
BigXionFlasher USB V 0.2.4 rev. 97
|
||||||
|
© 2011-2013 by Thomas Koenig <info@bigxionflasher.org>
|
||||||
|
@see www.bigxionflasher.org
|
||||||
|
|
||||||
|
Bionx Bike Info
|
||||||
|
© 2018 Thorsten Schmidt (tschmidt@ts-soft.de)
|
||||||
|
@see www.ts-soft.de
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
@see https://github.com/bikemike/bionx-bikeinfo
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include <bcdriverstatewidget.h>
|
||||||
|
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QMouseEvent>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Hilfswidget: Zeigt den DriverState als Icon an.
|
||||||
|
*/
|
||||||
|
|
||||||
|
BCDriverStateWidget::BCDriverStateWidget(QWidget* parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
{
|
||||||
|
QHBoxLayout* layout = new QHBoxLayout(this);
|
||||||
|
layout->setContentsMargins(10, 2, 10, 2);
|
||||||
|
//layout->setSpacing(8);
|
||||||
|
|
||||||
|
_led = new QLabel(this);
|
||||||
|
_led->setFixedSize(12, 12);
|
||||||
|
|
||||||
|
layout->addWidget(_led);
|
||||||
|
|
||||||
|
// Startzustand
|
||||||
|
onDriverStateChanged(BCDriver::DriverState::NotPresent, "Kein Treiber geladen.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Hauptfunktion zum Setzen des Status
|
||||||
|
// 'customMessage' ist optional. Wenn leer, wird ein Standardtext genommen.
|
||||||
|
void BCDriverStateWidget::onDriverStateChanged(BCDriver::DriverState state, const QString& customMessage)
|
||||||
|
{
|
||||||
|
Q_UNUSED(customMessage)
|
||||||
|
_state = state;
|
||||||
|
updateStyle();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BCDriverStateWidget::updateStyle()
|
||||||
|
{
|
||||||
|
QString ledStyle;
|
||||||
|
QString toolTipText;
|
||||||
|
|
||||||
|
switch (_state)
|
||||||
|
{
|
||||||
|
case BCDriver::DriverState::NotPresent:
|
||||||
|
// FLUENT GRAY (Neutral)
|
||||||
|
// Wir machen es dunkelgrau mit hellem Rand -> "Ausgeschaltet"-Look
|
||||||
|
ledStyle = "background-color: #3B3B3B; border: 1px solid #606060;";
|
||||||
|
toolTipText = "Kein Treiber geladen.";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BCDriver::DriverState::Error:
|
||||||
|
// FLUENT RED (Critical)
|
||||||
|
ledStyle = "background-color: #C42B1C; border: 1px solid #A80000;";
|
||||||
|
toolTipText = "Fehler beim Laden des Treibers.";
|
||||||
|
break;
|
||||||
|
|
||||||
|
// hier: dll vorhanden, Treiber geladen
|
||||||
|
case BCDriver::DriverState::Loaded:
|
||||||
|
case BCDriver::DriverState::Initialized:
|
||||||
|
case BCDriver::DriverState::Opened:
|
||||||
|
// ORANGE
|
||||||
|
ledStyle = "background-color: #FF8C00; border: 1px solid #A80000;";
|
||||||
|
toolTipText = "Kein Gerät verbunden.";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BCDriver::DriverState::DeviceReady:
|
||||||
|
// FLUENT GREEN (Success)
|
||||||
|
ledStyle = "background-color: #107C10; border: 1px solid #0E600E;";
|
||||||
|
toolTipText = "Verbindung erfolgreich hergestellt.";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Styles anwenden (immer rund machen)
|
||||||
|
_led->setStyleSheet(ledStyle + "border-radius: 6px;");
|
||||||
|
setToolTip(toolTipText);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief minimale click event
|
||||||
|
*/
|
||||||
|
|
||||||
|
void BCDriverStateWidget::mouseReleaseEvent(QMouseEvent* event)
|
||||||
|
{
|
||||||
|
if (event->button() == Qt::LeftButton)
|
||||||
|
emit clicked();
|
||||||
|
QWidget::mouseReleaseEvent(event);
|
||||||
|
}
|
||||||
@@ -30,51 +30,8 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef BCGUIHELPERS_H
|
#ifndef BC_DRIVERSTATEWIDGET_H
|
||||||
#define BCGUIHELPERS_H
|
#define BC_DRIVERSTATEWIDGET_H
|
||||||
|
|
||||||
#include <QPushButton>
|
|
||||||
#include <QLabel>
|
|
||||||
#include <QHBoxLayout>
|
|
||||||
#include <QMouseEvent>
|
|
||||||
|
|
||||||
#include <bcdriver.h>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Einfaches Buttonwidget, um zwischen Dark- und Lightmode
|
|
||||||
* zu wechseln
|
|
||||||
*/
|
|
||||||
|
|
||||||
class BCThemeSwitchButton : public QPushButton
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
explicit BCThemeSwitchButton(QWidget *parent = nullptr);
|
|
||||||
void setDarkMode( bool isDark );
|
|
||||||
|
|
||||||
signals:
|
|
||||||
|
|
||||||
void themeChanged(bool isDark);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
|
|
||||||
void toggleMode();
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
void updateIcon();
|
|
||||||
|
|
||||||
bool _isDarkMode{false};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// -----------------------------------------------------------------------------------
|
|
||||||
/// -----------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -82,6 +39,12 @@ private:
|
|||||||
* Drivers anzuzeigen.
|
* Drivers anzuzeigen.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <QLabel>
|
||||||
|
|
||||||
|
|
||||||
|
#include <bcdriver.h>
|
||||||
class BCDriverStateWidget : public QWidget
|
class BCDriverStateWidget : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -110,4 +73,4 @@ protected:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BCGUIHELPERS_H
|
#endif // BC_DRIVERSTATEWIDGET_H
|
||||||
@@ -151,7 +151,6 @@ BCDriver::DriverStateResult BCDriverTinyCan::loadDriver()
|
|||||||
return _driverState;
|
return _driverState;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// #1. erstmal komplett zurücksetzen
|
// #1. erstmal komplett zurücksetzen
|
||||||
resetDriver();
|
resetDriver();
|
||||||
// #2. Treiber laden, initialisieren und
|
// #2. Treiber laden, initialisieren und
|
||||||
@@ -177,27 +176,18 @@ BCDriver::DriverStateResult BCDriverTinyCan::loadDriver()
|
|||||||
BCDriver::DriverStateResult BCDriverTinyCan::setConsoleSlaveMode()
|
BCDriver::DriverStateResult BCDriverTinyCan::setConsoleSlaveMode()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// Wir versuchen ein Test-Byte zu lesen, hier: einfach die Hardware
|
||||||
|
// Revision der Console.
|
||||||
|
|
||||||
uint32_t console = static_cast<uint32_t>(BCDevice::ID::Console);
|
uint32_t console = static_cast<uint32_t>(BCDevice::ID::Console);
|
||||||
uint8_t slaveFlag = static_cast<uint8_t> (BC::ID::Cons_Status_Slave);
|
uint8_t slaveFlag = static_cast<uint8_t> (BC::ID::Cons_Status_Slave);
|
||||||
|
|
||||||
qDebug() << "XXX BCDriverTinyCan::Driver Init: putting Console in slave mode ... ";
|
unsigned int retry = cTimeOuts;
|
||||||
|
|
||||||
TransmitResult isSlave = 0;
|
TransmitResult isSlave = 0;
|
||||||
// Already slave?
|
// Already slave?
|
||||||
isSlave = readRawByte( console, slaveFlag );
|
isSlave = readRawByte( console, slaveFlag );
|
||||||
if( isSlave.has_value() )
|
if( isSlave.has_value() && isSlave.value() == 1 )
|
||||||
{
|
goto happyEnd;
|
||||||
qDebug() << "Console responded: " << isSlave.value();
|
|
||||||
if( isSlave.value() == 1 )
|
|
||||||
{
|
|
||||||
qDebug() << "Console already in slave mode. good!";
|
|
||||||
return DriverState::DeviceReady;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
qDebug() << "BCDriverTinyCan::BCDriverTinyCan::XXX Driver Init: putting Console in slave mode ... ";
|
|
||||||
|
|
||||||
unsigned int retry = cTimeOuts;
|
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@@ -208,11 +198,17 @@ BCDriver::DriverStateResult BCDriverTinyCan::setConsoleSlaveMode()
|
|||||||
} while( retry-- && !(*isSlave) );
|
} while( retry-- && !(*isSlave) );
|
||||||
|
|
||||||
bc::delay_millis( 500 ); // give the Console some time to settle
|
bc::delay_millis( 500 ); // give the Console some time to settle
|
||||||
//if( !isSlave )
|
|
||||||
//emit statusHint( QString("putting Console in slave mode ") + (isSlave ? "done" : "failed") );
|
if( isSlave.has_value() && isSlave.value() == 1 )
|
||||||
|
goto happyEnd;
|
||||||
|
|
||||||
// ist das jetzt irgendwie schlimm, wenn wir keine slave Console haben
|
// ist das jetzt irgendwie schlimm, wenn wir keine slave Console haben
|
||||||
return isSlave ? DriverState::DeviceReady : DriverState::Opened;
|
return DriverState::Opened;
|
||||||
|
|
||||||
|
happyEnd:
|
||||||
|
|
||||||
|
_driverState = DriverState::DeviceReady;
|
||||||
|
return DriverState::DeviceReady;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,75 +233,14 @@ void BCDriverTinyCan::resetDriver()
|
|||||||
TransmitResult BCDriverTinyCan::readRawByte( uint32_t deviceID, uint8_t registerID ) const
|
TransmitResult BCDriverTinyCan::readRawByte( uint32_t deviceID, uint8_t registerID ) const
|
||||||
{
|
{
|
||||||
|
|
||||||
qDebug() << " --- CAN Read Byte: Device: "<< deviceID << " register: " << registerID << " TRY! ";
|
|
||||||
|
|
||||||
struct TCanMsg msg;
|
|
||||||
int err, retry = 20;
|
|
||||||
int timeout = 80;
|
|
||||||
|
|
||||||
unsigned char receipient = (unsigned char) deviceID;
|
|
||||||
unsigned char reg = (unsigned char) registerID;
|
|
||||||
|
|
||||||
msg.MsgFlags = 0L;
|
|
||||||
msg.Id = receipient;
|
|
||||||
msg.MsgLen = 2;
|
|
||||||
msg.MsgData[0] = 0x00;
|
|
||||||
msg.MsgData[1] = reg;
|
|
||||||
|
|
||||||
CanTransmit(0, &msg, 1);
|
|
||||||
|
|
||||||
while(timeout-- && CanTransmitGetCount(0))
|
|
||||||
bc::delay_millis( cTIMEOUT_MS );
|
|
||||||
|
|
||||||
if (timeout == -1)
|
|
||||||
qDebug() << "error: could not send value to node ";
|
|
||||||
|
|
||||||
retry:
|
|
||||||
|
|
||||||
timeout = 80;
|
|
||||||
while(timeout-- && !CanReceiveGetCount(0))
|
|
||||||
bc::delay_millis( cTIMEOUT_MS );
|
|
||||||
|
|
||||||
if (timeout == -1)
|
|
||||||
{
|
|
||||||
qDebug() << "error: no response from node";
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((err = CanReceive(0, &msg, 1)) > 0)
|
|
||||||
{
|
|
||||||
qDebug() << " retry: " << retry << " BIB:" << BC::ID::ID_Bib << " msg.Id: " << msg.Id << " msg.MsgLen: " << msg.MsgLen << " msg.MsgData[1]: " << msg.MsgData[1] << " reg: " << reg;
|
|
||||||
if (--retry && (msg.Id != (uint32_t)BC::ID::ID_Bib|| msg.MsgLen != 4 || msg.MsgData[1] != reg))
|
|
||||||
goto retry;
|
|
||||||
|
|
||||||
if (!retry)
|
|
||||||
{
|
|
||||||
qDebug() << "XXX error: no response from node: " << err;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
qDebug() << " --- CAN Read Byte: Device: "<< deviceID << " register: " << registerID << " BYTE: " << (uint32_t) msg.MsgData[3];
|
|
||||||
return (unsigned int) msg.MsgData[3];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
qDebug() << "Error:" <<err;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
//TransmitResult
|
|
||||||
qDebug() << " --- BCDriverTinyCan::readRawByte DriverState: " << getDriverState();
|
|
||||||
|
|
||||||
if( _driverState <DriverState::Opened )
|
if( _driverState <DriverState::Opened )
|
||||||
return std::unexpected(QString("readRawValue error: driver not loaded." ) );
|
return std::unexpected(QString("readRawValue error: Treiber nicht geladen." ) );
|
||||||
|
|
||||||
unsigned char receipient = (unsigned char ) deviceID;
|
|
||||||
::TCanMsg msg;
|
::TCanMsg msg;
|
||||||
|
|
||||||
// msg verpacken
|
// msg verpacken
|
||||||
msg.MsgFlags = 0L;
|
msg.MsgFlags = 0L;
|
||||||
msg.Id = receipient;//deviceID;
|
msg.Id = deviceID;
|
||||||
msg.MsgLen = 2;
|
msg.MsgLen = 2;
|
||||||
msg.MsgData[0] = 0x00;
|
msg.MsgData[0] = 0x00;
|
||||||
msg.MsgData[1] = registerID;
|
msg.MsgData[1] = registerID;
|
||||||
@@ -313,16 +248,15 @@ retry:
|
|||||||
// msg verschicken
|
// msg verschicken
|
||||||
::CanTransmit( 0, &msg, 1 );
|
::CanTransmit( 0, &msg, 1 );
|
||||||
|
|
||||||
int retries = cRetries; // 5?
|
int retries = cRetries; // 5
|
||||||
// cTimeOuts (== 20) mal cTIMEOUT_MS (== 10 ms ) Versuche ...
|
int timeOuts = cTimeOuts; // 20
|
||||||
int timeOuts = cTimeOuts; // 20 ?
|
|
||||||
|
|
||||||
// ... warten bis der Sendepuffer leer ist
|
// ... warten bis der Sendepuffer leer ist
|
||||||
while( timeOuts-- && ::CanTransmitGetCount( 0 ) )
|
while( timeOuts-- && ::CanTransmitGetCount( 0 ) )
|
||||||
bc::delay_millis( cTIMEOUT_MS );
|
bc::delay_millis( cTIMEOUT_MS );
|
||||||
|
|
||||||
if( timeOuts == -1 )
|
if( timeOuts == -1 )
|
||||||
return std::unexpected(QString("readRawValue error: could not send value" ));
|
return std::unexpected(QString("readRawValue error: Sendefehler" ));
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
|
|
||||||
@@ -332,47 +266,35 @@ retry:
|
|||||||
while( timeOuts-- && !::CanReceiveGetCount( 0 ) )
|
while( timeOuts-- && !::CanReceiveGetCount( 0 ) )
|
||||||
bc::delay_millis( cTIMEOUT_MS );
|
bc::delay_millis( cTIMEOUT_MS );
|
||||||
|
|
||||||
if( timeOuts == -1 )
|
if (timeOuts == -1)
|
||||||
return std::unexpected(QString("getValue error: no response from node" ));
|
return std::unexpected(QString("readRawValue error: (Node)Timeout" ));
|
||||||
|
|
||||||
// message empfangen
|
// message empfangen
|
||||||
int err = ::CanReceive( 0, &msg, 1 );
|
int err = ::CanReceive( 0, &msg, 1 );
|
||||||
//qDebug() << "HÄÄ ?" << err << "reg: "<< registerID <<" timeOuts: " << timeOuts;
|
|
||||||
|
|
||||||
if( err < 0 )
|
if( err < 0 )
|
||||||
//throw BCException( "getValue error: could not receive value" );
|
return std::unexpected(QString("CAN response errror: Timeout"));
|
||||||
qDebug( "getValue error: could not receive value" );
|
|
||||||
|
|
||||||
//qDebug() << "HÄÄ 2" <<msg.Id;
|
if( --retries && ( msg.Id != (uint32_t)BC::ID::ID_Bib || msg.MsgLen != 4 || msg.MsgData[1] != registerID ) )
|
||||||
//qDebug() << "HÄÄ 2" <<msg.MsgLen;
|
|
||||||
//qDebug() << "HÄÄ 2" <<msg.MsgData[1];
|
|
||||||
|
|
||||||
//if( err > 0 )
|
|
||||||
if( --retries && ( msg.Id != BIB || msg.MsgLen != 4 || msg.MsgData[1] != registerID ) )
|
|
||||||
goto retry;
|
goto retry;
|
||||||
|
|
||||||
if( !timeOuts )
|
if( !timeOuts )
|
||||||
return std::unexpected(QString("CAN response errror: timeout" ));
|
return std::unexpected(QString("CAN response errror: Timeout" ));
|
||||||
|
|
||||||
qDebug() << " --- CAN Read Byte: " << (uint32_t) msg.MsgData[3] << " Device:: "<< deviceID << " register: " << registerID;
|
|
||||||
return (uint32_t) msg.MsgData[3];
|
return (uint32_t) msg.MsgData[3];
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// void BCDriverTinyCan::setValue( unsigned char receipient, unsigned char reg, unsigned char value )
|
|
||||||
TransmitResult BCDriverTinyCan::writeRawByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const
|
TransmitResult BCDriverTinyCan::writeRawByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const
|
||||||
{
|
{
|
||||||
|
|
||||||
if( _driverState <DriverState::Opened )
|
if( _driverState <DriverState::Opened )
|
||||||
return std::unexpected(QString("readRawValue error: driver not loaded." ) );
|
return std::unexpected(QString("readRawValue error: driver not loaded." ) );
|
||||||
|
|
||||||
qDebug() << " --- BCDriverTinyCan writeRawValue: " << value;
|
|
||||||
|
|
||||||
::TCanMsg msg;
|
::TCanMsg msg;
|
||||||
int timeout_count = cTIMEOUT_COUNT;
|
int timeout_count = cTIMEOUT_COUNT;
|
||||||
|
|
||||||
|
|
||||||
msg.MsgFlags = 0L;
|
msg.MsgFlags = 0L;
|
||||||
msg.Id = deviceID;
|
msg.Id = deviceID;
|
||||||
msg.MsgLen = 4;
|
msg.MsgLen = 4;
|
||||||
@@ -389,6 +311,6 @@ TransmitResult BCDriverTinyCan::writeRawByte( uint32_t deviceID, uint8_t registe
|
|||||||
if( timeout_count == -1 )
|
if( timeout_count == -1 )
|
||||||
return std::unexpected(QString("error: could not send value to %1" ).arg( deviceID ) );
|
return std::unexpected(QString("error: could not send value to %1" ).arg( deviceID ) );
|
||||||
|
|
||||||
return uint32_t(1); // als 'true'
|
return uint32_t(0); // kein Fehler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,8 +30,8 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef BCDRIVERTINYCAN_H
|
#ifndef BC_DRIVERTINYCAN_H
|
||||||
#define BCDRIVERTINYCAN_H
|
#define BC_DRIVERTINYCAN_H
|
||||||
|
|
||||||
#include <bcdriver.h>
|
#include <bcdriver.h>
|
||||||
|
|
||||||
@@ -60,4 +60,4 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BCDRIVERTINYCAN_H
|
#endif // BC_DRIVERTINYCAN_H
|
||||||
|
|||||||
250
bcguihelpers.cpp
250
bcguihelpers.cpp
@@ -1,250 +0,0 @@
|
|||||||
/***************************************************************************
|
|
||||||
|
|
||||||
BionxControl
|
|
||||||
© 2025 -2026 christoph holzheuer
|
|
||||||
christoph.holzheuer@gmail.com
|
|
||||||
|
|
||||||
Using:
|
|
||||||
|
|
||||||
mhs_can_drv.c
|
|
||||||
© 2011 - 2023 by MHS-Elektronik GmbH & Co. KG, Germany
|
|
||||||
Klaus Demlehner, klaus@mhs-elektronik.de
|
|
||||||
@see www.mhs-elektronik.de
|
|
||||||
|
|
||||||
Based on Bionx data type descriptions from:
|
|
||||||
|
|
||||||
BigXionFlasher USB V 0.2.4 rev. 97
|
|
||||||
© 2011-2013 by Thomas Koenig <info@bigxionflasher.org>
|
|
||||||
@see www.bigxionflasher.org
|
|
||||||
|
|
||||||
Bionx Bike Info
|
|
||||||
© 2018 Thorsten Schmidt (tschmidt@ts-soft.de)
|
|
||||||
@see www.ts-soft.de
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
@see https://github.com/bikemike/bionx-bikeinfo
|
|
||||||
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
#include <bcguihelpers.h>
|
|
||||||
|
|
||||||
|
|
||||||
BCThemeSwitchButton::BCThemeSwitchButton(QWidget *parent )
|
|
||||||
: QPushButton(parent)
|
|
||||||
{
|
|
||||||
// Visuelles Setup: Flach, keine Ränder, Hand-Cursor
|
|
||||||
setFlat(true);
|
|
||||||
setCursor(Qt::PointingHandCursor);
|
|
||||||
setFixedSize(24, 24); // Kleiner Footprint im StatusBar
|
|
||||||
|
|
||||||
// CSS: Transparent, damit es sich nahtlos in den StatusBar einfügt
|
|
||||||
// Schriftgröße etwas erhöhen, damit die Emojis gut erkennbar sind
|
|
||||||
|
|
||||||
setStyleSheet(R"(
|
|
||||||
BCThemeSwitchButton
|
|
||||||
{
|
|
||||||
border: none;
|
|
||||||
background-color: green;
|
|
||||||
font-size: 11pt;
|
|
||||||
}
|
|
||||||
BCThemeSwitchButton:Hover
|
|
||||||
{
|
|
||||||
background-color: rgba(128, 128, 128, 30);
|
|
||||||
border-radius: 24px;
|
|
||||||
}
|
|
||||||
)");
|
|
||||||
|
|
||||||
// Initialer Status (Startet im Dark Mode -> zeigt Mond)
|
|
||||||
updateIcon();
|
|
||||||
|
|
||||||
connect(this, &QPushButton::clicked, this, &BCThemeSwitchButton::toggleMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Setzt den DarkMode
|
|
||||||
*/
|
|
||||||
|
|
||||||
void BCThemeSwitchButton::setDarkMode( bool isDark )
|
|
||||||
{
|
|
||||||
_isDarkMode = !isDark;
|
|
||||||
toggleMode();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Schaltet den akutellen Mode um.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void BCThemeSwitchButton::toggleMode()
|
|
||||||
{
|
|
||||||
_isDarkMode = !_isDarkMode;
|
|
||||||
updateIcon();
|
|
||||||
emit themeChanged(_isDarkMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Icon & Tooltip anpassen
|
|
||||||
*/
|
|
||||||
|
|
||||||
void BCThemeSwitchButton::updateIcon()
|
|
||||||
{
|
|
||||||
// Logik:
|
|
||||||
// Ist Dark Mode an? Zeige Mond (oder Sonne, je nach Geschmack).
|
|
||||||
// Hier: Zeige das Symbol des AKTUELLEN Modus.
|
|
||||||
setText(_isDarkMode ? "🌙" : "☀️");
|
|
||||||
setToolTip(_isDarkMode ? "Zum LightMode wechseln" : "Zum DarkMode wechseln");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// -----------------------------------------------------------------------------------
|
|
||||||
/// -----------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Hilfswidget: Zeigt den DriverState als Icon an.
|
|
||||||
*/
|
|
||||||
|
|
||||||
BCDriverStateWidget::BCDriverStateWidget(QWidget* parent)
|
|
||||||
: QWidget(parent)
|
|
||||||
{
|
|
||||||
QHBoxLayout* layout = new QHBoxLayout(this);
|
|
||||||
layout->setContentsMargins(10, 2, 10, 2);
|
|
||||||
//layout->setSpacing(8);
|
|
||||||
|
|
||||||
_led = new QLabel(this);
|
|
||||||
_led->setFixedSize(12, 12);
|
|
||||||
|
|
||||||
layout->addWidget(_led);
|
|
||||||
|
|
||||||
// Startzustand
|
|
||||||
onDriverStateChanged(BCDriver::DriverState::NotPresent, "Not Present");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Hauptfunktion zum Setzen des Status
|
|
||||||
// 'customMessage' ist optional. Wenn leer, wird ein Standardtext genommen.
|
|
||||||
void BCDriverStateWidget::onDriverStateChanged(BCDriver::DriverState state, const QString& customMessage)
|
|
||||||
{
|
|
||||||
_state = state;
|
|
||||||
qDebug() << " --- StateWidget: " << state << " - " << customMessage;
|
|
||||||
|
|
||||||
updateStyle();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
void BCDriverStateWidget::updateStyle()
|
|
||||||
{
|
|
||||||
QString ledStyle;
|
|
||||||
QString labelColor;
|
|
||||||
QString toolTipText;
|
|
||||||
|
|
||||||
switch (_state)
|
|
||||||
{
|
|
||||||
case BCDriver::DriverState::DeviceReady:
|
|
||||||
// FLUENT GREEN (Success)
|
|
||||||
ledStyle = "background-color: #107C10; border: 1px solid #0E600E;#FF5F1F; #FF8C00;<- das isses #FF6700";
|
|
||||||
labelColor = "#FFFFFF"; // Weiß (Hervorgehoben)
|
|
||||||
toolTipText = "Verbindung erfolgreich hergestellt.";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BCDriver::DriverState::Error:
|
|
||||||
// FLUENT RED (Critical)
|
|
||||||
ledStyle = "background-color: #C42B1C; border: 1px solid #A80000;";
|
|
||||||
labelColor = "#FF99A4"; // Ein helleres Rot für Text, damit es auf Dunkel lesbar ist
|
|
||||||
toolTipText = "Kritischer Fehler bei der Verbindung!";
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// FLUENT GRAY (Neutral)
|
|
||||||
// Wir machen es dunkelgrau mit hellem Rand -> "Ausgeschaltet"-Look
|
|
||||||
ledStyle = "background-color: #3B3B3B; border: 1px solid #606060;";
|
|
||||||
labelColor = "#9E9E9E"; // Ausgegrauter Text
|
|
||||||
toolTipText = "System ist offline.";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Styles anwenden (immer rund machen)
|
|
||||||
_led->setStyleSheet(ledStyle + "border-radius: 6px;");
|
|
||||||
|
|
||||||
// Textfarbe setzen
|
|
||||||
_label->setStyleSheet(QString("color: %1; font-weight: %2;")
|
|
||||||
.arg(labelColor)
|
|
||||||
.arg(_state == BCDriver::DriverState::DeviceReady ? "bold" : "normal"));
|
|
||||||
|
|
||||||
setToolTip(toolTipText);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void BCDriverStateWidget::updateStyle()
|
|
||||||
{
|
|
||||||
QString ledStyle;
|
|
||||||
QString toolTipText;
|
|
||||||
/*
|
|
||||||
NotPresent,
|
|
||||||
Error,
|
|
||||||
Loaded,
|
|
||||||
Initialized,
|
|
||||||
Opened, // bis hierher: dll vorhanden, Treiber geladen
|
|
||||||
DeviceReady
|
|
||||||
*/
|
|
||||||
switch (_state)
|
|
||||||
{
|
|
||||||
case BCDriver::DriverState::NotPresent:
|
|
||||||
// FLUENT GRAY (Neutral)
|
|
||||||
// Wir machen es dunkelgrau mit hellem Rand -> "Ausgeschaltet"-Look
|
|
||||||
ledStyle = "background-color: #3B3B3B; border: 1px solid #606060;";
|
|
||||||
toolTipText = "Treiber nicht geladen.";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BCDriver::DriverState::Error:
|
|
||||||
// FLUENT RED (Critical)
|
|
||||||
ledStyle = "background-color: #C42B1C; border: 1px solid #A80000;";
|
|
||||||
toolTipText = "Fehler beim Laden des Treibers.";
|
|
||||||
break;
|
|
||||||
|
|
||||||
// hier: dll vorhanden, Treiber geladen
|
|
||||||
case BCDriver::DriverState::Loaded:
|
|
||||||
case BCDriver::DriverState::Initialized:
|
|
||||||
case BCDriver::DriverState::Opened:
|
|
||||||
// FLUENT RED (Critical)
|
|
||||||
ledStyle = "background-color: #FF8C00; border: 1px solid #A80000;";
|
|
||||||
toolTipText = "Fehler beim Laden des Treibers.";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BCDriver::DriverState::DeviceReady:
|
|
||||||
// FLUENT GREEN (Success)
|
|
||||||
ledStyle = "background-color: #107C10; border: 1px solid #0E600E;";
|
|
||||||
toolTipText = "Verbindung erfolgreich hergestellt.";
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Styles anwenden (immer rund machen)
|
|
||||||
_led->setStyleSheet(ledStyle + "border-radius: 6px;");
|
|
||||||
|
|
||||||
/*
|
|
||||||
// Textfarbe setzen
|
|
||||||
_setStyleSheet(QString("color: %1; font-weight: %2;")
|
|
||||||
.arg(labelColor)
|
|
||||||
.arg(_state == BCDriver::DriverState::DeviceReady ? "bold" : "normal"));
|
|
||||||
*/
|
|
||||||
setToolTip(toolTipText);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BCDriverStateWidget::mouseReleaseEvent(QMouseEvent* event)
|
|
||||||
{
|
|
||||||
if (event->button() == Qt::LeftButton)
|
|
||||||
{
|
|
||||||
emit clicked();
|
|
||||||
}
|
|
||||||
QWidget::mouseReleaseEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
188
bcmainwindow.cpp
188
bcmainwindow.cpp
@@ -29,14 +29,16 @@
|
|||||||
|
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
#include "qassert.h"
|
#include <bcthemebutton.h>
|
||||||
|
#include <bcdriverstatewidget.h>
|
||||||
#include <bcmainwindow.h>
|
#include <bcmainwindow.h>
|
||||||
#include <bcanimateddelegate.h>
|
#include <bcvaluedelegate.h>
|
||||||
#include <ui_bcmainwindow.h>
|
#include <ui_bcmainwindow.h>
|
||||||
#include <bcguihelpers.h>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Das Mainwindow erzeugen
|
* @brief Das Mainwindow erzeugen
|
||||||
@@ -50,8 +52,12 @@ BCMainWindow::BCMainWindow(QWidget *parent)
|
|||||||
qRegisterMetaType<BCValue>("BCValue");
|
qRegisterMetaType<BCValue>("BCValue");
|
||||||
qRegisterMetaType<QList<BCValue>>("BCValueList");
|
qRegisterMetaType<QList<BCValue>>("BCValueList");
|
||||||
|
|
||||||
setupUi(this);
|
#if defined(Q_OS_LINUX)
|
||||||
|
// Für Touch screen: Window FRam weglassen
|
||||||
|
//setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
setupUi(this);
|
||||||
|
|
||||||
// Wir schreiben den 'initMainWindow()' Aufruf mit Hilfe des
|
// Wir schreiben den 'initMainWindow()' Aufruf mit Hilfe des
|
||||||
// timers in die Event-Queue, damit er erst ausgeführt wird,
|
// timers in die Event-Queue, damit er erst ausgeführt wird,
|
||||||
@@ -81,7 +87,6 @@ BCMainWindow::~BCMainWindow()
|
|||||||
|
|
||||||
void BCMainWindow::initMainWindow()
|
void BCMainWindow::initMainWindow()
|
||||||
{
|
{
|
||||||
|
|
||||||
// Lambda um die buttons mit ihren Actions zu verbinden
|
// Lambda um die buttons mit ihren Actions zu verbinden
|
||||||
auto configureAction = [&]( QToolButton* button, QAction* action, BCDevice::ID deviceID )
|
auto configureAction = [&]( QToolButton* button, QAction* action, BCDevice::ID deviceID )
|
||||||
{
|
{
|
||||||
@@ -89,20 +94,22 @@ void BCMainWindow::initMainWindow()
|
|||||||
button->setDefaultAction( action);
|
button->setDefaultAction( action);
|
||||||
// new way: die DeviceID muss aber explizit vom Lambda eingefanden werden.
|
// new way: die DeviceID muss aber explizit vom Lambda eingefanden werden.
|
||||||
connect( action, &QAction::triggered, this, [this,deviceID]()
|
connect( action, &QAction::triggered, this, [this,deviceID]()
|
||||||
{
|
{
|
||||||
onShowDevicePanel( deviceID );
|
onShowDevicePanel( deviceID );
|
||||||
});
|
});
|
||||||
|
|
||||||
if( _devicePanels.contains(deviceID) )
|
if( _devicePanels.contains(deviceID) )
|
||||||
{
|
{
|
||||||
BCDeviceView* currentPanel = _devicePanels[deviceID];
|
BCDeviceView* currentPanel = _devicePanels[deviceID];
|
||||||
// ... und ihre device ID
|
// ... und ihre device ID
|
||||||
currentPanel->setDeviceID( deviceID );
|
currentPanel->setDeviceID( deviceID );
|
||||||
// Wenn ein Device (entspricht einem Datenmodel) fertig eingelesen wurde,
|
// Wenn ein Device (entspricht einem Datenmodel) fertig eingelesen wurde,
|
||||||
// wird es weitergereicht.
|
// wird es weitergereicht.
|
||||||
// Problem: alle Panels bekommen alle Datenmodelle angeboten.
|
// Problem: alle Panels bekommen alle Datenmodelle angeboten.
|
||||||
connect( &_dataManager, &BCXmlLoader::valueListReady, currentPanel, &BCDeviceView::onValueListReady );
|
connect( &_dataManager, &BCXmlLoader::valueListReady, currentPanel, &BCDeviceView::onValueListReady );
|
||||||
}
|
|
||||||
|
connect( currentPanel->model(), SIGNAL(makeSimonHappy()), this, SLOT(onStartAnimation() ) );
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Wir wollen die Devices den Views zuordnen können
|
// Wir wollen die Devices den Views zuordnen können
|
||||||
@@ -110,63 +117,57 @@ void BCMainWindow::initMainWindow()
|
|||||||
_devicePanels[BCDevice::ID::Battery] = _batteryPanel;
|
_devicePanels[BCDevice::ID::Battery] = _batteryPanel;
|
||||||
_devicePanels[BCDevice::ID::Motor] = _motorPanel;
|
_devicePanels[BCDevice::ID::Motor] = _motorPanel;
|
||||||
|
|
||||||
// Die actions an die Buttons binden
|
// Die actions an die Buttons binden
|
||||||
configureAction(_motorButton, _motorAction, BCDevice::ID::Motor );
|
configureAction(_motorButton, _motorAction, BCDevice::ID::Motor );
|
||||||
configureAction(_consoleButton, _consoleAction, BCDevice::ID::Console );
|
configureAction(_consoleButton, _consoleAction, BCDevice::ID::Console );
|
||||||
configureAction(_batteryButton, _batteryAction, BCDevice::ID::Battery );
|
configureAction(_batteryButton, _batteryAction, BCDevice::ID::Battery );
|
||||||
|
|
||||||
/*
|
|
||||||
bool m_isDarkMode = false;
|
|
||||||
QString icon = m_isDarkMode ? "☀️" : "🌙";
|
|
||||||
fitzeButton->setText(icon);
|
|
||||||
|
|
||||||
QString style = QString(
|
|
||||||
"QPushButton {"
|
|
||||||
" background-color: %1;"
|
|
||||||
" border: 1px solid %2;"
|
|
||||||
" border-radius: 6px;"
|
|
||||||
" font-size: 12pt;"
|
|
||||||
" padding: 0px;"
|
|
||||||
"}"
|
|
||||||
"QPushButton:hover {"
|
|
||||||
" background-color: %3;"
|
|
||||||
"}"
|
|
||||||
).arg(m_isDarkMode ? "#2B2B2B" : "#FFFFFF")
|
|
||||||
.arg(m_isDarkMode ? "#3F3F3F" : "#E1DFDD")
|
|
||||||
.arg(m_isDarkMode ? "#3A3A3A" : "#F9F9F9");
|
|
||||||
|
|
||||||
fitzeButton->setStyleSheet(style);
|
|
||||||
*/
|
|
||||||
|
|
||||||
initStatusBar();
|
initStatusBar();
|
||||||
|
|
||||||
// besser: model::emit dataChanged
|
_connectButton->setDefaultAction( _connectAction);
|
||||||
// also: emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole, ValueRole});
|
_syncButton->setDefaultAction( _syncAction);
|
||||||
connect( _connectButton, &QToolButton::clicked, &_transmitter, &BCTransmitter::onToggleDriverConnection );
|
|
||||||
connect( _syncButton, &QToolButton::clicked, this, &BCMainWindow::onSyncDeviceView );
|
connect( _connectAction, &QAction::triggered, &_transmitter, &BCTransmitter::onToggleDriverConnection );
|
||||||
|
connect( _syncAction, &QAction::triggered, this, &BCMainWindow::onSyncDeviceView );
|
||||||
connect( _exitButton, &QToolButton::clicked, qApp, &QCoreApplication::quit );
|
connect( _exitButton, &QToolButton::clicked, qApp, &QCoreApplication::quit );
|
||||||
|
|
||||||
connect( &_transmitter, &BCTransmitter::valueUpdated, this, &BCMainWindow::onValueUpdated );
|
connect( &_transmitter, &BCTransmitter::valueUpdated, this, &BCMainWindow::onValueUpdated );
|
||||||
connect( this, &BCMainWindow::requestValueUpdate, &_transmitter, &BCTransmitter::onUpdateValue);
|
connect( this, &BCMainWindow::requestValueUpdate, &_transmitter, &BCTransmitter::onUpdateValue);
|
||||||
connect( &_worker, &QThread::finished, &_transmitter, &QObject::deleteLater);
|
connect( &_worker, &QThread::finished, &_transmitter, &QObject::deleteLater);
|
||||||
connect( &_transmitter, &BCTransmitter::driverStateChanged, this, &BCMainWindow::onDriverStateChanged );
|
connect( &_transmitter, &BCTransmitter::driverStateChanged, this, &BCMainWindow::onDriverStateChanged );
|
||||||
|
connect( &_transmitter, &BCTransmitter::endOfProcessing, this, &BCMainWindow::onEndOfProcessing );
|
||||||
|
connect( this, &BCMainWindow::endOfTransmission, &_transmitter, &BCTransmitter::onEndOfTransmission );
|
||||||
|
|
||||||
// transmitter starten
|
// transmitter starten
|
||||||
_transmitter.moveToThread(&_worker);
|
_transmitter.moveToThread(&_worker);
|
||||||
_worker.start();
|
_worker.start();
|
||||||
|
|
||||||
// die Daten des eBikes laden
|
try
|
||||||
_dataManager.loadXmlBikeData(":/bikeinfo.xml"_L1);
|
{
|
||||||
|
// die Daten des eBikes laden
|
||||||
|
_dataManager.loadXmlBikeData(":/bikeinfo.xml"_L1);
|
||||||
|
}
|
||||||
|
catch( BCException& exception )
|
||||||
|
{
|
||||||
|
QMessageBox::critical( this, "Ladefehler", exception.what() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Konsolendaten als erstes anzeigen
|
||||||
_consoleAction->trigger();
|
_consoleAction->trigger();
|
||||||
//_batteryAction->trigger();
|
//_batteryAction->trigger();
|
||||||
|
|
||||||
|
/*
|
||||||
// Dummy sync beim starten
|
// Dummy sync beim starten
|
||||||
|
|
||||||
QTimer::singleShot(1000, this, [this]()
|
QTimer::singleShot(1000, this, [this]()
|
||||||
{
|
{
|
||||||
onSyncDeviceView();
|
onSyncDeviceView();
|
||||||
});
|
});
|
||||||
}
|
*/
|
||||||
|
|
||||||
|
// not least
|
||||||
|
_delightWidget = new BCDelightPMWidget(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// 2. Bild für den Zustand UNCHECKED (Off) hinzufügen
|
// 2. Bild für den Zustand UNCHECKED (Off) hinzufügen
|
||||||
@@ -180,31 +181,30 @@ connectIcon.addFile(":/icons/plug_connected.svg", QSize(), QIcon::Normal, QIc
|
|||||||
|
|
||||||
void BCMainWindow::initStatusBar()
|
void BCMainWindow::initStatusBar()
|
||||||
{
|
{
|
||||||
QStatusBar *statBar = statusBar();
|
|
||||||
|
|
||||||
BCDriverStateWidget* conState = new BCDriverStateWidget(this);
|
BCDriverStateWidget* conState = new BCDriverStateWidget(this);
|
||||||
connect( &_transmitter, &BCTransmitter::driverStateChanged, conState, &BCDriverStateWidget::onDriverStateChanged );
|
connect( &_transmitter, &BCTransmitter::driverStateChanged, conState, &BCDriverStateWidget::onDriverStateChanged );
|
||||||
connect( conState, &BCDriverStateWidget::clicked, _connectAction, &QAction::trigger );
|
connect( conState, &BCDriverStateWidget::clicked, _connectAction, &QAction::trigger );
|
||||||
|
|
||||||
statBar->addPermanentWidget(conState);
|
_statusBar->addPermanentWidget(conState);
|
||||||
conState->installEventFilter(this);
|
conState->installEventFilter(this);
|
||||||
|
|
||||||
BCThemeSwitchButton* themeBtn = new BCThemeSwitchButton(this);
|
BCThemeButton* themeBtn = new BCThemeButton(this);
|
||||||
statBar->addPermanentWidget(themeBtn);
|
_statusBar->addPermanentWidget(themeBtn);
|
||||||
connect(themeBtn, &BCThemeSwitchButton::themeChanged, this, [this](bool isDark)
|
connect(themeBtn, &BCThemeButton::themeChanged, this, [this](bool isDark)
|
||||||
{
|
{
|
||||||
|
QString message = isDark ? "using DarkMode." : "using LightMode.";
|
||||||
|
onShowMessage( message );
|
||||||
|
setApplicationStyleSheet( isDark ? cDarkModeStyle : cLightModeStyle );
|
||||||
|
|
||||||
QString message = isDark ? "Dark Mode Activated" : "Light Mode Activated";
|
|
||||||
statusBar()->showMessage( message, 3000);
|
|
||||||
setApplicationStyleSheet( isDark ? ":claude_dark_mode.qss"_L1 : ":claude_light_mode.qss"_L1 );
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Wir starten im light mode
|
// Wir starten im light mode
|
||||||
//themeBtn->setDarkMode( false );
|
//themeBtn->setDarkMode( false );
|
||||||
|
|
||||||
statBar->showMessage("Ready");
|
onShowMessage("Ready. (Using dummy driver)");
|
||||||
|
|
||||||
setApplicationStyleSheet(":bionxcontrol.qss"_L1);
|
setApplicationStyleSheet(cLightModeStyle);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,6 +239,7 @@ bool BCMainWindow::setApplicationStyleSheet( QAnyStringView path )
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
qWarning() << "Konnte Stylesheet nicht laden:" << styleFile.errorString();
|
qWarning() << "Konnte Stylesheet nicht laden:" << styleFile.errorString();
|
||||||
|
//qApp->setStyleSheet(" ");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,59 +254,73 @@ void BCMainWindow::setHeaderLabel( const QString& headerText)
|
|||||||
_headerLabel->setText( " BionxControl: " + headerText );
|
_headerLabel->setText( " BionxControl: " + headerText );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void BCMainWindow::onShowMessage( const QString& message, int timeOut )
|
void BCMainWindow::onShowMessage( const QString& message, int timeOut )
|
||||||
{
|
{
|
||||||
_statusbar->showMessage( message, timeOut );
|
_statusBar->showMessage( message, timeOut );
|
||||||
}
|
}
|
||||||
|
|
||||||
void BCMainWindow::autoConnect()
|
|
||||||
|
void BCMainWindow::onStartAnimation()
|
||||||
{
|
{
|
||||||
// __fix!
|
_delightWidget->onStartChaos();
|
||||||
// if( !connect)
|
|
||||||
// fallBack
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void BCMainWindow::onDriverStateChanged( BCDriver::DriverState state, const QString& message )
|
void BCMainWindow::onDriverStateChanged( BCDriver::DriverState state, const QString& message )
|
||||||
{
|
{
|
||||||
qDebug() << " --- on DriverStatusChanged: " << state << ":" << message;
|
Q_UNUSED(state)
|
||||||
_statusbar->showMessage( message, 8000 );
|
onShowMessage( message, 8000 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void BCMainWindow::onShowDevicePanel( BCDevice::ID deviceID )
|
void BCMainWindow::onShowDevicePanel( BCDevice::ID deviceID )
|
||||||
{
|
{
|
||||||
qDebug() << " --- onShowDevicePanel:" << deviceID;
|
|
||||||
if( _devicePanels.contains( deviceID ) )
|
if( _devicePanels.contains( deviceID ) )
|
||||||
{
|
{
|
||||||
BCDeviceView* nxtPanel = _devicePanels[deviceID];
|
BCDeviceView* nxtPanel = _devicePanels[deviceID];
|
||||||
if( nxtPanel != _currentPanel )
|
if( nxtPanel != _currentPanel )
|
||||||
{
|
{
|
||||||
_currentPanel = nxtPanel;
|
_currentPanel = nxtPanel;
|
||||||
qDebug() << " --- Firz: " << _currentPanel->property( BCKeyHeaderLabel );
|
setHeaderLabel( _currentPanel->property( cBCKeyHeaderLabel ).toString() );
|
||||||
setHeaderLabel( _currentPanel->property( BCKeyHeaderLabel ).toString() );
|
_stackedWidget->setCurrentWidget( _currentPanel );
|
||||||
_stackedWidget->setCurrentWidget( nxtPanel );
|
if( _currentPanel->firstExpose() )
|
||||||
|
{
|
||||||
|
// Dummy sync beim starten
|
||||||
|
QTimer::singleShot(1000, this, [this]()
|
||||||
|
{
|
||||||
|
onSyncDeviceView();
|
||||||
|
});
|
||||||
|
}
|
||||||
// knopf auch abschalten?
|
// knopf auch abschalten?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void BCMainWindow::onConnectButtonToggled(bool checked )
|
/**
|
||||||
{
|
* @brief SLOT, wird aufgerufen, wenn der Treiber eine frischen Wert abgeholt hat.
|
||||||
//_dataManager.setDriverConnectionState( checked );
|
*/
|
||||||
}
|
|
||||||
|
|
||||||
void BCMainWindow::onValueUpdated(BCDevice::ID deviceID, int index, BCValue::State state, const QString& newValue )
|
void BCMainWindow::onValueUpdated(BCDevice::ID deviceID, int index, BCValue::Flags newState, uint32_t rawValue )
|
||||||
{
|
{
|
||||||
qDebug() << "Reply: from: " << deviceID << " at: " << index << "finished. Success:" << (uint8_t)state << " on:" << newValue;
|
|
||||||
if( _devicePanels.contains( deviceID ) )
|
if( _devicePanels.contains( deviceID ) )
|
||||||
{
|
{
|
||||||
BCDeviceView& panel = *_devicePanels[deviceID];
|
BCDeviceView& panel = *_devicePanels[deviceID];
|
||||||
panel.onValueUpdated( index, state, newValue );
|
panel.updateValue( index, newState, rawValue );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SLOT, wird aufgerufen, wenn der Treiber die Datenübertrgeung beendet hat.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void BCMainWindow::onEndOfProcessing()
|
||||||
|
{
|
||||||
|
_syncButton->setEnabled( true );
|
||||||
|
onShowMessage( "Synchronization complete.");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SLOT, der aufgerufen wird, um das akutelle Device (Battery, Motor, ... )
|
* @brief SLOT, der aufgerufen wird, um das akutelle Device (Battery, Motor, ... )
|
||||||
* zu synchronisieren, d.h. die aktuellen Werte über den CAN-Bus abzufragen.
|
* zu synchronisieren, d.h. die aktuellen Werte über den CAN-Bus abzufragen.
|
||||||
@@ -313,27 +328,28 @@ void BCMainWindow::onValueUpdated(BCDevice::ID deviceID, int index, BCValue::Sta
|
|||||||
|
|
||||||
void BCMainWindow::onSyncDeviceView()
|
void BCMainWindow::onSyncDeviceView()
|
||||||
{
|
{
|
||||||
|
|
||||||
Q_ASSERT_X(_currentPanel, "onSyncDeviceView()", "_currentpanel ist null!");
|
Q_ASSERT_X(_currentPanel, "onSyncDeviceView()", "_currentpanel ist null!");
|
||||||
|
const BCValueList& currentList =_currentPanel->getValueList();
|
||||||
|
|
||||||
qDebug() << " ---Syncing";
|
// wir schalten den Sync-Button hier ab,
|
||||||
|
// wenn der Autrag bearbeitet wurde, wird der
|
||||||
|
// Button wieder eingeschaltet.
|
||||||
|
_syncButton->setEnabled( false );
|
||||||
|
|
||||||
const BCValueList& currentList =_currentPanel->getValueListX();
|
QString devName = _currentPanel->property( cBCKeyHeaderLabel ).toString();
|
||||||
|
onShowMessage( "Reading: " + devName );
|
||||||
// alle einzeln? echt jetzt?
|
|
||||||
|
|
||||||
for( const BCValuePtr& value : currentList )
|
for( const BCValuePtr& value : currentList )
|
||||||
{
|
{
|
||||||
qDebug() << " --- begin sync of value: " << QThread::currentThreadId() << " : " << value->label;
|
|
||||||
// wir setzen auf 'lesen'
|
// wir setzen auf 'lesen'
|
||||||
value->state.setFlag( BCValue::State::ReadMe );
|
value->setFlag( BCValue::Flag::ReadMe );
|
||||||
|
|
||||||
// statt '_transmitter.onUpdateValue( value )' müssen wir hier
|
// statt '_transmitter.onUpdateValue( value )' müssen wir hier
|
||||||
// über emit requestValueUpdate() zur Thread sysnchronisation
|
// über emit requestValueUpdate() zur Thread sysnchronisation
|
||||||
// entkoppeln,
|
// entkoppeln,
|
||||||
|
|
||||||
emit requestValueUpdate( value);
|
emit requestValueUpdate( value);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
emit endOfTransmission();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,8 +30,8 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef BCMAINWINDOW_H
|
#ifndef BC_MAINWINDOW_H
|
||||||
#define BCMAINWINDOW_H
|
#define BC_MAINWINDOW_H
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
@@ -39,6 +39,7 @@
|
|||||||
#include <ui_bcmainwindow.h>
|
#include <ui_bcmainwindow.h>
|
||||||
#include <bcxmlloader.h>
|
#include <bcxmlloader.h>
|
||||||
#include <bctransmitter.h>
|
#include <bctransmitter.h>
|
||||||
|
#include <bcdelightpmwidget.h>
|
||||||
|
|
||||||
class BCDeviceView;
|
class BCDeviceView;
|
||||||
|
|
||||||
@@ -57,26 +58,27 @@ public slots:
|
|||||||
|
|
||||||
//void onValueListReady( BCDevice::ID deviceID );
|
//void onValueListReady( BCDevice::ID deviceID );
|
||||||
void onShowDevicePanel( BCDevice::ID deviceID );
|
void onShowDevicePanel( BCDevice::ID deviceID );
|
||||||
void onConnectButtonToggled(bool active );
|
|
||||||
void onDriverStateChanged( BCDriver::DriverState state, const QString& message="" );
|
void onDriverStateChanged( BCDriver::DriverState state, const QString& message="" );
|
||||||
|
|
||||||
// Slots für Rückmeldungen vom Transmitter
|
// Slots für Rückmeldungen vom Transmitter
|
||||||
void onValueUpdated( BCDevice::ID deviceID, int index, BCValue::State state, const QString& newValue="" );
|
void onValueUpdated( BCDevice::ID deviceID, int index, BCValue::Flags newState, uint32_t rawValue );
|
||||||
|
void onEndOfProcessing();
|
||||||
void onSyncDeviceView();
|
void onSyncDeviceView();
|
||||||
|
|
||||||
void onShowMessage( const QString& message, int timeOut=3000);
|
void onShowMessage( const QString& message, int timeOut=4000);
|
||||||
|
void onStartAnimation();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
// Internes Signal, um Daten an den Worker Thread zu senden
|
// Internes Signal, um Daten an den Worker Thread zu senden
|
||||||
void requestValueUpdate( BCValuePtrConst value);
|
void requestValueUpdate( BCValuePtrConst value);
|
||||||
|
void endOfTransmission();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
bool setApplicationStyleSheet( QAnyStringView path );
|
bool setApplicationStyleSheet( QAnyStringView path );
|
||||||
void initMainWindow();
|
void initMainWindow();
|
||||||
void initStatusBar();
|
void initStatusBar();
|
||||||
void autoConnect();
|
|
||||||
|
|
||||||
//bool eventFilter(QObject *obj, QEvent *event) override;
|
//bool eventFilter(QObject *obj, QEvent *event) override;
|
||||||
|
|
||||||
@@ -86,15 +88,17 @@ protected:
|
|||||||
// und dem Device, das sie darstellen.
|
// und dem Device, das sie darstellen.
|
||||||
|
|
||||||
using BCDeviceViews = QHash<BCDevice::ID, BCDeviceView*>;
|
using BCDeviceViews = QHash<BCDevice::ID, BCDeviceView*>;
|
||||||
BCDeviceViews _devicePanels;
|
BCDeviceViews _devicePanels;
|
||||||
BCDeviceView* _currentPanel{};
|
BCDeviceView* _currentPanel{};
|
||||||
|
BCDelightPMWidget* _delightWidget{};
|
||||||
|
QThread _worker;
|
||||||
|
BCTransmitter _transmitter;
|
||||||
|
|
||||||
QThread _worker;
|
static constexpr const char* cBCKeyHeaderLabel = "BCHeaderLabel";
|
||||||
BCTransmitter _transmitter;
|
static constexpr const char* cDarkModeStyle = ":bc_dark.qss";
|
||||||
|
static constexpr const char* cLightModeStyle = ":bc_light.qss";
|
||||||
static constexpr const char* BCKeyHeaderLabel = "BCHeaderLabel";
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // BCMAINWINDOW_H
|
#endif // BC_MAINWINDOW_H
|
||||||
|
|||||||
@@ -165,14 +165,10 @@
|
|||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
|
||||||
<iconset resource="bionxcontrol.qrc">
|
|
||||||
<normaloff>:/sync_yellow.svg</normaloff>:/sync_yellow.svg</iconset>
|
|
||||||
</property>
|
|
||||||
<property name="iconSize">
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
<width>48</width>
|
<width>64</width>
|
||||||
<height>48</height>
|
<height>64</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="autoRaise">
|
<property name="autoRaise">
|
||||||
@@ -191,14 +187,10 @@
|
|||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
|
||||||
<iconset resource="bionxcontrol.qrc">
|
|
||||||
<normaloff>:/connect.svg</normaloff>:/connect.svg</iconset>
|
|
||||||
</property>
|
|
||||||
<property name="iconSize">
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
<width>48</width>
|
<width>64</width>
|
||||||
<height>48</height>
|
<height>64</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="autoRaise">
|
<property name="autoRaise">
|
||||||
@@ -214,17 +206,20 @@
|
|||||||
<height>64</height>
|
<height>64</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Quit application.</string>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Quit</string>
|
<string>Quit</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="bionxcontrol.qrc">
|
<iconset resource="bionxcontrol.qrc">
|
||||||
<normaloff>:/exit_red.svg</normaloff>:/exit_red.svg</iconset>
|
<normaloff>:/exit_red.png</normaloff>:/exit_red.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSize">
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
<width>48</width>
|
<width>64</width>
|
||||||
<height>48</height>
|
<height>64</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="autoRaise">
|
<property name="autoRaise">
|
||||||
@@ -250,7 +245,7 @@
|
|||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>2</number>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="BCDeviceView" name="_consolePanel">
|
<widget class="BCDeviceView" name="_consolePanel">
|
||||||
<property name="frameShape">
|
<property name="frameShape">
|
||||||
@@ -262,6 +257,9 @@
|
|||||||
<property name="lineWidth">
|
<property name="lineWidth">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="editTriggers">
|
||||||
|
<set>QAbstractItemView::EditTrigger::NoEditTriggers</set>
|
||||||
|
</property>
|
||||||
<property name="showGrid">
|
<property name="showGrid">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
@@ -291,6 +289,9 @@
|
|||||||
<property name="lineWidth">
|
<property name="lineWidth">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="editTriggers">
|
||||||
|
<set>QAbstractItemView::EditTrigger::NoEditTriggers</set>
|
||||||
|
</property>
|
||||||
<property name="showGrid">
|
<property name="showGrid">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
@@ -320,6 +321,12 @@
|
|||||||
<property name="lineWidth">
|
<property name="lineWidth">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="editTriggers">
|
||||||
|
<set>QAbstractItemView::EditTrigger::NoEditTriggers</set>
|
||||||
|
</property>
|
||||||
|
<property name="selectionBehavior">
|
||||||
|
<enum>QAbstractItemView::SelectionBehavior::SelectRows</enum>
|
||||||
|
</property>
|
||||||
<property name="showGrid">
|
<property name="showGrid">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
@@ -345,8 +352,11 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QStatusBar" name="_statusbar"/>
|
<widget class="QStatusBar" name="_statusBar"/>
|
||||||
<action name="_motorAction">
|
<action name="_motorAction">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset>
|
<iconset>
|
||||||
<normaloff>:bionx_motor.png</normaloff>:bionx_motor.png</iconset>
|
<normaloff>:bionx_motor.png</normaloff>:bionx_motor.png</iconset>
|
||||||
@@ -355,10 +365,13 @@
|
|||||||
<string>motor</string>
|
<string>motor</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Motoreinstellungen anzeigen und bearbeiten</string>
|
<string>Show and edit motor settings.</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="_batteryAction">
|
<action name="_batteryAction">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset>
|
<iconset>
|
||||||
<normaloff>:bionx_akku.png</normaloff>:bionx_akku.png</iconset>
|
<normaloff>:bionx_akku.png</normaloff>:bionx_akku.png</iconset>
|
||||||
@@ -367,10 +380,13 @@
|
|||||||
<string>battery</string>
|
<string>battery</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Batterieeinstellungen anzeigen und bearbeiten</string>
|
<string>Show and edit battery settings.</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="_consoleAction">
|
<action name="_consoleAction">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset>
|
<iconset>
|
||||||
<normaloff>:bionx_console.png</normaloff>:bionx_console.png</iconset>
|
<normaloff>:bionx_console.png</normaloff>:bionx_console.png</iconset>
|
||||||
@@ -379,19 +395,37 @@
|
|||||||
<string>console</string>
|
<string>console</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Konseleneinstellungen anzeigen und bearbeiten</string>
|
<string>Show and edit console settings.</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="_connectAction">
|
<action name="_connectAction">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset>
|
<iconset resource="bionxcontrol.qrc">
|
||||||
<normaloff>:/connected.png</normaloff>:/connected.png</iconset>
|
<normaloff>:/connect.png</normaloff>:/connect.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>connect</string>
|
<string>connect</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>TinyCAN native Treiber laden</string>
|
<string>Load TinyCAN native driver.</string>
|
||||||
|
</property>
|
||||||
|
<property name="menuRole">
|
||||||
|
<enum>QAction::MenuRole::TextHeuristicRole</enum>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="_syncAction">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="bionxcontrol.qrc">
|
||||||
|
<normaloff>:/sync.png</normaloff>:/sync.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>sync</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Synchronise with eBike settings.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="menuRole">
|
<property name="menuRole">
|
||||||
<enum>QAction::MenuRole::TextHeuristicRole</enum>
|
<enum>QAction::MenuRole::TextHeuristicRole</enum>
|
||||||
|
|||||||
269
bcsliderstyle.h
269
bcsliderstyle.h
@@ -1,269 +0,0 @@
|
|||||||
/***************************************************************************
|
|
||||||
|
|
||||||
BionxControl
|
|
||||||
© 2025 -2026 christoph holzheuer
|
|
||||||
christoph.holzheuer@gmail.com
|
|
||||||
|
|
||||||
Using:
|
|
||||||
|
|
||||||
mhs_can_drv.c
|
|
||||||
© 2011 - 2023 by MHS-Elektronik GmbH & Co. KG, Germany
|
|
||||||
Klaus Demlehner, klaus@mhs-elektronik.de
|
|
||||||
@see www.mhs-elektronik.de
|
|
||||||
|
|
||||||
Based on Bionx data type descriptions from:
|
|
||||||
|
|
||||||
BigXionFlasher USB V 0.2.4 rev. 97
|
|
||||||
© 2011-2013 by Thomas Koenig <info@bigxionflasher.org>
|
|
||||||
@see www.bigxionflasher.org
|
|
||||||
|
|
||||||
Bionx Bike Info
|
|
||||||
© 2018 Thorsten Schmidt (tschmidt@ts-soft.de)
|
|
||||||
@see www.ts-soft.de
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
@see https://github.com/bikemike/bionx-bikeinfo
|
|
||||||
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef BCSLIDERSTYLE_H
|
|
||||||
#define BCSLIDERSTYLE_H
|
|
||||||
|
|
||||||
#include <QStyledItemDelegate>
|
|
||||||
#include <QApplication>
|
|
||||||
#include <QWidget>
|
|
||||||
#include <QTableView>
|
|
||||||
#include <QStandardItemModel>
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
#include <QHeaderView>
|
|
||||||
|
|
||||||
#include <QSlider>
|
|
||||||
#include <QPainter>
|
|
||||||
|
|
||||||
#include <QApplication>
|
|
||||||
#include <QWidget>
|
|
||||||
#include <QPushButton>
|
|
||||||
#include <QLineEdit>
|
|
||||||
#include <QSlider>
|
|
||||||
#include <QCheckBox>
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
#include <QHBoxLayout>
|
|
||||||
#include <QLabel>
|
|
||||||
#include <QProxyStyle>
|
|
||||||
#include <QPainter>
|
|
||||||
#include <QStyleOptionSlider>
|
|
||||||
#include <QGraphicsDropShadowEffect>
|
|
||||||
|
|
||||||
// Fluent Design Slider Style
|
|
||||||
class FluentSliderStyle : public QProxyStyle
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
FluentSliderStyle()
|
|
||||||
: QProxyStyle()
|
|
||||||
{}
|
|
||||||
|
|
||||||
// Wichtig: Genug Platz für Handle reservieren
|
|
||||||
int pixelMetric(PixelMetric metric, const QStyleOption* option = nullptr, const QWidget* widget = nullptr) const override
|
|
||||||
{
|
|
||||||
switch (metric)
|
|
||||||
{
|
|
||||||
case PM_SliderThickness:
|
|
||||||
return 32; // Höhe für horizontalen Slider
|
|
||||||
case PM_SliderLength:
|
|
||||||
return 20; // Handle-Größe
|
|
||||||
case PM_SliderControlThickness:
|
|
||||||
return 20;
|
|
||||||
case PM_SliderSpaceAvailable:
|
|
||||||
if (option)
|
|
||||||
{
|
|
||||||
if (const QStyleOptionSlider* sliderOpt = qstyleoption_cast<const QStyleOptionSlider*>(option)) {
|
|
||||||
if (sliderOpt->orientation == Qt::Horizontal) {
|
|
||||||
return sliderOpt->rect.width() - 20;
|
|
||||||
} else {
|
|
||||||
return sliderOpt->rect.height() - 20;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return QProxyStyle::pixelMetric(metric, option, widget);
|
|
||||||
|
|
||||||
default:
|
|
||||||
return QProxyStyle::pixelMetric(metric, option, widget);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QRect subControlRect(ComplexControl cc, const QStyleOptionComplex* opt,SubControl sc, const QWidget* widget) const override
|
|
||||||
{
|
|
||||||
if (cc == CC_Slider) {
|
|
||||||
if (const QStyleOptionSlider* slider = qstyleoption_cast<const QStyleOptionSlider*>(opt)) {
|
|
||||||
QRect rect = slider->rect;
|
|
||||||
int handleSize = 20;
|
|
||||||
|
|
||||||
if (sc == SC_SliderHandle) {
|
|
||||||
// Handle Position korrekt berechnen
|
|
||||||
if (slider->orientation == Qt::Horizontal) {
|
|
||||||
int range = slider->maximum - slider->minimum;
|
|
||||||
int pos = slider->sliderPosition - slider->minimum;
|
|
||||||
int pixelRange = rect.width() - handleSize;
|
|
||||||
int pixelPos = (range != 0) ? (pos * pixelRange) / range : 0;
|
|
||||||
|
|
||||||
return QRect(rect.x() + pixelPos,
|
|
||||||
rect.center().y() - handleSize / 2,
|
|
||||||
handleSize, handleSize);
|
|
||||||
} else {
|
|
||||||
int range = slider->maximum - slider->minimum;
|
|
||||||
int pos = slider->sliderPosition - slider->minimum;
|
|
||||||
int pixelRange = rect.height() - handleSize;
|
|
||||||
int pixelPos = (range != 0) ? (pos * pixelRange) / range : 0;
|
|
||||||
|
|
||||||
return QRect(rect.center().x() - handleSize / 2,
|
|
||||||
rect.bottom() - pixelPos - handleSize,
|
|
||||||
handleSize, handleSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return QProxyStyle::subControlRect(cc, opt, sc, widget);
|
|
||||||
}
|
|
||||||
|
|
||||||
void drawComplexControl(ComplexControl control, const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget) const override
|
|
||||||
{
|
|
||||||
if (control == CC_Slider)
|
|
||||||
{
|
|
||||||
if (const QStyleOptionSlider* slider = qstyleoption_cast<const QStyleOptionSlider*>(option)) {
|
|
||||||
painter->setRenderHint(QPainter::Antialiasing);
|
|
||||||
|
|
||||||
// Fluent Colors
|
|
||||||
QColor accentColor(0, 120, 212); // #0078D4
|
|
||||||
QColor inactiveColor(138, 136, 134); // #8A8886
|
|
||||||
QColor bgColor(255, 255, 255); // White background
|
|
||||||
|
|
||||||
if (slider->orientation == Qt::Horizontal) {
|
|
||||||
drawHorizontalFluentSlider(painter, slider, accentColor, inactiveColor, bgColor);
|
|
||||||
} else {
|
|
||||||
drawVerticalFluentSlider(painter, slider, accentColor, inactiveColor, bgColor);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QProxyStyle::drawComplexControl(control, option, painter, widget);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
void drawHorizontalFluentSlider(QPainter* painter, const QStyleOptionSlider* slider,
|
|
||||||
const QColor& activeColor, const QColor& inactiveColor,
|
|
||||||
const QColor& bgColor) const {
|
|
||||||
QRect groove = slider->rect;
|
|
||||||
QRect handle = subControlRect(CC_Slider, slider, SC_SliderHandle, nullptr);
|
|
||||||
|
|
||||||
int grooveHeight = 4;
|
|
||||||
// Track sollte im Widget-Zentrum sein, nicht im groove-Zentrum
|
|
||||||
int grooveY = slider->rect.center().y() - grooveHeight / 2;
|
|
||||||
|
|
||||||
// Full background track
|
|
||||||
QRect fullTrack(groove.left(), grooveY, groove.width(), grooveHeight);
|
|
||||||
painter->setPen(Qt::NoPen);
|
|
||||||
painter->setBrush(inactiveColor.lighter(150));
|
|
||||||
painter->drawRoundedRect(fullTrack, grooveHeight / 2, grooveHeight / 2);
|
|
||||||
|
|
||||||
// Active track (filled portion)
|
|
||||||
int activeWidth = handle.center().x() - groove.left();
|
|
||||||
QRect activeTrack(groove.left(), grooveY, activeWidth, grooveHeight);
|
|
||||||
painter->setBrush(activeColor);
|
|
||||||
painter->drawRoundedRect(activeTrack, grooveHeight / 2, grooveHeight / 2);
|
|
||||||
|
|
||||||
// Handle (Thumb) - Fluent style is more subtle
|
|
||||||
int handleSize = 20;
|
|
||||||
QRect thumbRect(handle.center().x() - handleSize / 2,
|
|
||||||
handle.center().y() - handleSize / 2,
|
|
||||||
handleSize, handleSize);
|
|
||||||
|
|
||||||
// Hover effect - subtle glow
|
|
||||||
if (slider->state & State_MouseOver) {
|
|
||||||
painter->setBrush(QColor(activeColor.red(), activeColor.green(),
|
|
||||||
activeColor.blue(), 30));
|
|
||||||
int glowSize = 32;
|
|
||||||
QRect glow(handle.center().x() - glowSize / 2,
|
|
||||||
handle.center().y() - glowSize / 2,
|
|
||||||
glowSize, glowSize);
|
|
||||||
painter->drawEllipse(glow);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Thumb
|
|
||||||
painter->setBrush(bgColor);
|
|
||||||
painter->setPen(QPen(activeColor, 2));
|
|
||||||
painter->drawEllipse(thumbRect);
|
|
||||||
|
|
||||||
// Inner circle for pressed state
|
|
||||||
if (slider->state & State_Sunken) {
|
|
||||||
int innerSize = 8;
|
|
||||||
QRect inner(handle.center().x() - innerSize / 2,
|
|
||||||
handle.center().y() - innerSize / 2,
|
|
||||||
innerSize, innerSize);
|
|
||||||
painter->setPen(Qt::NoPen);
|
|
||||||
painter->setBrush(activeColor);
|
|
||||||
painter->drawEllipse(inner);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void drawVerticalFluentSlider(QPainter* painter, const QStyleOptionSlider* slider,
|
|
||||||
const QColor& activeColor, const QColor& inactiveColor,
|
|
||||||
const QColor& bgColor) const {
|
|
||||||
QRect groove = slider->rect;
|
|
||||||
QRect handle = subControlRect(CC_Slider, slider, SC_SliderHandle, nullptr);
|
|
||||||
|
|
||||||
int grooveWidth = 4;
|
|
||||||
// Track sollte im Widget-Zentrum sein
|
|
||||||
int grooveX = slider->rect.center().x() - grooveWidth / 2;
|
|
||||||
|
|
||||||
// Full background track
|
|
||||||
QRect fullTrack(grooveX, groove.top(), grooveWidth, groove.height());
|
|
||||||
painter->setPen(Qt::NoPen);
|
|
||||||
painter->setBrush(inactiveColor.lighter(150));
|
|
||||||
painter->drawRoundedRect(fullTrack, grooveWidth / 2, grooveWidth / 2);
|
|
||||||
|
|
||||||
// Active track
|
|
||||||
int activeHeight = groove.bottom() - handle.center().y();
|
|
||||||
QRect activeTrack(grooveX, handle.center().y(), grooveWidth, activeHeight);
|
|
||||||
painter->setBrush(activeColor);
|
|
||||||
painter->drawRoundedRect(activeTrack, grooveWidth / 2, grooveWidth / 2);
|
|
||||||
|
|
||||||
// Handle
|
|
||||||
int handleSize = 20;
|
|
||||||
QRect thumbRect(handle.center().x() - handleSize / 2,
|
|
||||||
handle.center().y() - handleSize / 2,
|
|
||||||
handleSize, handleSize);
|
|
||||||
|
|
||||||
if (slider->state & State_MouseOver) {
|
|
||||||
painter->setBrush(QColor(activeColor.red(), activeColor.green(),
|
|
||||||
activeColor.blue(), 30));
|
|
||||||
int glowSize = 32;
|
|
||||||
QRect glow(handle.center().x() - glowSize / 2,
|
|
||||||
handle.center().y() - glowSize / 2,
|
|
||||||
glowSize, glowSize);
|
|
||||||
painter->drawEllipse(glow);
|
|
||||||
}
|
|
||||||
|
|
||||||
painter->setBrush(bgColor);
|
|
||||||
painter->setPen(QPen(activeColor, 2));
|
|
||||||
painter->drawEllipse(thumbRect);
|
|
||||||
|
|
||||||
if (slider->state & State_Sunken) {
|
|
||||||
int innerSize = 8;
|
|
||||||
QRect inner(handle.center().x() - innerSize / 2,
|
|
||||||
handle.center().y() - innerSize / 2,
|
|
||||||
innerSize, innerSize);
|
|
||||||
painter->setPen(Qt::NoPen);
|
|
||||||
painter->setBrush(activeColor);
|
|
||||||
painter->drawEllipse(inner);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif // BCSLIDERSTYLE_H
|
|
||||||
80
bcthemebutton.cpp
Normal file
80
bcthemebutton.cpp
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
BionxControl
|
||||||
|
© 2025 -2026 christoph holzheuer
|
||||||
|
christoph.holzheuer@gmail.com
|
||||||
|
|
||||||
|
Using:
|
||||||
|
|
||||||
|
mhs_can_drv.c
|
||||||
|
© 2011 - 2023 by MHS-Elektronik GmbH & Co. KG, Germany
|
||||||
|
Klaus Demlehner, klaus@mhs-elektronik.de
|
||||||
|
@see www.mhs-elektronik.de
|
||||||
|
|
||||||
|
Based on Bionx data type descriptions from:
|
||||||
|
|
||||||
|
BigXionFlasher USB V 0.2.4 rev. 97
|
||||||
|
© 2011-2013 by Thomas Koenig <info@bigxionflasher.org>
|
||||||
|
@see www.bigxionflasher.org
|
||||||
|
|
||||||
|
Bionx Bike Info
|
||||||
|
© 2018 Thorsten Schmidt (tschmidt@ts-soft.de)
|
||||||
|
@see www.ts-soft.de
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
@see https://github.com/bikemike/bionx-bikeinfo
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include <bcthemebutton.h>
|
||||||
|
|
||||||
|
|
||||||
|
BCThemeButton::BCThemeButton(QWidget *parent )
|
||||||
|
: QPushButton(parent)
|
||||||
|
{
|
||||||
|
// Visuelles Setup: Flach, keine Ränder, Hand-Cursor
|
||||||
|
setFlat(true);
|
||||||
|
setCursor(Qt::PointingHandCursor);
|
||||||
|
setFixedSize( 24, 24 );
|
||||||
|
updateIcon();
|
||||||
|
|
||||||
|
connect(this, &QPushButton::clicked, this, &BCThemeButton::toggleMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Setzt den DarkMode
|
||||||
|
*/
|
||||||
|
|
||||||
|
void BCThemeButton::setDarkMode( bool isDark )
|
||||||
|
{
|
||||||
|
_isDarkMode = !isDark;
|
||||||
|
toggleMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Schaltet den akutellen Mode um.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void BCThemeButton::toggleMode()
|
||||||
|
{
|
||||||
|
_isDarkMode = !_isDarkMode;
|
||||||
|
updateIcon();
|
||||||
|
emit themeChanged(_isDarkMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Icon & Tooltip anpassen
|
||||||
|
*/
|
||||||
|
|
||||||
|
void BCThemeButton::updateIcon()
|
||||||
|
{
|
||||||
|
setText(_isDarkMode ? "🌙" : "☀️");
|
||||||
|
setToolTip(_isDarkMode ? "Use LightMode" : "Use DarkMode");
|
||||||
|
}
|
||||||
@@ -30,5 +30,43 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#include <bcsliderstyle.h>
|
#ifndef BC_THEMESWITCHBUTTON_H
|
||||||
|
#define BC_THEMESWITCHBUTTON_H
|
||||||
|
|
||||||
|
#include <QPushButton>
|
||||||
|
|
||||||
|
#include <bcdriver.h>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Einfaches Buttonwidget, um zwischen Dark- und Lightmode
|
||||||
|
* zu wechseln
|
||||||
|
*/
|
||||||
|
|
||||||
|
class BCThemeButton : public QPushButton
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit BCThemeButton(QWidget *parent = nullptr);
|
||||||
|
void setDarkMode( bool isDark );
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
void themeChanged(bool isDark);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void toggleMode();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void updateIcon();
|
||||||
|
|
||||||
|
bool _isDarkMode{false};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // BC_THEMESWITCHBUTTON_H
|
||||||
234
bctoggleswitch.cpp
Normal file
234
bctoggleswitch.cpp
Normal file
@@ -0,0 +1,234 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
BionxControl
|
||||||
|
© 2025 -2026 christoph holzheuer
|
||||||
|
christoph.holzheuer@gmail.com
|
||||||
|
|
||||||
|
Using:
|
||||||
|
|
||||||
|
mhs_can_drv.c
|
||||||
|
© 2011 - 2023 by MHS-Elektronik GmbH & Co. KG, Germany
|
||||||
|
Klaus Demlehner, klaus@mhs-elektronik.de
|
||||||
|
@see www.mhs-elektronik.de
|
||||||
|
|
||||||
|
Based on Bionx data type descriptions from:
|
||||||
|
|
||||||
|
BigXionFlasher USB V 0.2.4 rev. 97
|
||||||
|
© 2011-2013 by Thomas Koenig <info@bigxionflasher.org>
|
||||||
|
@see www.bigxionflasher.org
|
||||||
|
|
||||||
|
Bionx Bike Info
|
||||||
|
© 2018 Thorsten Schmidt (tschmidt@ts-soft.de)
|
||||||
|
@see www.ts-soft.de
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
@see https://github.com/bikemike/bionx-bikeinfo
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "bctoggleswitch.h"
|
||||||
|
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QPropertyAnimation>
|
||||||
|
#include <QEasingCurve>
|
||||||
|
#include <QEnterEvent>
|
||||||
|
#include <QEvent>
|
||||||
|
|
||||||
|
BCToggleSwitch::BCToggleSwitch(QWidget *parent)
|
||||||
|
: QAbstractButton(parent)
|
||||||
|
, m_position(0.0f)
|
||||||
|
{
|
||||||
|
setCheckable(true);
|
||||||
|
setCursor(Qt::PointingHandCursor);
|
||||||
|
|
||||||
|
// Widget ist jetzt mit setGeometry / Layouts skalierbar
|
||||||
|
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
|
||||||
|
|
||||||
|
// Animation initialisieren
|
||||||
|
m_animation = new QPropertyAnimation(this, "position", this);
|
||||||
|
m_animation->setDuration(200);
|
||||||
|
m_animation->setEasingCurve(QEasingCurve::OutQuad);
|
||||||
|
|
||||||
|
// Signal verknüpfen
|
||||||
|
connect(this, &QAbstractButton::toggled, this, [this](bool checked)
|
||||||
|
{
|
||||||
|
m_animation->stop();
|
||||||
|
m_animation->setStartValue(m_position);
|
||||||
|
m_animation->setEndValue(checked ? 1.0f : 0.0f);
|
||||||
|
m_animation->start();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
float BCToggleSwitch::position() const
|
||||||
|
{
|
||||||
|
return m_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BCToggleSwitch::setPosition(float pos)
|
||||||
|
{
|
||||||
|
m_position = pos;
|
||||||
|
update(); // Trigger Repaint
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize BCToggleSwitch::sizeHint() const
|
||||||
|
{
|
||||||
|
return QSize(44, 22);
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize BCToggleSwitch::minimumSizeHint() const
|
||||||
|
{
|
||||||
|
return QSize(30, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BCToggleSwitch::paintEvent(QPaintEvent *)
|
||||||
|
{
|
||||||
|
QPainter p(this);
|
||||||
|
p.setRenderHint(QPainter::Antialiasing);
|
||||||
|
|
||||||
|
QRect ownRect = rect();
|
||||||
|
|
||||||
|
// Standard-Hintergrundfarbe des aktuellen Qt-Themes
|
||||||
|
p.fillRect(ownRect, palette().window());
|
||||||
|
|
||||||
|
// Auf deaktivierten Zustand prüfen und die statische Methode aufrufen
|
||||||
|
if (!isEnabled()) {
|
||||||
|
paintToggleIndicator(&p, ownRect, isChecked(), m_position, palette());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Farben aus der aktuellen Palette ---
|
||||||
|
QColor onColor = palette().color(QPalette::Highlight);
|
||||||
|
QColor offBorderColor = palette().color(QPalette::Mid);
|
||||||
|
QColor offKnobColor = palette().color(QPalette::Dark);
|
||||||
|
QColor knobOnColor = palette().color(QPalette::HighlightedText);
|
||||||
|
|
||||||
|
// Proportionale Werte aus der Widget-Höhe ableiten
|
||||||
|
qreal h = ownRect.height();
|
||||||
|
qreal radius = h / 2.0;
|
||||||
|
qreal penW = qMax(1.0, h / 14.0); // Strichstärke skaliert mit
|
||||||
|
qreal padding = qMax(2.0, h * 0.14); // Innenabstand skaliert mit
|
||||||
|
|
||||||
|
// 1. Hintergrund (Track) zeichnen
|
||||||
|
p.setPen(Qt::NoPen);
|
||||||
|
|
||||||
|
if (isChecked() || m_position > 0.5f)
|
||||||
|
{
|
||||||
|
// AN-Zustand: Hintergrund gefüllt
|
||||||
|
p.setBrush(onColor);
|
||||||
|
p.drawRoundedRect(ownRect, radius, radius);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// AUS-Zustand: Nur Rahmen
|
||||||
|
p.setBrush(Qt::NoBrush);
|
||||||
|
|
||||||
|
// Hover-Status prüfen
|
||||||
|
if (underMouse())
|
||||||
|
p.setPen(QPen(offBorderColor.darker(120), penW));
|
||||||
|
else
|
||||||
|
p.setPen(QPen(offBorderColor, penW));
|
||||||
|
|
||||||
|
// Rechteck etwas verkleinern, damit der Rahmen nicht abgeschnitten wird
|
||||||
|
qreal inset = penW / 2.0;
|
||||||
|
p.drawRoundedRect(QRectF(ownRect).adjusted(inset, inset, -inset, -inset),
|
||||||
|
radius - inset, radius - inset);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Knopf (Thumb) zeichnen
|
||||||
|
qreal knobDiameter = h - (2 * padding);
|
||||||
|
|
||||||
|
// Interpolation der Position
|
||||||
|
qreal startX = padding;
|
||||||
|
qreal endX = ownRect.width() - knobDiameter - padding;
|
||||||
|
qreal currentX = startX + (m_position * (endX - startX));
|
||||||
|
|
||||||
|
QRectF knobRect(currentX, padding, knobDiameter, knobDiameter);
|
||||||
|
|
||||||
|
if (isChecked() || m_position > 0.5f)
|
||||||
|
{
|
||||||
|
p.setBrush(knobOnColor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (underMouse())
|
||||||
|
p.setBrush(offKnobColor.darker(110));
|
||||||
|
else
|
||||||
|
p.setBrush(offKnobColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
p.setPen(Qt::NoPen);
|
||||||
|
p.drawEllipse(knobRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BCToggleSwitch::paintToggleIndicator(QPainter* p, const QRect& rect, bool isChecked, float position, const QPalette& palette)
|
||||||
|
{
|
||||||
|
// --- Farben für den deaktivierten Zustand aus der Palette ---
|
||||||
|
QColor disabledBorderColor = palette.color(QPalette::Disabled, QPalette::Mid);
|
||||||
|
QColor disabledKnobColor = palette.color(QPalette::Disabled, QPalette::Dark);
|
||||||
|
QColor disabledOnColor = palette.color(QPalette::Disabled, QPalette::Highlight);
|
||||||
|
QColor disabledKnobOnColor = palette.color(QPalette::Disabled, QPalette::HighlightedText);
|
||||||
|
|
||||||
|
QRectF r(rect);
|
||||||
|
qreal h = r.height();
|
||||||
|
qreal radius = h / 2.0;
|
||||||
|
qreal penW = qMax(1.0, h / 14.0);
|
||||||
|
qreal padding = qMax(2.0, h * 0.14);
|
||||||
|
|
||||||
|
// 1. Hintergrund (Track) zeichnen
|
||||||
|
p->setPen(Qt::NoPen);
|
||||||
|
|
||||||
|
if (isChecked || position > 0.5f)
|
||||||
|
{
|
||||||
|
// AN-Zustand (deaktiviert)
|
||||||
|
p->setBrush(disabledOnColor);
|
||||||
|
p->drawRoundedRect(r, radius, radius);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// AUS-Zustand (deaktiviert)
|
||||||
|
p->setBrush(Qt::NoBrush);
|
||||||
|
p->setPen(QPen(disabledBorderColor, penW));
|
||||||
|
qreal inset = penW / 2.0;
|
||||||
|
p->drawRoundedRect(r.adjusted(inset, inset, -inset, -inset),
|
||||||
|
radius - inset, radius - inset);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Knopf (Thumb) zeichnen
|
||||||
|
qreal knobDiameter = h - (2 * padding);
|
||||||
|
|
||||||
|
// X- und Y-Offsets des übergebenen Rects berücksichtigen!
|
||||||
|
qreal startX = r.x() + padding;
|
||||||
|
qreal endX = r.x() + r.width() - knobDiameter - padding;
|
||||||
|
qreal currentX = startX + (position * (endX - startX));
|
||||||
|
|
||||||
|
QRectF knobRect(currentX, r.y() + padding, knobDiameter, knobDiameter);
|
||||||
|
|
||||||
|
p->setPen(Qt::NoPen);
|
||||||
|
|
||||||
|
if (isChecked || position > 0.5f)
|
||||||
|
{
|
||||||
|
p->setBrush(disabledKnobOnColor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p->setBrush(disabledKnobColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
p->drawEllipse(knobRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BCToggleSwitch::enterEvent(QEnterEvent *event)
|
||||||
|
{
|
||||||
|
update(); // Für Hover-Effekt neu zeichnen
|
||||||
|
QAbstractButton::enterEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BCToggleSwitch::leaveEvent(QEvent *event)
|
||||||
|
{
|
||||||
|
update(); // Hover entfernen
|
||||||
|
QAbstractButton::leaveEvent(event);
|
||||||
|
}
|
||||||
41
bctoggleswitch.h
Normal file
41
bctoggleswitch.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#ifndef BC_TOGGLESWITCH_H
|
||||||
|
#define BC_TOGGLESWITCH_H
|
||||||
|
|
||||||
|
#include <QAbstractButton>
|
||||||
|
|
||||||
|
|
||||||
|
class QPropertyAnimation;
|
||||||
|
|
||||||
|
class BCToggleSwitch : public QAbstractButton
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
// Property für die Animation (0.0 bis 1.0)
|
||||||
|
Q_PROPERTY(float position READ position WRITE setPosition)
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit BCToggleSwitch(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
// Getter & Setter für die Animations-Property
|
||||||
|
float position() const;
|
||||||
|
void setPosition(float pos);
|
||||||
|
|
||||||
|
QSize sizeHint() const override;
|
||||||
|
QSize minimumSizeHint() const override;
|
||||||
|
|
||||||
|
// Statische Methode zum Zeichnen des passiven/deaktivierten Zustands
|
||||||
|
static void paintToggleIndicator(QPainter* p, const QRect& rect, bool isChecked, float position, const QPalette& palette);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void paintEvent(QPaintEvent *event) override;
|
||||||
|
void enterEvent(QEnterEvent *event) override;
|
||||||
|
void leaveEvent(QEvent *event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
float m_position; // 0.0 = Aus, 1.0 = An
|
||||||
|
QPropertyAnimation* m_animation;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // BC_TOGGLESWITCH_H
|
||||||
@@ -56,33 +56,23 @@ BCTransmitter::BCTransmitter(QObject *parent)
|
|||||||
|
|
||||||
void BCTransmitter::onToggleDriverConnection( bool connect )
|
void BCTransmitter::onToggleDriverConnection( bool connect )
|
||||||
{
|
{
|
||||||
qDebug() << " --- onToggleDriverConnection: " << connect;
|
if( connect )
|
||||||
emit driverStateChanged(BCDriver::DriverState::Initialized, "BUSY!");
|
emit driverStateChanged(BCDriver::DriverState::NotPresent, "Native Treiber wird geladen.");
|
||||||
bc::delay_millis(350);
|
|
||||||
// kill all pending stuff
|
/*
|
||||||
QCoreApplication::removePostedEvents(this, QEvent::MetaCall);
|
// kill all pending stuff
|
||||||
// FIX! Ende der current op abwarten!
|
//QCoreApplication::removePostedEvents(this, QEvent::MetaCall);
|
||||||
BCDriver::DriverState state = connect ? BCDriver::DriverState::DeviceReady : BCDriver::DriverState::NotPresent;
|
BCDriver::DriverState state = connect ? BCDriver::DriverState::DeviceReady : BCDriver::DriverState::NotPresent;
|
||||||
const QString& message = connect ? "Trying to connect" : " FAILED";
|
const QString& message = connect ? "Trying to connect" : " FAILED";
|
||||||
emit driverStateChanged(state, message);
|
emit driverStateChanged(state, message);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
|
||||||
// Hier sind wir noch in GUI Thread
|
|
||||||
QMutexLocker locker(&_mutex);
|
|
||||||
// weitere operation stoppen
|
|
||||||
_isBusy = true;
|
|
||||||
connect ? connectCanDriver() : disconnectCanDriver();
|
|
||||||
_isBusy = false;
|
|
||||||
*/
|
*/
|
||||||
}
|
|
||||||
|
|
||||||
|
connect ? connectCanDriver() : disconnectCanDriver();
|
||||||
void BCTransmitter::onStartNativeDriver()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void BCTransmitter::connectCanDriver()
|
void BCTransmitter::connectCanDriver()
|
||||||
{
|
{
|
||||||
// hier gehts nur um den echten Treiber
|
// hier gehts nur um den echten Treiber
|
||||||
@@ -92,38 +82,49 @@ void BCTransmitter::connectCanDriver()
|
|||||||
if( _tinyCanDriver.getDriverState() != BCDriver::DriverState::DeviceReady )
|
if( _tinyCanDriver.getDriverState() != BCDriver::DriverState::DeviceReady )
|
||||||
result = _tinyCanDriver.loadAndStartDriver();
|
result = _tinyCanDriver.loadAndStartDriver();
|
||||||
|
|
||||||
QString message("FitzeFatze!");
|
|
||||||
// hat geklappt
|
|
||||||
if( _tinyCanDriver.getDriverState() >= BCDriver::DriverState::Opened )
|
|
||||||
{
|
|
||||||
uint32_t console = static_cast<uint32_t>(BCDevice::ID::Console);
|
|
||||||
uint8_t hwRev = static_cast<uint8_t> (BC::ID::Cons_Rev_Hw);
|
|
||||||
|
|
||||||
TransmitResult hwVersion = _tinyCanDriver.readRawByte( console, hwRev);
|
QString message("Treiber geladen (nicht verbunden)");
|
||||||
if( hwVersion.has_value() )
|
|
||||||
|
// Der result-Wert im ERfolgsfall ist der driver state.
|
||||||
|
if(result.has_value() )
|
||||||
|
{
|
||||||
|
switch( result.value() )
|
||||||
{
|
{
|
||||||
message = " ---- HAIL to the king!";
|
case BCDriver::DriverState::Opened:
|
||||||
qDebug() << message;
|
|
||||||
// swap driver
|
message = "Treiber geladen (Device antwortet nicht)";
|
||||||
_canDriver = &_tinyCanDriver;
|
break;
|
||||||
}
|
|
||||||
else
|
case BCDriver::DriverState::DeviceReady:
|
||||||
{
|
|
||||||
qDebug() << "Console not responding";
|
message = "Treiber geladen und Device verbunden.";
|
||||||
|
// swap driver
|
||||||
|
_canDriver = &_tinyCanDriver;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else // Fehlerfall, wir holen die Fehlermeldung
|
||||||
{
|
{
|
||||||
message = result.error();
|
message = result.error();
|
||||||
}
|
}
|
||||||
|
|
||||||
emit driverStateChanged( _tinyCanDriver.getDriverState(), message );
|
emit driverStateChanged( _tinyCanDriver.getDriverState(), message );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Native-Treiber zurücksetzen, Dummy-Treiber wieder aktivieren.
|
||||||
|
*/
|
||||||
|
|
||||||
void BCTransmitter::disconnectCanDriver()
|
void BCTransmitter::disconnectCanDriver()
|
||||||
{
|
{
|
||||||
_tinyCanDriver.resetDriver();
|
_tinyCanDriver.resetDriver();
|
||||||
_canDriver = &_dummyDriver;
|
_canDriver = &_dummyDriver;
|
||||||
emit driverStateChanged( _tinyCanDriver.getDriverState(), "Disconnected" );
|
emit driverStateChanged( _tinyCanDriver.getDriverState(), "Disconnected, Dummy Treiber aktiviert." );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -143,57 +144,49 @@ void BCTransmitter::onUpdateValue( BCValuePtrConst valuePtr)
|
|||||||
// Kosmetik
|
// Kosmetik
|
||||||
const BCValue& value = *(valuePtr.get());
|
const BCValue& value = *(valuePtr.get());
|
||||||
|
|
||||||
qDebug() << "------- DE.-.QUEUE: " << QThread::currentThreadId() << ": " << value.label;
|
uint32_t devID = static_cast<uint32_t>(value.deviceID());
|
||||||
|
uint8_t regID = static_cast<uint8_t> (value.registerID());
|
||||||
|
|
||||||
// Value ist 'under construction'
|
// Für den Fehlerfall: Wir senden den alten Wert einfach zurück
|
||||||
//emit valueUpdated( value.deviceID, value.indexRow, BCValue::State::Locked );
|
uint32_t newValue = value.rawValue();
|
||||||
|
BCValue::Flag newState = BCValue::Flag::Failed;
|
||||||
|
|
||||||
|
|
||||||
uint32_t devID = static_cast<uint32_t>(value.deviceID);
|
if(value.testFlag( BCValue::Flag::WriteMe ) )
|
||||||
uint8_t regID = static_cast<uint8_t> (value.registerID);
|
|
||||||
|
|
||||||
QString newVisibleValue;
|
|
||||||
BCValue::State newState = BCValue::State::NoState;
|
|
||||||
|
|
||||||
if(value.state.testFlag( BCValue::State::WriteMe ) )
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
// oder sollen wir hier beides erlauben ? readFlag & writeFlag ?
|
// oder sollen wir hier beides erlauben ? readFlag & writeFlag ?
|
||||||
// Was kommt dann zuerst? Schreiben und lesen als verify ?
|
// Was kommt dann zuerst? Schreiben und lesen als verify ?
|
||||||
|
|
||||||
else if( value.state.testFlag( BCValue::State::ReadMe ) )
|
else if( value.testFlag( BCValue::Flag::ReadMe ) )
|
||||||
{
|
{
|
||||||
// wir sind hier im anderen thread! nicht einfach so reinschreiben, nur lesen
|
// wir sind hier im anderen thread! nicht einfach so reinschreiben, nur lesen
|
||||||
TransmitResult result = value.isWord ? readWordValue( devID, regID ) : readByteValue( devID, regID );
|
TransmitResult result = value.isWord() ? readWordValue( devID, regID ) : readByteValue( devID, regID );
|
||||||
if( result.has_value() )
|
if( result.has_value() )
|
||||||
{
|
{
|
||||||
// quark! das gehört hier nicht hin!
|
newState = BCValue::Flag::InSync;
|
||||||
newVisibleValue = value.formatValues( result.value() );
|
newValue = result.value();
|
||||||
newState = BCValue::State::InSync;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
newState = BCValue::State::Failed;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
emit valueUpdated( value.deviceID, value.indexRow, newState, newVisibleValue );
|
emit valueUpdated( value.deviceID(), value.indexRow(), newState, newValue );
|
||||||
|
}
|
||||||
// __fix
|
|
||||||
//bc::processEventsFor(150);
|
/**
|
||||||
bc::delay_millis(50);
|
* @brief Wenn dieser SLOT in der Event-Queue erreicht wird, dedeutet dies, das die
|
||||||
|
* Übertrgung vom Mainwindow abgeschlossen wurde. Wir schicken zur Bestätigung das
|
||||||
|
* Signal 'endOfProcessing' (Welches dann den 'Sync' - Button wieder einschaltet.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void BCTransmitter::onEndOfTransmission()
|
||||||
|
{
|
||||||
|
emit endOfProcessing();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BCTransmitter::onProcessValue()
|
|
||||||
{}
|
|
||||||
|
|
||||||
TransmitResult BCTransmitter::readByteValue( uint32_t deviceID, uint8_t registerID )
|
TransmitResult BCTransmitter::readByteValue( uint32_t deviceID, uint8_t registerID )
|
||||||
{
|
{
|
||||||
//qDebug() << " --- YES: Read ByteValue: " << registerID;
|
|
||||||
// Wir lesen nur ein Byte und gut.
|
// Wir lesen nur ein Byte und gut.
|
||||||
return _canDriver->readRawByte( deviceID, registerID );
|
return _canDriver->readRawByte( deviceID, registerID );
|
||||||
}
|
}
|
||||||
@@ -201,8 +194,6 @@ TransmitResult BCTransmitter::readByteValue( uint32_t deviceID, uint8_t register
|
|||||||
|
|
||||||
TransmitResult BCTransmitter::readWordValue( uint32_t deviceID, uint8_t registerID )
|
TransmitResult BCTransmitter::readWordValue( uint32_t deviceID, uint8_t registerID )
|
||||||
{
|
{
|
||||||
//qDebug() << " --- YES: Read WordValue: " << registerID;
|
|
||||||
|
|
||||||
uint32_t result{};
|
uint32_t result{};
|
||||||
// hi byte Leseversuch.
|
// hi byte Leseversuch.
|
||||||
TransmitResult value = _canDriver->readRawByte( deviceID, registerID );
|
TransmitResult value = _canDriver->readRawByte( deviceID, registerID );
|
||||||
|
|||||||
@@ -30,13 +30,12 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef BCTRANSMITTER_H
|
#ifndef BC_TRANSMITTER_H
|
||||||
#define BCTRANSMITTER_H
|
#define BC_TRANSMITTER_H
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QQueue>
|
#include <QQueue>
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
#include <atomic>
|
|
||||||
|
|
||||||
#include <bcvalue.h>
|
#include <bcvalue.h>
|
||||||
#include <bcdrivertinycan.h>
|
#include <bcdrivertinycan.h>
|
||||||
@@ -64,12 +63,12 @@ public slots:
|
|||||||
|
|
||||||
void onToggleDriverConnection( bool connect );
|
void onToggleDriverConnection( bool connect );
|
||||||
void onUpdateValue(BCValuePtrConst valuePtr );
|
void onUpdateValue(BCValuePtrConst valuePtr );
|
||||||
void onProcessValue();
|
void onEndOfTransmission();
|
||||||
void onStartNativeDriver();
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void valueUpdated(BCDevice::ID deviceID, int index, BCValue::State state, const QString& newValue="" );
|
void endOfProcessing();
|
||||||
|
void valueUpdated(BCDevice::ID deviceID, int index, BCValue::Flag state, uint32_t rawValue );
|
||||||
void driverStateChanged( BCDriver::DriverState state, const QString& message="" );
|
void driverStateChanged( BCDriver::DriverState state, const QString& message="" );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -80,13 +79,6 @@ private:
|
|||||||
TransmitResult readByteValue( uint32_t deviceID, uint8_t registerID );
|
TransmitResult readByteValue( uint32_t deviceID, uint8_t registerID );
|
||||||
TransmitResult readWordValue( uint32_t deviceID, uint8_t registerID );
|
TransmitResult readWordValue( uint32_t deviceID, uint8_t registerID );
|
||||||
|
|
||||||
//using BCDataQueue = QQueue<BCValuePtrConst>;
|
|
||||||
|
|
||||||
//BCDataQueue _valueQueue;
|
|
||||||
//QMutex _mutex;
|
|
||||||
//std::atomic<bool> _isBusy{ false };
|
|
||||||
|
|
||||||
// __fix!
|
|
||||||
BCDriver* _canDriver{};
|
BCDriver* _canDriver{};
|
||||||
BCDriverTinyCan _tinyCanDriver{};
|
BCDriverTinyCan _tinyCanDriver{};
|
||||||
BCDriverDummy _dummyDriver{};
|
BCDriverDummy _dummyDriver{};
|
||||||
@@ -94,4 +86,4 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // BCTRANSMITTER_H
|
#endif // BC_TRANSMITTER_H
|
||||||
|
|||||||
245
bcvalue.cpp
245
bcvalue.cpp
@@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <QMetaEnum>
|
#include <QMetaEnum>
|
||||||
|
#include <QTextStream>
|
||||||
|
|
||||||
#include <bcvalue.h>
|
#include <bcvalue.h>
|
||||||
|
|
||||||
@@ -39,28 +40,252 @@
|
|||||||
|
|
||||||
|
|
||||||
BCValue::BCValue( BCDevice::ID deviceID_, BC::ID registerID_)
|
BCValue::BCValue( BCDevice::ID deviceID_, BC::ID registerID_)
|
||||||
: deviceID{deviceID_}, registerID{registerID_}
|
: _deviceID{deviceID_}, _registerID{registerID_}
|
||||||
{
|
{
|
||||||
visibleValue = "--";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString BCValue::formatValues( uint32_t value ) const
|
QString BCValue::formatValue() const
|
||||||
{
|
{
|
||||||
if( factor == 1 )
|
if( _factor == 1 )
|
||||||
return QString::number( value );
|
return QString::number( _rawValue );
|
||||||
|
|
||||||
double result = value * factor;
|
double result =_rawValue * _factor;
|
||||||
return QString::number(result, 'f', 2);
|
return QString::number(result, 'f', 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BCValue::isWord() const
|
||||||
|
{
|
||||||
|
return _valueFlags.testFlag(BCValue::Flag::IsWord);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BCValue::isReadOnly() const
|
||||||
|
{
|
||||||
|
return _valueFlags.testFlag(BCValue::Flag::ReadOnly);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BCValue::isBoolean() const
|
||||||
|
{
|
||||||
|
return valueType() == BCValue::ValueType::Bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BCValue::isChecked() const
|
||||||
|
{
|
||||||
|
return isBoolean() && rawValue() == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BCValue::testFlag( BCValue::Flag flag ) const
|
||||||
|
{
|
||||||
|
return _valueFlags.testFlag( flag );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BCValue::setFlag( BCValue::Flag flag, bool state) const
|
||||||
|
{
|
||||||
|
_valueFlags.setFlag( flag, state );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BCDevice::ID BCValue::deviceID() const noexcept
|
||||||
|
{
|
||||||
|
return _deviceID;
|
||||||
|
}
|
||||||
|
|
||||||
|
BC::ID BCValue::registerID() const noexcept
|
||||||
|
{
|
||||||
|
return _registerID;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t BCValue::rawValue() const noexcept
|
||||||
|
{
|
||||||
|
return _rawValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Speichert einen via CAN-Bus gelesenen Wert in
|
||||||
|
* der BCValue Struktur.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void BCValue::setRawValue(uint32_t newRawValue) const
|
||||||
|
{
|
||||||
|
// die per Zufallsgenerator erzeugten Werte des Dummy-Treibers
|
||||||
|
// können beliebigen Unsinn enthalten, also müssen wir sie
|
||||||
|
// auch skalieren.
|
||||||
|
|
||||||
|
if( _valueType == ValueType::Bool )
|
||||||
|
{
|
||||||
|
_rawValue = newRawValue > 0 ? 1 : 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
double value = newRawValue * _factor;
|
||||||
|
|
||||||
|
if( _optMin.has_value() && _optMax.has_value() )
|
||||||
|
{
|
||||||
|
|
||||||
|
double min = _optMin.value();
|
||||||
|
double max = _optMax.value();
|
||||||
|
|
||||||
|
value = (int) qBound( min,value, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
_rawValue = value / _factor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BCValue::ValueType BCValue::valueType() const noexcept
|
||||||
|
{
|
||||||
|
return _valueType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int BCValue::indexRow() const noexcept
|
||||||
|
{
|
||||||
|
return _indexRow;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BCValue::setIndexRow(int newIndexRow)
|
||||||
|
{
|
||||||
|
_indexRow = newIndexRow;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString BCValue::label() const
|
||||||
|
{
|
||||||
|
return _label;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString BCValue::unitLabel() const
|
||||||
|
{
|
||||||
|
return _unitLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BCValue::setFromDouble( double value )
|
||||||
|
{
|
||||||
|
//if( _isReadOnly)
|
||||||
|
switch(_valueType)
|
||||||
|
{
|
||||||
|
|
||||||
|
// wir betrachten plain
|
||||||
|
|
||||||
|
case ValueType::Bool :
|
||||||
|
_rawValue = value > 0 ? 1 : 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ValueType::Plain :
|
||||||
|
case ValueType::Number:
|
||||||
|
case ValueType::Float:
|
||||||
|
|
||||||
|
if( _optMin.has_value() && _optMax.has_value() )
|
||||||
|
{
|
||||||
|
|
||||||
|
double min = _optMin.value();
|
||||||
|
double max = _optMax.value();
|
||||||
|
|
||||||
|
value = qBound( min,value,max);
|
||||||
|
}
|
||||||
|
_rawValue = value / _factor;
|
||||||
|
|
||||||
|
default :
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
double BCValue::calcMinMaxRatio() const
|
||||||
|
{
|
||||||
|
|
||||||
|
double ratio = 1;
|
||||||
|
|
||||||
|
if( _optMin.has_value() && _optMax.has_value() )
|
||||||
|
{
|
||||||
|
|
||||||
|
double min = _optMin.value();
|
||||||
|
double max = _optMax.value();
|
||||||
|
|
||||||
|
double range = max - min;
|
||||||
|
|
||||||
|
// Safety: Division durch Null verhindern (wenn min == max)
|
||||||
|
if (std::abs(range) < 1e-9)
|
||||||
|
return ratio;
|
||||||
|
|
||||||
|
double value = _rawValue * _factor;
|
||||||
|
// Die eigentliche Formel
|
||||||
|
ratio = ((value - min) / range);
|
||||||
|
}
|
||||||
|
return ratio;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool BCValue::hasValuesForSlider(ValueRange& valueRange) const
|
||||||
|
{
|
||||||
|
valueRange.value = valueRange.min = valueRange.max = 0;
|
||||||
|
|
||||||
|
// min & max sind vorraussetzung für den slider
|
||||||
|
if( !_optMin.has_value() || !_optMax.has_value() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// wir erwarten hier, das value zwischen min
|
||||||
|
// und max liegt weil wir das schon bei setRawValue
|
||||||
|
// überprüft haben.
|
||||||
|
|
||||||
|
valueRange.value = _rawValue * _factor;
|
||||||
|
valueRange.min = _optMin.value();
|
||||||
|
valueRange.max = _optMax.value();
|
||||||
|
valueRange.ratio = calcMinMaxRatio();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void BCValue::dumpValue() const
|
void BCValue::dumpValue() const
|
||||||
{
|
{
|
||||||
|
|
||||||
qDebug() << "DeviceID: " << deviceID << " Register: " << registerID << " state:" " << state << " << " label: " << label;
|
qDebug() << "DeviceID: " << _deviceID << " Register: " << _registerID << " state:" " << state << " << " label: " << _label;
|
||||||
qDebug() << "visibleValue: " << visibleValue << " min: " << min << " max: " << max << " factor: " << factor << " ValueType: " << (char)valueType << " ";
|
qDebug() << "formattedValue: " << formatValue() << " min: " << _optMin << " max: " << _optMax << " factor: " << _factor << " ValueType: " << (char)_valueType << " ";
|
||||||
qDebug() << "indexRow: " << indexRow << " isWord: " << isWord;
|
qDebug() << "indexRow: " << _indexRow << " isWord: " << isWord() << " isRO: " << isReadOnly();
|
||||||
qDebug();
|
qDebug();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ----
|
QString BCValue::toString() const
|
||||||
|
{
|
||||||
|
QString result;
|
||||||
|
QTextStream stream(&result);
|
||||||
|
|
||||||
|
stream << *this;
|
||||||
|
|
||||||
|
/*
|
||||||
|
qDebug() << "DeviceID: " << _deviceID << " Register: " << _registerID << " state:" " << state << " << " label: " << _label;
|
||||||
|
qDebug() << "formattedValue: " << formatValue() << " min: " << _optMin << " max: " << _optMax << " factor: " << _factor << " ValueType: " << (char)_valueType << " ";
|
||||||
|
qDebug() << "indexRow: " << _indexRow << " isWord: " << isWord() << " isRO: " << isReadOnly();
|
||||||
|
qDebug();
|
||||||
|
*/
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Generischer Operator für ALLE Q_GADGETs
|
||||||
|
inline QTextStream& operator<<(QTextStream& out, const BCValue& obj)
|
||||||
|
{
|
||||||
|
const QMetaObject* meta = &obj.staticMetaObject;
|
||||||
|
|
||||||
|
out << meta->className() << " { ";
|
||||||
|
|
||||||
|
// Iteriere über alle Properties (Reflection)
|
||||||
|
for (int i = 0; i < meta->propertyCount(); ++i) {
|
||||||
|
QMetaProperty prop = meta->property(i);
|
||||||
|
const char* propName = prop.name();
|
||||||
|
QVariant val = prop.readOnGadget(&obj);
|
||||||
|
|
||||||
|
out << propName << ": " << val.toString();
|
||||||
|
|
||||||
|
if (i < meta->propertyCount() - 1) out << ", ";
|
||||||
|
}
|
||||||
|
out << " }";
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|||||||
125
bcvalue.h
125
bcvalue.h
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
Using:
|
Using:
|
||||||
|
|
||||||
mhs_can_drv.c
|
mhsMEMBER _canMEMBER _drv.c
|
||||||
© 2011 - 2023 by MHS-Elektronik GmbH & Co. KG, Germany
|
© 2011 - 2023 by MHS-Elektronik GmbH & Co. KG, Germany
|
||||||
Klaus Demlehner, klaus@mhs-elektronik.de
|
Klaus Demlehner, klaus@mhs-elektronik.de
|
||||||
@see www.mhs-elektronik.de
|
@see www.mhs-elektronik.de
|
||||||
@@ -30,18 +30,14 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef BCVALUE_H
|
#ifndef BC_VALUEMEMBER_H
|
||||||
#define BCVALUE_H
|
#define BC_VALUEMEMBER_H
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QString>
|
|
||||||
#include <QList>
|
|
||||||
#include <QVariant>
|
|
||||||
|
|
||||||
#include <expected>
|
#include <expected>
|
||||||
#include <bc.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <bc.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Werte haben verschiedene Längen (1,2 und 4 Byte) und werder auf unterschiedliche Art und Weise
|
Werte haben verschiedene Längen (1,2 und 4 Byte) und werder auf unterschiedliche Art und Weise
|
||||||
ausgelesen und geschrieben (Siehe BCValueTypeWord). Sie können also Wert-Typen zugeordnet werden. Ein Werttyp
|
ausgelesen und geschrieben (Siehe BCValueTypeWord). Sie können also Wert-Typen zugeordnet werden. Ein Werttyp
|
||||||
@@ -60,11 +56,14 @@ using OptDouble = std::optional<double>;
|
|||||||
|
|
||||||
// Enthält den gelesenen Wert oder einen Fehlerstring
|
// Enthält den gelesenen Wert oder einen Fehlerstring
|
||||||
using TransmitResult = std::expected<uint32_t,QString>;
|
using TransmitResult = std::expected<uint32_t,QString>;
|
||||||
// Funktionsobject, um Werte aus der Transmitterschicht zu holden
|
// Funktionsobject, um Werte aus der Transmitterschicht zu holen
|
||||||
//using ReadValueFunc = std::function<TransmitResult( const BCAbstractTransmitter& transmitter, uint32_t deviceID, uint8_t registerID )>;
|
//using ReadValueFunc = std::function<TransmitResult( const BCAbstractTransmitter& transmitter, uint32MEMBER _t deviceID, uint8MEMBER _t registerID )>;
|
||||||
|
|
||||||
class BCValue
|
class BCValue
|
||||||
{
|
{
|
||||||
|
Q_GADGET
|
||||||
|
|
||||||
|
friend class BCXmlLoader;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -72,61 +71,105 @@ public:
|
|||||||
// später der Editor
|
// später der Editor
|
||||||
enum class ValueType : uint8_t
|
enum class ValueType : uint8_t
|
||||||
{
|
{
|
||||||
Plain,
|
Plain, // nur lesen, sowas wie SerialNo
|
||||||
Bool,
|
Bool,
|
||||||
Number,
|
Number,
|
||||||
Float
|
Float
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class State : uint8_t
|
enum class Flag : uint8_t
|
||||||
{
|
{
|
||||||
NoState = 0x00,
|
NoFlag = 0x00,
|
||||||
ReadMe = 0x01,
|
ReadMe = 0x01,
|
||||||
WriteMe = 0x02,
|
WriteMe = 0x02,
|
||||||
ReadOnly = 0x04,
|
ReadOnly = 0x04,
|
||||||
Locked = 0x08,
|
Locked = 0x08,
|
||||||
Failed = 0x10,
|
Failed = 0x10,
|
||||||
InSync = 0x20,
|
InSync = 0x20,
|
||||||
OK = 0x40
|
OK = 0x40,
|
||||||
|
IsWord = 0x80
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(States, State )
|
Q_DECLARE_FLAGS(Flags, Flag )
|
||||||
|
Q_FLAG(Flags)
|
||||||
|
|
||||||
BCValue( BCDevice::ID deviceID_, BC::ID registerID_ );
|
//Q_PROPERTY(Flags valueFlags MEMBER _valueFlags )
|
||||||
|
Q_PROPERTY(BCDevice::ID deviceID MEMBER _deviceID READ deviceID )
|
||||||
|
Q_PROPERTY(BC::ID registerID MEMBER _registerID READ registerID )
|
||||||
|
Q_PROPERTY(ValueType valueType MEMBER _valueType READ valueType )
|
||||||
|
Q_PROPERTY(int indexRow MEMBER _indexRow READ indexRow)
|
||||||
|
Q_PROPERTY(QString label MEMBER _label READ label )
|
||||||
|
Q_PROPERTY(uint32_t rawValue MEMBER _rawValue READ rawValue )
|
||||||
|
Q_PROPERTY(QString unitLabel MEMBER _unitLabel READ unitLabel )
|
||||||
|
Q_PROPERTY(double factor MEMBER _factor )
|
||||||
|
//QMEMBER _PROPERTY(OptDouble MEMBER _optMin)
|
||||||
|
//QMEMBER _PROPERTY(OptDouble MEMBER _optMax)
|
||||||
|
|
||||||
QString formatValues( uint32_t value ) const;
|
struct ValueRange
|
||||||
void dumpValue() const;
|
{
|
||||||
|
int value{0};
|
||||||
|
int min{0};
|
||||||
|
int max{0};
|
||||||
|
double ratio{1};
|
||||||
|
};
|
||||||
|
|
||||||
|
BCValue( BCDevice::ID deviceID, BC::ID registerID );
|
||||||
|
|
||||||
|
QString formatValue() const;
|
||||||
|
double calcMinMaxRatio() const;
|
||||||
|
void dumpValue() const;
|
||||||
|
bool isWord() const;
|
||||||
|
bool isReadOnly() const;
|
||||||
|
bool isBoolean() const;
|
||||||
|
bool isChecked() const;
|
||||||
|
|
||||||
|
bool testFlag( Flag flag ) const;
|
||||||
|
void setFlag( Flag flag, bool state=true ) const;
|
||||||
|
|
||||||
|
BCDevice::ID deviceID() const noexcept;
|
||||||
|
BC::ID registerID() const noexcept;
|
||||||
|
|
||||||
|
uint32_t rawValue() const noexcept;
|
||||||
|
void setRawValue(uint32_t newRawValue) const;
|
||||||
|
void setFromDouble( double value );
|
||||||
|
|
||||||
|
ValueType valueType() const noexcept;
|
||||||
|
int indexRow() const noexcept;
|
||||||
|
|
||||||
|
void setIndexRow(int newIndexRow);
|
||||||
|
QString label() const;
|
||||||
|
QString unitLabel() const;
|
||||||
|
|
||||||
|
bool hasValuesForSlider( ValueRange& valueRange ) const;
|
||||||
|
|
||||||
|
QString toString() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
mutable Flags _valueFlags{BCValue::Flag::NoFlag};
|
||||||
|
BCDevice::ID _deviceID{BCDevice::ID::Invalid};
|
||||||
|
BC::ID _registerID{BC::ID::Invalid};
|
||||||
|
ValueType _valueType{ValueType::Plain};
|
||||||
|
int _indexRow{-1};
|
||||||
|
QString _label;
|
||||||
|
mutable uint32_t _rawValue{};
|
||||||
|
QString _unitLabel;
|
||||||
|
double _factor{1};
|
||||||
|
OptDouble _optMin;
|
||||||
|
OptDouble _optMax;
|
||||||
|
|
||||||
mutable States state{BCValue::State::ReadOnly};
|
|
||||||
BCDevice::ID deviceID{BCDevice::ID::Invalid};
|
|
||||||
BC::ID registerID{BC::ID::Invalid};
|
|
||||||
ValueType valueType{ValueType::Plain};
|
|
||||||
int indexRow{-1};
|
|
||||||
QString label;
|
|
||||||
mutable QString visibleValue;
|
|
||||||
mutable double rawValue;
|
|
||||||
bool isWord{false};
|
|
||||||
QString unitLabel;
|
|
||||||
double factor{1};
|
|
||||||
OptDouble min;
|
|
||||||
OptDouble max;
|
|
||||||
};
|
};
|
||||||
Q_DECLARE_OPERATORS_FOR_FLAGS(BCValue::States)
|
Q_DECLARE_OPERATORS_FOR_FLAGS(BCValue::Flags)
|
||||||
|
Q_DECLARE_METATYPE(BCValue::Flags)
|
||||||
|
|
||||||
|
|
||||||
//Q_DECLARE_METATYPE(const BCValue&)
|
|
||||||
|
|
||||||
using BCValuePtr = std::shared_ptr<BCValue>;
|
using BCValuePtr = std::shared_ptr<BCValue>;
|
||||||
using BCValuePtrConst = std::shared_ptr<const BCValue>;
|
using BCValuePtrConst = std::shared_ptr<const BCValue>;
|
||||||
|
|
||||||
//using BCValueList = QList<BCValue>;
|
//using BCValueList = QList<BCValue>;
|
||||||
using BCValueList = QList<BCValuePtr>;
|
using BCValueList = QList<BCValuePtr>;
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(const BCValuePtr)
|
Q_DECLARE_METATYPE(const BCValuePtr)
|
||||||
|
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(BCValueList)
|
Q_DECLARE_METATYPE(BCValueList)
|
||||||
|
|
||||||
|
// Generischer Operator für ALLE GADGETs
|
||||||
|
inline QTextStream& operator<<(QTextStream& out, const BCValue& obj);
|
||||||
|
|
||||||
#endif // BCVALUE_H
|
#endif // BCVALUE_H
|
||||||
|
|||||||
379
bcvaluedelegate.cpp
Normal file
379
bcvaluedelegate.cpp
Normal file
@@ -0,0 +1,379 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
BionxControl
|
||||||
|
© 2025 -2026 christoph holzheuer
|
||||||
|
christoph.holzheuer@gmail.com
|
||||||
|
|
||||||
|
Using:
|
||||||
|
|
||||||
|
mhs_can_drv.c
|
||||||
|
© 2011 - 2023 by MHS-Elektronik GmbH & Co. KG, Germany
|
||||||
|
Klaus Demlehner, klaus@mhs-elektronik.de
|
||||||
|
@see www.mhs-elektronik.de
|
||||||
|
|
||||||
|
Based on Bionx data type descriptions from:
|
||||||
|
|
||||||
|
BigXionFlasher USB V 0.2.4 rev. 97
|
||||||
|
© 2011-2013 by Thomas Koenig <info@bigxionflasher.org>
|
||||||
|
@see www.bigxionflasher.org
|
||||||
|
|
||||||
|
Bionx Bike Info
|
||||||
|
© 2018 Thorsten Schmidt (tschmidt@ts-soft.de)
|
||||||
|
@see www.ts-soft.de
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
@see https://github.com/bikemike/bionx-bikeinfo
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include <QSlider>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include <QVariantAnimation>
|
||||||
|
#include <QPropertyAnimation>
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
|
#include <bcdeviceview.h>
|
||||||
|
#include <bcvaluedelegate.h>
|
||||||
|
#include <bcvalueslider.h>
|
||||||
|
#include <bctoggleswitch.h>
|
||||||
|
|
||||||
|
BCValueDelegate::BCValueDelegate(const BCValueList& valueList, BCDeviceView* view)
|
||||||
|
: QStyledItemDelegate{view}, _valueList{valueList}, _view{view}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QWidget* BCValueDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
|
||||||
|
Q_UNUSED(option)
|
||||||
|
Q_UNUSED(index)
|
||||||
|
|
||||||
|
const BCValue& bcValue = *(_valueList[ index.row() ].get());
|
||||||
|
|
||||||
|
BCValue::ValueRange params;
|
||||||
|
bool hasData = bcValue.hasValuesForSlider( params );
|
||||||
|
|
||||||
|
qDebug() << " --- Create Editor: " << bcValue.label() << " value: " << params.value << " min: " << params.min << " max: " << params.max << " ratio:" << bcValue.calcMinMaxRatio()*100.0 << '%';
|
||||||
|
|
||||||
|
if( bcValue.isBoolean() )
|
||||||
|
{
|
||||||
|
auto* toggleSwitch = new BCToggleSwitch{parent};
|
||||||
|
toggleSwitch->setChecked(bcValue.isChecked() );
|
||||||
|
|
||||||
|
// Signal für sofortige Updates
|
||||||
|
connect(toggleSwitch, &BCToggleSwitch::toggled, this, [this, toggleSwitch](bool checked)
|
||||||
|
{
|
||||||
|
qDebug() << "--- toggled: " << checked;
|
||||||
|
// Commit data sofort bei Änderung
|
||||||
|
emit const_cast<BCValueDelegate*>(this)->commitData(toggleSwitch);
|
||||||
|
});
|
||||||
|
|
||||||
|
return toggleSwitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if( !hasData )
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
auto* valueSlider = new BCValueSlider{parent};
|
||||||
|
valueSlider->setValueAndRange( params );
|
||||||
|
// Signal für sofortige Updates
|
||||||
|
connect(valueSlider, &BCValueSlider::valueChanged, this, [this, valueSlider]()
|
||||||
|
{
|
||||||
|
// Commit data sofort bei Änderung
|
||||||
|
emit const_cast<BCValueDelegate*>(this)->commitData(valueSlider);
|
||||||
|
});
|
||||||
|
return valueSlider;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BCValueDelegate::setEditorData(QWidget *editor, const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(editor)
|
||||||
|
Q_UNUSED(index)
|
||||||
|
|
||||||
|
// tue nix.
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BCValueDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(index)
|
||||||
|
|
||||||
|
const BCValue& bcValue = *(_valueList[ index.row()].get());
|
||||||
|
QRect editorRect = bcValue.isBoolean() ? adjustEditorRect(option.rect, 0, 6, -130, -6) : adjustEditorRect(option.rect, 0, 0, 8, 0);
|
||||||
|
editor->setGeometry(editorRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BCValueDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
if (index.column() != 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QVariant reValue;
|
||||||
|
|
||||||
|
const BCValue& bcValue = *(_valueList[index.row()].get());
|
||||||
|
if (bcValue.isBoolean())
|
||||||
|
{
|
||||||
|
if (BCToggleSwitch* toggleSswitch = qobject_cast<BCToggleSwitch*>(editor))
|
||||||
|
reValue = toggleSswitch->isChecked() ? 1 : 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (BCValueSlider* slider = qobject_cast<BCValueSlider*>(editor))
|
||||||
|
reValue = slider->value();
|
||||||
|
}
|
||||||
|
|
||||||
|
model->setData(index, reValue, Qt::EditRole);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BCValueDelegate::paint(QPainter *painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
int row = index.row();
|
||||||
|
if( index.column() != 1 || row<0 || row >= _valueList.size() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
QStyleOptionViewItem opt = option;
|
||||||
|
initStyleOption(&opt, index);
|
||||||
|
|
||||||
|
const BCValue& bcValue = *(_valueList[ index.row()].get());
|
||||||
|
|
||||||
|
if( bcValue.isBoolean() )
|
||||||
|
{
|
||||||
|
paintBooleanValue( painter, opt, bcValue );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Standard-Zeichnen (Text, Hintergrund, Selection) durchführen
|
||||||
|
QStyledItemDelegate::paint(painter, opt, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !bcValue.isReadOnly() )
|
||||||
|
{
|
||||||
|
// Wir zeichnen boolean Values an toggle switches
|
||||||
|
if (bcValue.isBoolean())
|
||||||
|
{
|
||||||
|
//paintPlainToggleSwitch(painter, opt, bcValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
paintPlainSliderIndicator(painter, opt.rect, bcValue.calcMinMaxRatio());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_rowOpacities.contains(row))
|
||||||
|
paintHighlightRow(painter, opt,index.row());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void BCValueDelegate::paintBooleanValue( QPainter *painter, const QStyleOptionViewItem& option, const BCValue& bcValue ) const
|
||||||
|
{
|
||||||
|
|
||||||
|
QRect textRect = option.rect.adjusted( 2,0,0,0);
|
||||||
|
|
||||||
|
// 3. Den tatsächlichen Wert aus dem Model auslesen
|
||||||
|
QString text = bcValue.rawValue() == 1 ? BCTags::Yes : BCTags::No;
|
||||||
|
|
||||||
|
// 3. Die korrekte Textfarbe ermitteln (extrem wichtig für die UX!)
|
||||||
|
// Wenn die Zeile markiert ist (Selected), muss der Text meist weiß sein,
|
||||||
|
// ansonsten schwarz (oder je nach System-Theme).
|
||||||
|
QPalette::ColorRole textRole = (option.state & QStyle::State_Selected)
|
||||||
|
? QPalette::HighlightedText
|
||||||
|
: QPalette::Text;
|
||||||
|
|
||||||
|
// 4. Den Text nativ durch den Style zeichnen lassen
|
||||||
|
QApplication::style()->drawItemText(
|
||||||
|
painter,
|
||||||
|
textRect,
|
||||||
|
Qt::AlignLeft | Qt::AlignVCenter, // Ausrichtung innerhalb von textRect
|
||||||
|
option.palette, // Farbpalette der View übernehmen
|
||||||
|
option.state & QStyle::State_Enabled, // Prüfen, ob die Zelle klickbar/aktiv ist
|
||||||
|
text, // Der zu zeichnende String
|
||||||
|
textRole // Die ermittelte Farb-Rolle
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect BCValueDelegate::adjustEditorRect( const QRect& rect, int x1, int y1, int x2, int y2 ) const
|
||||||
|
{
|
||||||
|
return rect.adjusted
|
||||||
|
(
|
||||||
|
rect.width() - cTextBlockOffset + x1, // Von rechts: cTextBlockOffset (==130) px (Breite der Progress Bar)
|
||||||
|
y1, // Oben: kein Offset
|
||||||
|
x2, // Rechts: 8px Padding
|
||||||
|
y2 // Unten: kein Offset
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// option.rect.adjusted(option.rect.width() - cTextBlockOffset,4,0,0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Zeichnet der 'Sliderindicator', also den Anteil des Gesamtwerts als Fortschrittsbalken
|
||||||
|
*/
|
||||||
|
|
||||||
|
void BCValueDelegate::paintPlainSliderIndicator(QPainter* painter, const QRect& rect, double ratio )const
|
||||||
|
{
|
||||||
|
QRect sliderRect = adjustEditorRect( rect, 0, 0, -35, 0 );
|
||||||
|
// Kleinen Slider-Indikator zeichnen
|
||||||
|
painter->save();
|
||||||
|
painter->setRenderHint(QPainter::Antialiasing);
|
||||||
|
|
||||||
|
QRect barRect = sliderRect;
|
||||||
|
|
||||||
|
int yOffset = sliderRect.height()/2;
|
||||||
|
barRect.setY( rect.y() + yOffset - 3 );
|
||||||
|
barRect.setHeight( 6);
|
||||||
|
|
||||||
|
// Mini Progress Bar: der Gesamtbereich
|
||||||
|
painter->setPen(Qt::NoPen);
|
||||||
|
painter->setBrush(QColor(0xE0E0E0));
|
||||||
|
painter->drawRoundedRect(barRect, 4, 4);
|
||||||
|
|
||||||
|
// Mini Progress Bar: der Wertebereich
|
||||||
|
barRect.setWidth( ratio * barRect.width() );
|
||||||
|
painter->setBrush(QColor(0x0078D4));
|
||||||
|
painter->drawRoundedRect(barRect, 4, 4);
|
||||||
|
|
||||||
|
painter->restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BCValueDelegate::paintHighlightRow(QPainter* painter, const QStyleOptionViewItem& option, int row) const
|
||||||
|
{
|
||||||
|
painter->save();
|
||||||
|
painter->setRenderHint(QPainter::Antialiasing);
|
||||||
|
qreal opacity =_rowOpacities.value(row);
|
||||||
|
painter->setOpacity(opacity);
|
||||||
|
// Margin von 2px
|
||||||
|
const int m = 3;
|
||||||
|
QRect itemRect = option.rect.adjusted(m,m,-m,-m);
|
||||||
|
|
||||||
|
// Border (2px solid #2196F3)
|
||||||
|
// oranger rahmen
|
||||||
|
QPen borderPen( QColor(0xFF8C00), 1);
|
||||||
|
painter->setPen(borderPen);
|
||||||
|
painter->setBrush(Qt::NoBrush);
|
||||||
|
|
||||||
|
// highlight background
|
||||||
|
//QColor highlightColor = option.palette.highlight().color();
|
||||||
|
//highlightColor.setAlphaF(0.3); // 0.0 bis 1.0 (float ist oft lesbarer)
|
||||||
|
//painter->fillRect(option.rect, highlightColor);
|
||||||
|
|
||||||
|
painter->drawRoundedRect(itemRect, 2, 2);
|
||||||
|
|
||||||
|
painter->restore();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BCValueDelegate::paintPlainToggleSwitch(QPainter* painter, const QStyleOptionViewItem& option, const BCValue& bcValue) const
|
||||||
|
{
|
||||||
|
BCToggleSwitch::paintToggleIndicator(painter, option.rect, bcValue.isChecked(), 20, option.widget->palette());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Startet die Animation für die übergebene Zeile
|
||||||
|
* @param row
|
||||||
|
*/
|
||||||
|
|
||||||
|
void BCValueDelegate::onHighlightRow(int row)
|
||||||
|
{
|
||||||
|
// Alte Animation für diese Zeile stoppen falls vorhanden
|
||||||
|
if (_rowAnimations.contains(row))
|
||||||
|
{
|
||||||
|
_rowAnimations[row]->stop();
|
||||||
|
_rowAnimations[row]->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
// QVariantAnimation ist flexibler als QPropertyAnimation
|
||||||
|
auto* anim = new QVariantAnimation(this);
|
||||||
|
anim->setDuration(800);
|
||||||
|
anim->setStartValue(0.0);
|
||||||
|
anim->setEndValue(1.0);
|
||||||
|
|
||||||
|
// Custom Easing für Fade-in/out Effekt
|
||||||
|
anim->setEasingCurve(QEasingCurve::OutQuad);
|
||||||
|
|
||||||
|
connect(anim, &QVariantAnimation::valueChanged, this, [this, row](const QVariant& value)
|
||||||
|
{
|
||||||
|
qreal progress = value.toReal();
|
||||||
|
qreal opacity;
|
||||||
|
|
||||||
|
// Schnelles Fade-in (20%), langsames Fade-out (80%)
|
||||||
|
if (progress < 0.2) {
|
||||||
|
opacity = progress * 5.0; // 0->1 in 20%
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
opacity = 1.0 - ((progress - 0.2) / 0.8); // 1->0 in 80%
|
||||||
|
}
|
||||||
|
|
||||||
|
_rowOpacities[row] = opacity;
|
||||||
|
updateRow(row);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(anim, &QVariantAnimation::finished, this, [this, row, anim]()
|
||||||
|
{
|
||||||
|
_rowOpacities.remove(row);
|
||||||
|
_rowAnimations.remove(row);
|
||||||
|
updateRow(row);
|
||||||
|
anim->deleteLater();
|
||||||
|
});
|
||||||
|
|
||||||
|
_rowAnimations[row] = anim;
|
||||||
|
anim->start(QAbstractAnimation::DeleteWhenStopped);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stopt alle gerade laufenden Animationen
|
||||||
|
*/
|
||||||
|
|
||||||
|
void BCValueDelegate::clearAllHighlights()
|
||||||
|
{
|
||||||
|
for(auto* anim : std::as_const(_rowAnimations))
|
||||||
|
{
|
||||||
|
anim->stop();
|
||||||
|
anim->deleteLater();
|
||||||
|
}
|
||||||
|
_rowAnimations.clear();
|
||||||
|
_rowOpacities.clear();
|
||||||
|
|
||||||
|
if (_view)
|
||||||
|
_view->viewport()->update();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Zeichnet die übegebene Zeile neu.
|
||||||
|
* @param row
|
||||||
|
*/
|
||||||
|
|
||||||
|
void BCValueDelegate::updateRow(int row)
|
||||||
|
{
|
||||||
|
if (_view && _view->model() && row >= 0)
|
||||||
|
{
|
||||||
|
QModelIndex idx = _view->model()->index(row,1);
|
||||||
|
QRect rect = _view->visualRect(idx);
|
||||||
|
if (!rect.isEmpty())
|
||||||
|
_view->viewport()->update(rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -30,8 +30,8 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef BCANIMATEDDELEGATE_H
|
#ifndef BC_VALUEDELEGATE_H
|
||||||
#define BCANIMATEDDELEGATE_H
|
#define BC_VALUEDELEGATE_H
|
||||||
|
|
||||||
#include <QStyledItemDelegate>
|
#include <QStyledItemDelegate>
|
||||||
|
|
||||||
@@ -39,56 +39,53 @@
|
|||||||
|
|
||||||
class QPropertyAnimation;
|
class QPropertyAnimation;
|
||||||
class QVariantAnimation;
|
class QVariantAnimation;
|
||||||
class QTableView;
|
class BCDeviceView;
|
||||||
|
|
||||||
|
|
||||||
class BCAnimatedDelegate : public QStyledItemDelegate
|
class BCValueDelegate : public QStyledItemDelegate
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
explicit BCAnimatedDelegate(const BCValueList& valueList, QTableView* view );
|
explicit BCValueDelegate(const BCValueList& valueList, BCDeviceView* view );
|
||||||
|
|
||||||
// QString displayText(const QVariant& dataValue, const QLocale& locale) const override;
|
|
||||||
|
|
||||||
// Zuständig für den Edit-Modus (Doppelklick)
|
// Zuständig für den Edit-Modus (Doppelklick)
|
||||||
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex& index) const override;
|
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
|
||||||
void setEditorData(QWidget *editor, const QModelIndex& index) const override;
|
void setEditorData(QWidget *editor, const QModelIndex& index) const override;
|
||||||
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex& index) const override;
|
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex& index) const override;
|
||||||
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex& index) const override;
|
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
|
||||||
|
void paint(QPainter *painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
|
||||||
QSize sizeHint(const QStyleOptionViewItem &option,const QModelIndex& index) const override;
|
|
||||||
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex& index) const override;
|
|
||||||
|
|
||||||
void clearAllHighlights();
|
void clearAllHighlights();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void onHighlightRow(int row);
|
void onHighlightRow(int row);
|
||||||
|
|
||||||
|
protected:
|
||||||
signals:
|
|
||||||
|
|
||||||
//void viewUpdateNeeded();
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
void updateRow(int row);
|
void updateRow(int row);
|
||||||
void paintHighlightRow(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
|
void paintHighlightRow(QPainter* painter, const QStyleOptionViewItem& option, int row) const;
|
||||||
void paintSliderIndicator(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
|
void paintPlainToggleSwitch(QPainter* painter, const QStyleOptionViewItem& option, const BCValue& bcValue) const;
|
||||||
|
void paintPlainSliderIndicator(QPainter* painter, const QRect& rect, double ratio ) const;
|
||||||
|
void paintBooleanValue( QPainter *painter, const QStyleOptionViewItem& option, const BCValue& bcValue ) const;
|
||||||
|
|
||||||
|
QRect adjustEditorRect(const QRect& rect, int x1, int y1, int x2, int y2) const;
|
||||||
|
|
||||||
const BCValueList& _valueList;
|
const BCValueList& _valueList;
|
||||||
QTableView* _view{};
|
BCDeviceView* _view{};
|
||||||
|
|
||||||
QPropertyAnimation* _animation{};
|
QPropertyAnimation* _animation{};
|
||||||
|
|
||||||
private:
|
QHash<int, qreal> _rowOpacities;
|
||||||
|
QHash<int, QVariantAnimation*> _rowAnimations;
|
||||||
|
|
||||||
QHash<int, qreal> m_rowOpacities;
|
static constexpr int cTextBlockOffset = 160;
|
||||||
QHash<int, QVariantAnimation*> m_rowAnimations;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // BCANIMATEDDELEGATE_H
|
#endif // BC_VALUEDELEGATE_H
|
||||||
@@ -45,8 +45,6 @@ BCValueModel::BCValueModel(QObject *parent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gibt die interne Werteliste als const ref zurück
|
* @brief Gibt die interne Werteliste als const ref zurück
|
||||||
* @return Die WerteListe
|
* @return Die WerteListe
|
||||||
@@ -81,27 +79,18 @@ void BCValueModel::takeValueList(BCValueList& newValueList)
|
|||||||
* @param newValue Der neue sichtbare Zahlenwert, formatiert als QString, optionall
|
* @param newValue Der neue sichtbare Zahlenwert, formatiert als QString, optionall
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void BCValueModel::onValueUpdated( int row, BCValue::State state, const QString& newVisisbleValue )
|
void BCValueModel::updateValue(int row, BCValue::Flags newState, uint32_t rawValue )
|
||||||
{
|
{
|
||||||
if( row > -1 && row < _valueList.size() )
|
if( row > -1 && row < _valueList.size() )
|
||||||
{
|
{
|
||||||
const BCValue& value = *(_valueList[row].get());
|
const BCValue& value = *(_valueList[row].get());
|
||||||
|
|
||||||
|
// Obacht hier!
|
||||||
|
//value.valueFlags = state;
|
||||||
|
value.setRawValue( rawValue );
|
||||||
|
|
||||||
QModelIndex idx = index(row,1);
|
QModelIndex idx = index(row,1);
|
||||||
|
|
||||||
//qDebug();
|
|
||||||
//qDebug() << " --- OLD:"<< newVisisbleValue;
|
|
||||||
//value.dumpValue();
|
|
||||||
|
|
||||||
value.state = state;
|
|
||||||
|
|
||||||
if( !newVisisbleValue.isEmpty() && newVisisbleValue != value.visibleValue )
|
|
||||||
{
|
|
||||||
value.visibleValue = newVisisbleValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//qDebug() << " --- NEW: " << newVisisbleValue;
|
|
||||||
//value.dumpValue();
|
|
||||||
|
|
||||||
// wir schicken auf jeden fall einen update request
|
// wir schicken auf jeden fall einen update request
|
||||||
emit dataChanged(idx, idx, {Qt::DisplayRole, Qt::EditRole});
|
emit dataChanged(idx, idx, {Qt::DisplayRole, Qt::EditRole});
|
||||||
}
|
}
|
||||||
@@ -132,12 +121,10 @@ int BCValueModel::columnCount(const QModelIndex& parent) const
|
|||||||
{
|
{
|
||||||
if (parent.isValid())
|
if (parent.isValid())
|
||||||
return 0;
|
return 0;
|
||||||
return 3;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gibt die Model-Daten zurück.
|
* @brief Gibt die Model-Daten zurück.
|
||||||
*/
|
*/
|
||||||
@@ -156,66 +143,59 @@ QVariant BCValueModel::data(const QModelIndex& index, int role) const
|
|||||||
const BCValue& value = *(_valueList.at( row ).get());
|
const BCValue& value = *(_valueList.at( row ).get());
|
||||||
|
|
||||||
if( col == 0 )
|
if( col == 0 )
|
||||||
return value.label;
|
return value.label();
|
||||||
|
|
||||||
if( col == 1)
|
if( col == 1)
|
||||||
{
|
{
|
||||||
if( role == Qt::DisplayRole )
|
if( role == Qt::DisplayRole )
|
||||||
return QString("%1 %2").arg( value.visibleValue, value.unitLabel);
|
return QString("%1 %2").arg( value.formatValue(), value.unitLabel());
|
||||||
|
|
||||||
return value.visibleValue;
|
return value.formatValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Das Model Gibt hier, unabhängig von der DataRole, immer das
|
|
||||||
* gesamte BCValue Object zurück. Die Umsetzung von Status- und Typeinfromationen in GUI-Elemente
|
|
||||||
* findet nicht hier, sondern im BCDelagate statt.
|
|
||||||
|
|
||||||
// falsch! wie geben hier doch ordentlich die einzelwerte zurück
|
|
||||||
|
|
||||||
// Bonus: Rechtsbündig für Zahlen
|
|
||||||
if (role == Qt::TextAlignmentRole && (index.column() == 0 || index.column() == 2)) {
|
|
||||||
return Qt::AlignRight | Qt::AlignVCenter;
|
|
||||||
}
|
|
||||||
|
|
||||||
//return QVariant::fromValue( entry );
|
|
||||||
|
|
||||||
return QVariant();
|
|
||||||
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Qt::ItemFlags BCValueModel::flags(const QModelIndex& index) const
|
Qt::ItemFlags BCValueModel::flags(const QModelIndex& index) const
|
||||||
{
|
{
|
||||||
|
Qt::ItemFlags flag = Qt::NoItemFlags | Qt::ItemNeverHasChildren;// | Qt::ItemIsSelectable;
|
||||||
// die label spalte lässt sich nicht editieren
|
// die label spalte lässt sich nicht editieren
|
||||||
if (!index.isValid() || index.column() == 0 )
|
if (!index.isValid() || index.column() == 0 )
|
||||||
return Qt::NoItemFlags;
|
return flag;
|
||||||
|
int row = index.row();
|
||||||
return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
|
if( row>-1 && row<_valueList.size() )
|
||||||
|
{
|
||||||
|
const BCValue& bcValue = *_valueList[row].get();
|
||||||
|
//qDebug() << " --- flags: " << bcValue.label() << " Ro: " << bcValue.isReadOnly() << " Bool: " << bcValue.isBoolean();
|
||||||
|
flag = bcValue.isReadOnly() ? flag : flag|Qt::ItemIsEditable|Qt::ItemIsEnabled;
|
||||||
|
}
|
||||||
|
return flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool BCValueModel::setData(const QModelIndex& index, const QVariant& value, int role)
|
bool BCValueModel::setData(const QModelIndex& index, const QVariant& variant, int role)
|
||||||
{
|
{
|
||||||
|
|
||||||
// __fix!
|
|
||||||
|
|
||||||
if (index.isValid() && role == Qt::EditRole)
|
if (index.isValid() && role == Qt::EditRole)
|
||||||
{
|
{
|
||||||
BCValuePtr item = _valueList[index.row()];
|
|
||||||
|
qDebug() << " --- SetData: at: " << index.row() << " --- set: " << variant.toString();
|
||||||
|
|
||||||
|
BCValuePtr value = _valueList[index.row()];
|
||||||
|
|
||||||
// Wir erwarten hier nur den Value-Teil (vom Slider/Editor)
|
// Wir erwarten hier nur den Value-Teil (vom Slider/Editor)
|
||||||
// Checken ob Int oder Double
|
// Checken ob Int oder Double
|
||||||
if (value.canConvert<double>())
|
if (variant.canConvert<int>())
|
||||||
{
|
{
|
||||||
item->visibleValue = value.toString();
|
if( variant.toInt() == 42)
|
||||||
|
{
|
||||||
|
emit makeSimonHappy();
|
||||||
|
}
|
||||||
|
// QUARK!
|
||||||
|
value->setRawValue( variant.toInt() );
|
||||||
}
|
}
|
||||||
|
|
||||||
_valueList[index.row()] = item;
|
|
||||||
emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole});
|
emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,8 +30,8 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef BCVALUEMODEL_H
|
#ifndef BC_VALUEMODEL_H
|
||||||
#define BCVALUEMODEL_H
|
#define BC_VALUEMODEL_H
|
||||||
|
|
||||||
#include <QAbstractTableModel>
|
#include <QAbstractTableModel>
|
||||||
#include <bcvalue.h>
|
#include <bcvalue.h>
|
||||||
@@ -59,16 +59,16 @@ public:
|
|||||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||||
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
|
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||||
|
|
||||||
//QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
|
||||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
|
||||||
|
|
||||||
// Nötig für Editierbarkeit
|
|
||||||
Qt::ItemFlags flags(const QModelIndex& index) const override;
|
Qt::ItemFlags flags(const QModelIndex& index) const override;
|
||||||
|
|
||||||
|
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||||
bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override;
|
bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override;
|
||||||
|
|
||||||
public slots:
|
void updateValue(int row, BCValue::Flags newState, uint32_t rawValue );
|
||||||
|
|
||||||
void onValueUpdated(int index, BCValue::State state, const QString& newVisisbleValue="" );
|
signals:
|
||||||
|
|
||||||
|
void makeSimonHappy();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@@ -77,4 +77,4 @@ protected:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BCVALUEMODEL_H
|
#endif // BC_VALUEMODEL_H
|
||||||
|
|||||||
85
bcvalueslider.cpp
Normal file
85
bcvalueslider.cpp
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
BionxControl
|
||||||
|
© 2025 -2026 christoph holzheuer
|
||||||
|
christoph.holzheuer@gmail.com
|
||||||
|
|
||||||
|
Using:
|
||||||
|
|
||||||
|
mhs_can_drv.c
|
||||||
|
© 2011 - 2023 by MHS-Elektronik GmbH & Co. KG, Germany
|
||||||
|
Klaus Demlehner, klaus@mhs-elektronik.de
|
||||||
|
@see www.mhs-elektronik.de
|
||||||
|
|
||||||
|
Based on Bionx data type descriptions from:
|
||||||
|
|
||||||
|
BigXionFlasher USB V 0.2.4 rev. 97
|
||||||
|
© 2011-2013 by Thomas Koenig <info@bigxionflasher.org>
|
||||||
|
@see www.bigxionflasher.org
|
||||||
|
|
||||||
|
Bionx Bike Info
|
||||||
|
© 2018 Thorsten Schmidt (tschmidt@ts-soft.de)
|
||||||
|
@see www.ts-soft.de
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
@see https://github.com/bikemike/bionx-bikeinfo
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include <QPushButton>
|
||||||
|
|
||||||
|
#include <bcvalueslider.h>
|
||||||
|
|
||||||
|
|
||||||
|
BCValueSlider::BCValueSlider( QWidget *parent )
|
||||||
|
: QWidget(parent)
|
||||||
|
{
|
||||||
|
setupUi(this);
|
||||||
|
|
||||||
|
// wir wollen ja modern sein
|
||||||
|
//_sliderStyle = std::make_unique<BCValueSliderStyle>();
|
||||||
|
//_slider->setStyle(_sliderStyle.get());
|
||||||
|
setAutoFillBackground(true);
|
||||||
|
|
||||||
|
QSizePolicy sp = _commitButton->sizePolicy();
|
||||||
|
sp.setRetainSizeWhenHidden(true); // <--- Das ist der magische Schalter
|
||||||
|
_commitButton->setSizePolicy(sp);
|
||||||
|
|
||||||
|
// Wenn Slider bewegt wird -> Signal nach außen senden
|
||||||
|
connect(_slider, &QSlider::valueChanged, this, [this](int val)
|
||||||
|
{
|
||||||
|
emit valueChanged(val);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Wenn Reset gedrückt wird -> Slider auf 0 (löst auch valueChanged aus)
|
||||||
|
connect(_commitButton, &QPushButton::clicked, this, [this]()
|
||||||
|
{
|
||||||
|
emit valueCommited( value() );
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int BCValueSlider::value() const
|
||||||
|
{
|
||||||
|
return _slider->value();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BCValueSlider::setValueAndRange( const BCValue::ValueRange& params )
|
||||||
|
{
|
||||||
|
_slider->setRange( params.min, params.max);
|
||||||
|
// Block Signals verhindern Endlosschleifen, falls das Model
|
||||||
|
// das Widget während des Updates neu setzt (passiert manchmal bei Live-Updates).
|
||||||
|
if (params.value != _slider->value())
|
||||||
|
{
|
||||||
|
bool blocked = _slider->blockSignals(true);
|
||||||
|
_slider->setValue(params.value);
|
||||||
|
_slider->blockSignals(blocked);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
38
bcvalueslider.h
Normal file
38
bcvalueslider.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#ifndef BC_VALUESLIDER_H
|
||||||
|
#define BC_VALUESLIDER_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QTableView>
|
||||||
|
#include <QSlider>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QProxyStyle>
|
||||||
|
|
||||||
|
#include <bcvalue.h>
|
||||||
|
#include <ui_bcvalueslider.h>
|
||||||
|
|
||||||
|
class QSlider;
|
||||||
|
class QPushButton;
|
||||||
|
class BCValue;
|
||||||
|
|
||||||
|
|
||||||
|
class BCValueSlider : public QWidget, private Ui_BCValueSlider
|
||||||
|
{
|
||||||
|
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit BCValueSlider(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
int value() const;
|
||||||
|
void setValueAndRange( const BCValue::ValueRange& params );
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
void valueChanged(int value);
|
||||||
|
void valueCommited(int value);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // BC_VALUESLIDER_H
|
||||||
95
bcvalueslider.ui
Normal file
95
bcvalueslider.ui
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>BCValueSlider</class>
|
||||||
|
<widget class="QWidget" name="BCValueSlider">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>111</width>
|
||||||
|
<height>24</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>60</width>
|
||||||
|
<height>24</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SizeConstraint::SetMinimumSize</enum>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QSlider" name="_slider">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Orientation::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="_commitButton">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>24</width>
|
||||||
|
<height>24</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777212</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>PointingHandCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="bionxcontrol.qrc">
|
||||||
|
<normaloff>:/update.png</normaloff>:/update.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>24</width>
|
||||||
|
<height>24</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="popupMode">
|
||||||
|
<enum>QToolButton::ToolButtonPopupMode::InstantPopup</enum>
|
||||||
|
</property>
|
||||||
|
<property name="toolButtonStyle">
|
||||||
|
<enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
|
||||||
|
</property>
|
||||||
|
<property name="autoRaise">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources>
|
||||||
|
<include location="bionxcontrol.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
137
bcxmlloader.cpp
137
bcxmlloader.cpp
@@ -51,33 +51,30 @@ BCXmlLoader::BCXmlLoader(QObject *parent)
|
|||||||
|
|
||||||
void BCXmlLoader::loadXmlBikeData( const QString& fileName )
|
void BCXmlLoader::loadXmlBikeData( const QString& fileName )
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
auto printAttrs = [](const QXmlStreamReader& xml)
|
auto printAttrs = [](const QXmlStreamReader& xml)
|
||||||
{
|
{
|
||||||
QStringList parts;
|
QStringList parts;
|
||||||
for (const auto &attr : xml.attributes()) {
|
for (const auto &attr : xml.attributes())
|
||||||
|
{
|
||||||
parts << attr.name().toString() + "=\"" + attr.value().toString() + "\"";
|
parts << attr.name().toString() + "=\"" + attr.value().toString() + "\"";
|
||||||
}
|
}
|
||||||
qDebug().noquote() << parts.join(" ");
|
qDebug().noquote() << parts.join(" ");
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
QMetaEnum bcDeviceEnum{QMetaEnum::fromType<BCDevice::ID>()};
|
QMetaEnum bcDeviceEnum{QMetaEnum::fromType<BCDevice::ID>()};
|
||||||
|
|
||||||
QFile file(fileName);
|
QFile file(fileName);
|
||||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
|
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||||
{
|
throw BCException( "Fehler", "Datei konnte nicht geöffnet werden.");
|
||||||
// __fix throw
|
|
||||||
QMessageBox::warning(nullptr, "Fehler", "Datei konnte nicht geöffnet werden.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_xml.setDevice(&file);
|
_xml.setDevice(&file);
|
||||||
|
|
||||||
if (_xml.readNextStartElement())
|
if (_xml.readNextStartElement())
|
||||||
{
|
{
|
||||||
if (_xml.name() != "Bike"_L1 )
|
if (_xml.name() != "Bike"_L1 )
|
||||||
// fix throw
|
throw BCException( "Fehler", "Falsches Datenformat.");
|
||||||
_xml.raiseError(QObject::tr("The file is not an 'Bike' file."));
|
|
||||||
}
|
}
|
||||||
// ??
|
// ??
|
||||||
Q_ASSERT(_xml.isStartElement() && _xml.name() == "Bike"_L1);
|
Q_ASSERT(_xml.isStartElement() && _xml.name() == "Bike"_L1);
|
||||||
@@ -88,25 +85,26 @@ void BCXmlLoader::loadXmlBikeData( const QString& fileName )
|
|||||||
if (token == QXmlStreamReader::StartElement)
|
if (token == QXmlStreamReader::StartElement)
|
||||||
{
|
{
|
||||||
QString deviceType = _xml.attributes().value("Type"_L1).toString();
|
QString deviceType = _xml.attributes().value("Type"_L1).toString();
|
||||||
//printAttrs (_xml);
|
|
||||||
// Wir wollen die Device-ID aus dem XML Tag ermitteln
|
// Wir wollen die Device-ID aus dem XML Tag ermitteln
|
||||||
const char* deviceKey = _xml.attributes().value("Type"_L1).toLatin1().constData();
|
if( deviceType.isEmpty() )
|
||||||
bool ok;
|
continue;
|
||||||
|
|
||||||
|
QByteArray byteArray = deviceType.toUtf8();
|
||||||
|
const char* deviceKey = byteArray.constData();
|
||||||
|
bool ok=false;
|
||||||
auto optDeviceID = bcDeviceEnum.keyToValue(deviceKey,&ok);
|
auto optDeviceID = bcDeviceEnum.keyToValue(deviceKey,&ok);
|
||||||
//_currentDeviceID = BCDevice::ID( deviceID.value_or( BCDevice::ID::Invalid ) );
|
//_currentDeviceID = BCDevice::ID( deviceID.value_or( BCDevice::ID::Invalid ) );
|
||||||
//if( optDeviceID.has_value())
|
//if( optDeviceID.has_value())
|
||||||
if(ok)
|
if(!ok)
|
||||||
{
|
throw BCException( "Fehler", QString("Devicetype %1 existiert nicht.").arg(deviceType) );
|
||||||
qDebug() << " --- Device: " << _xml.name() << ": " << deviceType << " : " << optDeviceID;
|
//BCDevice::ID currentDeviceID = BCDevice::ID( optDeviceID.value() );
|
||||||
//BCDevice::ID currentDeviceID = BCDevice::ID( optDeviceID.value() );
|
BCDevice::ID currentDeviceID = BCDevice::ID( optDeviceID );
|
||||||
BCDevice::ID currentDeviceID = BCDevice::ID( optDeviceID );
|
loadXmlBikeDeviceData(currentDeviceID);
|
||||||
loadXmlBikeDeviceData(currentDeviceID);
|
} // if startElement
|
||||||
}
|
} // end while
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Lädt deie Daten des BionX eBikes
|
* @brief Lädt deie Daten des BionX eBikes
|
||||||
* @param deviceID
|
* @param deviceID
|
||||||
@@ -117,15 +115,13 @@ void BCXmlLoader::loadXmlBikeDeviceData(BCDevice::ID deviceID)
|
|||||||
auto printAttrs = [](const QXmlStreamReader& xml)
|
auto printAttrs = [](const QXmlStreamReader& xml)
|
||||||
{
|
{
|
||||||
QStringList parts;
|
QStringList parts;
|
||||||
for (const auto &attr : xml.attributes()) {
|
for (const auto &attr : xml.attributes())
|
||||||
parts << attr.name().toString() + "=\"" + attr.value().toString() + "\"";
|
parts << attr.name().toString() + "=\"" + attr.value().toString() + "\"";
|
||||||
}
|
|
||||||
qDebug().noquote() << parts.join(" ");
|
qDebug().noquote() << parts.join(" ");
|
||||||
};
|
};
|
||||||
|
|
||||||
printAttrs (_xml);
|
printAttrs (_xml);
|
||||||
Q_ASSERT(_xml.isStartElement() && _xml.name() == "Device"_L1);
|
Q_ASSERT(_xml.isStartElement() && _xml.name() == BCTags::Device );
|
||||||
|
|
||||||
|
|
||||||
// temporäre Wertliste für neues Device
|
// temporäre Wertliste für neues Device
|
||||||
BCValueList currentValues;
|
BCValueList currentValues;
|
||||||
@@ -133,9 +129,7 @@ void BCXmlLoader::loadXmlBikeDeviceData(BCDevice::ID deviceID)
|
|||||||
while( _xml.readNextStartElement() )
|
while( _xml.readNextStartElement() )
|
||||||
{
|
{
|
||||||
if( _xml.attributes().hasAttribute(BCTags::ID) )
|
if( _xml.attributes().hasAttribute(BCTags::ID) )
|
||||||
{
|
{
|
||||||
//qDebug() << " --- found: " << _xml.name() << " : " << _xml.attributes().value(BCTags::ID);
|
|
||||||
|
|
||||||
// füllen des Parameter packs
|
// füllen des Parameter packs
|
||||||
BCValueParams params
|
BCValueParams params
|
||||||
{
|
{
|
||||||
@@ -146,6 +140,7 @@ void BCXmlLoader::loadXmlBikeDeviceData(BCDevice::ID deviceID)
|
|||||||
.Min = _xml.attributes().value(BCTags::Min).toString(),
|
.Min = _xml.attributes().value(BCTags::Min).toString(),
|
||||||
.Max = _xml.attributes().value(BCTags::Max).toString(),
|
.Max = _xml.attributes().value(BCTags::Max).toString(),
|
||||||
.IsWord = _xml.attributes().value(BCTags::IsWord).toString(),
|
.IsWord = _xml.attributes().value(BCTags::IsWord).toString(),
|
||||||
|
.ReadOnly = _xml.attributes().value(BCTags::ReadOnly).toString(),
|
||||||
.ValueType = _xml.attributes().value(BCTags::ValueType).toString(),
|
.ValueType = _xml.attributes().value(BCTags::ValueType).toString(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -154,7 +149,7 @@ void BCXmlLoader::loadXmlBikeDeviceData(BCDevice::ID deviceID)
|
|||||||
if(newValue)
|
if(newValue)
|
||||||
{
|
{
|
||||||
// wir merken uns gleich den index in der Werteliste
|
// wir merken uns gleich den index in der Werteliste
|
||||||
(*newValue)->indexRow = currentValues.size();
|
(*newValue)->setIndexRow( currentValues.size() );
|
||||||
currentValues.push_back( *newValue );
|
currentValues.push_back( *newValue );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,6 +164,11 @@ void BCXmlLoader::loadXmlBikeDeviceData(BCDevice::ID deviceID)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Erzeugt einen BCValue für die DeviceID aus dem gegebenen parameter pack
|
||||||
|
*/
|
||||||
|
|
||||||
std::optional<BCValuePtr> BCXmlLoader::makeValue( BCDevice::ID deviceID, const BCValueParams& params )
|
std::optional<BCValuePtr> BCXmlLoader::makeValue( BCDevice::ID deviceID, const BCValueParams& params )
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -180,66 +180,57 @@ std::optional<BCValuePtr> BCXmlLoader::makeValue( BCDevice::ID deviceID, const B
|
|||||||
{ "Float", BCValue::ValueType::Float }
|
{ "Float", BCValue::ValueType::Float }
|
||||||
};
|
};
|
||||||
|
|
||||||
auto setIfExists = [&]<typename T>( QStringView source, T& target )
|
auto setIfExists = [&]<typename T>( T& target, QStringView source )
|
||||||
{
|
{
|
||||||
if( !source.isEmpty() )
|
if( !source.isEmpty() )
|
||||||
{
|
{
|
||||||
bool ok;
|
bool ok;
|
||||||
double testVal = source.toDouble(&ok);
|
double testVal = source.toDouble(&ok);
|
||||||
if (ok)
|
if (ok)
|
||||||
target = testVal;
|
target = testVal;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Wir brauchen:
|
||||||
/*
|
// - einen gültige ID String um die enum ID herauszufinden.
|
||||||
Wir brauchen:
|
// - einen gültige UnitType String um den ValueType herauszufinden.
|
||||||
- einen gültige ID String um die enum ID herauszufinden.
|
|
||||||
- einen gültige UnitType String um den ValueType herauszufinden.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
// geht nicht auf qt6.8 von debian trixie
|
// geht nicht auf qt6.8 von debian trixie
|
||||||
//std::optional<quint64> IDVal = s_bcValueEnum.keyToValue64( params.ID.toLatin1().constData() );
|
//std::optional<quint64> IDVal = s_bcValueEnum.keyToValue64( params.ID.toLatin1().constData() );
|
||||||
bool ok;
|
bool ok;
|
||||||
static QMetaEnum s_bcValueEnum{QMetaEnum::fromType<BC::ID>()};
|
static QMetaEnum s_bcValueEnum{QMetaEnum::fromType<BC::ID>()};
|
||||||
int IDVal = s_bcValueEnum.keyToValue( params.ID.toLatin1().constData(), &ok );
|
QByteArray byteArray = params.ID.toUtf8();
|
||||||
qDebug() << " --- should create: " << params.Label;
|
int IDVal = s_bcValueEnum.keyToValue( params.ID.toUtf8().constData(), &ok );
|
||||||
//if( IDVal.has_value() )
|
//if( IDVal.has_value() )
|
||||||
if( ok )
|
if( !ok )
|
||||||
{
|
throw BCException( "Fehler", QString("Devicetype %1 existiert nicht.").arg(params.ID) );
|
||||||
BCValuePtr newValuePtr = std::make_shared<BCValue>( deviceID, static_cast<BC::ID>(IDVal) );
|
|
||||||
BCValue& newValue = *newValuePtr.get();
|
|
||||||
|
|
||||||
setIfExists( params.Factor, newValue.factor );
|
BCValuePtr newValuePtr = std::make_shared<BCValue>( deviceID, static_cast<BC::ID>(IDVal) );
|
||||||
setIfExists( params.Min, newValue.min );
|
BCValue& newValue = *newValuePtr.get();
|
||||||
setIfExists( params.Max, newValue.max );
|
|
||||||
setIfExists( params.IsWord, newValue.isWord );
|
|
||||||
|
|
||||||
newValue.label = params.Label;
|
// ValueType
|
||||||
newValue.unitLabel = params.UnitLabel;
|
if( !s_valueTypes.contains( params.ValueType ) )
|
||||||
|
throw BCException( "Fehler", QString("ValueType %1 existiert nicht.").arg(params.ValueType) );
|
||||||
|
|
||||||
if( s_valueTypes.contains( params.ValueType ) )
|
newValue._valueType = s_valueTypes[params.ValueType];
|
||||||
newValue.valueType = s_valueTypes[params.ValueType];
|
|
||||||
|
|
||||||
/*
|
newValue._label = params.Label;
|
||||||
QString ID;
|
newValue._unitLabel = params.UnitLabel;
|
||||||
QString Label;
|
|
||||||
QString UnitLabel;
|
|
||||||
QString Factor;
|
|
||||||
QString Min;
|
|
||||||
QString Max;
|
|
||||||
QString IsWord;
|
|
||||||
QString ValueType;
|
|
||||||
*/
|
|
||||||
|
|
||||||
qDebug() << " --- created: " << params.Label;
|
setIfExists( newValue._factor, params.Factor );
|
||||||
newValue.dumpValue();
|
setIfExists( newValue._optMin, params.Min );
|
||||||
|
setIfExists( newValue._optMax, params.Max );
|
||||||
|
|
||||||
return std::optional<BCValuePtr>( newValuePtr );
|
if( params.IsWord == "true")
|
||||||
}
|
newValue._valueFlags.setFlag( BCValue::Flag::IsWord, true );
|
||||||
|
|
||||||
|
if( params.ReadOnly == "true")
|
||||||
|
newValue._valueFlags.setFlag( BCValue::Flag::ReadOnly, true );
|
||||||
|
|
||||||
|
//newValue.dumpValue();
|
||||||
|
|
||||||
|
return std::optional<BCValuePtr>( newValuePtr );
|
||||||
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ protected:
|
|||||||
QString Min;
|
QString Min;
|
||||||
QString Max;
|
QString Max;
|
||||||
QString IsWord;
|
QString IsWord;
|
||||||
|
QString ReadOnly;
|
||||||
QString ValueType;
|
QString ValueType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,34 @@
|
|||||||
<RCC>
|
<RCC>
|
||||||
<qresource prefix="/">
|
<qresource prefix="/">
|
||||||
<file alias="bikeinfo.xml">resources/bikeinfo.xml</file>
|
<file alias="bikeinfo.xml">resources/bikeinfo.xml</file>
|
||||||
<file alias="bionxcontrol.qss">resources/bionxcontrol.qss</file>
|
<file alias="bc_light.qss">resources/bc_light.qss</file>
|
||||||
<file alias="claude_dark_mode.qss">resources/claude_dark_mode.qss</file>
|
|
||||||
<file alias="claude_light_mode.qss">resources/claude_light_mode.qss</file>
|
|
||||||
<file alias="bionx_akku.png">resources/bionx_akku.png</file>
|
<file alias="bionx_akku.png">resources/bionx_akku.png</file>
|
||||||
<file alias="bionx_console.png">resources/bionx_console.png</file>
|
<file alias="bionx_console.png">resources/bionx_console.png</file>
|
||||||
<file alias="bionx_motor.png">resources/bionx_motor.png</file>
|
<file alias="bionx_motor.png">resources/bionx_motor.png</file>
|
||||||
<file alias="connect.svg">resources/connect.svg</file>
|
<file alias="connect.png">resources/connect.png</file>
|
||||||
<file alias="exit.svg">resources/exit.svg</file>
|
<file alias="exit.png">resources/exit.png</file>
|
||||||
<file alias="exit_red.svg">resources/exit_red.svg</file>
|
<file alias="exit_red.png">resources/exit_red.png</file>
|
||||||
<file alias="sync_green.svg">resources/sync_green.svg</file>
|
<file alias="sync_green.png">resources/sync_green.png</file>
|
||||||
<file alias="sync_yellow.svg">resources/sync_yellow.svg</file>
|
<file alias="sync_yellow.png">resources/sync_yellow.png</file>
|
||||||
<file alias="connect_white.svg">resources/connect_white.svg</file>
|
<file alias="sync.png">resources/sync.png</file>
|
||||||
<file alias="sync.svg">resources/sync.svg</file>
|
<file alias="bc_dark.qss">resources/bc_dark.qss</file>
|
||||||
|
<file>resources/smile/face-angel.png</file>
|
||||||
|
<file>resources/smile/face-angry.png</file>
|
||||||
|
<file>resources/smile/face-cool.png</file>
|
||||||
|
<file>resources/smile/face-crying.png</file>
|
||||||
|
<file>resources/smile/face-embarrassed.png</file>
|
||||||
|
<file>resources/smile/face-glasses.png</file>
|
||||||
|
<file>resources/smile/face-kiss.png</file>
|
||||||
|
<file>resources/smile/face-laugh.png</file>
|
||||||
|
<file>resources/smile/face-monkey.png</file>
|
||||||
|
<file>resources/smile/face-plain.png</file>
|
||||||
|
<file>resources/smile/face-raspberry.png</file>
|
||||||
|
<file>resources/smile/face-sad.png</file>
|
||||||
|
<file>resources/smile/face-sick.png</file>
|
||||||
|
<file>resources/smile/face-smile.png</file>
|
||||||
|
<file>resources/smile/face-smile-big.png</file>
|
||||||
|
<file>resources/smile/face-smirk.png</file>
|
||||||
|
<file>resources/smile/face-surprise.png</file>
|
||||||
|
<file alias="update.png">resources/update.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|||||||
40
build_and_deploy.sh
Executable file
40
build_and_deploy.sh
Executable file
@@ -0,0 +1,40 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Bricht das Skript ab, falls ein Befehl (z. B. der Build) fehlschlägt
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# --- Variablen (Bitte anpassen!) ---
|
||||||
|
IMAGE_NAME="qt-cross-rpi"
|
||||||
|
# Trage hier den genauen Namen deines fertig kompilierten Executables ein:
|
||||||
|
BINARY_NAME="BionxControl"
|
||||||
|
TARGET_USER="chris"
|
||||||
|
TARGET_IP="192.168.0.106"
|
||||||
|
TARGET_DIR="/home/chris/projects/BionxControl"
|
||||||
|
# Den Namen der Toolchain aus deiner Vorlage oder der zuvor erstellten Datei
|
||||||
|
TOOLCHAIN_FILE="armhf-toolchain.cmake"
|
||||||
|
|
||||||
|
echo "=== 1. Baue das Docker-Image ==="
|
||||||
|
docker build -t ${IMAGE_NAME} .
|
||||||
|
|
||||||
|
echo "=== 2. Kompiliere das Projekt im Container ==="
|
||||||
|
# Wir führen die Build-Befehle direkt im Container aus, anstatt interaktiv zu starten.
|
||||||
|
# Das -it flag wurde entfernt, da wir es als Skript ausführen.
|
||||||
|
docker run --rm -v "$(pwd):/workspace" ${IMAGE_NAME} bash -c "
|
||||||
|
echo 'Bereinige altes Build-Verzeichnis...'
|
||||||
|
rm -rf dockerbuild
|
||||||
|
|
||||||
|
mkdir dockerbuild
|
||||||
|
cd dockerbuild
|
||||||
|
|
||||||
|
echo 'Führe CMake aus...'
|
||||||
|
cmake -DCMAKE_TOOLCHAIN_FILE=../${TOOLCHAIN_FILE} -G Ninja ..
|
||||||
|
|
||||||
|
echo 'Starte Build (Ninja)...'
|
||||||
|
ninja
|
||||||
|
"
|
||||||
|
|
||||||
|
echo "=== 3. Deploy auf den Raspberry Pi via scp ==="
|
||||||
|
# Kopiert das neu gebaute Binary auf die Zielmaschine
|
||||||
|
scp "dockerbuild/${BINARY_NAME}" "${TARGET_USER}@${TARGET_IP}:${TARGET_DIR}"
|
||||||
|
|
||||||
|
echo "=== Deployment erfolgreich abgeschlossen! ==="
|
||||||
@@ -75,20 +75,3 @@ https://github.com/MHS-Elektronik/OBD-Display
|
|||||||
|
|
||||||
sudo apt install fonts-open-sans
|
sudo apt install fonts-open-sans
|
||||||
|
|
||||||
|
|
||||||
RANT
|
|
||||||
|
|
||||||
--- STRUKTUR
|
|
||||||
|
|
||||||
Denglish -> Comments, Bezeichnungen 'aligned', 'given'
|
|
||||||
Weltsprache, mag ja sein,
|
|
||||||
|
|
||||||
Schlimmer: Doku & Bücher -> c++, qt, OO nicht verstanden
|
|
||||||
|
|
||||||
includes_ pfade hartcodiert statt im Makefile -> Kunstfehler
|
|
||||||
Projecte willkürlich verstreut
|
|
||||||
|
|
||||||
Respektlose Schlampigkeit: copy & paste: es werden sogar die Artefakte des MKS mitkopiert ->
|
|
||||||
---
|
|
||||||
|
|
||||||
---
|
|
||||||
@@ -22,11 +22,11 @@
|
|||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
#define CAN_FEATURE_LOM 0x0001 // Silent Mode (LOM = Listen only Mode)
|
#define CAN_FEATURE_LOM 0x0001 // Silent Mode (LOM = Listen only Mode)
|
||||||
#define CAN_FEATURE_ARD 0x0002 // Automatic Retransmission disable
|
#define CAN_FEATURE_ARD 0x0002 // Automatic Retransmission disable
|
||||||
#define CAN_FEATURE_TX_ACK 0x0004 // TX ACK (Gesendete Nachrichten best<EFBFBD>tigen)
|
#define CAN_FEATURE_TX_ACK 0x0004 // TX ACK (Gesendete Nachrichten bestätigen)
|
||||||
#define CAN_FEATURE_ERROR_MSGS 0x0008 // Error Messages Support
|
#define CAN_FEATURE_ERROR_MSGS 0x0008 // Error Messages Support
|
||||||
#define CAN_FEATURE_FD_HARDWARE 0x0010 // CAN-FD Hardware
|
#define CAN_FEATURE_FD_HARDWARE 0x0010 // CAN-FD Hardware
|
||||||
#define CAN_FEATURE_FIFO_OV_MODE 0x0020 // FIFO OV Mode (Auto Clear, OV CAN Messages)
|
#define CAN_FEATURE_FIFO_OV_MODE 0x0020 // FIFO OV Mode (Auto Clear, OV CAN Messages)
|
||||||
#define CAN_FEATURE_ECU_FLASH 0x0040 // Hardware beschleunigung f<EFBFBD>r ISO-TP ECU-Flash programmierung
|
#define CAN_FEATURE_ECU_FLASH 0x0040 // Hardware beschleunigung für ISO-TP ECU-Flash programmierung
|
||||||
#define CAN_FEATURE_CAN_TEST 0x4000 // Tiny-CAN Tester Firmware
|
#define CAN_FEATURE_CAN_TEST 0x4000 // Tiny-CAN Tester Firmware
|
||||||
#define CAN_FEATURE_HW_TIMESTAMP 0x8000 // Hardware Time Stamp
|
#define CAN_FEATURE_HW_TIMESTAMP 0x8000 // Hardware Time Stamp
|
||||||
|
|
||||||
@@ -165,32 +165,32 @@
|
|||||||
struct TModulFeatures
|
struct TModulFeatures
|
||||||
{
|
{
|
||||||
uint32_t CanClock; // Clock-Frequenz des CAN-Controllers, muss nicht mit
|
uint32_t CanClock; // Clock-Frequenz des CAN-Controllers, muss nicht mit
|
||||||
// der Clock-Frequenz des Mikrocontrollers <EFBFBD>bereinstimmen
|
// der Clock-Frequenz des Mikrocontrollers übereinstimmen
|
||||||
uint32_t Flags; // Unterst<EFBFBD>tzte Features des Moduls:
|
uint32_t Flags; // Unterstützte Features des Moduls:
|
||||||
// Bit Define-Makro
|
// Bit Define-Makro
|
||||||
// 0x0001 CAN_FEATURE_LOM -> Silent Mode (LOM = Listen only Mode)
|
// 0x0001 CAN_FEATURE_LOM -> Silent Mode (LOM = Listen only Mode)
|
||||||
// 0x0002 CAN_FEATURE_ARD -> Automatic Retransmission disable
|
// 0x0002 CAN_FEATURE_ARD -> Automatic Retransmission disable
|
||||||
// 0x0004 CAN_FEATURE_TX_ACK -> TX ACK (Gesendete Nachrichten best<EFBFBD>tigen)
|
// 0x0004 CAN_FEATURE_TX_ACK -> TX ACK (Gesendete Nachrichten bestätigen)
|
||||||
// 0x0008 CAN_FEATURE_ERROR_MSGS -> Error Messages Support
|
// 0x0008 CAN_FEATURE_ERROR_MSGS -> Error Messages Support
|
||||||
// 0x0010 CAN_FEATURE_FD_HARDWARE -> CAN-FD Hardware
|
// 0x0010 CAN_FEATURE_FD_HARDWARE -> CAN-FD Hardware
|
||||||
// 0x0020 CAN_FEATURE_FIFO_OV_MODE -> FIFO OV Mode (Auto Clear, OV CAN Messages)
|
// 0x0020 CAN_FEATURE_FIFO_OV_MODE -> FIFO OV Mode (Auto Clear, OV CAN Messages)
|
||||||
// 0x0040 CAN_FEATURE_ECU_FLASH -> Hardware beschleunigung f<EFBFBD>r ISO-TP ECU-Flash programmierung
|
// 0x0040 CAN_FEATURE_ECU_FLASH -> Hardware beschleunigung für ISO-TP ECU-Flash programmierung
|
||||||
// 0x4000 CAN_FEATURE_CAN_TEST -> Tiny-CAN Tester Firmware
|
// 0x4000 CAN_FEATURE_CAN_TEST -> Tiny-CAN Tester Firmware
|
||||||
// 0x8000 CAN_FEATURE_HW_TIMESTAMP -> Hardware Time Stamp
|
// 0x8000 CAN_FEATURE_HW_TIMESTAMP -> Hardware Time Stamp
|
||||||
uint32_t CanChannelsCount; // Anzahl der CAN Schnittstellen, reserviert f<EFBFBD>r
|
uint32_t CanChannelsCount; // Anzahl der CAN Schnittstellen, reserviert für
|
||||||
// zuk<EFBFBD>nftige Module mit mehr als einer Schnittstelle
|
// zukünftige Module mit mehr als einer Schnittstelle
|
||||||
uint32_t HwRxFilterCount; // Anzahl der zur Verf<EFBFBD>gung stehenden Receive-Filter
|
uint32_t HwRxFilterCount; // Anzahl der zur Verfügung stehenden Receive-Filter
|
||||||
uint32_t HwTxPufferCount; // Anzahl der zur Verf<EFBFBD>gung stehenden Transmit Puffer mit Timer
|
uint32_t HwTxPufferCount; // Anzahl der zur Verfügung stehenden Transmit Puffer mit Timer
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
struct TCanDevicesList
|
struct TCanDevicesList
|
||||||
{
|
{
|
||||||
uint32_t TCanIdx; // Ist das Device ge<EFBFBD>ffnet ist der Wert auf dem Device-Index
|
uint32_t TCanIdx; // Ist das Device geöffnet ist der Wert auf dem Device-Index
|
||||||
// gesetzt, ansonsten ist der Wert auf "INDEX_INVALID" gesetzt.
|
// gesetzt, ansonsten ist der Wert auf "INDEX_INVALID" gesetzt.
|
||||||
uint32_t HwId; // Ein 32 Bit Schl<EFBFBD>ssel der die Hardware eindeutig Identifiziert.
|
uint32_t HwId; // Ein 32 Bit Schlüssel der die Hardware eindeutig Identifiziert.
|
||||||
// Manche Module m<EFBFBD>ssen erst ge<EFBFBD>ffnet werden damit dieser Wert
|
// Manche Module müssen erst geöffnet werden damit dieser Wert
|
||||||
// gesetzt wird
|
// gesetzt wird
|
||||||
char DeviceName[255]; // Nur Linux: entspricht den Device Namen des USB-Devices,
|
char DeviceName[255]; // Nur Linux: entspricht den Device Namen des USB-Devices,
|
||||||
// z.B. /dev/ttyUSB0
|
// z.B. /dev/ttyUSB0
|
||||||
@@ -199,7 +199,7 @@ struct TCanDevicesList
|
|||||||
// muss in den USB-Controller programmiert sein,
|
// muss in den USB-Controller programmiert sein,
|
||||||
// was zur Zeit nur bei den Modulen Tiny-CAN II-XL,
|
// was zur Zeit nur bei den Modulen Tiny-CAN II-XL,
|
||||||
// IV-XL u. M1 der Fall ist.
|
// IV-XL u. M1 der Fall ist.
|
||||||
struct TModulFeatures ModulFeatures; // Unterst<EFBFBD>tzte Features des Moduls, nur g<EFBFBD>ltig
|
struct TModulFeatures ModulFeatures; // Unterstützte Features des Moduls, nur gültig
|
||||||
// wenn HwId > 0
|
// wenn HwId > 0
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
@@ -207,28 +207,28 @@ struct TCanDevicesList
|
|||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
struct TCanDeviceInfo
|
struct TCanDeviceInfo
|
||||||
{
|
{
|
||||||
uint32_t HwId; // Ein 32 Bit Schl<EFBFBD>ssel der die Hardware eindeutig Identifiziert.
|
uint32_t HwId; // Ein 32 Bit Schlüssel der die Hardware eindeutig Identifiziert.
|
||||||
uint32_t FirmwareVersion; // Version der Firmware des Tiny-CAN Moduls
|
uint32_t FirmwareVersion; // Version der Firmware des Tiny-CAN Moduls
|
||||||
uint32_t FirmwareInfo; // Informationen zum Stand der Firmware Version
|
uint32_t FirmwareInfo; // Informationen zum Stand der Firmware Version
|
||||||
// 0 = Unbekannt
|
// 0 = Unbekannt
|
||||||
// 1 = Firmware veraltet, Device kann nicht ge<EFBFBD>ffnet werden
|
// 1 = Firmware veraltet, Device kann nicht geöffnet werden
|
||||||
// 2 = Firmware veraltet, Funktionsumfang eingeschr<EFBFBD>nkt
|
// 2 = Firmware veraltet, Funktionsumfang eingeschränkt
|
||||||
// 3 = Firmware veraltet, keine Einschr<EFBFBD>nkungen
|
// 3 = Firmware veraltet, keine Einschränkungen
|
||||||
// 4 = Firmware auf Stand
|
// 4 = Firmware auf Stand
|
||||||
// 5 = Firmware neuer als Erwartet
|
// 5 = Firmware neuer als Erwartet
|
||||||
char SerialNumber[16]; // Seriennummer des Moduls
|
char SerialNumber[16]; // Seriennummer des Moduls
|
||||||
char Description[64]; // Modul Bezeichnung, z.B. "Tiny-CAN IV-XL"
|
char Description[64]; // Modul Bezeichnung, z.B. "Tiny-CAN IV-XL"
|
||||||
struct TModulFeatures ModulFeatures; // Unterst<EFBFBD>tzte Features des Moduls
|
struct TModulFeatures ModulFeatures; // Unterstützte Features des Moduls
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
struct TCanInfoVar // <*> ge<EFBFBD>ndert von TInfoVar in TCanInfoVar
|
struct TCanInfoVar // <*> geändert von TInfoVar in TCanInfoVar
|
||||||
{
|
{
|
||||||
uint32_t Key; // Variablen Schl<EFBFBD>ssel
|
uint32_t Key; // Variablen Schlüssel
|
||||||
uint32_t Type; // Variablen Type
|
uint32_t Type; // Variablen Type
|
||||||
uint32_t Size; // (Max)Gr<EFBFBD><EFBFBD>e der Variable in Byte
|
uint32_t Size; // (Max)Größe der Variable in Byte
|
||||||
char Data[255]; // Wert der Variable
|
char Data[255]; // Wert der Variable
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
/* www.mhs-elektronik.de */
|
/* www.mhs-elektronik.de */
|
||||||
/* Autor : Demlehner Klaus, info@mhs-elektronik.de */
|
/* Autor : Demlehner Klaus, info@mhs-elektronik.de */
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
|
|
||||||
#include "mhs_can_drv.c"
|
#include "mhs_can_drv.c"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -126,14 +126,14 @@ Byte 0
|
|||||||
|
|
||||||
struct TCanFlagsBits
|
struct TCanFlagsBits
|
||||||
{
|
{
|
||||||
unsigned Len:4; // Len -> Datenl<EFBFBD>nge 0 - 8 Byte
|
unsigned Len:4; // Len -> Datenlänge 0 - 8 Byte
|
||||||
unsigned TxD:1; // TxD -> 1 = Tx CAN Nachricht, 0 = Rx CAN Nachricht
|
unsigned TxD:1; // TxD -> 1 = Tx CAN Nachricht, 0 = Rx CAN Nachricht
|
||||||
// Eine Erfolgreich versendete Nachricht wird als Best<EFBFBD>tigung
|
// Eine Erfolgreich versendete Nachricht wird als Bestätigung
|
||||||
// ins Empfangsfifo zur<EFBFBD>ckgeschrieben
|
// ins Empfangsfifo zurückgeschrieben
|
||||||
// Nicht alle Module unterst<EFBFBD>tzen diese Funktion u. das
|
// Nicht alle Module unterstützen diese Funktion u. das
|
||||||
// Feature muss aktiveirt sein
|
// Feature muss aktiveirt sein
|
||||||
unsigned Error:1; // Error -> 1 = CAN Bus Fehler Nachricht
|
unsigned Error:1; // Error -> 1 = CAN Bus Fehler Nachricht
|
||||||
// Nicht alle Module unterst<EFBFBD>tzen diese Funktion u. das
|
// Nicht alle Module unterstützen diese Funktion u. das
|
||||||
// Feature muss aktiveirt sein
|
// Feature muss aktiveirt sein
|
||||||
unsigned RTR:1; // Remote Transmition Request bit -> Kennzeichnet eine RTR Nachricht
|
unsigned RTR:1; // Remote Transmition Request bit -> Kennzeichnet eine RTR Nachricht
|
||||||
unsigned EFF:1; // Extended Frame Format bit -> 1 = 29 Bit Id's, 0 = 11 Bit Id's
|
unsigned EFF:1; // Extended Frame Format bit -> 1 = 29 Bit Id's, 0 = 11 Bit Id's
|
||||||
@@ -193,15 +193,15 @@ struct TCanMsg
|
|||||||
struct TCanFdFlagsBits
|
struct TCanFdFlagsBits
|
||||||
{
|
{
|
||||||
unsigned Source:8; // Quelle der Nachricht (Device)
|
unsigned Source:8; // Quelle der Nachricht (Device)
|
||||||
unsigned Len:8; // Len -> Datenl<EFBFBD>nge 0 - 64 Byte
|
unsigned Len:8; // Len -> Datenlänge 0 - 64 Byte
|
||||||
|
|
||||||
unsigned TxD:1; // TxD -> 1 = Tx CAN Nachricht, 0 = Rx CAN Nachricht
|
unsigned TxD:1; // TxD -> 1 = Tx CAN Nachricht, 0 = Rx CAN Nachricht
|
||||||
// Eine Erfolgreich versendete Nachricht wird als Best<EFBFBD>tigung
|
// Eine Erfolgreich versendete Nachricht wird als Bestätigung
|
||||||
// ins Empfangsfifo zur<EFBFBD>ckgeschrieben
|
// ins Empfangsfifo zurückgeschrieben
|
||||||
// Nicht alle Module unterst<EFBFBD>tzen diese Funktion u. das
|
// Nicht alle Module unterstützen diese Funktion u. das
|
||||||
// Feature muss aktiveirt sein
|
// Feature muss aktiveirt sein
|
||||||
unsigned Error:1; // Error -> 1 = CAN Bus Fehler Nachricht
|
unsigned Error:1; // Error -> 1 = CAN Bus Fehler Nachricht
|
||||||
// Nicht alle Module unterst<EFBFBD>tzen diese Funktion u. das
|
// Nicht alle Module unterstützen diese Funktion u. das
|
||||||
// Feature muss aktiveirt sein
|
// Feature muss aktiveirt sein
|
||||||
unsigned RTR:1; // Remote Transmition Request bit -> Kennzeichnet eine RTR Nachricht
|
unsigned RTR:1; // Remote Transmition Request bit -> Kennzeichnet eine RTR Nachricht
|
||||||
unsigned EFF:1; // Extended Frame Format bit -> 1 = 29 Bit Id's, 0 = 11 Bit Id's
|
unsigned EFF:1; // Extended Frame Format bit -> 1 = 29 Bit Id's, 0 = 11 Bit Id's
|
||||||
|
|||||||
37
main.cpp
37
main.cpp
@@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QSysInfo>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
@@ -40,35 +41,25 @@
|
|||||||
#include <bcmainwindow.h>
|
#include <bcmainwindow.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
/*
|
|
||||||
app.setStyleSheet(R"(
|
|
||||||
QWidget {
|
|
||||||
background-color: #F3F3F3;
|
|
||||||
font-family: 'Segoe UI Variable', 'Segoe UI', sans-serif;
|
|
||||||
}
|
|
||||||
)");
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
app.setStyleSheet(R"(
|
|
||||||
* {
|
|
||||||
font-family: 'Calibri', 'Carlito', 'Arial', sans-serif;
|
|
||||||
font-size: 12pt;
|
|
||||||
})");
|
|
||||||
|
|
||||||
*/
|
BCMainWindow mainWindow;
|
||||||
//QFont font("segoe UI", 12); // Name, Größe
|
//mainWindow.resize(800, 480);
|
||||||
//QFont font("calibri", 12); // Name, Größe
|
|
||||||
//app.setFont(font);
|
if (QSysInfo::machineHostName() == BCTags::Host )
|
||||||
|
{
|
||||||
|
mainWindow.setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
|
||||||
|
mainWindow.showFullScreen();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Normaler Fenster-Modus (z. B. für die Entwicklung auf dem Desktop)
|
||||||
|
mainWindow.show();
|
||||||
|
}
|
||||||
|
|
||||||
BCMainWindow w;
|
|
||||||
w.show();
|
|
||||||
|
|
||||||
return app.exec();
|
return app.exec();
|
||||||
|
|
||||||
|
|||||||
90
nodes/nodes/ntx.h
Normal file
90
nodes/nodes/ntx.h
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
#ifndef NTX_H
|
||||||
|
#define NTX_H
|
||||||
|
|
||||||
|
#include <variant>
|
||||||
|
#include <string>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Basistypen für die Kernbibliothek
|
||||||
|
* unser string typ, ohne den namespace
|
||||||
|
*
|
||||||
|
* Wir nehmen hier std::string, der immer UTF-8 kodiert ist.
|
||||||
|
* std::wstring ist plattformabhängig und führt zu Problemen. (Windows UTF-16 vs. Linux UTF-32)
|
||||||
|
* std::string_view für als mögliche Alternative zu const std::string&
|
||||||
|
*/
|
||||||
|
|
||||||
|
using NtxString = std::string;
|
||||||
|
using NtxStringView = std::string_view;
|
||||||
|
using NtxStringList = std::vector<NtxString>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file ntx.h
|
||||||
|
* Enthält die grundlegenden Typdefinitionen und Hilfsfunktionen
|
||||||
|
* für die Kernbibliothek, z.B. NtxClassTypeId, NtxVariant und String-Konvertierungen.
|
||||||
|
* Alle anderen Header (z.B. ntxinode.h, ntxipayload.h) inkludieren dieses als Basis.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
|
||||||
|
// Datentyp für die Typid einer Klasse von Knoten (_nicht_ eines einzelen Knotens)
|
||||||
|
// Option A: Performant (Aktuell)
|
||||||
|
using NtxClassTypeId = uint64_t;
|
||||||
|
|
||||||
|
// Option B: Flexibel / Lesbar (Zukunft?)
|
||||||
|
// using NtxClassTypeId = std::string;
|
||||||
|
|
||||||
|
// Option C: Legacy / Embedded
|
||||||
|
// using NtxClassTypeId = uint32_t;
|
||||||
|
|
||||||
|
// Generischer Zugriff über std::variant (wie eingangs besprochen)
|
||||||
|
using NtxVariant = std::variant<std::monostate, bool, int, double, NtxString>;
|
||||||
|
|
||||||
|
inline bool isEmpty(const NtxVariant& v) {
|
||||||
|
return std::holds_alternative<std::monostate>(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class... Ts>
|
||||||
|
struct overload : Ts... { using Ts::operator()...; };
|
||||||
|
|
||||||
|
inline NtxString variantToString(const NtxVariant& v)
|
||||||
|
{
|
||||||
|
return std::visit(overload
|
||||||
|
{
|
||||||
|
[](std::monostate) { return NtxString{}; },
|
||||||
|
[](const NtxString& s) { return s; },
|
||||||
|
[](bool b) { return NtxString{b ? "true" : "false"}; },
|
||||||
|
[](auto num) { return std::to_string(num); } // Catch-all für int, double
|
||||||
|
}, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Core (UTF-8) -> Qt (UTF-16)
|
||||||
|
// Uses SSO (Small String Optimization) from Qt where possible.
|
||||||
|
inline QString toQt(const NtxString& str)
|
||||||
|
{
|
||||||
|
return QString::fromUtf8(str.data(), static_cast<int>(str.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline QString toQt(NtxStringView str)
|
||||||
|
{
|
||||||
|
return QString::fromUtf8(str.data(), static_cast<int>(str.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Qt (UTF-16) -> Core (UTF-8)
|
||||||
|
inline NtxString fromQt(const QString& qstr)
|
||||||
|
{
|
||||||
|
return qstr.toStdString(); // Qt converts this internally via toUtf8()
|
||||||
|
}
|
||||||
|
|
||||||
|
inline QString toQString(const NtxVariant& variant)
|
||||||
|
{
|
||||||
|
return toQt(variantToString(variant));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
|
|
||||||
|
|
||||||
|
#endif // NTX_H
|
||||||
|
|
||||||
73
nodes/nodes/ntxcompostionnode.h
Normal file
73
nodes/nodes/ntxcompostionnode.h
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
#ifndef NTX_HASANODE_H
|
||||||
|
#define NTX_HASANODE_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <variant>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include <ntxnodebase.h>
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Implementierung via Komposition (Has-A).
|
||||||
|
*
|
||||||
|
* Hält die Payload als Member 'm_payload'.
|
||||||
|
*/
|
||||||
|
template<typename TPayload>
|
||||||
|
class NtxHasANode : public NtxNodeBase
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Konstruktor forwarding an m_payload
|
||||||
|
template<typename... Args>
|
||||||
|
explicit NtxHasANode(Args&&... args)
|
||||||
|
: NtxNodeBase{},
|
||||||
|
m_payload{std::forward<Args>(args)...}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========================================
|
||||||
|
// NtxINode Interface: Payload Forwarding
|
||||||
|
// ========================================
|
||||||
|
|
||||||
|
size_t getValueCount() const override { return m_payload.getValueCount(); }
|
||||||
|
void clearValues() override { m_payload.clearValues(); }
|
||||||
|
|
||||||
|
bool hasValue(const NtxString& key) const override { return m_payload.hasValue(key); }
|
||||||
|
void setValue(const NtxString& key, const NtxVariant& value) override { m_payload.setValue(key, value); }
|
||||||
|
NtxVariant getValue(const NtxString& key) const override { return m_payload.getValue(key); }
|
||||||
|
void removeValue(const NtxString& key) override { m_payload.removeValue(key); }
|
||||||
|
|
||||||
|
bool hasValue(size_t index) const override { return m_payload.hasValue(index); }
|
||||||
|
void setValue(size_t index, const NtxVariant& value) override { m_payload.setValue(index, value); }
|
||||||
|
NtxVariant getValue(size_t index) const override { return m_payload.getValue(index); }
|
||||||
|
|
||||||
|
// Deducing This Support (Raw Access)
|
||||||
|
// TPayload muss doGetValues() oder Zugriff auf den Vektor unterstützen
|
||||||
|
std::vector<NtxVariant>& doGetValues() override { return m_payload.doGetValues(); }
|
||||||
|
const std::vector<NtxVariant>& doGetValues() const override { return m_payload.doGetValues(); }
|
||||||
|
|
||||||
|
void forEachAttribute(NtxPayloadVisitor visitor) const override
|
||||||
|
{
|
||||||
|
m_payload.forEachAttribute(visitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxNodePtr clone() const override
|
||||||
|
{
|
||||||
|
auto newNode = std::make_shared<NtxHasANode<TPayload>>();
|
||||||
|
newNode->m_payload = this->m_payload; // Copy Payload
|
||||||
|
newNode->setClassTypeId(this->getClassTypeId());
|
||||||
|
return newNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
TPayload m_payload;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
|
|
||||||
|
#endif // NTX_HASANODE_H
|
||||||
115
nodes/nodes/ntxibasicnode.cpp
Normal file
115
nodes/nodes/ntxibasicnode.cpp
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
#include <ntxibasicnode.h>
|
||||||
|
#include <ntxnodefactory.h>
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
|
||||||
|
// ========================================
|
||||||
|
// NtxINode Interface: CType Aspekt
|
||||||
|
// ========================================
|
||||||
|
|
||||||
|
const NtxClassTypeId NtxIBasicNode::getClassTypeId() const
|
||||||
|
{
|
||||||
|
return m_ctypeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NtxString& NtxIBasicNode::getClassTypeLabel() const
|
||||||
|
{
|
||||||
|
return NtxNodeFactory::lookupCTypeLabel(getClassTypeId());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========================================
|
||||||
|
// NtxINode Interface: Tree Structure
|
||||||
|
// ========================================
|
||||||
|
|
||||||
|
void NtxIBasicNode::setParent(NtxNodePtr parent)
|
||||||
|
{
|
||||||
|
m_parent = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t NtxIBasicNode::getChildCount() const
|
||||||
|
{
|
||||||
|
return m_children.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxIBasicNode::hasChildren() const
|
||||||
|
{
|
||||||
|
return !m_children.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxIBasicNode::addChild(NtxNodePtr child)
|
||||||
|
{
|
||||||
|
if (child)
|
||||||
|
{
|
||||||
|
m_children.push_back(child);
|
||||||
|
child->setParent(this->shared_from_this());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxIBasicNode::insertChild(size_t index, NtxNodePtr child)
|
||||||
|
{
|
||||||
|
if (!child) return;
|
||||||
|
|
||||||
|
if (index >= m_children.size())
|
||||||
|
m_children.push_back(child);
|
||||||
|
else
|
||||||
|
m_children.insert(m_children.begin() + index, child);
|
||||||
|
|
||||||
|
child->setParent(this->shared_from_this());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxIBasicNode::removeChild(size_t index)
|
||||||
|
{
|
||||||
|
if (index >= m_children.size()) return false;
|
||||||
|
|
||||||
|
if (m_children[index])
|
||||||
|
m_children[index]->setParent(nullptr);
|
||||||
|
|
||||||
|
m_children.erase(m_children.begin() + index);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t NtxIBasicNode::getChildIndex(const NtxNodePtr& child) const
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < m_children.size(); ++i)
|
||||||
|
{
|
||||||
|
if (m_children[i] == child) return i;
|
||||||
|
}
|
||||||
|
return static_cast<size_t>(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxIBasicNode::clearChildren()
|
||||||
|
{
|
||||||
|
for (auto& child : m_children)
|
||||||
|
{
|
||||||
|
if (child) child->setParent(nullptr);
|
||||||
|
}
|
||||||
|
m_children.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========================================
|
||||||
|
// Protected Hooks
|
||||||
|
// ========================================
|
||||||
|
|
||||||
|
void NtxIBasicNode::setClassTypeLabel(const NtxString& idString)
|
||||||
|
{
|
||||||
|
setClassTypeId(NtxNodeFactory::generateCTypeId(idString));
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxIBasicNode::setClassTypeId(NtxClassTypeId classTypeId)
|
||||||
|
{
|
||||||
|
m_ctypeId = classTypeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxNodePtr NtxIBasicNode::doGetParent() const noexcept
|
||||||
|
{
|
||||||
|
return m_parent.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxNodePtr NtxIBasicNode::doGetChild(size_t index) const noexcept
|
||||||
|
{
|
||||||
|
if (index >= m_children.size()) return nullptr;
|
||||||
|
return m_children[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
66
nodes/nodes/ntxibasicnode.h
Normal file
66
nodes/nodes/ntxibasicnode.h
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
#ifndef NTX_NODEBASE_H
|
||||||
|
#define NTX_NODEBASE_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
#include <ntxinode.h>
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Abstrakte Basisklasse, die Baumstruktur und Typ-Information verwaltet.
|
||||||
|
*
|
||||||
|
* Implementiert alle Aspekte von NtxINode, die unabhängig von der Payload sind.
|
||||||
|
*/
|
||||||
|
class NtxIBasicNode : public NtxINode
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
NtxIBasicNode() = default;
|
||||||
|
~NtxIBasicNode() override = default;
|
||||||
|
|
||||||
|
// ========================================
|
||||||
|
// NtxINode Interface: CType Aspekt
|
||||||
|
// ========================================
|
||||||
|
|
||||||
|
const NtxClassTypeId getClassTypeId() const override;
|
||||||
|
const NtxString& getClassTypeLabel() const override;
|
||||||
|
|
||||||
|
// ========================================
|
||||||
|
// NtxINode Interface: Tree Structure
|
||||||
|
// ========================================
|
||||||
|
|
||||||
|
void setParent(NtxNodePtr parent) override;
|
||||||
|
|
||||||
|
size_t getChildCount() const override;
|
||||||
|
bool hasChildren() const override;
|
||||||
|
|
||||||
|
void addChild(NtxNodePtr child) override;
|
||||||
|
void insertChild(size_t index, NtxNodePtr child) override;
|
||||||
|
bool removeChild(size_t index) override;
|
||||||
|
size_t getChildIndex(const NtxNodePtr& child) const override;
|
||||||
|
void clearChildren() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// --- Implementierung virtueller Hooks ---
|
||||||
|
|
||||||
|
void setClassTypeLabel(const NtxString& idString) override;
|
||||||
|
void setClassTypeId(NtxClassTypeId classTypeId) override;
|
||||||
|
|
||||||
|
NtxNodePtr doGetParent() const noexcept override;
|
||||||
|
NtxNodePtr doGetChild(size_t index) const noexcept override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
NtxClassTypeId m_ctypeId{};
|
||||||
|
NtxNodeWeakPtr m_parent;
|
||||||
|
NtxNodeList m_children;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
|
|
||||||
|
#endif // NTX_NODEBASE_H
|
||||||
37
nodes/nodes/ntxiclasstype.h
Normal file
37
nodes/nodes/ntxiclasstype.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#ifndef NTX_ICLASSTYPE_H
|
||||||
|
#define NTX_ICLASSTYPE_H
|
||||||
|
|
||||||
|
#include <ntx.h>
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Minimales Interface für den 'ClassType' Aspekt: Der CType entspricht
|
||||||
|
* dem Element-namen eines Knotens im XML. Die ClassTypeId ist eine performante
|
||||||
|
* Repräsentation (z.B. Hash) dieses Namens. Kann unterschiedliche Implementierungen haben,
|
||||||
|
* z.B.: einfaches Hochzählen, Hash des Strings, den String selbst oder eine Meta-Klasse,
|
||||||
|
* vgl. QObject.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class NtxIClassType
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual ~NtxIClassType() = default;
|
||||||
|
|
||||||
|
virtual const NtxClassTypeId getClassTypeId() const = 0;
|
||||||
|
virtual const NtxString& getClassTypeLabel() const = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// ✅ Protected - nur abgeleitete Klassen und Friends
|
||||||
|
virtual void setClassTypeLabel(const NtxString& idString) = 0;
|
||||||
|
virtual void setClassTypeId(NtxClassTypeId classTypeId) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
|
|
||||||
|
#endif // NTX_ICLASSTYPE_H
|
||||||
143
nodes/nodes/ntxiclasstyperepo.cpp
Normal file
143
nodes/nodes/ntxiclasstyperepo.cpp
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#include <ntxiclasstyperepo.h>
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
// =========================================================
|
||||||
|
// NtxCTypeHashRepo
|
||||||
|
// =========================================================
|
||||||
|
|
||||||
|
NtxClassTypeId NtxCTypeHashRepo::generateId(const NtxString& label)
|
||||||
|
{
|
||||||
|
std::hash<NtxString> hasher;
|
||||||
|
// Expliziter Cast falls NtxClassTypeId kleiner als size_t ist
|
||||||
|
NtxClassTypeId id = static_cast<NtxClassTypeId>(hasher(label));
|
||||||
|
|
||||||
|
// Optimistischer Check (Read Lock)
|
||||||
|
{
|
||||||
|
std::shared_lock lock(m_mutex);
|
||||||
|
if (m_idToLabel.find(id) != m_idToLabel.end())
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Registrieren (Write Lock)
|
||||||
|
{
|
||||||
|
std::unique_lock lock(m_mutex);
|
||||||
|
m_idToLabel[id] = label;
|
||||||
|
}
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxClassTypeId NtxCTypeHashRepo::lookupId(const NtxString& label) const
|
||||||
|
{
|
||||||
|
std::hash<NtxString> hasher;
|
||||||
|
NtxClassTypeId id = static_cast<NtxClassTypeId>(hasher(label));
|
||||||
|
|
||||||
|
if (isRegistered(id))
|
||||||
|
return id;
|
||||||
|
|
||||||
|
return {}; // Default constructed ID (0)
|
||||||
|
}
|
||||||
|
|
||||||
|
const NtxString& NtxCTypeHashRepo::lookupLabel(NtxClassTypeId id) const
|
||||||
|
{
|
||||||
|
std::shared_lock lock(m_mutex);
|
||||||
|
auto it = m_idToLabel.find(id);
|
||||||
|
if (it != m_idToLabel.end())
|
||||||
|
return it->second;
|
||||||
|
|
||||||
|
static const NtxString empty;
|
||||||
|
return empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxCTypeHashRepo::isRegistered(NtxClassTypeId id) const
|
||||||
|
{
|
||||||
|
std::shared_lock lock(m_mutex);
|
||||||
|
return m_idToLabel.find(id) != m_idToLabel.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxCTypeHashRepo::isRegistered(const NtxString& label) const
|
||||||
|
{
|
||||||
|
std::hash<NtxString> hasher;
|
||||||
|
return isRegistered(static_cast<NtxClassTypeId>(hasher(label)));
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t NtxCTypeHashRepo::getRegisteredCount() const
|
||||||
|
{
|
||||||
|
std::shared_lock lock(m_mutex);
|
||||||
|
return m_idToLabel.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// =========================================================
|
||||||
|
// NtxCTypeCounterRepo
|
||||||
|
// =========================================================
|
||||||
|
|
||||||
|
NtxCTypeCounterRepo::NtxCTypeCounterRepo()
|
||||||
|
: m_nextId(1) // Start bei 1, 0 ist invalid
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxClassTypeId NtxCTypeCounterRepo::generateId(const NtxString& label)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
std::shared_lock lock(m_mutex);
|
||||||
|
auto it = m_labelToId.find(label);
|
||||||
|
if (it != m_labelToId.end())
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::unique_lock lock(m_mutex);
|
||||||
|
// Double check
|
||||||
|
if (auto it = m_labelToId.find(label); it != m_labelToId.end())
|
||||||
|
return it->second;
|
||||||
|
|
||||||
|
NtxClassTypeId newId = m_nextId++;
|
||||||
|
m_idToLabel[newId] = label;
|
||||||
|
m_labelToId[label] = newId;
|
||||||
|
|
||||||
|
return newId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxClassTypeId NtxCTypeCounterRepo::lookupId(const NtxString& label) const
|
||||||
|
{
|
||||||
|
std::shared_lock lock(m_mutex);
|
||||||
|
auto it = m_labelToId.find(label);
|
||||||
|
if (it != m_labelToId.end())
|
||||||
|
return it->second;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const NtxString& NtxCTypeCounterRepo::lookupLabel(NtxClassTypeId id) const
|
||||||
|
{
|
||||||
|
std::shared_lock lock(m_mutex);
|
||||||
|
auto it = m_idToLabel.find(id);
|
||||||
|
if (it != m_idToLabel.end())
|
||||||
|
return it->second;
|
||||||
|
|
||||||
|
static const NtxString empty;
|
||||||
|
return empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxCTypeCounterRepo::isRegistered(NtxClassTypeId id) const
|
||||||
|
{
|
||||||
|
std::shared_lock lock(m_mutex);
|
||||||
|
return m_idToLabel.find(id) != m_idToLabel.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxCTypeCounterRepo::isRegistered(const NtxString& label) const
|
||||||
|
{
|
||||||
|
std::shared_lock lock(m_mutex);
|
||||||
|
return m_labelToId.find(label) != m_labelToId.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t NtxCTypeCounterRepo::getRegisteredCount() const
|
||||||
|
{
|
||||||
|
std::shared_lock lock(m_mutex);
|
||||||
|
return m_idToLabel.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
126
nodes/nodes/ntxiclasstyperepo.h
Normal file
126
nodes/nodes/ntxiclasstyperepo.h
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
#ifndef NTX_CTYPEREPOSITORY_H
|
||||||
|
#define NTX_CTYPEREPOSITORY_H
|
||||||
|
|
||||||
|
#include <ntx.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <shared_mutex>
|
||||||
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @brief Repository Interface für CType ID Management.
|
||||||
|
* Entkoppelt die ID-Generierungsstrategie von der Knoten-Implementierung.
|
||||||
|
*/
|
||||||
|
class NtxIClassTypeRepo
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual ~NtxIClassTypeRepo() = default;
|
||||||
|
|
||||||
|
// Generiert oder holt eine ID für das Label
|
||||||
|
virtual NtxClassTypeId generateId(const NtxString& label) = 0;
|
||||||
|
|
||||||
|
// Lookups (Thread-safe read)
|
||||||
|
virtual NtxClassTypeId lookupId(const NtxString& label) const = 0;
|
||||||
|
virtual const NtxString& lookupLabel(NtxClassTypeId id) const = 0;
|
||||||
|
|
||||||
|
// Checks
|
||||||
|
virtual bool isRegistered(NtxClassTypeId id) const = 0;
|
||||||
|
virtual bool isRegistered(const NtxString& label) const = 0;
|
||||||
|
|
||||||
|
// Diagnostics
|
||||||
|
virtual size_t getRegisteredCount() const = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Hash-basierte Implementierung (std::hash).
|
||||||
|
*/
|
||||||
|
class NtxCTypeHashRepo : public NtxIClassTypeRepo
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
NtxClassTypeId generateId(const NtxString& label) override;
|
||||||
|
NtxClassTypeId lookupId(const NtxString& label) const override;
|
||||||
|
const NtxString& lookupLabel(NtxClassTypeId id) const override;
|
||||||
|
|
||||||
|
bool isRegistered(NtxClassTypeId id) const override;
|
||||||
|
bool isRegistered(const NtxString& label) const override;
|
||||||
|
size_t getRegisteredCount() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::unordered_map<NtxClassTypeId, NtxString> m_idToLabel;
|
||||||
|
mutable std::shared_mutex m_mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Zähler-basierte Implementierung (1, 2, 3...).
|
||||||
|
*/
|
||||||
|
class NtxCTypeCounterRepo : public NtxIClassTypeRepo
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
NtxCTypeCounterRepo();
|
||||||
|
|
||||||
|
NtxClassTypeId generateId(const NtxString& label) override;
|
||||||
|
NtxClassTypeId lookupId(const NtxString& label) const override;
|
||||||
|
const NtxString& lookupLabel(NtxClassTypeId id) const override;
|
||||||
|
|
||||||
|
bool isRegistered(NtxClassTypeId id) const override;
|
||||||
|
bool isRegistered(const NtxString& label) const override;
|
||||||
|
size_t getRegisteredCount() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::unordered_map<NtxClassTypeId, NtxString> m_idToLabel;
|
||||||
|
std::unordered_map<NtxString, NtxClassTypeId> m_labelToId;
|
||||||
|
NtxClassTypeId m_nextId;
|
||||||
|
mutable std::shared_mutex m_mutex;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <string_view>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
constexpr uint64_t fnv1a_64(std::string_view text) {
|
||||||
|
uint64_t hash = 14695981039346656037ull; // 64-bit offset
|
||||||
|
for (char c : text) {
|
||||||
|
hash ^= static_cast<uint64_t>(c);
|
||||||
|
hash *= 1099511628211ull; // 64-bit prime
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ein Funktor (Funktionsobjekt), das die STL-Vorgaben für Hash-Funktionen erfüllt
|
||||||
|
struct FastFnv1aHasher {
|
||||||
|
std::size_t operator()(std::string_view sv) const {
|
||||||
|
// (Nutzt hier die fnv1a_64 Funktion von oben)
|
||||||
|
return fnv1a_64(sv);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Deine Map:
|
||||||
|
// Key: string_view (Zero-Copy)
|
||||||
|
// Value: MyData
|
||||||
|
// Hasher: Dein eigener, pfeilschneller FNV-1a (statt dem langsamen std::hash)
|
||||||
|
std::unordered_map<std::string_view, MyData, FastFnv1aHasher> xmlElements;
|
||||||
|
|
||||||
|
OBACHT! Lifetime! Woher kommt die StringView ?
|
||||||
|
|
||||||
|
-> doch: string internisieren ! -> Aber was ist mit copy_over_net ?
|
||||||
|
claude.ai: String Interning ist die richtige Wahl
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
|
|
||||||
|
#endif // NTX_CTYPEREPOSITORY_H
|
||||||
33
nodes/nodes/ntxinode.cpp
Normal file
33
nodes/nodes/ntxinode.cpp
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#include <ntxinode.h>
|
||||||
|
#include <ntxnodeiterators.h>
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
NtxNodeIterator NtxINode::begin()
|
||||||
|
{
|
||||||
|
return NtxNodeIterator(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxNodeIterator NtxINode::end()
|
||||||
|
{
|
||||||
|
return NtxNodeIterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxCNodeIterator NtxINode::begin() const
|
||||||
|
{
|
||||||
|
return NtxCNodeIterator(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxCNodeIterator NtxINode::end() const
|
||||||
|
{
|
||||||
|
return NtxCNodeIterator();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
|
|
||||||
176
nodes/nodes/ntxinode.h
Normal file
176
nodes/nodes/ntxinode.h
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
#ifndef NTX_INODE_H
|
||||||
|
#define NTX_INODE_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
#include <optional>
|
||||||
|
#include <ranges> // for std::ranges::subrange
|
||||||
|
#include <type_traits> // for std::conditional_t, std::is_const_v
|
||||||
|
|
||||||
|
#include <ntx.h>
|
||||||
|
#include <ntxiclasstype.h>
|
||||||
|
#include <ntxipayload.h>
|
||||||
|
#include <ntxnodeiterators.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file ntxinode.h
|
||||||
|
* NtxINode ist die zentrale Schnittstelle, die NtxIClassType und NtxIPayload vereint
|
||||||
|
* und zusätzlich die Baumstruktur definiert.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
|
||||||
|
class NtxINode;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct NtxNodeDepthFirstIterator;
|
||||||
|
|
||||||
|
using NtxNodePtr = std::shared_ptr<NtxINode>;
|
||||||
|
using NtxNodeCPtr = std::shared_ptr<const NtxINode>;
|
||||||
|
using NtxNodeWeakPtr = std::weak_ptr<NtxINode>;
|
||||||
|
using NtxNodeList = std::vector<NtxNodePtr>;
|
||||||
|
|
||||||
|
using NtxNodeIterator = NtxNodeDepthFirstIterator<NtxINode>;
|
||||||
|
using NtxCNodeIterator = NtxNodeDepthFirstIterator<const NtxINode>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Zentrales Interface für einen Knoten im Baum. Basiert auf NtxIClassType und NtxIPayload.
|
||||||
|
* Gibt die Baumstruktur vor (Eltern, Kinder, Geschwister) und bietet Iteratoren für die Traversierung.
|
||||||
|
* Die konkrete Implementierung erfolgt in NtxNode oder abgeleiteten Klassen.
|
||||||
|
* Nutzlast- und ClassType-Aspekte können durch Mixins realisiert werden.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class NtxINode :
|
||||||
|
|
||||||
|
public NtxIClassType,
|
||||||
|
public NtxIPayload,
|
||||||
|
public std::enable_shared_from_this<NtxINode>
|
||||||
|
|
||||||
|
{
|
||||||
|
friend class NtxNodeFactory;
|
||||||
|
friend class NtxLinkNode;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual ~NtxINode() = default;
|
||||||
|
|
||||||
|
// --- Tree Structure ---
|
||||||
|
virtual void setParent(NtxNodePtr parent) = 0;
|
||||||
|
|
||||||
|
// Vereinfacht durch Deducing this und if constexpr
|
||||||
|
template <typename Self>
|
||||||
|
auto getParent(this Self&& self)
|
||||||
|
{
|
||||||
|
auto ptr = self.doGetParent();
|
||||||
|
if constexpr (std::is_const_v<std::remove_reference_t<Self>>)
|
||||||
|
return std::const_pointer_cast<const NtxINode>(ptr);
|
||||||
|
else
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Self>
|
||||||
|
auto getChild(this Self&& self, size_t index)
|
||||||
|
{
|
||||||
|
auto ptr = self.doGetChild(index);
|
||||||
|
if constexpr (std::is_const_v<std::remove_reference_t<Self>>)
|
||||||
|
return std::const_pointer_cast<const NtxINode>(ptr);
|
||||||
|
else
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Self>
|
||||||
|
auto getSibling(this Self&& self)
|
||||||
|
{
|
||||||
|
auto parent = self.getParent();
|
||||||
|
using ResultType = decltype(parent); // NtxNodePtr oder NtxNodeCPtr
|
||||||
|
|
||||||
|
if (!parent) return ResultType{};
|
||||||
|
|
||||||
|
const size_t childCount = parent->getChildCount();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < childCount; ++i)
|
||||||
|
{
|
||||||
|
auto child = parent->getChild(i);
|
||||||
|
// Hinweis: child.get() ist raw-pointer, &self ist Adresse des aktuellen Objekts
|
||||||
|
if (child.get() == &self)
|
||||||
|
{
|
||||||
|
if (i + 1 < childCount)
|
||||||
|
return parent->getChild(i + 1);
|
||||||
|
else
|
||||||
|
return ResultType{};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ResultType{};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<size_t> ownPos() const
|
||||||
|
{
|
||||||
|
auto parent = doGetParent(); // Nutze internal (non-deducing) getter um const-cast zu vermeiden
|
||||||
|
if (!parent) return std::nullopt;
|
||||||
|
|
||||||
|
const size_t childCount = parent->getChildCount();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < childCount; ++i)
|
||||||
|
{
|
||||||
|
auto child = parent->getChild(i); // NtxNodePtr comparison
|
||||||
|
if (child.get() == this)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual size_t getChildCount() const = 0;
|
||||||
|
virtual bool hasChildren() const = 0;
|
||||||
|
|
||||||
|
virtual void addChild(NtxNodePtr child) = 0;
|
||||||
|
virtual void insertChild(size_t index, NtxNodePtr child) = 0;
|
||||||
|
virtual bool removeChild(size_t index) = 0;
|
||||||
|
virtual size_t getChildIndex(const NtxNodePtr& child) const = 0;
|
||||||
|
virtual void clearChildren() = 0;
|
||||||
|
|
||||||
|
virtual NtxNodePtr clone() const = 0;
|
||||||
|
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// Unified Iterators via Deducing This
|
||||||
|
// =======================================================================
|
||||||
|
|
||||||
|
// Ersetzt begin/end und cbegin/cend Logik
|
||||||
|
template <typename Self>
|
||||||
|
auto begin(this Self&& self)
|
||||||
|
{
|
||||||
|
using NodeType = std::remove_reference_t<Self>; // NtxINode oder const NtxINode
|
||||||
|
// Konstruktor erwartet Pointer, &self ist sicher
|
||||||
|
return NtxNodeDepthFirstIterator<NodeType>(&self);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Self>
|
||||||
|
auto end(this Self&& self)
|
||||||
|
{
|
||||||
|
using NodeType = std::remove_reference_t<Self>;
|
||||||
|
return NtxNodeDepthFirstIterator<NodeType>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// Ranges Support (C++23 Style)
|
||||||
|
// =======================================================================
|
||||||
|
|
||||||
|
template <typename Self>
|
||||||
|
auto descendants(this Self&& self)
|
||||||
|
{
|
||||||
|
return std::ranges::subrange(self.begin(), self.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual NtxNodePtr doGetParent() const = 0;
|
||||||
|
virtual NtxNodePtr doGetChild(size_t index) const = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
|
|
||||||
|
#endif // NTX_INODE_H
|
||||||
|
|
||||||
98
nodes/nodes/ntxipayload.h
Normal file
98
nodes/nodes/ntxipayload.h
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
#ifndef NTX_IPAYLOAD_H
|
||||||
|
#define NTX_IPAYLOAD_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
#include <optional>
|
||||||
|
#include <variant> // for std::get_if
|
||||||
|
#include <functional> // for std::function
|
||||||
|
#include <type_traits> // for std::remove_reference_t
|
||||||
|
|
||||||
|
#include <ntx.h>
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
|
||||||
|
class NtxIPayload;
|
||||||
|
|
||||||
|
using NtxPayloadVisitor = std::function<void(const NtxString&, const NtxVariant&)> const;
|
||||||
|
using NtxPayloadPtr = std::shared_ptr<NtxIPayload>;
|
||||||
|
|
||||||
|
// --- Payload Iterator-Typen (analog zu NtxMaptor<NtxVariant>) ---
|
||||||
|
using NtxPayloadIterator = std::vector<NtxVariant>::iterator;
|
||||||
|
using NtxPayloadCIterator = std::vector<NtxVariant>::const_iterator;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Minimales Interface für 'Nutzlast' Aspekt. Kann beliebige Key-Value Paare speichern,
|
||||||
|
* wobei die Werte über NtxVariant typisiert sind. Implementierungen können intern
|
||||||
|
* z.B. std::unordered_map verwenden, einen 'Maptor' oder auf eine Meta-Klasse verweisen
|
||||||
|
* Das Interface bietet auch typsichere Zugriffsmethoden über Templates, die auf std::variant basieren.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class NtxIPayload
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual ~NtxIPayload() = default;
|
||||||
|
|
||||||
|
virtual size_t getPropertyCount() const = 0;
|
||||||
|
virtual void clearProperties() = 0;
|
||||||
|
|
||||||
|
// --- NtxIPayload Interface: Key-basiert ---
|
||||||
|
virtual bool hasProperty(const NtxString& key) const = 0;
|
||||||
|
virtual void setProperty(const NtxString& key, const NtxVariant& value) = 0;
|
||||||
|
virtual NtxVariant getProperty(const NtxString& key) const = 0;
|
||||||
|
virtual void removeProperty(const NtxString& key) = 0;
|
||||||
|
|
||||||
|
// --- NtxIPayload Interface: Index-basiert ---
|
||||||
|
virtual bool hasProperty(size_t index) const = 0;
|
||||||
|
virtual void setProperty(size_t index, const NtxVariant& value) = 0;
|
||||||
|
virtual NtxVariant getProperty(size_t index) const = 0;
|
||||||
|
|
||||||
|
//virtual NtxIPayload clone() const = 0;
|
||||||
|
template<typename TPayload>
|
||||||
|
TPayload clonePayload() const
|
||||||
|
{
|
||||||
|
return TPayload(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Payload Wrapper (Convenience) ---
|
||||||
|
template <typename T>
|
||||||
|
void set(const NtxString& key, T&& value)
|
||||||
|
{
|
||||||
|
setProperty(key, NtxVariant(std::forward<T>(value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
std::optional<T> get(const NtxString& key) const
|
||||||
|
{
|
||||||
|
// 1. Hole rohen Variant
|
||||||
|
NtxVariant raw = getProperty(key);
|
||||||
|
|
||||||
|
// 2. Prüfe ob der Typ T im Variant aktiv ist
|
||||||
|
// std::get_if liefert nullptr, wenn der Typ nicht passt.
|
||||||
|
if (const T* valPtr = std::get_if<T>(&raw))
|
||||||
|
return *valPtr;
|
||||||
|
// Typ passt nicht oder Key existiert nicht (monostate)
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @brief Komfort-Überladung: Liefert 'defaultValue', wenn Key fehlt oder Typ falsch ist.
|
||||||
|
template <typename T>
|
||||||
|
T get(const NtxString& key, const T& defaultValue) const
|
||||||
|
{
|
||||||
|
auto res = get<T>(key);
|
||||||
|
if (res.has_value())
|
||||||
|
return res.value();
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void forEachProperty(NtxPayloadVisitor visitor) const = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
|
|
||||||
|
#endif // NTX_IPAYLOAD_H
|
||||||
212
nodes/nodes/ntxlinknode.cpp
Normal file
212
nodes/nodes/ntxlinknode.cpp
Normal file
@@ -0,0 +1,212 @@
|
|||||||
|
#include <ntxlinknode.h>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#include <ntxnodeiterators.h>
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
|
||||||
|
class NtxProxyNodeExpiredException : public std::runtime_error
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
using std::runtime_error::runtime_error;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
NtxNodePtr lockOriginalNodeOrThrow(const NtxNodeWeakPtr& original)
|
||||||
|
{
|
||||||
|
auto orig = original.lock();
|
||||||
|
if (!orig)
|
||||||
|
throw NtxProxyNodeExpiredException("NtxLinkNode: Original node expired");
|
||||||
|
return orig;
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxNodeCPtr lockOriginalNodeOrThrowConst(const NtxNodeWeakPtr& original)
|
||||||
|
{
|
||||||
|
auto orig = original.lock();
|
||||||
|
if (!orig)
|
||||||
|
throw NtxProxyNodeExpiredException("NtxLinkNode: Original node expired");
|
||||||
|
return orig;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Private constructor
|
||||||
|
NtxLinkNode::NtxLinkNode(NtxNodePtr originalNode)
|
||||||
|
: m_originalNode{originalNode}
|
||||||
|
{
|
||||||
|
if (!originalNode)
|
||||||
|
{
|
||||||
|
throw std::invalid_argument("NtxLinkNode: Original node cannot be nullptr");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Factory method
|
||||||
|
NtxNodePtr NtxLinkNode::makeLink(NtxNodePtr originalNode)
|
||||||
|
{
|
||||||
|
return std::shared_ptr<NtxLinkNode>(new NtxLinkNode(originalNode));
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxLinkNode::setParent(NtxNodePtr parent)
|
||||||
|
{
|
||||||
|
lockOriginalNodeOrThrow(m_originalNode)->setParent(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// Type Access
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
const NtxClassTypeId NtxLinkNode::getClassTypeId() const
|
||||||
|
{
|
||||||
|
return lockOriginalNodeOrThrow(m_originalNode)->getClassTypeId();
|
||||||
|
}
|
||||||
|
|
||||||
|
const NtxString& NtxLinkNode::getClassTypeLabel() const
|
||||||
|
{
|
||||||
|
return lockOriginalNodeOrThrow(m_originalNode)->getClassTypeLabel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxLinkNode::setClassTypeLabel(const NtxString& idString)
|
||||||
|
{
|
||||||
|
lockOriginalNodeOrThrow(m_originalNode)->setClassTypeLabel(idString);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxLinkNode::setClassTypeId(NtxClassTypeId classTypeId)
|
||||||
|
{
|
||||||
|
lockOriginalNodeOrThrow(m_originalNode)->setClassTypeId(classTypeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// Original Node Access
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
NtxNodePtr NtxLinkNode::getOriginalNode()
|
||||||
|
{
|
||||||
|
return lockOriginalNodeOrThrow(m_originalNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxNodeCPtr NtxLinkNode::getOriginalNode() const
|
||||||
|
{
|
||||||
|
return lockOriginalNodeOrThrowConst(m_originalNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxLinkNode::isValid() const
|
||||||
|
{
|
||||||
|
return !m_originalNode.expired();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// Payload: Key-basiert
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
bool NtxLinkNode::hasProperty(const NtxString& key) const
|
||||||
|
{
|
||||||
|
return lockOriginalNodeOrThrow(m_originalNode)->hasProperty(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxLinkNode::setProperty(const NtxString& key, const NtxVariant& value)
|
||||||
|
{
|
||||||
|
lockOriginalNodeOrThrow(m_originalNode)->setProperty(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxVariant NtxLinkNode::getProperty(const NtxString& key) const
|
||||||
|
{
|
||||||
|
return lockOriginalNodeOrThrow(m_originalNode)->getProperty(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxLinkNode::removeProperty(const NtxString& key)
|
||||||
|
{
|
||||||
|
lockOriginalNodeOrThrow(m_originalNode)->removeProperty(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxLinkNode::clearProperties()
|
||||||
|
{
|
||||||
|
lockOriginalNodeOrThrow(m_originalNode)->clearProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxLinkNode::forEachProperty(NtxPayloadVisitor visitor) const
|
||||||
|
{
|
||||||
|
lockOriginalNodeOrThrow(m_originalNode)->forEachProperty(visitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// Payload: Index-basiert
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
bool NtxLinkNode::hasProperty(size_t index) const
|
||||||
|
{
|
||||||
|
return lockOriginalNodeOrThrow(m_originalNode)->hasProperty(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxLinkNode::setProperty(size_t index, const NtxVariant& value)
|
||||||
|
{
|
||||||
|
lockOriginalNodeOrThrow(m_originalNode)->setProperty(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxVariant NtxLinkNode::getProperty(size_t index) const
|
||||||
|
{
|
||||||
|
return lockOriginalNodeOrThrow(m_originalNode)->getProperty(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// Children
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
size_t NtxLinkNode::getChildCount() const
|
||||||
|
{
|
||||||
|
return lockOriginalNodeOrThrow(m_originalNode)->getChildCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxLinkNode::hasChildren() const
|
||||||
|
{
|
||||||
|
return lockOriginalNodeOrThrow(m_originalNode)->hasChildren();
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxNodePtr NtxLinkNode::doGetParent() const
|
||||||
|
{
|
||||||
|
return lockOriginalNodeOrThrow(m_originalNode)->doGetParent();
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxNodePtr NtxLinkNode::doGetChild(size_t index) const
|
||||||
|
{
|
||||||
|
return lockOriginalNodeOrThrow(m_originalNode)->getChild(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxLinkNode::addChild(NtxNodePtr child)
|
||||||
|
{
|
||||||
|
lockOriginalNodeOrThrow(m_originalNode)->addChild(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxLinkNode::removeChild(size_t index)
|
||||||
|
{
|
||||||
|
return lockOriginalNodeOrThrow(m_originalNode)->removeChild(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxLinkNode::clearChildren()
|
||||||
|
{
|
||||||
|
lockOriginalNodeOrThrow(m_originalNode)->clearChildren();
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxNodePtr NtxLinkNode::clone() const
|
||||||
|
{
|
||||||
|
return lockOriginalNodeOrThrow(m_originalNode)->clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxLinkNode::insertChild(size_t index, NtxNodePtr child)
|
||||||
|
{
|
||||||
|
lockOriginalNodeOrThrow(m_originalNode)->insertChild(index, child);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t NtxLinkNode::getChildIndex(const NtxNodePtr& child) const
|
||||||
|
{
|
||||||
|
return lockOriginalNodeOrThrow(m_originalNode)->getChildIndex(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t NtxLinkNode::getPropertyCount() const
|
||||||
|
{
|
||||||
|
return lockOriginalNodeOrThrow(m_originalNode)->getPropertyCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
72
nodes/nodes/ntxlinknode.h
Normal file
72
nodes/nodes/ntxlinknode.h
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
#ifndef NTX_LINKNODE_H
|
||||||
|
#define NTX_LINKNODE_H
|
||||||
|
|
||||||
|
#include <ntxinode.h>
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
|
||||||
|
class NtxLinkNode : public NtxINode
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Factory method to create a link to an original node
|
||||||
|
static NtxNodePtr makeLink(NtxNodePtr originalNode);
|
||||||
|
|
||||||
|
void setParent(NtxNodePtr parent) override;
|
||||||
|
|
||||||
|
const NtxClassTypeId getClassTypeId() const override;
|
||||||
|
const NtxString& getClassTypeLabel() const override;
|
||||||
|
void setClassTypeLabel(const NtxString& idString) override;
|
||||||
|
void setClassTypeId(const NtxClassTypeId classTypeId) override;
|
||||||
|
|
||||||
|
// Kinder
|
||||||
|
size_t getChildCount() const override;
|
||||||
|
bool hasChildren() const override;
|
||||||
|
|
||||||
|
void addChild(NtxNodePtr child) override;
|
||||||
|
void insertChild(size_t index, NtxNodePtr child) override;
|
||||||
|
bool removeChild(size_t index) override;
|
||||||
|
size_t getChildIndex(const NtxNodePtr& child) const override;
|
||||||
|
size_t getPropertyCount() const override;
|
||||||
|
void clearChildren() override;
|
||||||
|
|
||||||
|
NtxNodePtr clone() const override;
|
||||||
|
|
||||||
|
// Payload: Key-basiert
|
||||||
|
bool hasProperty(const NtxString& key) const override;
|
||||||
|
void setProperty(const NtxString& key, const NtxVariant& value) override;
|
||||||
|
NtxVariant getProperty(const NtxString& key) const override;
|
||||||
|
void removeProperty(const NtxString& key) override;
|
||||||
|
void clearProperties() override;
|
||||||
|
void forEachProperty(NtxPayloadVisitor visitor) const override;
|
||||||
|
|
||||||
|
// Payload: Index-basiert
|
||||||
|
bool hasProperty(size_t index) const override;
|
||||||
|
void setProperty(size_t index, const NtxVariant& value) override;
|
||||||
|
NtxVariant getProperty(size_t index) const override;
|
||||||
|
|
||||||
|
// Returns the original node this link points to
|
||||||
|
NtxNodePtr getOriginalNode();
|
||||||
|
NtxNodeCPtr getOriginalNode() const;
|
||||||
|
|
||||||
|
// Checks if the link is still valid (original node exists)
|
||||||
|
bool isValid() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
NtxNodePtr doGetParent() const override;
|
||||||
|
NtxNodePtr doGetChild(size_t index) const override;
|
||||||
|
|
||||||
|
// Private constructor - use makeLink() factory method
|
||||||
|
explicit NtxLinkNode(NtxNodePtr originalNode);
|
||||||
|
|
||||||
|
// Weak pointer to avoid circular references
|
||||||
|
NtxNodeWeakPtr m_originalNode;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
|
|
||||||
|
#endif // NTX_LINKNODE_H
|
||||||
18
nodes/nodes/ntxnode.cpp
Normal file
18
nodes/nodes/ntxnode.cpp
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#include <ntxnode.h>
|
||||||
|
#include <ntxnodefactory.h>
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
// Für Factory mit CTypeId
|
||||||
|
NtxNode::NtxNode(NtxClassTypeId id)
|
||||||
|
: NtxNode()
|
||||||
|
{
|
||||||
|
setClassTypeId(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
45
nodes/nodes/ntxnode.h
Normal file
45
nodes/nodes/ntxnode.h
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#ifndef NTX_NODE_H
|
||||||
|
#define NTX_NODE_H
|
||||||
|
|
||||||
|
#include <ntxtcloneable.h>
|
||||||
|
#include <ntxtaggregatenode.h>
|
||||||
|
#include <ntxtmixinnode.h>
|
||||||
|
#include <ntxmaptor.h>
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
class NtxNodeFactory;
|
||||||
|
|
||||||
|
using NtxVariantMaptor = NtxMaptor<NtxVariant>;
|
||||||
|
using NtxMixInNode = NtxTMixInNode<NtxVariantMaptor>;
|
||||||
|
using NtxAggregateNode = NtxTAggregateNode<NtxVariantMaptor>;
|
||||||
|
|
||||||
|
//class NtxNode : public NtxTCloneable<NtxNode, NtxMixInNode>
|
||||||
|
class NtxNode : public NtxTCloneable<NtxNode, NtxAggregateNode>
|
||||||
|
{
|
||||||
|
friend class NtxNodeFactory;
|
||||||
|
friend class NtxLinkNode;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
NtxNode() = default;
|
||||||
|
~NtxNode() override = default;
|
||||||
|
|
||||||
|
// Copy-Ctor wird von NtxTCloneable::clone() benötigt
|
||||||
|
NtxNode(const NtxNode&) = default;
|
||||||
|
NtxNode& operator=(const NtxNode&) = delete;
|
||||||
|
|
||||||
|
NtxNode(NtxNode&&) noexcept = default;
|
||||||
|
NtxNode& operator=(NtxNode&&) noexcept = default;
|
||||||
|
|
||||||
|
// clone() wird automatisch durch NtxTCloneable generiert
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
explicit NtxNode(NtxClassTypeId id);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
|
|
||||||
|
#endif // NTX_NODE_H
|
||||||
112
nodes/nodes/ntxnodefactory.cpp
Normal file
112
nodes/nodes/ntxnodefactory.cpp
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "ntxnodefactory.h"
|
||||||
|
#include "ntxnode.h"
|
||||||
|
#include <ntxiclasstyperepo.h> // implementation of default repository
|
||||||
|
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
|
||||||
|
NtxNodeFactory::NtxNodeFactory()
|
||||||
|
: m_ctypeRepository(std::make_unique<NtxCTypeHashRepo>()) // Default: Hash-basiert
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxNodeFactory& NtxNodeFactory::getInstance()
|
||||||
|
{
|
||||||
|
static NtxNodeFactory instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NtxString& NtxNodeFactory::lookupCTypeLabel(NtxClassTypeId id)
|
||||||
|
{
|
||||||
|
return getInstance().getCTypeRepository().lookupLabel(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxClassTypeId NtxNodeFactory::generateCTypeId(const NtxString& cTypeLabel)
|
||||||
|
{
|
||||||
|
return getInstance().getCTypeRepository().generateId(cTypeLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NtxNodePtr NtxNodeFactory::makeNode(const NtxString& label)
|
||||||
|
{
|
||||||
|
return getInstance().makeNodeByLabel(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxNodePtr NtxNodeFactory::makeNode(NtxClassTypeId id)
|
||||||
|
{
|
||||||
|
return getInstance().makeNodeById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxNodePtr NtxNodeFactory::makeSharedNode(const NtxString& label, NtxNodePtr sharedSource)
|
||||||
|
{
|
||||||
|
return getInstance().makeSharedNodeByLabel(label, sharedSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxNodePtr NtxNodeFactory::makeSharedNode(NtxClassTypeId id, NtxNodePtr sharedSource)
|
||||||
|
{
|
||||||
|
return getInstance().makeSharedNodeById(id, sharedSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Geile Recursion!
|
||||||
|
NtxNodePtr NtxNodeFactory::cloneNode(NtxNodeCPtr originalNode)
|
||||||
|
{
|
||||||
|
return originalNode->clone();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
NtxNodePtr NtxNodeFactory::makeNodeByLabel(const NtxString& ctypelabel)
|
||||||
|
{
|
||||||
|
// ID generieren und zuweisen
|
||||||
|
NtxClassTypeId id = m_ctypeRepository->generateId(ctypelabel);
|
||||||
|
return makeNodeById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxNodePtr NtxNodeFactory::makeNodeById(NtxClassTypeId id)
|
||||||
|
{
|
||||||
|
// Node erstellen über friend-Zugriff
|
||||||
|
auto node = std::shared_ptr<NtxNode>(new NtxNode(id));
|
||||||
|
|
||||||
|
// Label aus Repository holen (wird in NtxIBasicNode::getClassTypeLabel() automatisch gemacht)
|
||||||
|
// Kein expliziter setClassTypeLabel-Aufruf nötig
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxNodePtr NtxNodeFactory::makeSharedNodeByLabel(const NtxString& label, NtxNodePtr sharedSource)
|
||||||
|
{
|
||||||
|
// ID generieren und zuweisen
|
||||||
|
NtxClassTypeId id = m_ctypeRepository->generateId(label);
|
||||||
|
return makeSharedNodeById(id, sharedSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxNodePtr NtxNodeFactory::makeSharedNodeById(NtxClassTypeId id, NtxNodePtr sharedSource)
|
||||||
|
{
|
||||||
|
return nullptr; // std::shared_ptr<NtxSharedNode>(new NtxSharedNode(id, sharedSource));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
NtxIClassTypeRepo& NtxNodeFactory::getCTypeRepository()
|
||||||
|
{
|
||||||
|
return *m_ctypeRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NtxIClassTypeRepo& NtxNodeFactory::getCTypeRepository() const
|
||||||
|
{
|
||||||
|
return *m_ctypeRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxNodeFactory::setCTypeRepository(std::unique_ptr<NtxIClassTypeRepo> repo)
|
||||||
|
{
|
||||||
|
if (repo)
|
||||||
|
m_ctypeRepository = std::move(repo);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
59
nodes/nodes/ntxnodefactory.h
Normal file
59
nodes/nodes/ntxnodefactory.h
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#ifndef NTX_NODEFACTORY_H
|
||||||
|
#define NTX_NODEFACTORY_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <ntxinode.h>
|
||||||
|
#include <ntxiclasstyperepo.h> // Include for repo interface
|
||||||
|
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @brief Factory für die Erstellung von Nodes. Das Management von den ClassTypeIds und ihren
|
||||||
|
* ClassTypeLabels wird hier versteckt. @see NtxIClassTypeRepo
|
||||||
|
*/
|
||||||
|
class NtxNodeFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Singleton-Zugriff auf die Factory-Instanz.
|
||||||
|
static NtxNodeFactory& getInstance();
|
||||||
|
// Statische Hilfsmethoden für CType-Management und Node-Erstellung.
|
||||||
|
static const NtxString& lookupCTypeLabel(NtxClassTypeId id);
|
||||||
|
static NtxClassTypeId generateCTypeId(const NtxString& cTypeLabel);
|
||||||
|
|
||||||
|
static NtxNodePtr makeNode(const NtxString& label);
|
||||||
|
static NtxNodePtr makeNode(NtxClassTypeId id);
|
||||||
|
static NtxNodePtr makeSharedNode(const NtxString& label, NtxNodePtr sharedSource);
|
||||||
|
static NtxNodePtr makeSharedNode(NtxClassTypeId id, NtxNodePtr sharedSource);
|
||||||
|
//static NtxNodePtr makeLinkedNode(const NtxString& label, NtxNodePtr sharedSource);
|
||||||
|
//static NtxNodePtr makeLinkedNode(NtxClassTypeId id, NtxNodePtr sharedSource);
|
||||||
|
|
||||||
|
//static NtxNodePtr cloneNode(NtxNodeCPtr originalNode);
|
||||||
|
|
||||||
|
NtxNodePtr makeNodeByLabel(const NtxString& label);
|
||||||
|
NtxNodePtr makeNodeById(NtxClassTypeId id);
|
||||||
|
NtxNodePtr makeSharedNodeByLabel(const NtxString& label, NtxNodePtr sharedSource);
|
||||||
|
NtxNodePtr makeSharedNodeById(NtxClassTypeId id, NtxNodePtr sharedSource);
|
||||||
|
|
||||||
|
NtxIClassTypeRepo& getCTypeRepository();
|
||||||
|
const NtxIClassTypeRepo& getCTypeRepository() const;
|
||||||
|
void setCTypeRepository(std::unique_ptr<NtxIClassTypeRepo> repo);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
NtxNodeFactory();
|
||||||
|
~NtxNodeFactory() = default;
|
||||||
|
|
||||||
|
// Nicht kopierbar
|
||||||
|
NtxNodeFactory(const NtxNodeFactory&) = delete;
|
||||||
|
NtxNodeFactory& operator=(const NtxNodeFactory&) = delete;
|
||||||
|
|
||||||
|
// Das zentrale Repository für alle Nodes
|
||||||
|
std::unique_ptr<NtxIClassTypeRepo> m_ctypeRepository;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
|
|
||||||
|
#endif // NTX_NODEFACTORY_H
|
||||||
127
nodes/nodes/ntxnodeiterators.h
Normal file
127
nodes/nodes/ntxnodeiterators.h
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
#ifndef NTXNODE_ITERATORS_H
|
||||||
|
#define NTXNODE_ITERATORS_H
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
|
#include <stack>
|
||||||
|
#include <type_traits> // Wichtig für std::remove_cv_t
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Tiefensuche-Iterator für NtxINode Baumstrukturen
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
struct NtxNodeDepthFirstIterator
|
||||||
|
{
|
||||||
|
// C++20 Concepts Support:
|
||||||
|
// Wir definieren iterator_concept, um explizit Forward Iterator Verhalten zu signalisieren.
|
||||||
|
using iterator_concept = std::forward_iterator_tag;
|
||||||
|
using iterator_category = std::forward_iterator_tag;
|
||||||
|
|
||||||
|
using difference_type = std::ptrdiff_t;
|
||||||
|
|
||||||
|
// FIX 1: value_type darf NIE const sein, auch wenn T const ist!
|
||||||
|
using value_type = std::remove_cv_t<T>;
|
||||||
|
|
||||||
|
using pointer = T*;
|
||||||
|
using reference = T&;
|
||||||
|
|
||||||
|
NtxNodeDepthFirstIterator()
|
||||||
|
: m_root{ nullptr }, m_current{ nullptr }
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit NtxNodeDepthFirstIterator(pointer node)
|
||||||
|
: m_root{ node }, m_current{ node }
|
||||||
|
{
|
||||||
|
if (m_current) {
|
||||||
|
m_stack.push({ m_current, 0 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer get() const
|
||||||
|
{
|
||||||
|
return m_current;
|
||||||
|
}
|
||||||
|
|
||||||
|
int level() const
|
||||||
|
{
|
||||||
|
return static_cast<int>(m_stack.size()) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIX 2: Dereferenzierung muss const sein
|
||||||
|
pointer operator->() const
|
||||||
|
{
|
||||||
|
return m_current;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIX 2: Dereferenzierung muss const sein
|
||||||
|
reference operator*() const
|
||||||
|
{
|
||||||
|
return *m_current;
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit operator bool() const
|
||||||
|
{
|
||||||
|
return m_current != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxNodeDepthFirstIterator& operator++()
|
||||||
|
{
|
||||||
|
if (!m_current || m_stack.empty()) {
|
||||||
|
m_current = nullptr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!m_stack.empty()) {
|
||||||
|
auto& top = m_stack.top();
|
||||||
|
auto node = top.first;
|
||||||
|
auto& nextChildIndex = top.second;
|
||||||
|
|
||||||
|
// node->getChildCount() funktioniert, da T (bzw. ntx::NtxINode) hier vollständig bekannt ist
|
||||||
|
const auto childCount = node->getChildCount();
|
||||||
|
while (nextChildIndex < childCount) {
|
||||||
|
auto child = node->getChild(nextChildIndex++);
|
||||||
|
if (child) {
|
||||||
|
m_current = child.get();
|
||||||
|
m_stack.push({ m_current, 0 });
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_stack.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_current = nullptr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxNodeDepthFirstIterator operator++(int)
|
||||||
|
{
|
||||||
|
NtxNodeDepthFirstIterator tmp = *this;
|
||||||
|
++(*this);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hidden Friends für Vergleiche (ADL)
|
||||||
|
friend bool operator==(const NtxNodeDepthFirstIterator& a, const NtxNodeDepthFirstIterator& b)
|
||||||
|
{
|
||||||
|
return a.m_current == b.m_current;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator!=(const NtxNodeDepthFirstIterator& a, const NtxNodeDepthFirstIterator& b)
|
||||||
|
{
|
||||||
|
return a.m_current != b.m_current;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
pointer m_root;
|
||||||
|
pointer m_current;
|
||||||
|
std::stack<std::pair<pointer, size_t>> m_stack;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
|
|
||||||
|
#endif // NTXNODE_ITERATORS_H
|
||||||
57
nodes/nodes/ntxnodeproxy.h
Normal file
57
nodes/nodes/ntxnodeproxy.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
#ifndef NTX_NODEPROXY_H
|
||||||
|
#define NTX_NODEPROXY_H
|
||||||
|
|
||||||
|
#include <ntxinode.h>
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Transparenter Proxy für NtxINodePtr.
|
||||||
|
*
|
||||||
|
* operator->() → delegiert ALLE Methodenaufrufe an den internen Pointer.
|
||||||
|
* operator NtxINodePtr() → impliziter Cast wo NtxINodePtr erwartet wird.
|
||||||
|
*
|
||||||
|
* Keine einzige NtxINode-Methode muss reimplementiert werden.
|
||||||
|
*/
|
||||||
|
class NtxNodeProxy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit NtxNodeProxy(NtxINodePtr node)
|
||||||
|
: m_node(std::move(node))
|
||||||
|
{}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
// Das Herzstück: leitet JEDEN Methodenaufruf transparent weiter
|
||||||
|
// proxy->getProperty("x") → m_node->getProperty("x")
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
NtxINode* operator->() { return m_node.get(); }
|
||||||
|
const NtxINode* operator->() const { return m_node.get(); }
|
||||||
|
|
||||||
|
NtxINode& operator*() { return *m_node; }
|
||||||
|
const NtxINode& operator*() const { return *m_node; }
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
// Implizite Konvertierung — überall wo NtxINodePtr erwartet wird
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
operator NtxINodePtr() const { return m_node; }
|
||||||
|
operator NtxNodeCPtr() const { return m_node; }
|
||||||
|
operator bool() const { return m_node != nullptr; }
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
// Expliziter Zugriff
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
NtxINodePtr get() const { return m_node; }
|
||||||
|
|
||||||
|
void reset(NtxINodePtr node = nullptr) { m_node = std::move(node); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
NtxINodePtr m_node;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
|
|
||||||
|
#endif // NTX_NODEPROXY_H
|
||||||
150
nodes/nodes/ntxsharedpayload.cpp
Normal file
150
nodes/nodes/ntxsharedpayload.cpp
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
#include <ntxsharedpayload.h>
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// NtxSharedPayload: Key-basiert
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
NtxSharedPayload::NtxSharedPayload(const NtxPayloadPtr& original)
|
||||||
|
: m_originalPayload(original)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxSharedPayload::hasValue(const NtxString& key) const
|
||||||
|
{
|
||||||
|
return m_originalPayload && m_originalPayload->hasValue(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxSharedPayload::setValue(const NtxString& key, const NtxVariant& value)
|
||||||
|
{
|
||||||
|
if (m_originalPayload)
|
||||||
|
m_originalPayload->setValue(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxVariant NtxSharedPayload::getValue(const NtxString& key) const
|
||||||
|
{
|
||||||
|
if (m_originalPayload)
|
||||||
|
return m_originalPayload->getValue(key);
|
||||||
|
return NtxVariant{};
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxSharedPayload::removeValue(const NtxString& key)
|
||||||
|
{
|
||||||
|
if (m_originalPayload)
|
||||||
|
m_originalPayload->removeValue(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxSharedPayload::clearValues()
|
||||||
|
{
|
||||||
|
if (m_originalPayload)
|
||||||
|
m_originalPayload->clearValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t NtxSharedPayload::getValueCount() const
|
||||||
|
{
|
||||||
|
return m_originalPayload ? m_originalPayload->getValueCount() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxSharedPayload::forEachProperty(NtxPayloadVisitor visitor) const
|
||||||
|
{
|
||||||
|
if (m_originalPayload)
|
||||||
|
m_originalPayload->forEachProperty(visitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
NtxStringList NtxSharedPayload::getValueKeys() const
|
||||||
|
{
|
||||||
|
if (m_originalPayload)
|
||||||
|
return m_originalPayload->getValueKeys();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// NtxSharedPayload: Index-basiert
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
bool NtxSharedPayload::hasValue(size_t index) const
|
||||||
|
{
|
||||||
|
return m_originalPayload && m_originalPayload->hasValue(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxSharedPayload::setValue(size_t index, const NtxVariant& value)
|
||||||
|
{
|
||||||
|
if (m_originalPayload)
|
||||||
|
m_originalPayload->setValue(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxVariant NtxSharedPayload::getValue(size_t index) const
|
||||||
|
{
|
||||||
|
if (m_originalPayload)
|
||||||
|
return m_originalPayload->getValue(index);
|
||||||
|
return NtxVariant{};
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// NtxSharedPayload: Iteratoren
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
/*
|
||||||
|
NtxPayloadIterator NtxSharedPayload::valuesBegin()
|
||||||
|
{
|
||||||
|
if (m_originalPayload)
|
||||||
|
return m_originalPayload->valuesBegin();
|
||||||
|
// Leerer Iterator: Kein gültiger Fallback möglich → UB vermeiden
|
||||||
|
static std::vector<NtxVariant> empty;
|
||||||
|
return empty.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxPayloadIterator NtxSharedPayload::valuesEnd()
|
||||||
|
{
|
||||||
|
if (m_originalPayload)
|
||||||
|
return m_originalPayload->valuesEnd();
|
||||||
|
static std::vector<NtxVariant> empty;
|
||||||
|
return empty.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxPayloadCIterator NtxSharedPayload::valuesBegin() const
|
||||||
|
{
|
||||||
|
if (m_originalPayload)
|
||||||
|
return m_originalPayload->valuesBegin();
|
||||||
|
static const std::vector<NtxVariant> empty;
|
||||||
|
return empty.cbegin();
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxPayloadCIterator NtxSharedPayload::valuesEnd() const
|
||||||
|
{
|
||||||
|
if (m_originalPayload)
|
||||||
|
return m_originalPayload->valuesEnd();
|
||||||
|
static const std::vector<NtxVariant> empty;
|
||||||
|
return empty.cend();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// NtxSharedPayload: Sonstiges
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
NtxPayloadPtr NtxSharedPayload::getOriginalPayload() const
|
||||||
|
{
|
||||||
|
return m_originalPayload;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxSharedPayload::setOriginalPayload(const NtxPayloadPtr& original)
|
||||||
|
{
|
||||||
|
m_originalPayload = original;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxSharedPayload::isValid() const
|
||||||
|
{
|
||||||
|
return m_originalPayload != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxSharedPayload::detach()
|
||||||
|
{
|
||||||
|
m_originalPayload.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
89
nodes/nodes/ntxtaggregatenode.h
Normal file
89
nodes/nodes/ntxtaggregatenode.h
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
#ifndef NTX_AGGREGATENODE_H
|
||||||
|
#define NTX_AGGREGATENODE_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <ntxibasicnode.h>
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Implementierung via Aggregation (KISS-Variante).
|
||||||
|
*
|
||||||
|
* Besitzt oder referenziert einen NtxIPayload über shared_ptr.
|
||||||
|
* Owning: NtxTAggregateNode(std::make_shared<MyPayload>(...))
|
||||||
|
* Referencing: NtxTAggregateNode(existingPayloadPtr)
|
||||||
|
*/
|
||||||
|
template<typename TPayloadImpl>
|
||||||
|
class NtxTAggregateNode : public NtxIBasicNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Owning: erstellt eigene TPayloadImpl-Instanz
|
||||||
|
/*
|
||||||
|
template<typename... Args>
|
||||||
|
explicit NtxTAggregateNode(Args&&... args)
|
||||||
|
: NtxIBasicNode{}
|
||||||
|
, m_payload(std::make_shared<TPayloadImpl>(std::forward<Args>(args)...))
|
||||||
|
{}
|
||||||
|
*/
|
||||||
|
|
||||||
|
NtxTAggregateNode()
|
||||||
|
: NtxIBasicNode{}, m_payload(std::make_shared<TPayloadImpl>())
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Referencing: verknüpft bestehenden Payload
|
||||||
|
explicit NtxTAggregateNode(std::shared_ptr<TPayloadImpl> sharedPayload)
|
||||||
|
: NtxIBasicNode{}
|
||||||
|
, m_payload(std::move(sharedPayload))
|
||||||
|
{}
|
||||||
|
|
||||||
|
// Payload zur Laufzeit austauschen (Owning ↔ Referencing)
|
||||||
|
void setPayload(NtxPayloadPtr payload) { m_payload = std::move(payload); }
|
||||||
|
NtxPayloadPtr getPayload() const { return m_payload; }
|
||||||
|
|
||||||
|
// ========================================
|
||||||
|
// NtxIPayload Interface: Delegation
|
||||||
|
// ========================================
|
||||||
|
|
||||||
|
size_t getPropertyCount() const override { return m_payload->getPropertyCount(); }
|
||||||
|
void clearProperties() override { m_payload->clearProperties(); }
|
||||||
|
|
||||||
|
bool hasProperty(const NtxString& key) const override { return m_payload->hasProperty(key); }
|
||||||
|
void setProperty(const NtxString& key, const NtxVariant& value) override
|
||||||
|
{ m_payload->setProperty(key, value); }
|
||||||
|
NtxVariant getProperty(const NtxString& key) const override
|
||||||
|
{ return m_payload->getProperty(key); }
|
||||||
|
void removeProperty(const NtxString& key) override { m_payload->removeProperty(key); }
|
||||||
|
|
||||||
|
bool hasProperty(size_t index) const override { return m_payload->hasProperty(index); }
|
||||||
|
void setProperty(size_t index, const NtxVariant& value) override
|
||||||
|
{ m_payload->setProperty(index, value); }
|
||||||
|
NtxVariant getProperty(size_t index) const override { return m_payload->getProperty(index); }
|
||||||
|
|
||||||
|
void forEachProperty(NtxPayloadVisitor visitor) const override
|
||||||
|
{
|
||||||
|
//m_payload->forEachProperty(visitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxNodePtr clone() const override
|
||||||
|
{
|
||||||
|
// m_payload ist bereits shared_ptr<TPayloadImpl> — kein cast nötig
|
||||||
|
auto newNode = std::make_shared<NtxTAggregateNode<TPayloadImpl>>(
|
||||||
|
std::make_shared<TPayloadImpl>(*m_payload));
|
||||||
|
newNode->setClassTypeId(this->getClassTypeId());
|
||||||
|
return newNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// NtxPayloadPtr m_payload; // Nein! das ist eine völlig unnötige Einschränkung auf IPayload.
|
||||||
|
std::shared_ptr<TPayloadImpl> m_payload;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
|
|
||||||
|
#endif // NTX_AGGREGATENODE_H
|
||||||
34
nodes/nodes/ntxtcloneable.h
Normal file
34
nodes/nodes/ntxtcloneable.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#ifndef NTX_CLONEABLE_H
|
||||||
|
#define NTX_CLONEABLE_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <ntxinode.h>
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CRTP-Mixin: generiert clone() automatisch für jede Subklasse.
|
||||||
|
*
|
||||||
|
* Voraussetzung: Derived ist copy-konstruierbar.
|
||||||
|
*
|
||||||
|
* Verwendung:
|
||||||
|
* class MyNode : public NtxTCloneable<MyNode, NtxTMixInNode<MyPayload>> { ... };
|
||||||
|
*/
|
||||||
|
template<typename Derived, typename Base>
|
||||||
|
class NtxTCloneable : public Base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
using Base::Base; // Konstruktoren durchreichen
|
||||||
|
|
||||||
|
NtxNodePtr clone() const override
|
||||||
|
{
|
||||||
|
return std::make_shared<Derived>(static_cast<const Derived&>(*this));
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
|
|
||||||
|
#endif // NTX_CLONEABLE_H
|
||||||
73
nodes/nodes/ntxtmixinnode.h
Normal file
73
nodes/nodes/ntxtmixinnode.h
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
#ifndef NTX_TMIXINNODE_H
|
||||||
|
#define NTX_TMIXINNODE_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <variant>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include <ntxibasicnode.h>
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Implementierung via Vererbung (Mixin).
|
||||||
|
*
|
||||||
|
* TPayloadImpl wird als Basisklasse eingemischt.
|
||||||
|
*/
|
||||||
|
template<typename TPayloadImpl>
|
||||||
|
class NtxTMixInNode : public NtxIBasicNode, public TPayloadImpl
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Konstruktor forwarding an PayloadImpl
|
||||||
|
template<typename... Args>
|
||||||
|
explicit NtxTMixInNode(Args&&... args)
|
||||||
|
: NtxIBasicNode{},
|
||||||
|
TPayloadImpl{std::forward<Args>(args)...}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========================================
|
||||||
|
// NtxINode Interface: Payload Forwarding
|
||||||
|
// ========================================
|
||||||
|
|
||||||
|
size_t getPropertyCount() const override { return TPayloadImpl::getPropertyCount(); }
|
||||||
|
void clearProperties() override { TPayloadImpl::clearProperties(); }
|
||||||
|
|
||||||
|
bool hasProperty(const NtxString& key) const override { return TPayloadImpl::hasProperty(key); }
|
||||||
|
void setProperty(const NtxString& key, const NtxVariant& value) override { TPayloadImpl::setProperty(key, value); }
|
||||||
|
NtxVariant getProperty(const NtxString& key) const override { return TPayloadImpl::getProperty(key); }
|
||||||
|
void removeProperty(const NtxString& key) override { TPayloadImpl::removeProperty(key); }
|
||||||
|
|
||||||
|
bool hasProperty(size_t index) const override { return TPayloadImpl::hasProperty(index); }
|
||||||
|
void setProperty(size_t index, const NtxVariant& value) override { TPayloadImpl::setProperty(index, value); }
|
||||||
|
NtxVariant getProperty(size_t index) const override { return TPayloadImpl::getProperty(index); }
|
||||||
|
|
||||||
|
|
||||||
|
// Deducing This Support (Raw Access)
|
||||||
|
//std::vector<NtxVariant>& doGetValues() override { return TPayloadImpl::doGetValues(); }
|
||||||
|
//const std::vector<NtxVariant>& doGetValues() const override { return TPayloadImpl::doGetValues(); }
|
||||||
|
|
||||||
|
|
||||||
|
void forEachProperty(NtxPayloadVisitor visitor) const override
|
||||||
|
{
|
||||||
|
//TPayloadImpl::forEachProperty(visitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NtxNodePtr clone() const override
|
||||||
|
{
|
||||||
|
// Basic Clone Implementation: Kopiert PayloadImpl Teil via Copy-Ctor
|
||||||
|
auto newNode = std::make_shared<NtxTMixInNode<TPayloadImpl>>(*static_cast<const TPayloadImpl*>(this));
|
||||||
|
// Base Properties kopieren
|
||||||
|
newNode->setClassTypeId(this->getClassTypeId());
|
||||||
|
return newNode;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
|
|
||||||
|
#endif // NTX_TMIXINNODE_H
|
||||||
83
nodes/services/ntxclipboard.cpp
Normal file
83
nodes/services/ntxclipboard.cpp
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
#include "ntxclipboard.h"
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
void NtxClipboard::copyNodes(const NtxNodeList& nodes)
|
||||||
|
{
|
||||||
|
m_nodeEntryList.clear();
|
||||||
|
|
||||||
|
for (const auto& node : nodes)
|
||||||
|
{
|
||||||
|
if (!node) continue;
|
||||||
|
|
||||||
|
NtxNodeEntry entry;
|
||||||
|
entry.clone = createOrphanClone(node);
|
||||||
|
entry.originalParent = node->getParent();
|
||||||
|
entry.originalPosition = node->ownPos().value_or(0);
|
||||||
|
|
||||||
|
m_nodeEntryList.push_back(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxClipboard::cutNodes(const NtxNodeList& nodes)
|
||||||
|
{
|
||||||
|
// Identisch zu copyNodes - Der Unterschied liegt in NtxHeadNode
|
||||||
|
copyNodes(nodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxNodeList NtxClipboard::pasteNodes() const
|
||||||
|
{
|
||||||
|
NtxNodeList result;
|
||||||
|
|
||||||
|
for (const auto& entry : m_nodeEntryList)
|
||||||
|
{
|
||||||
|
if (!entry.clone) continue;
|
||||||
|
|
||||||
|
// Neuen Klon vom Clipboard-Clone erstellen (mehrfaches Paste möglich)
|
||||||
|
auto freshClone = entry.clone->clone();
|
||||||
|
if (freshClone)
|
||||||
|
{
|
||||||
|
result.push_back(freshClone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxClipboard::isEmpty() const
|
||||||
|
{
|
||||||
|
return m_nodeEntryList.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t NtxClipboard::getCount() const
|
||||||
|
{
|
||||||
|
return m_nodeEntryList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxClipboard::clear()
|
||||||
|
{
|
||||||
|
m_nodeEntryList.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
const NtxNodeEntryList& NtxClipboard::getEntries() const
|
||||||
|
{
|
||||||
|
return m_nodeEntryList;
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxNodePtr NtxClipboard::createOrphanClone(NtxNodePtr node) const
|
||||||
|
{
|
||||||
|
if (!node) return nullptr;
|
||||||
|
|
||||||
|
// Deep-Clone erstellen
|
||||||
|
auto clone = node->clone();
|
||||||
|
|
||||||
|
// Parent-Verbindung trennen (Elternlos machen)
|
||||||
|
if (clone)
|
||||||
|
{
|
||||||
|
clone->setParent(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
47
nodes/services/ntxclipboard.h
Normal file
47
nodes/services/ntxclipboard.h
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#ifndef NTX_CLIPBOARD_H
|
||||||
|
#define NTX_CLIPBOARD_H
|
||||||
|
|
||||||
|
#include <ntxicommand.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @brief Einfaches Clipboard für Copy/Cut/Paste-Operationen.
|
||||||
|
*
|
||||||
|
* Speichert elternlose Deep-Clones mit Original-Position für Undo.
|
||||||
|
* Kein Singleton - wird als Member von NtxHeadNode verwendet.
|
||||||
|
*/
|
||||||
|
class NtxClipboard
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
NtxClipboard() = default;
|
||||||
|
~NtxClipboard() = default;
|
||||||
|
|
||||||
|
// Copy/Cut Operations
|
||||||
|
void copyNodes(const NtxNodeList& nodes);
|
||||||
|
void cutNodes(const NtxNodeList& nodes);
|
||||||
|
|
||||||
|
// Paste Operations
|
||||||
|
NtxNodeList pasteNodes() const;
|
||||||
|
|
||||||
|
// State
|
||||||
|
bool isEmpty() const;
|
||||||
|
size_t getCount() const;
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
// Access
|
||||||
|
const NtxNodeEntryList& getEntries() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
NtxNodeEntryList m_nodeEntryList;
|
||||||
|
|
||||||
|
NtxNodePtr createOrphanClone(NtxNodePtr node) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
|
|
||||||
|
#endif // NTX_CLIPBOARD_H
|
||||||
141
nodes/services/ntxcmdlist.cpp
Normal file
141
nodes/services/ntxcmdlist.cpp
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
#include <NtxCmdList.h>
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
|
||||||
|
NtxCmdList::NtxCmdList()
|
||||||
|
: m_executedCount(0)
|
||||||
|
{
|
||||||
|
setDescription("Multi Command");
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxCmdList::NtxCmdList(const NtxString& description)
|
||||||
|
: m_executedCount(0)
|
||||||
|
{
|
||||||
|
setDescription(description);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxCmdList::execute()
|
||||||
|
{
|
||||||
|
m_executedCount = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < m_commands.size(); ++i)
|
||||||
|
{
|
||||||
|
if (!m_commands[i]->canExecute())
|
||||||
|
{
|
||||||
|
rollback(i);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_commands[i]->execute())
|
||||||
|
{
|
||||||
|
rollback(i);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_executedCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxCmdList::undo()
|
||||||
|
{
|
||||||
|
if (m_executedCount == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (size_t i = m_executedCount; i > 0; --i)
|
||||||
|
{
|
||||||
|
size_t index = i - 1;
|
||||||
|
|
||||||
|
if (!m_commands[index]->canUndo())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
m_commands[index]->undo();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_executedCount = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxCmdList::canExecute() const
|
||||||
|
{
|
||||||
|
if (m_commands.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (const auto& cmd : m_commands)
|
||||||
|
{
|
||||||
|
if (!cmd->canExecute())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxCmdList::canUndo() const
|
||||||
|
{
|
||||||
|
if (m_executedCount == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < m_executedCount; ++i)
|
||||||
|
{
|
||||||
|
if (m_commands[i]->canUndo())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxString NtxCmdList::getDescription() const
|
||||||
|
{
|
||||||
|
NtxString desc = NtxICommand::getDescription();
|
||||||
|
|
||||||
|
if (!desc.empty())
|
||||||
|
return desc;
|
||||||
|
|
||||||
|
if (m_commands.empty())
|
||||||
|
return "Empty Multi Command";
|
||||||
|
|
||||||
|
return "Multi Command (" + std::to_string(m_commands.size()) + " commands)";
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxCmdList::addCommand(NtxCommandUPtr command)
|
||||||
|
{
|
||||||
|
if (command)
|
||||||
|
{
|
||||||
|
m_commands.push_back(std::move(command));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxCmdList::clear()
|
||||||
|
{
|
||||||
|
m_commands.clear();
|
||||||
|
m_executedCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t NtxCmdList::count() const
|
||||||
|
{
|
||||||
|
return m_commands.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxCmdList::isEmpty() const
|
||||||
|
{
|
||||||
|
return m_commands.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxCmdList::rollback(size_t upToIndex)
|
||||||
|
{
|
||||||
|
for (size_t i = upToIndex; i > 0; --i)
|
||||||
|
{
|
||||||
|
size_t index = i - 1;
|
||||||
|
|
||||||
|
if (m_commands[index]->canUndo())
|
||||||
|
{
|
||||||
|
m_commands[index]->undo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_executedCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
42
nodes/services/ntxcmdlist.h
Normal file
42
nodes/services/ntxcmdlist.h
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
#ifndef NTX_CMDLIST_H
|
||||||
|
#define NTX_CMDLIST_H
|
||||||
|
|
||||||
|
#include <ntxicommand.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
|
||||||
|
class NtxCmdList : public NtxICommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
NtxCmdList();
|
||||||
|
explicit NtxCmdList(const NtxString& description);
|
||||||
|
~NtxCmdList() override = default;
|
||||||
|
|
||||||
|
bool execute() override;
|
||||||
|
bool undo() override;
|
||||||
|
|
||||||
|
bool canExecute() const override;
|
||||||
|
bool canUndo() const override;
|
||||||
|
|
||||||
|
NtxString getDescription() const override;
|
||||||
|
|
||||||
|
void addCommand(NtxCommandUPtr command);
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
size_t count() const;
|
||||||
|
bool isEmpty() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::vector<NtxCommandUPtr> m_commands;
|
||||||
|
size_t m_executedCount;
|
||||||
|
|
||||||
|
void rollback(size_t upToIndex);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
|
|
||||||
|
#endif // NTX_CMDLIST_H
|
||||||
55
nodes/services/ntxheadnode.cpp
Normal file
55
nodes/services/ntxheadnode.cpp
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#include <ntxheadnode.h>
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
|
||||||
|
bool NtxHeadNode::copyNode(NtxNodePtr node)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxHeadNode::cutNode(NtxNodePtr node)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxNodePtr NtxHeadNode::pasteNode(NtxNodePtr parent, int index)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxHeadNode::addNode(NtxNodePtr parent, NtxNodePtr node, int index)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxHeadNode::deleteNode(NtxNodePtr node)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxHeadNode::hasClipboard() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxHeadNode::clearClipboard()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxNodePtr NtxHeadNode::peekClipboard() const
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxHeadNode::validateNode(NtxNodePtr node) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxHeadNode::canAddToParent(NtxNodePtr parent, NtxNodePtr child) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
46
nodes/services/ntxheadnode.h
Normal file
46
nodes/services/ntxheadnode.h
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
#ifndef NTX_HEADNODE_H
|
||||||
|
#define NTX_HEADNODE_H
|
||||||
|
|
||||||
|
#include <ntxinode.h>
|
||||||
|
#include <ntxclipboard.h>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
class NtxINode;
|
||||||
|
using NtxNodePtr = std::shared_ptr<NtxINode>;
|
||||||
|
|
||||||
|
class NtxHeadNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
NtxHeadNode() = default;
|
||||||
|
~NtxHeadNode() = default;
|
||||||
|
|
||||||
|
NtxHeadNode(const NtxHeadNode&) = delete;
|
||||||
|
NtxHeadNode& operator=(const NtxHeadNode&) = delete;
|
||||||
|
NtxHeadNode(NtxHeadNode&&) = default;
|
||||||
|
NtxHeadNode& operator=(NtxHeadNode&&) = default;
|
||||||
|
|
||||||
|
bool copyNode(NtxNodePtr node);
|
||||||
|
bool cutNode(NtxNodePtr node);
|
||||||
|
NtxNodePtr pasteNode(NtxNodePtr parent, int index = -1);
|
||||||
|
bool addNode(NtxNodePtr parent, NtxNodePtr node, int index = -1);
|
||||||
|
bool deleteNode(NtxNodePtr node);
|
||||||
|
|
||||||
|
bool hasClipboard() const;
|
||||||
|
void clearClipboard();
|
||||||
|
NtxNodePtr peekClipboard() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
NtxClipboard m_clipboard; // ← Eigene Klasse als Member!
|
||||||
|
bool m_isCutOperation{false};
|
||||||
|
|
||||||
|
bool validateNode(NtxNodePtr node) const;
|
||||||
|
bool canAddToParent(NtxNodePtr parent, NtxNodePtr child) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
|
|
||||||
|
#endif // NTX_HEADNODE_H
|
||||||
21
nodes/services/ntxicommand.cpp
Normal file
21
nodes/services/ntxicommand.cpp
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#include <ntxicommand.h>
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
|
||||||
|
bool NtxICommand::canUndo() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxString NtxICommand::getDescription() const
|
||||||
|
{
|
||||||
|
return m_description;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxICommand::setDescription(const NtxString& description)
|
||||||
|
{
|
||||||
|
m_description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
52
nodes/services/ntxicommand.h
Normal file
52
nodes/services/ntxicommand.h
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
#ifndef NTX_ICOMMAND_H
|
||||||
|
#define NTX_ICOMMAND_H
|
||||||
|
|
||||||
|
#include <ntxinode.h>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
|
||||||
|
// Einfache Struct für Clipboard-Eintrag
|
||||||
|
struct NtxNodeEntry
|
||||||
|
{
|
||||||
|
NtxNodePtr clone; // Elternloser Deep-Clone
|
||||||
|
NtxNodeWeakPtr originalParent; // Schwache Referenz für Undo
|
||||||
|
size_t originalPosition; // Position im Original-Parent
|
||||||
|
};
|
||||||
|
|
||||||
|
using NtxNodeEntryList = std::vector<NtxNodeEntry>;
|
||||||
|
|
||||||
|
class NtxICommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual ~NtxICommand() = default;
|
||||||
|
|
||||||
|
virtual bool execute() = 0;
|
||||||
|
virtual bool undo() = 0;
|
||||||
|
|
||||||
|
virtual bool canExecute() const = 0;
|
||||||
|
virtual bool canUndo() const;
|
||||||
|
|
||||||
|
virtual NtxString getDescription() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
NtxICommand() = default;
|
||||||
|
NtxICommand(const NtxICommand&) = default;
|
||||||
|
NtxICommand& operator=(const NtxICommand&) = default;
|
||||||
|
|
||||||
|
void setDescription(const NtxString& description);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
NtxString m_description;
|
||||||
|
};
|
||||||
|
|
||||||
|
using NtxCommandPtr = std::shared_ptr<NtxICommand>;
|
||||||
|
using NtxCommandUPtr = std::unique_ptr<NtxICommand>;
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
|
|
||||||
|
#endif // NTX_ICOMMAND_H
|
||||||
161
nodes/services/ntxnodecommands.cpp
Normal file
161
nodes/services/ntxnodecommands.cpp
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
#include "ntxnodecommands.h"
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// NtxInsertNodeCmd
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
NtxInsertNodeCmd::NtxInsertNodeCmd(NtxNodePtr parent, NtxNodePtr node, size_t index)
|
||||||
|
: m_parent(std::move(parent))
|
||||||
|
, m_node(std::move(node))
|
||||||
|
, m_index(index)
|
||||||
|
{
|
||||||
|
setDescription("Insert node");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxInsertNodeCmd::execute()
|
||||||
|
{
|
||||||
|
if (!canExecute())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (m_index > m_parent->getChildCount())
|
||||||
|
m_index = m_parent->getChildCount();
|
||||||
|
|
||||||
|
m_parent->insertChild(m_index, m_node);
|
||||||
|
m_executed = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxInsertNodeCmd::undo()
|
||||||
|
{
|
||||||
|
if (!m_executed)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto idx = m_parent->getChildIndex(m_node);
|
||||||
|
if (idx == static_cast<size_t>(-1))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_parent->removeChild(idx);
|
||||||
|
m_executed = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxInsertNodeCmd::canExecute() const
|
||||||
|
{
|
||||||
|
return m_parent && m_node && !m_executed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// NtxRemoveNodeCmd
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
NtxRemoveNodeCmd::NtxRemoveNodeCmd(NtxNodePtr node)
|
||||||
|
: m_node(std::move(node))
|
||||||
|
{
|
||||||
|
setDescription("Remove node");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxRemoveNodeCmd::execute()
|
||||||
|
{
|
||||||
|
if (!canExecute())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_parent = m_node->getParent();
|
||||||
|
if (!m_parent)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto pos = m_node->ownPos();
|
||||||
|
if (!pos)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_index = *pos;
|
||||||
|
m_parent->removeChild(m_index);
|
||||||
|
m_executed = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxRemoveNodeCmd::undo()
|
||||||
|
{
|
||||||
|
if (!m_executed || !m_parent)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_parent->insertChild(m_index, m_node);
|
||||||
|
m_executed = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxRemoveNodeCmd::canExecute() const
|
||||||
|
{
|
||||||
|
return m_node && m_node->getParent() && !m_executed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// NtxMacroCommand
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
NtxMacroCommand::NtxMacroCommand(const NtxString& description)
|
||||||
|
{
|
||||||
|
setDescription(description);
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxCommandUPtr NtxMacroCommand::create(
|
||||||
|
const NtxString& description,
|
||||||
|
std::vector<NtxCommandUPtr> commands)
|
||||||
|
{
|
||||||
|
auto macro = std::make_unique<NtxMacroCommand>(description);
|
||||||
|
for (auto& cmd : commands)
|
||||||
|
macro->add(std::move(cmd));
|
||||||
|
return macro;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxMacroCommand::add(NtxCommandUPtr cmd)
|
||||||
|
{
|
||||||
|
if (cmd)
|
||||||
|
m_commands.push_back(std::move(cmd));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxMacroCommand::execute()
|
||||||
|
{
|
||||||
|
m_executedCount = 0;
|
||||||
|
|
||||||
|
for (auto& cmd : m_commands)
|
||||||
|
{
|
||||||
|
if (!cmd->execute())
|
||||||
|
{
|
||||||
|
// Rollback: Bereits ausgeführte rückgängig machen
|
||||||
|
for (size_t i = m_executedCount; i > 0; --i)
|
||||||
|
m_commands[i - 1]->undo();
|
||||||
|
m_executedCount = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
++m_executedCount;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxMacroCommand::undo()
|
||||||
|
{
|
||||||
|
for (size_t i = m_executedCount; i > 0; --i)
|
||||||
|
{
|
||||||
|
if (!m_commands[i - 1]->undo())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_executedCount = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxMacroCommand::canExecute() const
|
||||||
|
{
|
||||||
|
if (m_commands.empty())
|
||||||
|
return false;
|
||||||
|
for (const auto& cmd : m_commands)
|
||||||
|
{
|
||||||
|
if (!cmd->canExecute())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
102
nodes/services/ntxnodecommands.h
Normal file
102
nodes/services/ntxnodecommands.h
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
#ifndef NTX_NODECOMMANDS_H
|
||||||
|
#define NTX_NODECOMMANDS_H
|
||||||
|
|
||||||
|
#include <ntxicommand.h>
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// Atomar: Knoten einfügen
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Fügt einen Knoten an einer Position ein.
|
||||||
|
* Undo entfernt ihn wieder.
|
||||||
|
*/
|
||||||
|
class NtxInsertNodeCmd : public NtxICommand
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
NtxInsertNodeCmd(NtxNodePtr parent, NtxNodePtr node, size_t index);
|
||||||
|
|
||||||
|
bool execute() override;
|
||||||
|
bool undo() override;
|
||||||
|
bool canExecute() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
NtxNodePtr m_parent;
|
||||||
|
NtxNodePtr m_node;
|
||||||
|
size_t m_index;
|
||||||
|
bool m_executed{false};
|
||||||
|
};
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// Atomar: Knoten entfernen
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Entfernt einen Knoten. Merkt sich Parent + Position für Undo.
|
||||||
|
*/
|
||||||
|
class NtxRemoveNodeCmd : public NtxICommand
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit NtxRemoveNodeCmd(NtxNodePtr node);
|
||||||
|
|
||||||
|
bool execute() override;
|
||||||
|
bool undo() override;
|
||||||
|
bool canExecute() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
NtxNodePtr m_node;
|
||||||
|
NtxNodePtr m_parent;
|
||||||
|
size_t m_index{0};
|
||||||
|
bool m_executed{false};
|
||||||
|
};
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// Makro-Command (Composite Command)
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Führt mehrere Commands als atomare Einheit aus.
|
||||||
|
*
|
||||||
|
* execute(): Alle Commands vorwärts ausführen.
|
||||||
|
* undo(): Alle Commands rückwärts rückgängig machen.
|
||||||
|
* Bei Fehler: Rollback der bereits ausgeführten.
|
||||||
|
*/
|
||||||
|
class NtxMacroCommand : public NtxICommand
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
NtxMacroCommand() = default;
|
||||||
|
explicit NtxMacroCommand(const NtxString& description);
|
||||||
|
|
||||||
|
/// Factory: Erzeugt ein Makro aus einer Liste von Commands.
|
||||||
|
static NtxCommandUPtr create(
|
||||||
|
const NtxString& description,
|
||||||
|
std::vector<NtxCommandUPtr> commands);
|
||||||
|
|
||||||
|
void add(NtxCommandUPtr cmd);
|
||||||
|
|
||||||
|
bool execute() override;
|
||||||
|
bool undo() override;
|
||||||
|
bool canExecute() const override;
|
||||||
|
|
||||||
|
size_t commandCount() const { return m_commands.size(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::vector<NtxCommandUPtr> m_commands;
|
||||||
|
size_t m_executedCount{0};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
|
|
||||||
|
#endif // NTX_NODECOMMANDS_H
|
||||||
209
nodes/services/ntxnodetree.cpp
Normal file
209
nodes/services/ntxnodetree.cpp
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
#include <ntxnodetree.h>
|
||||||
|
#include <ntxnodefactory.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
|
||||||
|
NtxNodeTree::NtxNodeTree(NtxClassTypeId id)
|
||||||
|
{
|
||||||
|
//m_ctypeId = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxNodePtr NtxNodeTree::clone() const
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
auto cloned = NtxNodeFactory::makeNode(getClassTypeLabel());
|
||||||
|
qDebug() << "Cloning NtxNodeTree with CTypeLabel: NOT DONE: " << getClassTypeLabel().c_str();
|
||||||
|
|
||||||
|
forEachProperty([&](const NtxString& key, const NtxVariant& value) {
|
||||||
|
cloned->setProperty(key, value);
|
||||||
|
});
|
||||||
|
for (size_t i = 0; i < getChildCount(); ++i)
|
||||||
|
cloned->addChild(getChild(i)->clone());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return cloned;
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// Command-Ausführung (delegiert an NtxUndoStack)
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
bool NtxNodeTree::execute(NtxCommandUPtr cmd)
|
||||||
|
{
|
||||||
|
if (!cmd || !cmd->canExecute())
|
||||||
|
return false;
|
||||||
|
m_undoStack.push(std::move(cmd));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxNodeTree::undo()
|
||||||
|
{
|
||||||
|
if (!canUndo())
|
||||||
|
return false;
|
||||||
|
m_undoStack.undo();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxNodeTree::redo()
|
||||||
|
{
|
||||||
|
if (!canRedo())
|
||||||
|
return false;
|
||||||
|
m_undoStack.redo();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxNodeTree::canUndo() const { return m_undoStack.canUndo(); }
|
||||||
|
bool NtxNodeTree::canRedo() const { return m_undoStack.canRedo(); }
|
||||||
|
NtxString NtxNodeTree::undoText() const { return m_undoStack.undoText(); }
|
||||||
|
NtxString NtxNodeTree::redoText() const { return m_undoStack.redoText(); }
|
||||||
|
|
||||||
|
void NtxNodeTree::setClean() { m_undoStack.setClean(); }
|
||||||
|
bool NtxNodeTree::isDirty() const { return !m_undoStack.isClean(); }
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// Einzel-Operationen
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
bool NtxNodeTree::addNode(NtxNodePtr parent, NtxNodePtr node, size_t index)
|
||||||
|
{
|
||||||
|
return execute(std::make_unique<NtxInsertNodeCmd>(
|
||||||
|
std::move(parent), std::move(node), index));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxNodeTree::deleteNode(NtxNodePtr node)
|
||||||
|
{
|
||||||
|
return execute(std::make_unique<NtxRemoveNodeCmd>(std::move(node)));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxNodeTree::moveNode(NtxNodePtr node, NtxNodePtr newParent, size_t newIndex)
|
||||||
|
{
|
||||||
|
// Move = Remove + Insert als Makro
|
||||||
|
auto macro = std::make_unique<NtxMacroCommand>("Move node");
|
||||||
|
macro->add(std::make_unique<NtxRemoveNodeCmd>(node));
|
||||||
|
macro->add(std::make_unique<NtxInsertNodeCmd>(
|
||||||
|
std::move(newParent), std::move(node), newIndex));
|
||||||
|
return execute(std::move(macro));
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// Listen-Operationen (Makro-Commands)
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
bool NtxNodeTree::addNodes(NtxNodePtr parent, const NtxNodeList& nodes, size_t index)
|
||||||
|
{
|
||||||
|
std::vector<NtxCommandUPtr> cmds;
|
||||||
|
cmds.reserve(nodes.size());
|
||||||
|
|
||||||
|
for (size_t i = 0; i < nodes.size(); ++i)
|
||||||
|
{
|
||||||
|
cmds.push_back(std::make_unique<NtxInsertNodeCmd>(
|
||||||
|
parent, nodes[i], index + i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return execute(NtxMacroCommand::create(
|
||||||
|
"Insert " + std::to_string(nodes.size()) + " nodes",
|
||||||
|
std::move(cmds)));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxNodeTree::deleteNodes(const NtxNodeList& nodes)
|
||||||
|
{
|
||||||
|
std::vector<NtxCommandUPtr> cmds;
|
||||||
|
cmds.reserve(nodes.size());
|
||||||
|
|
||||||
|
// Rückwärts löschen → Indizes bleiben stabil
|
||||||
|
for (auto it = nodes.rbegin(); it != nodes.rend(); ++it)
|
||||||
|
cmds.push_back(std::make_unique<NtxRemoveNodeCmd>(*it));
|
||||||
|
|
||||||
|
return execute(NtxMacroCommand::create(
|
||||||
|
"Delete " + std::to_string(nodes.size()) + " nodes",
|
||||||
|
std::move(cmds)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// Clipboard
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
void NtxNodeTree::copyNodes(const NtxNodeList& nodes)
|
||||||
|
{
|
||||||
|
m_clipboard.copyNodes(nodes);
|
||||||
|
m_isCutOperation = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxNodeTree::cutNodes(const NtxNodeList& nodes)
|
||||||
|
{
|
||||||
|
m_clipboard.copyNodes(nodes);
|
||||||
|
m_isCutOperation = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxNodeList NtxNodeTree::pasteNodes(NtxNodePtr parent, size_t index)
|
||||||
|
{
|
||||||
|
NtxNodeList pasted = m_clipboard.pasteNodes();
|
||||||
|
if (pasted.empty())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
if (m_isCutOperation)
|
||||||
|
{
|
||||||
|
// Cut+Paste = Remove originals + Insert clones (als Makro)
|
||||||
|
auto macro = std::make_unique<NtxMacroCommand>(
|
||||||
|
"Paste " + std::to_string(pasted.size()) + " nodes (cut)");
|
||||||
|
|
||||||
|
// 1. Originale entfernen (rückwärts für stabile Indizes)
|
||||||
|
const auto& entries = m_clipboard.getEntries();
|
||||||
|
for (auto it = entries.rbegin(); it != entries.rend(); ++it)
|
||||||
|
{
|
||||||
|
if (auto origParent = it->originalParent.lock())
|
||||||
|
{
|
||||||
|
if (it->originalPosition < origParent->getChildCount())
|
||||||
|
{
|
||||||
|
auto origNode = origParent->getChild(it->originalPosition);
|
||||||
|
if (origNode)
|
||||||
|
macro->add(std::make_unique<NtxRemoveNodeCmd>(origNode));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Clones einfügen
|
||||||
|
for (size_t i = 0; i < pasted.size(); ++i)
|
||||||
|
{
|
||||||
|
macro->add(std::make_unique<NtxInsertNodeCmd>(
|
||||||
|
parent, pasted[i], index + i));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!execute(std::move(macro)))
|
||||||
|
return {};
|
||||||
|
|
||||||
|
m_isCutOperation = false;
|
||||||
|
m_clipboard.clear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Copy+Paste = nur Insert
|
||||||
|
if (!addNodes(parent, pasted, index))
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return pasted;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxNodeTree::hasClipboard() const
|
||||||
|
{
|
||||||
|
return !m_clipboard.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxNodeTree::clearClipboard()
|
||||||
|
{
|
||||||
|
m_clipboard.clear();
|
||||||
|
m_isCutOperation = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
99
nodes/services/ntxnodetree.h
Normal file
99
nodes/services/ntxnodetree.h
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
#ifndef NTX_NODETREE_H
|
||||||
|
#define NTX_NODETREE_H
|
||||||
|
|
||||||
|
#include <ntxnode.h>
|
||||||
|
#include <ntxclipboard.h>
|
||||||
|
#include <ntxundostack.h>
|
||||||
|
#include <ntxnodecommands.h>
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Service-Schicht für Knoten-Operationen mit Undo/Redo.
|
||||||
|
*
|
||||||
|
* Ist selbst ein NtxINode (Composite-Pattern): Kann als Wurzel
|
||||||
|
* eines Teilbaums dienen und in andere NtxNodeTrees eingehängt werden.
|
||||||
|
*
|
||||||
|
* Bietet:
|
||||||
|
* - Command-basierte Baum-Manipulation (add/delete/move)
|
||||||
|
* - Undo/Redo via NtxUndoStack
|
||||||
|
* - Copy/Cut/Paste via NtxClipboard
|
||||||
|
* - Listen-Operationen via NtxMacroCommand
|
||||||
|
*/
|
||||||
|
class NtxNodeTree //: public NtxNode
|
||||||
|
{
|
||||||
|
friend class NtxNodeFactory;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//~NtxNodeTree() override = default;
|
||||||
|
|
||||||
|
NtxNodeTree(const NtxNodeTree&) = delete;
|
||||||
|
NtxNodeTree& operator=(const NtxNodeTree&) = delete;
|
||||||
|
|
||||||
|
NtxNodePtr clone() const;// override;
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// Command-Ausführung
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
/// Führt ein beliebiges Command aus (mit Undo-Support).
|
||||||
|
bool execute(NtxCommandUPtr cmd);
|
||||||
|
|
||||||
|
bool undo();
|
||||||
|
bool redo();
|
||||||
|
bool canUndo() const;
|
||||||
|
bool canRedo() const;
|
||||||
|
NtxString undoText() const;
|
||||||
|
NtxString redoText() const;
|
||||||
|
|
||||||
|
void setClean();
|
||||||
|
bool isDirty() const;
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// Einzel-Operationen (erzeugen intern Commands)
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
bool addNode(NtxNodePtr parent, NtxNodePtr node, size_t index);
|
||||||
|
bool deleteNode(NtxNodePtr node);
|
||||||
|
bool moveNode(NtxNodePtr node, NtxNodePtr newParent, size_t newIndex);
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// Listen-Operationen (erzeugen NtxMacroCommand)
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
bool addNodes(NtxNodePtr parent, const NtxNodeList& nodes, size_t index);
|
||||||
|
bool deleteNodes(const NtxNodeList& nodes);
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// Clipboard
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
void copyNodes(const NtxNodeList& nodes);
|
||||||
|
void cutNodes(const NtxNodeList& nodes);
|
||||||
|
NtxNodeList pasteNodes(NtxNodePtr parent, size_t index);
|
||||||
|
|
||||||
|
bool hasClipboard() const;
|
||||||
|
void clearClipboard();
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// Zugriff auf Interna
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
NtxUndoStack& undoStack() { return m_undoStack; }
|
||||||
|
const NtxUndoStack& undoStack() const { return m_undoStack; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
NtxNodeTree() = default;
|
||||||
|
explicit NtxNodeTree(NtxClassTypeId id);
|
||||||
|
|
||||||
|
NtxUndoStack m_undoStack;
|
||||||
|
NtxClipboard m_clipboard;
|
||||||
|
bool m_isCutOperation{false};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
|
|
||||||
|
#endif // NTX_NODETREE_H
|
||||||
209
nodes/services/ntxnodexml.cpp
Normal file
209
nodes/services/ntxnodexml.cpp
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#include "ntxnodexml.h"
|
||||||
|
#include <ntxnodefactory.h>
|
||||||
|
#include <pugixml.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream> // Add this include at the top of the file
|
||||||
|
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
// Rekursive Hilfsfunktion
|
||||||
|
static NtxNodePtr parseElementRecursive(const pugi::xml_node& xmlNode)
|
||||||
|
{
|
||||||
|
if (!xmlNode)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
// 1. Tag-Name als ID-String verwenden
|
||||||
|
NtxString tagName = xmlNode.name();
|
||||||
|
|
||||||
|
// Ignoriere spezielle Knotentypen (Kommentare, PCDATA/Text, etc.) wenn sie leer sind
|
||||||
|
// In diesem einfachen Beispiel behandeln wir nur Element-Knoten als echte NtxNodes.
|
||||||
|
if (xmlNode.type() != pugi::node_element)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
// 2. Erzeuge Knoten via Factory (nutzt implizit CTypeFactory für Mapping)
|
||||||
|
NtxNodePtr newNode = NtxNodeFactory::makeNode(tagName);
|
||||||
|
if (!newNode)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
// 3. Attribute übertragen
|
||||||
|
for (pugi::xml_attribute attr : xmlNode.attributes())
|
||||||
|
{
|
||||||
|
NtxString key = attr.name();
|
||||||
|
|
||||||
|
// Einfache Heuristik für Typen:
|
||||||
|
// PugiXML liefert strings. Wir könnten versuchen zu konvertieren oder alles als String lassen.
|
||||||
|
// Hier: Alles als String speichern, oder versuchen int/double zu parsen.
|
||||||
|
// Fürs erste: Speichern als String, Payload erlaubt mixed types.
|
||||||
|
newNode->set(key, NtxString(attr.value()));
|
||||||
|
|
||||||
|
/* Optional: Intelligentes Parsen
|
||||||
|
if (attr.as_int() != 0 || std::string(attr.value()) == "0")
|
||||||
|
newNode->set(key, attr.as_int());
|
||||||
|
else
|
||||||
|
newNode->set(key, NtxString(attr.value()));
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Kinder rekursiv verarbeiten
|
||||||
|
for (pugi::xml_node child : xmlNode.children())
|
||||||
|
{
|
||||||
|
NtxNodePtr childNode = parseElementRecursive(child);
|
||||||
|
if (childNode)
|
||||||
|
{
|
||||||
|
newNode->addChild(childNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxNodePtr NtxNodeXml::loadFromFile(const std::string& filename)
|
||||||
|
{
|
||||||
|
pugi::xml_document doc;
|
||||||
|
pugi::xml_parse_result result = doc.load_file(filename.c_str());
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
std::cerr << "XML Load Error: " << result.description() << " in " << filename << std::endl;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wir nehmen den ersten Root-Knoten (das Wurzelelement)
|
||||||
|
// doc.document_element() gibt das erste Kind vom Typ Element zurück (ignoriert PI, DOCTYPE etc.)
|
||||||
|
return parseElementRecursive(doc.document_element());
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxNodePtr NtxNodeXml::loadFromString(const std::string& xmlContent)
|
||||||
|
{
|
||||||
|
pugi::xml_document doc;
|
||||||
|
pugi::xml_parse_result result = doc.load_string(xmlContent.c_str());
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
std::cerr << "XML Parse Error: " << result.description() << std::endl;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parseElementRecursive(doc.document_element());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rekursive Hilfsfunktion zum Serialisieren
|
||||||
|
static void serializeNodeRecursive(const NtxNodeCPtr& node, pugi::xml_node& xmlNode)
|
||||||
|
{
|
||||||
|
if (!node)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 1. Tag-Name aus CType-Label holen
|
||||||
|
NtxString tagName = node->getClassTypeLabel();
|
||||||
|
pugi::xml_node childElement = xmlNode.append_child(tagName.c_str());
|
||||||
|
|
||||||
|
// 2. Alle Attribute aus dem Payload schreiben
|
||||||
|
node->forEachProperty([&childElement](const NtxString& key, const NtxVariant& value)
|
||||||
|
{
|
||||||
|
// Konvertiere NtxVariant zu String und setze als XML-Attribut
|
||||||
|
std::visit([&childElement, &key](auto&& arg)
|
||||||
|
{
|
||||||
|
using T = std::decay_t<decltype(arg)>;
|
||||||
|
|
||||||
|
if constexpr (std::is_same_v<T, std::monostate>)
|
||||||
|
{
|
||||||
|
// Überspringe leere Werte
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<T, NtxString>)
|
||||||
|
{
|
||||||
|
childElement.append_attribute(key.c_str()).set_value(arg.c_str());
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<T, int>)
|
||||||
|
{
|
||||||
|
childElement.append_attribute(key.c_str()).set_value(arg);
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<T, double>)
|
||||||
|
{
|
||||||
|
childElement.append_attribute(key.c_str()).set_value(arg);
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<T, bool>)
|
||||||
|
{
|
||||||
|
childElement.append_attribute(key.c_str()).set_value(arg);
|
||||||
|
}
|
||||||
|
}, value);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 3. Kinder rekursiv verarbeiten
|
||||||
|
for (size_t i = 0; i < node->getChildCount(); ++i)
|
||||||
|
{
|
||||||
|
NtxNodeCPtr child = node->getChild(i);
|
||||||
|
if (child)
|
||||||
|
{
|
||||||
|
serializeNodeRecursive(child, childElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxNodeXml::saveToFile(const NtxNodePtr& node, const std::string& filename)
|
||||||
|
{
|
||||||
|
return saveToFile(std::const_pointer_cast<const NtxINode>(node), filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxNodeXml::saveToFile(const NtxNodeCPtr& node, const std::string& filename)
|
||||||
|
{
|
||||||
|
if (!node)
|
||||||
|
{
|
||||||
|
std::cerr << "Cannot save null node to file: " << filename << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pugi::xml_document doc;
|
||||||
|
|
||||||
|
// XML-Deklaration hinzufügen
|
||||||
|
pugi::xml_node declaration = doc.prepend_child(pugi::node_declaration);
|
||||||
|
declaration.append_attribute("version") = "1.0";
|
||||||
|
declaration.append_attribute("encoding") = "UTF-8";
|
||||||
|
|
||||||
|
// Root-Node serialisieren
|
||||||
|
serializeNodeRecursive(node, doc);
|
||||||
|
|
||||||
|
// In Datei speichern mit Formatierung
|
||||||
|
bool success = doc.save_file(filename.c_str(), " ", pugi::format_default, pugi::encoding_utf8);
|
||||||
|
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
std::cerr << "Failed to save XML to file: " << filename << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string NtxNodeXml::saveToString(const NtxNodePtr& node)
|
||||||
|
{
|
||||||
|
return saveToString(std::const_pointer_cast<const NtxINode>(node));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string NtxNodeXml::saveToString(const NtxNodeCPtr& node)
|
||||||
|
{
|
||||||
|
if (!node)
|
||||||
|
{
|
||||||
|
std::cerr << "Cannot serialize null node to string" << std::endl;
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
pugi::xml_document doc;
|
||||||
|
|
||||||
|
// XML-Deklaration hinzufügen
|
||||||
|
pugi::xml_node declaration = doc.prepend_child(pugi::node_declaration);
|
||||||
|
declaration.append_attribute("version") = "1.0";
|
||||||
|
declaration.append_attribute("encoding") = "UTF-8";
|
||||||
|
|
||||||
|
// Root-Node serialisieren
|
||||||
|
serializeNodeRecursive(node, doc);
|
||||||
|
|
||||||
|
// In String konvertieren
|
||||||
|
std::ostringstream oss;
|
||||||
|
doc.save(oss, " ", pugi::format_default, pugi::encoding_utf8);
|
||||||
|
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
27
nodes/services/ntxnodexml.h
Normal file
27
nodes/services/ntxnodexml.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#ifndef NTX_NODEXML_H
|
||||||
|
#define NTX_NODEXML_H
|
||||||
|
|
||||||
|
#include <ntxinode.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
class NtxNodeXml
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
static NtxNodePtr loadFromFile(const std::string& filename);
|
||||||
|
static NtxNodePtr loadFromString(const std::string& xmlContent);
|
||||||
|
|
||||||
|
// Methoden zum Speichern
|
||||||
|
static bool saveToFile(const NtxNodePtr& node, const std::string& filename);
|
||||||
|
static bool saveToFile(const NtxNodeCPtr& node, const std::string& filename);
|
||||||
|
|
||||||
|
static std::string saveToString(const NtxNodePtr& node);
|
||||||
|
static std::string saveToString(const NtxNodeCPtr& node);
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // NTX_NODEXML_H
|
||||||
156
nodes/services/ntxundostack.cpp
Normal file
156
nodes/services/ntxundostack.cpp
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
#include <ntxundostack.h>
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
|
||||||
|
NtxUndoStack::NtxUndoStack()
|
||||||
|
: m_index(0)
|
||||||
|
, m_cleanIndex(0)
|
||||||
|
, m_undoLimit(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxUndoStack::push(NtxCommandUPtr command)
|
||||||
|
{
|
||||||
|
if (!command)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!command->canExecute())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!command->execute())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_index < static_cast<int>(m_commands.size()))
|
||||||
|
{
|
||||||
|
m_commands.erase(m_commands.begin() + m_index, m_commands.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
m_commands.push_back(std::move(command));
|
||||||
|
m_index++;
|
||||||
|
|
||||||
|
if (m_cleanIndex > m_index)
|
||||||
|
m_cleanIndex = -1;
|
||||||
|
|
||||||
|
checkUndoLimit();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxUndoStack::canUndo() const
|
||||||
|
{
|
||||||
|
return m_index > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxUndoStack::canRedo() const
|
||||||
|
{
|
||||||
|
return m_index < static_cast<int>(m_commands.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxUndoStack::undo()
|
||||||
|
{
|
||||||
|
if (!canUndo())
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_index--;
|
||||||
|
|
||||||
|
if (m_commands[m_index]->canUndo())
|
||||||
|
{
|
||||||
|
m_commands[m_index]->undo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxUndoStack::redo()
|
||||||
|
{
|
||||||
|
if (!canRedo())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_commands[m_index]->canExecute())
|
||||||
|
{
|
||||||
|
m_commands[m_index]->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int NtxUndoStack::index() const
|
||||||
|
{
|
||||||
|
return m_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
int NtxUndoStack::count() const
|
||||||
|
{
|
||||||
|
return static_cast<int>(m_commands.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxString NtxUndoStack::undoText() const
|
||||||
|
{
|
||||||
|
if (!canUndo())
|
||||||
|
return NtxString();
|
||||||
|
|
||||||
|
return m_commands[m_index - 1]->getDescription();
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxString NtxUndoStack::redoText() const
|
||||||
|
{
|
||||||
|
if (!canRedo())
|
||||||
|
return NtxString();
|
||||||
|
|
||||||
|
return m_commands[m_index]->getDescription();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxUndoStack::clear()
|
||||||
|
{
|
||||||
|
m_commands.clear();
|
||||||
|
m_index = 0;
|
||||||
|
m_cleanIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxUndoStack::setClean()
|
||||||
|
{
|
||||||
|
m_cleanIndex = m_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxUndoStack::isClean() const
|
||||||
|
{
|
||||||
|
return m_cleanIndex == m_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxUndoStack::setUndoLimit(int limit)
|
||||||
|
{
|
||||||
|
m_undoLimit = limit;
|
||||||
|
checkUndoLimit();
|
||||||
|
}
|
||||||
|
|
||||||
|
int NtxUndoStack::undoLimit() const
|
||||||
|
{
|
||||||
|
return m_undoLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NtxICommand* NtxUndoStack::command(int index) const
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= static_cast<int>(m_commands.size()))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return m_commands[index].get();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxUndoStack::checkUndoLimit()
|
||||||
|
{
|
||||||
|
if (m_undoLimit <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int deleteCount = m_index - m_undoLimit;
|
||||||
|
if (deleteCount <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_commands.erase(m_commands.begin(), m_commands.begin() + deleteCount);
|
||||||
|
m_index -= deleteCount;
|
||||||
|
|
||||||
|
if (m_cleanIndex != -1)
|
||||||
|
{
|
||||||
|
m_cleanIndex -= deleteCount;
|
||||||
|
if (m_cleanIndex < 0)
|
||||||
|
m_cleanIndex = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
56
nodes/services/ntxundostack.h
Normal file
56
nodes/services/ntxundostack.h
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
#ifndef NTX_UNDO_STACK_H
|
||||||
|
#define NTX_UNDO_STACK_H
|
||||||
|
|
||||||
|
#include <ntxicommand.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
|
||||||
|
class NtxUndoStack
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
NtxUndoStack();
|
||||||
|
~NtxUndoStack() = default;
|
||||||
|
|
||||||
|
NtxUndoStack(const NtxUndoStack&) = delete;
|
||||||
|
NtxUndoStack& operator=(const NtxUndoStack&) = delete;
|
||||||
|
|
||||||
|
void push(NtxCommandUPtr command);
|
||||||
|
|
||||||
|
bool canUndo() const;
|
||||||
|
bool canRedo() const;
|
||||||
|
|
||||||
|
void undo();
|
||||||
|
void redo();
|
||||||
|
|
||||||
|
int index() const;
|
||||||
|
int count() const;
|
||||||
|
|
||||||
|
NtxString undoText() const;
|
||||||
|
NtxString redoText() const;
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
void setClean();
|
||||||
|
bool isClean() const;
|
||||||
|
|
||||||
|
void setUndoLimit(int limit);
|
||||||
|
int undoLimit() const;
|
||||||
|
|
||||||
|
const NtxICommand* command(int index) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::vector<NtxCommandUPtr> m_commands;
|
||||||
|
int m_index;
|
||||||
|
int m_cleanIndex;
|
||||||
|
int m_undoLimit;
|
||||||
|
|
||||||
|
void checkUndoLimit();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
|
|
||||||
|
#endif // NTX_UNDO_STACK_H
|
||||||
88
nodes/util/ntxmapindex.cpp
Normal file
88
nodes/util/ntxmapindex.cpp
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
#include <ntxmapindex.h>
|
||||||
|
#include <ranges> // Zwingend erforderlich für std::views und std::ranges::to
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
|
||||||
|
// --- Lookup ---
|
||||||
|
|
||||||
|
std::optional<size_t> NtxMapIndex::indexOf(const std::string& key) const noexcept
|
||||||
|
{
|
||||||
|
auto it = m_keyToIndex.find(key);
|
||||||
|
if (it != m_keyToIndex.end())
|
||||||
|
return it->second;
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxMapIndex::containsKey(const std::string& key) const noexcept
|
||||||
|
{
|
||||||
|
return m_keyToIndex.contains(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Modification ---
|
||||||
|
|
||||||
|
void NtxMapIndex::addKey(const std::string& key, size_t index)
|
||||||
|
{
|
||||||
|
m_keyToIndex[key] = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxMapIndex::removeAt(size_t index)
|
||||||
|
{
|
||||||
|
auto it = m_keyToIndex.begin();
|
||||||
|
while (it != m_keyToIndex.end())
|
||||||
|
{
|
||||||
|
if (it->second == index)
|
||||||
|
it = m_keyToIndex.erase(it);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (it->second > index)
|
||||||
|
it->second--;
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxMapIndex::removeKey(const std::string& key)
|
||||||
|
{
|
||||||
|
return m_keyToIndex.erase(key) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxMapIndex::replaceKey(const std::string& oldKey, const std::string& newKey)
|
||||||
|
{
|
||||||
|
auto it = m_keyToIndex.find(oldKey);
|
||||||
|
if (it == m_keyToIndex.end() || oldKey == newKey)
|
||||||
|
return false;
|
||||||
|
if (m_keyToIndex.contains(newKey))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
size_t idx = it->second;
|
||||||
|
m_keyToIndex.erase(it);
|
||||||
|
m_keyToIndex[newKey] = idx;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxMapIndex::addAlias(const std::string& existingKey, const std::string& alias)
|
||||||
|
{
|
||||||
|
auto idx = indexOf(existingKey);
|
||||||
|
if (!idx || containsKey(alias))
|
||||||
|
return false;
|
||||||
|
m_keyToIndex[alias] = *idx;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t NtxMapIndex::size() const noexcept
|
||||||
|
{
|
||||||
|
return m_keyToIndex.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NtxMapIndex::empty() const noexcept
|
||||||
|
{
|
||||||
|
return m_keyToIndex.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NtxMapIndex::clear() noexcept
|
||||||
|
{
|
||||||
|
m_keyToIndex.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
61
nodes/util/ntxmapindex.h
Normal file
61
nodes/util/ntxmapindex.h
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
#ifndef NTX_MAPINDEX_H
|
||||||
|
#define NTX_MAPINDEX_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <optional>
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Bidirektionaler Index: String-Key → size_t Position.
|
||||||
|
*
|
||||||
|
* Verwendet Komposition statt Vererbung.
|
||||||
|
* Key → Index: O(1) via unordered_map.
|
||||||
|
*/
|
||||||
|
class NtxMapIndex
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
NtxMapIndex() = default;
|
||||||
|
|
||||||
|
// --- Lookup ---
|
||||||
|
std::optional<size_t> indexOf(const std::string& key) const noexcept;
|
||||||
|
bool containsKey(const std::string& key) const noexcept;
|
||||||
|
|
||||||
|
// --- Iteration ---
|
||||||
|
|
||||||
|
/// Iteriert über alle Key→Index Paare.
|
||||||
|
/// Template muss im Header bleiben.
|
||||||
|
template <typename Fn>
|
||||||
|
void forEachKey(Fn&& fn) const
|
||||||
|
{
|
||||||
|
for (const auto& [key, idx] : m_keyToIndex)
|
||||||
|
fn(key, idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Modification ---
|
||||||
|
void addKey(const std::string& key, size_t index);
|
||||||
|
void removeAt(size_t index);
|
||||||
|
bool removeKey(const std::string& key);
|
||||||
|
bool replaceKey(const std::string& oldKey, const std::string& newKey);
|
||||||
|
bool addAlias(const std::string& existingKey, const std::string& alias);
|
||||||
|
|
||||||
|
size_t size() const noexcept;
|
||||||
|
bool empty() const noexcept;
|
||||||
|
void clear() noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::unordered_map<std::string, size_t> m_keyToIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
using NtxMapIndexPtr = std::shared_ptr<NtxMapIndex>;
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
|
|
||||||
|
#endif // NTX_MAPINDEX_H
|
||||||
177
nodes/util/ntxmaptor.h
Normal file
177
nodes/util/ntxmaptor.h
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
#ifndef NTX_MAPTOR_H
|
||||||
|
#define NTX_MAPTOR_H
|
||||||
|
|
||||||
|
#include "ntxmapindex.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <optional>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <memory>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace ntx
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generischer Maptor (Vector + Map), adaptiert an das NtxIPayload-Interface.
|
||||||
|
*
|
||||||
|
* Entfernt die STL-Container-Schnittstelle (push_back, begin, end, etc.) zugunsten
|
||||||
|
* der expliziten Payload-Methodik (setProperty, getProperty, etc.).
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
class NtxMaptor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
using NtxMapIndexPtr = std::shared_ptr<NtxMapIndex>;
|
||||||
|
|
||||||
|
// Zugriff auf Iteratoren für Range-Based Loops (via valuesBegin/End)
|
||||||
|
using iterator = typename std::vector<T>::iterator;
|
||||||
|
using const_iterator = typename std::vector<T>::const_iterator;
|
||||||
|
|
||||||
|
// --- Konstruktoren ---
|
||||||
|
|
||||||
|
NtxMaptor()
|
||||||
|
: m_index(std::make_shared<NtxMapIndex>())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit NtxMaptor(const NtxMapIndexPtr& index)
|
||||||
|
{
|
||||||
|
if (!index)
|
||||||
|
throw std::invalid_argument("NtxMaptor: index must not be null");
|
||||||
|
m_index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
NtxMaptor(const NtxMaptor&) = default;
|
||||||
|
NtxMaptor& operator=(const NtxMaptor&) = default;
|
||||||
|
NtxMaptor(NtxMaptor&&) noexcept = default;
|
||||||
|
NtxMaptor& operator=(NtxMaptor&&) noexcept = default;
|
||||||
|
|
||||||
|
virtual ~NtxMaptor() = default;
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// NtxIPayload Interface-Adaption
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
// --- Kapazität ---
|
||||||
|
|
||||||
|
[[nodiscard]] size_t getPropertyCount() const noexcept
|
||||||
|
{
|
||||||
|
return m_data.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearProperties()
|
||||||
|
{
|
||||||
|
m_data.clear();
|
||||||
|
m_index->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Key-basierter Zugriff ---
|
||||||
|
|
||||||
|
bool hasProperty(const std::string& key) const
|
||||||
|
{
|
||||||
|
return m_index->containsKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Setzt oder fügt einen Wert hinzu (Upsert).
|
||||||
|
* Wenn der Key existiert, wird der Wert überschrieben.
|
||||||
|
* Wenn nicht, wird er angehängt.
|
||||||
|
*/
|
||||||
|
void setProperty(const std::string& key, const T& value)
|
||||||
|
{
|
||||||
|
auto idx = m_index->indexOf(key);
|
||||||
|
if (idx)
|
||||||
|
{
|
||||||
|
m_data[*idx] = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_index->addKey(key, m_data.size());
|
||||||
|
m_data.push_back(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// "Deducing this" für const/non-const getProperty(key)
|
||||||
|
template <typename Self>
|
||||||
|
auto&& getProperty(this Self&& self, const std::string& key)
|
||||||
|
{
|
||||||
|
auto idx = self.m_index->indexOf(key);
|
||||||
|
if (!idx)
|
||||||
|
throw std::out_of_range("NtxMaptor: Key not found: " + key);
|
||||||
|
return std::forward<Self>(self).m_data[*idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeProperty(const std::string& key)
|
||||||
|
{
|
||||||
|
auto idx = m_index->indexOf(key);
|
||||||
|
if (!idx)
|
||||||
|
return;
|
||||||
|
|
||||||
|
size_t index = *idx;
|
||||||
|
// Index entfernen und nachfolgende Indizes im Index-Objekt korrigieren
|
||||||
|
m_index->removeAt(index);
|
||||||
|
// Daten aus Vektor entfernen
|
||||||
|
m_data.erase(m_data.begin() + static_cast<std::ptrdiff_t>(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Index-basierter Zugriff ---
|
||||||
|
|
||||||
|
bool hasProperty(size_t index) const
|
||||||
|
{
|
||||||
|
return index < m_data.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setProperty(size_t index, const T& value)
|
||||||
|
{
|
||||||
|
if (index >= m_data.size())
|
||||||
|
{
|
||||||
|
throw std::out_of_range("NtxMaptor: Index out of range");
|
||||||
|
}
|
||||||
|
m_data[index] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// "Deducing this" für const/non-const getProperty(index)
|
||||||
|
template <typename Self>
|
||||||
|
auto&& getProperty(this Self&& self, size_t index)
|
||||||
|
{
|
||||||
|
return std::forward<Self>(self).m_data.at(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Iteratoren (NtxIPayload Style) ---
|
||||||
|
|
||||||
|
// Erlaubt das Iterieren über die internen Werte
|
||||||
|
template <typename Self>
|
||||||
|
auto begin(this Self&& self) { return std::forward<Self>(self).m_data.begin(); }
|
||||||
|
|
||||||
|
template <typename Self>
|
||||||
|
auto end(this Self&& self) { return std::forward<Self>(self).m_data.end(); }
|
||||||
|
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// Erweiterte Index-Funktionen (Alias, Replace)
|
||||||
|
// Diese bleiben erhalten, da sie spezifische NtxMapIndex Features sind
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
bool replaceKey(const std::string& oldKey, const std::string& newKey)
|
||||||
|
{
|
||||||
|
return m_index->replaceKey(oldKey, newKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool addAlias(const std::string& key, const std::string& alias)
|
||||||
|
{
|
||||||
|
return m_index->addAlias(key, alias);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::vector<T> m_data;
|
||||||
|
NtxMapIndexPtr m_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ntx
|
||||||
|
|
||||||
|
#endif // NTX_MAPTOR_H
|
||||||
394
nodes/xml/ntc_dummy.xml
Normal file
394
nodes/xml/ntc_dummy.xml
Normal file
@@ -0,0 +1,394 @@
|
|||||||
|
<TestDataList Fitze="fatze">
|
||||||
|
<TestData Name="NT600-Testprojekt_min">
|
||||||
|
<TestDataBase/>
|
||||||
|
<TPNamesData>
|
||||||
|
<TPNames Name="NT600-Testprojekt_min">
|
||||||
|
<LogicalTpCount>4096</LogicalTpCount>
|
||||||
|
</TPNames>
|
||||||
|
</TPNamesData>
|
||||||
|
<ParaSetList>
|
||||||
|
<ParaSet Hardware="MT40" MeasType="Continuity">
|
||||||
|
<MeasPara>
|
||||||
|
<ParaValue Type="RLow" Value="100"/>
|
||||||
|
<ParaValue Type="RHigh" Value="20000"/>
|
||||||
|
<ParaValue Type="U" Value="20"/>
|
||||||
|
<ParaValue Type="I" Value="0.1"/>
|
||||||
|
<ParaValue Type="TDelay" Value="0.005"/>
|
||||||
|
</MeasPara>
|
||||||
|
</ParaSet>
|
||||||
|
<ParaSet Hardware="MT40" MeasType="Short">
|
||||||
|
<MeasPara>
|
||||||
|
<ParaValue Type="RLow" Value="100"/>
|
||||||
|
<ParaValue Type="RHigh" Value="20000"/>
|
||||||
|
<ParaValue Type="U" Value="20"/>
|
||||||
|
<ParaValue Type="I" Value="0.1"/>
|
||||||
|
<ParaValue Type="TDelay" Value="0.005"/>
|
||||||
|
</MeasPara>
|
||||||
|
<MeasControl>
|
||||||
|
<ParaValue Type="ModeShortTest" Value="Fast"/>
|
||||||
|
<ParaValue Type="ModeGroupTest" Value="GG"/>
|
||||||
|
<ParaValue Type="ModeGroupFaultLocation" Value="None"/>
|
||||||
|
<ParaValue Type="ModeClassicFaultLocation" Value="All"/>
|
||||||
|
</MeasControl>
|
||||||
|
</ParaSet>
|
||||||
|
<ParaSet Hardware="MT1500DC" MeasType="Insulation">
|
||||||
|
<MeasPara>
|
||||||
|
<ParaValue Type="RHigh" Value="1e+006"/>
|
||||||
|
<ParaValue Type="U" Value="100"/>
|
||||||
|
<ParaValue Type="TDwell" Value="0"/>
|
||||||
|
<ParaValue Type="TRise" Value="0"/>
|
||||||
|
<ParaValue Type="IsoVariation" Value="0"/>
|
||||||
|
</MeasPara>
|
||||||
|
<MeasControl>
|
||||||
|
<ParaValue Type="ModeISO" Value="ISO"/>
|
||||||
|
<ParaValue Type="ModeShortTest" Value="NormalFast"/>
|
||||||
|
<ParaValue Type="ModeGroupTest" Value="GG"/>
|
||||||
|
<ParaValue Type="ModeGroupFaultLocation" Value="None"/>
|
||||||
|
<ParaValue Type="ShortenMatrixAB" Value="false"/>
|
||||||
|
<ParaValue Type="ModeClassicFaultLocation" Value="All"/>
|
||||||
|
</MeasControl>
|
||||||
|
</ParaSet>
|
||||||
|
<ParaSet Hardware="MT2000" MeasType="BreakdownDC">
|
||||||
|
<MeasPara>
|
||||||
|
<ParaValue Type="U" Value="100"/>
|
||||||
|
<ParaValue Type="TDwell" Value="1"/>
|
||||||
|
<ParaValue Type="TRise" Value="0.02"/>
|
||||||
|
<ParaValue Type="TFall" Value="0"/>
|
||||||
|
<ParaValue Type="Imax" Value="0"/>
|
||||||
|
</MeasPara>
|
||||||
|
<MeasControl>
|
||||||
|
|
||||||
|
<ParaValue Type="ModeShortTest" Value="NormalExact"/>
|
||||||
|
<ParaValue Type="ModeGroupTest" Value="GG"/>
|
||||||
|
<ParaValue Type="ModeGroupFaultLocation" Value="None"/>
|
||||||
|
<ParaValue Type="ShortenMatrixAB" Value="false"/>
|
||||||
|
<ParaValue Type="ModeClassicFaultLocation" Value="All"/>
|
||||||
|
</MeasControl>
|
||||||
|
</ParaSet>
|
||||||
|
<ParaSet Hardware="MT40" MeasType="Detection">
|
||||||
|
<MeasPara>
|
||||||
|
<ParaValue Type="RLow" Value="100"/>
|
||||||
|
<ParaValue Type="RHigh" Value="20000"/>
|
||||||
|
<ParaValue Type="U" Value="20"/>
|
||||||
|
<ParaValue Type="I" Value="0.1"/>
|
||||||
|
<ParaValue Type="TDelay" Value="0.005"/>
|
||||||
|
</MeasPara>
|
||||||
|
<MeasControl>
|
||||||
|
<ParaValue Type="FastCompOpenTest" Value="false"/>
|
||||||
|
</MeasControl>
|
||||||
|
</ParaSet>
|
||||||
|
</ParaSetList>
|
||||||
|
<SegmentList>
|
||||||
|
<Segment Name="Segment 1" Enabled="Yes">
|
||||||
|
<SegmentMessage Text="" ConfirmationType="1" DisplayTime="1" Image=""/>
|
||||||
|
<QueryList>
|
||||||
|
<Query QueryMessage="TODO: to complete" QueryType="-1" FailedText=""/>
|
||||||
|
</QueryList>
|
||||||
|
<TestControls>
|
||||||
|
<General>
|
||||||
|
<UseSegmentParameters>On</UseSegmentParameters>
|
||||||
|
</General>
|
||||||
|
<EnabledTestSteps>
|
||||||
|
<Continuity>On</Continuity>
|
||||||
|
<Short>On</Short>
|
||||||
|
<Insulation>Off</Insulation>
|
||||||
|
<Breakdown>Off</Breakdown>
|
||||||
|
<Detection>Off</Detection>
|
||||||
|
<Component>On</Component>
|
||||||
|
</EnabledTestSteps>
|
||||||
|
<AdvancedSettings>
|
||||||
|
<Monitoring>Default</Monitoring>
|
||||||
|
<LooseContact>Default</LooseContact>
|
||||||
|
<StimulusBeforeMessage>Default</StimulusBeforeMessage>
|
||||||
|
<UseStimulusCards>Default</UseStimulusCards>
|
||||||
|
<ErrorStopComponent>Default</ErrorStopComponent>
|
||||||
|
<OptimizedLinkTest>Default</OptimizedLinkTest>
|
||||||
|
<AdvancedSwitchOpenTest>Default</AdvancedSwitchOpenTest>
|
||||||
|
<SegmentRetest>Default</SegmentRetest>
|
||||||
|
</AdvancedSettings>
|
||||||
|
</TestControls>
|
||||||
|
<ParaSetList>
|
||||||
|
<ParaSet Hardware="MT20" MeasType="Continuity">
|
||||||
|
<MeasPara>
|
||||||
|
<ParaValue Type="RLow" Value="100"/>
|
||||||
|
<ParaValue Type="RHigh" Value="20000"/>
|
||||||
|
<ParaValue Type="U" Value="12"/>
|
||||||
|
<ParaValue Type="I" Value="0.1"/>
|
||||||
|
<ParaValue Type="TDelay" Value="0.005"/>
|
||||||
|
</MeasPara>
|
||||||
|
<MeasControl>
|
||||||
|
<ParaValue Type="ModeMeasBidir" Value="true"/>
|
||||||
|
<ParaValue Type="ModeGroupTest" Value="GG"/>
|
||||||
|
<ParaValue Type="ModeClassicFaultLocation" Value="All"/>
|
||||||
|
<ParaValue Type="PreciseMode" Value="false" PleaseFindMe="treasure"/>
|
||||||
|
</MeasControl>
|
||||||
|
</ParaSet>
|
||||||
|
<ParaSet Hardware="MT20" MeasType="Short">
|
||||||
|
<MeasPara>
|
||||||
|
<ParaValue Type="RLow" Value="100"/>
|
||||||
|
<ParaValue Type="RHigh" Value="20000"/>
|
||||||
|
<ParaValue Type="U" Value="12"/>
|
||||||
|
<ParaValue Type="I" Value="0.1"/>
|
||||||
|
<ParaValue Type="TDelay" Value="0.005"/>
|
||||||
|
</MeasPara>
|
||||||
|
<MeasControl>
|
||||||
|
<ParaValue Type="ModeShortTest" Value="Fast"/>
|
||||||
|
<ParaValue Type="ModeMeasBidir" Value="true"/>
|
||||||
|
<ParaValue Type="ModeGroupTest" Value="GG"/>
|
||||||
|
<ParaValue Type="ModeGroupFaultLocation" Value="None"/>
|
||||||
|
<ParaValue Type="ModeClassicFaultLocation" Value="All"/>
|
||||||
|
<ParaValue Type="PreciseMode" Value="false"/>
|
||||||
|
</MeasControl>
|
||||||
|
</ParaSet>
|
||||||
|
<ParaSet Hardware="MT1500DC" MeasType="Insulation">
|
||||||
|
<MeasPara>
|
||||||
|
<ParaValue Type="RHigh" Value="1e+006"/>
|
||||||
|
<ParaValue Type="U" Value="100"/>
|
||||||
|
<ParaValue Type="TDwell" Value="0"/>
|
||||||
|
<ParaValue Type="TRise" Value="0"/>
|
||||||
|
<ParaValue Type="IsoVariation" Value="0"/>
|
||||||
|
</MeasPara>
|
||||||
|
<MeasControl>
|
||||||
|
<ParaValue Type="ModeISO" Value="ISO"/>
|
||||||
|
<ParaValue Type="ModeShortTest" Value="NormalFast"/>
|
||||||
|
<ParaValue Type="ModeGroupTest" Value="GG"/>
|
||||||
|
<ParaValue Type="ModeGroupFaultLocation" Value="None"/>
|
||||||
|
<ParaValue Type="ShortenMatrixAB" Value="false"/>
|
||||||
|
<ParaValue Type="ModeClassicFaultLocation" Value="All"/>
|
||||||
|
</MeasControl>
|
||||||
|
</ParaSet>
|
||||||
|
<ParaSet Hardware="MT2000" MeasType="BreakdownDC">
|
||||||
|
<MeasPara>
|
||||||
|
<ParaValue Type="U" Value="100"/>
|
||||||
|
<ParaValue Type="TDwell" Value="1"/>
|
||||||
|
<ParaValue Type="TRise" Value="0.02"/>
|
||||||
|
<ParaValue Type="TFall" Value="0"/>
|
||||||
|
<ParaValue Type="Imax" Value="0"/>
|
||||||
|
</MeasPara>
|
||||||
|
<MeasControl>
|
||||||
|
|
||||||
|
<ParaValue Type="ModeShortTest" Value="NormalExact"/>
|
||||||
|
<ParaValue Type="ModeGroupTest" Value="GG"/>
|
||||||
|
<ParaValue Type="ModeGroupFaultLocation" Value="None"/>
|
||||||
|
<ParaValue Type="ShortenMatrixAB" Value="false"/>
|
||||||
|
<ParaValue Type="ModeClassicFaultLocation" Value="All"/>
|
||||||
|
</MeasControl>
|
||||||
|
</ParaSet>
|
||||||
|
<ParaSet Hardware="MT40" MeasType="Detection">
|
||||||
|
<MeasPara>
|
||||||
|
<ParaValue Type="RLow" Value="100"/>
|
||||||
|
<ParaValue Type="RHigh" Value="20000"/>
|
||||||
|
<ParaValue Type="U" Value="20"/>
|
||||||
|
<ParaValue Type="I" Value="0.1"/>
|
||||||
|
<ParaValue Type="TDelay" Value="0.005"/>
|
||||||
|
</MeasPara>
|
||||||
|
<MeasControl>
|
||||||
|
<ParaValue Type="FastCompOpenTest" Value="false"/>
|
||||||
|
</MeasControl>
|
||||||
|
</ParaSet>
|
||||||
|
</ParaSetList>
|
||||||
|
<NetList>
|
||||||
|
<Net Name="Net 1">
|
||||||
|
<SubNet Name="*Sub 1">
|
||||||
|
<TestPoint>1</TestPoint>
|
||||||
|
<TestPoint>22</TestPoint>
|
||||||
|
</SubNet>
|
||||||
|
</Net>
|
||||||
|
<Net Name="Net 2">
|
||||||
|
<SubNet Name="*Sub 1">
|
||||||
|
<TestPoint>2</TestPoint>
|
||||||
|
<TestPoint>29</TestPoint>
|
||||||
|
</SubNet>
|
||||||
|
</Net>
|
||||||
|
<Net Name="Net 3">
|
||||||
|
<SubNet Name="*Sub 1">
|
||||||
|
<TestPoint>3</TestPoint>
|
||||||
|
<TestPoint>26</TestPoint>
|
||||||
|
</SubNet>
|
||||||
|
</Net>
|
||||||
|
<Net Name="Net 4">
|
||||||
|
<SubNet Name="*Sub 1">
|
||||||
|
<TestPoint>4</TestPoint>
|
||||||
|
<TestPoint>27</TestPoint>
|
||||||
|
</SubNet>
|
||||||
|
</Net>
|
||||||
|
<Net Name="Net 5">
|
||||||
|
<SubNet Name="*Sub 1">
|
||||||
|
<TestPoint>5</TestPoint>
|
||||||
|
<TestPoint>28</TestPoint>
|
||||||
|
</SubNet>
|
||||||
|
</Net>
|
||||||
|
<Net Name="Net 6">
|
||||||
|
<SubNet Name="*Sub 1">
|
||||||
|
<TestPoint>6</TestPoint>
|
||||||
|
<TestPoint>21</TestPoint>
|
||||||
|
</SubNet>
|
||||||
|
</Net>
|
||||||
|
<Net Name="Net 7">
|
||||||
|
<SubNet Name="*Sub 1">
|
||||||
|
<TestPoint>7</TestPoint>
|
||||||
|
<TestPoint>30</TestPoint>
|
||||||
|
</SubNet>
|
||||||
|
</Net>
|
||||||
|
<Net Name="Net 8">
|
||||||
|
<SubNet Name="*Sub 1">
|
||||||
|
<TestPoint>8</TestPoint>
|
||||||
|
<TestPoint>31</TestPoint>
|
||||||
|
</SubNet>
|
||||||
|
</Net>
|
||||||
|
</NetList>
|
||||||
|
<PrimList>
|
||||||
|
<Prim>
|
||||||
|
<PrimGroup Name="Grp 1">
|
||||||
|
<TestPoint>1</TestPoint>
|
||||||
|
<TestPoint>2</TestPoint>
|
||||||
|
<TestPoint>3</TestPoint>
|
||||||
|
<TestPoint>4</TestPoint>
|
||||||
|
<TestPoint>5</TestPoint>
|
||||||
|
<TestPoint>6</TestPoint>
|
||||||
|
<TestPoint>7</TestPoint>
|
||||||
|
<TestPoint>8</TestPoint>
|
||||||
|
<TestPoint>9</TestPoint>
|
||||||
|
<TestPoint>10</TestPoint>
|
||||||
|
<TestPoint>11</TestPoint>
|
||||||
|
<TestPoint>12</TestPoint>
|
||||||
|
<TestPoint>13</TestPoint>
|
||||||
|
<TestPoint>14</TestPoint>
|
||||||
|
<TestPoint>15</TestPoint>
|
||||||
|
<TestPoint>16</TestPoint>
|
||||||
|
<TestPoint>17</TestPoint>
|
||||||
|
<TestPoint>18</TestPoint>
|
||||||
|
<TestPoint>19</TestPoint>
|
||||||
|
<TestPoint>20</TestPoint>
|
||||||
|
<TestPoint>23</TestPoint>
|
||||||
|
<TestPoint>24</TestPoint>
|
||||||
|
<TestPoint>25</TestPoint>
|
||||||
|
<TestPoint>32</TestPoint>
|
||||||
|
<TestPoint>33</TestPoint>
|
||||||
|
<TestPoint>34</TestPoint>
|
||||||
|
<TestPoint>35</TestPoint>
|
||||||
|
<TestPoint>36</TestPoint>
|
||||||
|
<TestPoint>37</TestPoint>
|
||||||
|
<TestPoint>38</TestPoint>
|
||||||
|
<TestPoint>41</TestPoint>
|
||||||
|
<TestPoint>42</TestPoint>
|
||||||
|
<TestPoint>43</TestPoint>
|
||||||
|
<TestPoint>44</TestPoint>
|
||||||
|
<TestPoint>45</TestPoint>
|
||||||
|
<TestPoint>46</TestPoint>
|
||||||
|
<TestPoint>47</TestPoint>
|
||||||
|
<TestPoint>48</TestPoint>
|
||||||
|
<TestPoint>49</TestPoint>
|
||||||
|
<TestPoint>50</TestPoint>
|
||||||
|
<TestPoint>51</TestPoint>
|
||||||
|
<TestPoint>52</TestPoint>
|
||||||
|
<TestPoint>53</TestPoint>
|
||||||
|
<TestPoint>54</TestPoint>
|
||||||
|
<TestPoint>55</TestPoint>
|
||||||
|
<TestPoint>56</TestPoint>
|
||||||
|
<TestPoint>57</TestPoint>
|
||||||
|
<TestPoint>58</TestPoint>
|
||||||
|
<TestPoint>59</TestPoint>
|
||||||
|
<TestPoint>60</TestPoint>
|
||||||
|
<TestPoint>61</TestPoint>
|
||||||
|
<TestPoint>62</TestPoint>
|
||||||
|
<TestPoint>63</TestPoint>
|
||||||
|
<TestPoint>64</TestPoint>
|
||||||
|
</PrimGroup>
|
||||||
|
</Prim>
|
||||||
|
</PrimList>
|
||||||
|
<ComponentListData>
|
||||||
|
<ComponentList Type="Resistor">
|
||||||
|
<TypeParameters>
|
||||||
|
<ParaSet Hardware="MT20" MeasType="MfResistance">
|
||||||
|
<MeasPara>
|
||||||
|
<ParaValue Type="U" Value="12"/>
|
||||||
|
<ParaValue Type="TDelay" Value="0.005"/>
|
||||||
|
</MeasPara>
|
||||||
|
<MeasControl>
|
||||||
|
<ParaValue Type="ModeMeasBidir" Value="true"/>
|
||||||
|
<ParaValue Type="PreciseMode" Value="false"/>
|
||||||
|
</MeasControl>
|
||||||
|
</ParaSet>
|
||||||
|
</TypeParameters>
|
||||||
|
<Component Name="R 1" Type="Resistor" FromTestPoint="8" ToTestPoint="39" PlusTolerance="10" MinusTolerance="10" Value="1013.27" Offset="0"/>
|
||||||
|
<Component Name="R 2" Type="Resistor" FromTestPoint="10" ToTestPoint="39" PlusTolerance="10" MinusTolerance="10" Value="1013.27" Offset="0"/>
|
||||||
|
<Component Name="FAT_RESISTOR" Type="Resistor" FromTestPoint="11" ToTestPoint="39" PlusTolerance="10" MinusTolerance="10" Value="1013.27" Offset="0"/>
|
||||||
|
</ComponentList>
|
||||||
|
<ComponentList Type="Diode">
|
||||||
|
<TypeParameters>
|
||||||
|
<ParaSet Hardware="MT20" MeasType="MfDiode">
|
||||||
|
<MeasPara>
|
||||||
|
<ParaValue Type="U" Value="12"/>
|
||||||
|
<ParaValue Type="TDelay" Value="0.005"/>
|
||||||
|
</MeasPara>
|
||||||
|
<MeasControl>
|
||||||
|
<ParaValue Type="PreciseMode" Value="false"/>
|
||||||
|
</MeasControl>
|
||||||
|
</ParaSet>
|
||||||
|
</TypeParameters>
|
||||||
|
<Component Name="D 1" Type="Diode" FromTestPoint="7" ToTestPoint="40" PlusTolerance="10" MinusTolerance="10" MaxCurrent="0.001" ForwardVoltage="0.63" ReverseVoltage="12"/>
|
||||||
|
</ComponentList>
|
||||||
|
</ComponentListData>
|
||||||
|
</Segment>
|
||||||
|
</SegmentList>
|
||||||
|
</TestData>
|
||||||
|
</TestDataList>
|
||||||
|
<TestSysCfgData>
|
||||||
|
<TestSysCfg SystemVariant="CX">
|
||||||
|
<TesterConfig>
|
||||||
|
<TestSysBase>
|
||||||
|
<TesterDescription Name="Virtual NT " Device="22701 N000 0000" Calibration="2024-08-22" Production="" SystemType="DBTCab"/>
|
||||||
|
<SoftwareVersion Version="673" Release="E"/>
|
||||||
|
<Connection Type="TCPIP" Settings="127.0.0.1:2048"/>
|
||||||
|
<UserPort Inputs="0" Outputs="0"/>
|
||||||
|
<Options Kelvin="Yes" ExtVoltDetect="Yes" AMC="Yes"/>
|
||||||
|
</TestSysBase>
|
||||||
|
<MeasHardwareList>
|
||||||
|
<MeasHardware Name="MT40" SerialNumber="0" Calibration="1971-01-01" Production="2025-10-24"/>
|
||||||
|
<MeasHardware Name="MT20" SerialNumber="0" Calibration="1971-01-01" Production="2025-10-24"/>
|
||||||
|
<MeasHardware Name="MT1500DC" SerialNumber="0" Calibration="1971-01-01" Production="2025-10-24"/>
|
||||||
|
<MeasHardware Name="MT2000" SerialNumber="0" Calibration="1971-01-01" Production="2025-10-24"/>
|
||||||
|
<MeasHardware Name="MT_EXT" SerialNumber="0" Calibration="1971-01-01" Production="2025-10-24"/>
|
||||||
|
</MeasHardwareList>
|
||||||
|
<MatrixDescList>
|
||||||
|
<MatrixDesc Type="RM80" TPCount="64" ConnectorType="DIN41612-64" KelvinMode="" MaxVoltAC="1060" MaxVoltDC="1500" MaxCurrAC="2" MaxCurrDC="2" BounceTime="0.007" UsageType="TestPoint"/>
|
||||||
|
</MatrixDescList>
|
||||||
|
<RackList Gaps="No">
|
||||||
|
<Rack Number="1">
|
||||||
|
<MatrixList>
|
||||||
|
<Matrix Type="RM80" Slot="1" Kelvin="No" Start="1"/>
|
||||||
|
</MatrixList>
|
||||||
|
</Rack>
|
||||||
|
</RackList>
|
||||||
|
</TesterConfig>
|
||||||
|
<ControllerLst>
|
||||||
|
<Controller Type="TPU" Node="0"/>
|
||||||
|
</ControllerLst>
|
||||||
|
<SystemData/>
|
||||||
|
<Miscellaneous>
|
||||||
|
<SafetyFunctions ExtVoltDetect="Off" GndScan="Off">
|
||||||
|
<ParaSetList>
|
||||||
|
<ParaSet Hardware="MT_EXT" MeasType="ExtVoltage">
|
||||||
|
<MeasPara/>
|
||||||
|
</ParaSet>
|
||||||
|
<ParaSet Hardware="MT40" MeasType="GndScan">
|
||||||
|
<MeasPara>
|
||||||
|
<ParaValue Type="RLow" Value="100"/>
|
||||||
|
<ParaValue Type="RHigh" Value="20000"/>
|
||||||
|
<ParaValue Type="U" Value="20"/>
|
||||||
|
<ParaValue Type="I" Value="0.1"/>
|
||||||
|
<ParaValue Type="TDelay" Value="0.0005"/>
|
||||||
|
</MeasPara>
|
||||||
|
<MeasControl>
|
||||||
|
<ParaValue Type="ModeShortTest" Value="Fast"/>
|
||||||
|
<ParaValue Type="ModeGroupTest" Value="GG"/>
|
||||||
|
<ParaValue Type="ModeGroupFaultLocation" Value="None"/>
|
||||||
|
<ParaValue Type="ModeClassicFaultLocation" Value="All"/>
|
||||||
|
</MeasControl>
|
||||||
|
</ParaSet>
|
||||||
|
</ParaSetList>
|
||||||
|
</SafetyFunctions>
|
||||||
|
</Miscellaneous>
|
||||||
|
</TestSysCfg>
|
||||||
|
</TestSysCfgData>
|
||||||
140
nodes/xml/ntc_person.xml
Normal file
140
nodes/xml/ntc_person.xml
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Persons>
|
||||||
|
<Person Name="Anna Müller" Age="28" Email="anna.mueller@example.de" Salary="52000.50" Active="true">
|
||||||
|
<Address Street="Lindenstraße 12" City="Berlin" ZipCode="10115"/>
|
||||||
|
<Sibling Name="Max Müller" Age="17" EducationalInstitution="Friedrich-Schiller-Gymnasium">
|
||||||
|
<Friend Name="Leon Berger"/>
|
||||||
|
<Friend Name="Niklas Stein"/>
|
||||||
|
</Sibling>
|
||||||
|
<Sibling Name="Lisa Müller" Age="14" EducationalInstitution="Albert-Einstein-Realschule">
|
||||||
|
<Friend Name="Mia Scholz"/>
|
||||||
|
<Friend Name="Lena Kraft"/>
|
||||||
|
<Friend Name="Sophie Engel"/>
|
||||||
|
</Sibling>
|
||||||
|
</Person>
|
||||||
|
<Person Name="Thomas Schmidt" Age="45" Email="t.schmidt@example.de" Salary="78000.00" Active="true">
|
||||||
|
<Sibling Name="Petra Schmidt" Age="19" EducationalInstitution="Goethe-Universität Frankfurt">
|
||||||
|
<Friend Name="Carolin Seidel"/>
|
||||||
|
</Sibling>
|
||||||
|
</Person>
|
||||||
|
<Person Name="Maria Weber" Age="33" Email="m.weber@example.de" Salary="61500.75" Active="true">
|
||||||
|
<Sibling Name="Klaus Weber" Age="16" EducationalInstitution="Max-Planck-Gymnasium"/>
|
||||||
|
<Sibling Name="Eva Weber" Age="12" EducationalInstitution="Heinrich-Heine-Gesamtschule">
|
||||||
|
<Friend Name="Hannah Vogel"/>
|
||||||
|
<Friend Name="Leonie Fuchs"/>
|
||||||
|
</Sibling>
|
||||||
|
</Person>
|
||||||
|
<Person Name="Stefan Fischer" Age="52" Email="s.fischer@example.de" Salary="92000.00" Active="false">
|
||||||
|
<Address Street="Bachweg 5" City="Stuttgart" ZipCode="70173"/>
|
||||||
|
<Sibling Name="Monika Fischer" Age="15" EducationalInstitution="Leibniz-Gymnasium">
|
||||||
|
<Friend Name="Alina Roth"/>
|
||||||
|
<Friend Name="Marie Lorenz"/>
|
||||||
|
<Friend Name="Clara Dietrich"/>
|
||||||
|
</Sibling>
|
||||||
|
</Person>
|
||||||
|
<Person Name="Laura Hoffmann" Age="26" Email="laura.hoffmann@example.de" Salary="48000.00" Active="true">
|
||||||
|
<Sibling Name="Tim Hoffmann" Age="11" EducationalInstitution="Pestalozzi-Grundschule">
|
||||||
|
<Friend Name="Finn Krause"/>
|
||||||
|
</Sibling>
|
||||||
|
</Person>
|
||||||
|
<Person Name="Michael Bauer" Age="39" Email="m.bauer@example.de" Salary="67500.25" Active="true">
|
||||||
|
<Sibling Name="Susanne Bauer" Age="18" EducationalInstitution="Humboldt-Gymnasium">
|
||||||
|
<Friend Name="Janina Weiß"/>
|
||||||
|
<Friend Name="Katharina Sommer"/>
|
||||||
|
</Sibling>
|
||||||
|
<Sibling Name="Frank Bauer" Age="13" EducationalInstitution="Carl-von-Ossietzky-Realschule"/>
|
||||||
|
</Person>
|
||||||
|
<Person Name="Sandra Koch" Age="31" Email="s.koch@example.de" Salary="55000.00" Active="true">
|
||||||
|
<Sibling Name="Bernd Koch" Age="9" EducationalInstitution="Astrid-Lindgren-Grundschule">
|
||||||
|
<Friend Name="Paul Werner"/>
|
||||||
|
<Friend Name="Jonas Haas"/>
|
||||||
|
<Friend Name="Emil Schuster"/>
|
||||||
|
</Sibling>
|
||||||
|
</Person>
|
||||||
|
<Person Name="Daniel Wagner" Age="48" Email="d.wagner@example.de" Salary="85000.00" Active="true">
|
||||||
|
<Address Street="Königsallee 88" City="Düsseldorf" ZipCode="40212"/>
|
||||||
|
<Sibling Name="Claudia Wagner" Age="17" EducationalInstitution="Theodor-Heuss-Gymnasium">
|
||||||
|
<Friend Name="Nora Böhm"/>
|
||||||
|
</Sibling>
|
||||||
|
</Person>
|
||||||
|
<Person Name="Julia Becker" Age="29" Email="j.becker@example.de" Salary="51000.50" Active="false">
|
||||||
|
<Sibling Name="Martin Becker" Age="15" EducationalInstitution="Schiller-Realschule">
|
||||||
|
<Friend Name="David Pfeiffer"/>
|
||||||
|
<Friend Name="Lukas Franke"/>
|
||||||
|
</Sibling>
|
||||||
|
<Sibling Name="Anja Becker" Age="10" EducationalInstitution="Erich-Kästner-Grundschule"/>
|
||||||
|
</Person>
|
||||||
|
<Person Name="Christian Schulz" Age="36" Email="c.schulz@example.de" Salary="63000.00" Active="true">
|
||||||
|
<Sibling Name="Birgit Schulz" Age="19" EducationalInstitution="Technische Universität München">
|
||||||
|
<Friend Name="Stefanie Keller"/>
|
||||||
|
<Friend Name="Nadine Möller"/>
|
||||||
|
<Friend Name="Verena Huber"/>
|
||||||
|
</Sibling>
|
||||||
|
</Person>
|
||||||
|
<Person Name="Sabine Richter" Age="42" Email="s.richter@example.de" Salary="71000.00" Active="true">
|
||||||
|
<Address Street="Marktplatz 3" City="Heidelberg" ZipCode="69117"/>
|
||||||
|
<Sibling Name="Holger Richter" Age="16" EducationalInstitution="Konrad-Adenauer-Gymnasium">
|
||||||
|
<Friend Name="Maximilian Graf"/>
|
||||||
|
</Sibling>
|
||||||
|
</Person>
|
||||||
|
<Person Name="Markus Klein" Age="55" Email="m.klein@example.de" Salary="95000.00" Active="true">
|
||||||
|
<Sibling Name="Gabriele Klein" Age="14" EducationalInstitution="Sophie-Scholl-Gesamtschule">
|
||||||
|
<Friend Name="Emilia Winter"/>
|
||||||
|
<Friend Name="Charlotte Baumann"/>
|
||||||
|
</Sibling>
|
||||||
|
<Sibling Name="Ralf Klein" Age="8" EducationalInstitution="Wilhelm-Busch-Grundschule"/>
|
||||||
|
</Person>
|
||||||
|
<Person Name="Nicole Wolf" Age="27" Email="n.wolf@example.de" Salary="46500.00" Active="true">
|
||||||
|
<Address Street="Hafenstraße 21" City="Hamburg" ZipCode="20457"/>
|
||||||
|
<Sibling Name="Patrick Wolf" Age="12" EducationalInstitution="Otto-Hahn-Realschule">
|
||||||
|
<Friend Name="Felix Brandt"/>
|
||||||
|
<Friend Name="Moritz Hahn"/>
|
||||||
|
<Friend Name="Till Albrecht"/>
|
||||||
|
</Sibling>
|
||||||
|
</Person>
|
||||||
|
<Person Name="Florian Schröder" Age="34" Email="f.schroeder@example.de" Salary="58000.75" Active="false">
|
||||||
|
<Sibling Name="Kerstin Schröder" Age="18" EducationalInstitution="Willy-Brandt-Gesamtschule">
|
||||||
|
<Friend Name="Miriam Jäger"/>
|
||||||
|
</Sibling>
|
||||||
|
</Person>
|
||||||
|
<Person Name="Petra Neumann" Age="41" Email="p.neumann@example.de" Salary="69000.00" Active="true">
|
||||||
|
<Address Street="Schloßgasse 7" City="Freiburg" ZipCode="79098"/>
|
||||||
|
<Sibling Name="Uwe Neumann" Age="7" EducationalInstitution="Brüder-Grimm-Grundschule">
|
||||||
|
<Friend Name="Ben Schubert"/>
|
||||||
|
<Friend Name="Leo Heinrich"/>
|
||||||
|
</Sibling>
|
||||||
|
<Sibling Name="Heike Neumann" Age="13" EducationalInstitution="Clara-Schumann-Realschule"/>
|
||||||
|
</Person>
|
||||||
|
<Person Name="Andreas Braun" Age="38" Email="a.braun@example.de" Salary="64500.00" Active="true">
|
||||||
|
<Sibling Name="Tanja Braun" Age="11" EducationalInstitution="Johannes-Gutenberg-Grundschule">
|
||||||
|
<Friend Name="Maya Schmitt"/>
|
||||||
|
<Friend Name="Ida Lehmann"/>
|
||||||
|
<Friend Name="Rosa Günther"/>
|
||||||
|
</Sibling>
|
||||||
|
</Person>
|
||||||
|
<Person Name="Kathrin Zimmermann" Age="30" Email="k.zimmermann@example.de" Salary="53000.00" Active="true">
|
||||||
|
<Sibling Name="Tobias Zimmermann" Age="16" EducationalInstitution="Ernst-Moritz-Arndt-Gymnasium">
|
||||||
|
<Friend Name="Jan Vogt"/>
|
||||||
|
</Sibling>
|
||||||
|
</Person>
|
||||||
|
<Person Name="Robert Krüger" Age="47" Email="r.krueger@example.de" Salary="82000.00" Active="false">
|
||||||
|
<Sibling Name="Ingrid Krüger" Age="19" EducationalInstitution="Ruprecht-Karls-Universität Heidelberg">
|
||||||
|
<Friend Name="Helena Wirth"/>
|
||||||
|
<Friend Name="Franziska Otto"/>
|
||||||
|
</Sibling>
|
||||||
|
</Person>
|
||||||
|
<Person Name="Melanie Hartmann" Age="25" Email="m.hartmann@example.de" Salary="44000.00" Active="true">
|
||||||
|
<Sibling Name="Sven Hartmann" Age="15" EducationalInstitution="Bertolt-Brecht-Gymnasium">
|
||||||
|
<Friend Name="Tom Schreiber"/>
|
||||||
|
<Friend Name="Erik Ludwig"/>
|
||||||
|
<Friend Name="Philipp Arndt"/>
|
||||||
|
</Sibling>
|
||||||
|
<Sibling Name="Jana Hartmann" Age="6" EducationalInstitution="Maria-Montessori-Grundschule"/>
|
||||||
|
</Person>
|
||||||
|
<Person Name="Jens Lange" Age="44" Email="j.lange@example.de" Salary="73500.00" Active="true">
|
||||||
|
<Sibling Name="Silke Lange" Age="10" EducationalInstitution="Anne-Frank-Grundschule">
|
||||||
|
<Friend Name="Ella Simon"/>
|
||||||
|
<Friend Name="Amelie Horn"/>
|
||||||
|
</Sibling>
|
||||||
|
</Person>
|
||||||
|
</Persons>
|
||||||
230
resources/bc_dark.qss
Normal file
230
resources/bc_dark.qss
Normal file
@@ -0,0 +1,230 @@
|
|||||||
|
/* ===== Fluent Dark Mode Theme ===== */
|
||||||
|
/* Basierend auf Microsoft Fluent Design System */
|
||||||
|
|
||||||
|
/* === Color Palette === */
|
||||||
|
/* Background: #202020, #2b2b2b, #323232 */
|
||||||
|
/* Accent: #0078d4 (Fluent Blue) */
|
||||||
|
/* Text: #ffffff, #e4e4e4 */
|
||||||
|
/* Borders: #3d3d3d, #4d4d4d */
|
||||||
|
|
||||||
|
/* === QWidget Base === */
|
||||||
|
QWidget
|
||||||
|
{
|
||||||
|
background-color: #202020;
|
||||||
|
color: #ffffff;
|
||||||
|
font-family: "Segoe UI", "Roboto", sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QLabel#_headerLabel
|
||||||
|
{
|
||||||
|
font-size: 18pt;
|
||||||
|
/*font-weight: bold;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget:disabled
|
||||||
|
{
|
||||||
|
color: #6d6d6d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* === QToolButton === */
|
||||||
|
QToolButton
|
||||||
|
{
|
||||||
|
background-color: transparent;
|
||||||
|
color: #ffffff;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 6px 12px;
|
||||||
|
margin: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton:hover
|
||||||
|
{
|
||||||
|
background-color: rgba(255, 255, 255, 0.06);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton:pressed
|
||||||
|
{
|
||||||
|
background-color: rgba(255, 255, 255, 0.03);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton:checked
|
||||||
|
{
|
||||||
|
background-color: rgba(0, 120, 212, 0.15);
|
||||||
|
border: 1px solid #0078d4;
|
||||||
|
color: #0078d4;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton:checked:hover
|
||||||
|
{
|
||||||
|
background-color: rgba(0, 120, 212, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton:disabled
|
||||||
|
{
|
||||||
|
color: #6d6d6d;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Basis-Zustand: Alles weg */
|
||||||
|
QToolButton#_commitButton
|
||||||
|
{
|
||||||
|
background: transparent;
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
outline: none; /* Entfernt den Fokus-Rahmen (gepunktete Linie) */
|
||||||
|
padding: 0px; /* Entfernt Innenabstand */
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QToolButton#_commitButton:hover
|
||||||
|
{
|
||||||
|
background-color: rgba(0, 0, 0, 0.03);
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton#_commitButton:pressed
|
||||||
|
{
|
||||||
|
background-color: rgba(0, 0, 0, 0.06);
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton#_commitButton:checked
|
||||||
|
{
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton#_commitButton:focus
|
||||||
|
{
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* === QTableView === */
|
||||||
|
QTableView
|
||||||
|
{
|
||||||
|
background-color: #2b2b2b;
|
||||||
|
color: #ffffff;
|
||||||
|
border: 1px solid #3d3d3d;
|
||||||
|
border-radius: 4px;
|
||||||
|
selection-background-color: #0078d4;
|
||||||
|
selection-color: #ffffff;
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTableView::item
|
||||||
|
{
|
||||||
|
padding: 0px;
|
||||||
|
border: none;
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
QTableView::item:focus
|
||||||
|
{
|
||||||
|
outline: 0;
|
||||||
|
background-color: blue;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
QTableView::item:hover
|
||||||
|
{
|
||||||
|
background-color: rgba(255, 255, 255, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
QTableView::item:selected
|
||||||
|
{
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* === Corner Widget (zwischen Scrollbars) === */
|
||||||
|
QTableView QTableCornerButton::section
|
||||||
|
{
|
||||||
|
background-color: #323232;
|
||||||
|
border: none;
|
||||||
|
border-right: 1px solid #3d3d3d;
|
||||||
|
border-bottom: 1px solid #3d3d3d;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* === QScrollBar Vertical === */
|
||||||
|
QScrollBar:vertical
|
||||||
|
{
|
||||||
|
background: transparent;
|
||||||
|
width: 12px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::handle:vertical {
|
||||||
|
background: rgba(255, 255, 255, 0.2);
|
||||||
|
min-height: 30px;
|
||||||
|
border-radius: 6px;
|
||||||
|
margin: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::handle:vertical:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.35);
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::handle:vertical:pressed {
|
||||||
|
background: rgba(255, 255, 255, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::add-line:vertical,
|
||||||
|
QScrollBar::sub-line:vertical {
|
||||||
|
height: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::add-page:vertical,
|
||||||
|
QScrollBar::sub-page:vertical {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* === QScrollBar Horizontal === */
|
||||||
|
QScrollBar:horizontal {
|
||||||
|
background: transparent;
|
||||||
|
height: 12px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::handle:horizontal {
|
||||||
|
background: rgba(255, 255, 255, 0.2);
|
||||||
|
min-width: 30px;
|
||||||
|
border-radius: 6px;
|
||||||
|
margin: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::handle:horizontal:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.35);
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::handle:horizontal:pressed {
|
||||||
|
background: rgba(255, 255, 255, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::add-line:horizontal,
|
||||||
|
QScrollBar::sub-line:horizontal {
|
||||||
|
width: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::add-page:horizontal,
|
||||||
|
QScrollBar::sub-page:horizontal {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* === QToolTip === */
|
||||||
|
QToolTip
|
||||||
|
{
|
||||||
|
background-color: #323232;
|
||||||
|
color: #ffffff;
|
||||||
|
border: 1px solid #4d4d4d;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 6px 8px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
260
resources/bc_light.qss
Normal file
260
resources/bc_light.qss
Normal file
@@ -0,0 +1,260 @@
|
|||||||
|
/* ===== Fluent Light Mode Theme ===== */
|
||||||
|
/* Basierend auf Microsoft Fluent Design System */
|
||||||
|
|
||||||
|
/* === Color Palette === */
|
||||||
|
/* Background: #f3f3f3, #ffffff, #fafafa */
|
||||||
|
/* Accent: #0078d4 (Fluent Blue) */
|
||||||
|
/* Text: #000000, #1f1f1f */
|
||||||
|
/* Borders: #e1e1e1, #d1d1d1 */
|
||||||
|
|
||||||
|
|
||||||
|
/* === QWidget Base === */
|
||||||
|
QWidget {
|
||||||
|
background-color: #f3f3f3;
|
||||||
|
color: #1f1f1f;
|
||||||
|
font-family: "Segoe UI", "Roboto", sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QLabel#_headerLabel
|
||||||
|
{
|
||||||
|
font-size: 18pt;
|
||||||
|
/*font-weight: bold;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget:disabled {
|
||||||
|
color: #a0a0a0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* === QToolButton === */
|
||||||
|
QToolButton {
|
||||||
|
background-color: transparent;
|
||||||
|
color: #1f1f1f;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 6px 12px;
|
||||||
|
margin: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton:hover {
|
||||||
|
background-color: rgba(0, 0, 0, 0.03);
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton:pressed {
|
||||||
|
background-color: rgba(0, 0, 0, 0.06);
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton:checked {
|
||||||
|
background-color: rgba(0, 120, 212, 0.1);
|
||||||
|
border: 1px solid #0078d4;
|
||||||
|
color: #0078d4;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton:checked:hover {
|
||||||
|
background-color: rgba(0, 120, 212, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton:disabled {
|
||||||
|
color: #a0a0a0;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Basis-Zustand: Alles weg */
|
||||||
|
QToolButton#_commitButton {
|
||||||
|
background: transparent;
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
outline: none; /* Entfernt den Fokus-Rahmen (gepunktete Linie) */
|
||||||
|
padding: 0px; /* Entfernt Innenabstand */
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* WICHTIG: Auch die interaktiven Zustände überschreiben,
|
||||||
|
sonst flackert der Standard-Style beim Klicken wieder auf */
|
||||||
|
|
||||||
|
QToolButton#_commitButton:hover
|
||||||
|
{
|
||||||
|
background-color: rgba(0, 0, 0, 0.03);
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton#_commitButton:pressed
|
||||||
|
{
|
||||||
|
background-color: rgba(0, 0, 0, 0.06);
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton#_commitButton:checked
|
||||||
|
{
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton#_commitButton:focus {
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* === QTableView === */
|
||||||
|
QTableView
|
||||||
|
{
|
||||||
|
background-color: #ffffff;
|
||||||
|
alternate-background-color: #fafafa;
|
||||||
|
color: #1f1f1f;
|
||||||
|
gridline-color: #e1e1e1;
|
||||||
|
border: 1px solid #d1d1d1;
|
||||||
|
border-radius: 4px;
|
||||||
|
selection-background-color: #0078d4;
|
||||||
|
selection-color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTableView::item
|
||||||
|
{
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTableView::item:hover {
|
||||||
|
background-color: rgba(0, 0, 0, 0.03);
|
||||||
|
}
|
||||||
|
|
||||||
|
QTableView::item:selected {
|
||||||
|
background-color: #0078d4;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTableView::item:selected:hover
|
||||||
|
{
|
||||||
|
background-color: #005a9e;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTableView::item:selected:!active
|
||||||
|
{
|
||||||
|
background-color: rgba(0, 120, 212, 0.3);
|
||||||
|
color: #1f1f1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTableView:focus
|
||||||
|
{
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* === QScrollBar Vertical === */
|
||||||
|
QScrollBar:vertical {
|
||||||
|
background: transparent;
|
||||||
|
width: 12px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::handle:vertical {
|
||||||
|
background: rgba(0, 0, 0, 0.25);
|
||||||
|
min-height: 30px;
|
||||||
|
border-radius: 6px;
|
||||||
|
margin: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::handle:vertical:hover {
|
||||||
|
background: rgba(0, 0, 0, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::handle:vertical:pressed {
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::add-line:vertical,
|
||||||
|
QScrollBar::sub-line:vertical {
|
||||||
|
height: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::add-page:vertical,
|
||||||
|
QScrollBar::sub-page:vertical {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* === QScrollBar Horizontal === */
|
||||||
|
QScrollBar:horizontal {
|
||||||
|
background: transparent;
|
||||||
|
height: 12px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::handle:horizontal {
|
||||||
|
background: rgba(0, 0, 0, 0.25);
|
||||||
|
min-width: 30px;
|
||||||
|
border-radius: 6px;
|
||||||
|
margin: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::handle:horizontal:hover {
|
||||||
|
background: rgba(0, 0, 0, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::handle:horizontal:pressed {
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::add-line:horizontal,
|
||||||
|
QScrollBar::sub-line:horizontal {
|
||||||
|
width: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScrollBar::add-page:horizontal,
|
||||||
|
QScrollBar::sub-page:horizontal {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* === QToolTip === */
|
||||||
|
QToolTip {
|
||||||
|
background-color: #ffffff;
|
||||||
|
color: #1f1f1f;
|
||||||
|
border: 1px solid #d1d1d1;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 6px 8px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* === Corner Widget (zwischen Scrollbars) === */
|
||||||
|
QTableView QTableCornerButton::section {
|
||||||
|
background-color: #fafafa;
|
||||||
|
border: none;
|
||||||
|
border-right: 1px solid #e1e1e1;
|
||||||
|
border-bottom: 1px solid #e1e1e1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* QLineEdit */
|
||||||
|
QLineEdit {
|
||||||
|
background-color: #ffffff;
|
||||||
|
color: #1f1f1f;
|
||||||
|
border: 1px solid #d1d1d1;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 6px 8px;
|
||||||
|
selection-background-color: #0078d4;
|
||||||
|
selection-color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
QLineEdit:hover {
|
||||||
|
border: 1px solid #a0a0a0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
QLineEdit:focus {
|
||||||
|
border: 1px solid #0078d4;
|
||||||
|
border-bottom: 2px solid #0078d4;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
QLineEdit:disabled {
|
||||||
|
background-color: #fafafa;
|
||||||
|
color: #a0a0a0;
|
||||||
|
border: 1px solid #e1e1e1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
QSlider {
|
||||||
|
background: hotpink;
|
||||||
|
}
|
||||||
|
*/
|
||||||
@@ -2,68 +2,65 @@
|
|||||||
|
|
||||||
<Bike name='franken-wheeler'>
|
<Bike name='franken-wheeler'>
|
||||||
|
|
||||||
<Device Type="Console">
|
<Device Type='Motor'>
|
||||||
<Value ID='Cons_Rev_Hw' Label='Hardware Version' />
|
<Value ID='Motor_Rev_Hw' Label='Hardware Version' ValueType='Plain' ReadOnly='true' />
|
||||||
<Value ID='Cons_Rev_Sw' Label='Software Version' />
|
<Value ID='Motor_Rev_Sw' Label='Software Version' ValueType='Plain' ReadOnly='true' />
|
||||||
|
<Value ID='Motor_Sn_Item_Hi' Label='Motor Part Number' ValueType='Plain' IsWord='true' ReadOnly='true' />
|
||||||
<Value ID='Cons_Sn_Product_Hi' Label='Product Number' IsWord='1'/>
|
<Value ID='Motor_Sn_Item_Hi' Label='Motor Serial Number' ValueType='Plain' IsWord='true' ReadOnly='true' />
|
||||||
<Value ID='Cons_Sn_Oem_Hi' Label='OEM Number' IsWord='1' />
|
<Value ID='Motor_Status_Temperature' Label='Motor Temperature' ValueType='Float' UnitLabel='°C' />
|
||||||
|
<Value ID='Motor_Assist_Maxspeed' Label='Motor max. Speed' UnitLabel='km/h' Factor='0.1' Min='0' Max='70' ValueType='Float' />
|
||||||
<Value ID='Cons_Assist_Initlevel' Label='Assistance Init Level' Min='0' Max='4'/>
|
<Value ID='Motor_Geometry_Circ_Hi' Label='Wheel Circumference' IsWord='true' UnitLabel='mm' Min='0' Max='2300' ValueType='Number' Factor='1.5625' />
|
||||||
|
|
||||||
|
|
||||||
<Value ID='Cons_Assist_Level_1' Label='Assistance Level 1' Factor='1.5625' UnitLabel='%' Min='0' Max='400' />
|
|
||||||
<Value ID='Cons_Assist_Level_2' Label='Assistance Level 2' Factor='1.5625' UnitLabel='%' Min='0' Max='400' />
|
|
||||||
<Value ID='Cons_Assist_Level_3' Label='Assistance Level 3' Factor='1.5625' UnitLabel='%' Min='0' Max='400' />
|
|
||||||
<Value ID='Cons_Assist_Level_4' Label='Assistance Level 4' Factor='1.5625' UnitLabel='%' Min='0' Max='400' />
|
|
||||||
|
|
||||||
<Value ID='Cons_Assist_Maxspeed_Flag' Label='Max Limit Enabled' ValueType='bool' />
|
|
||||||
<Value ID='Cons_Assist_Maxspeed_Hi' Label='Max Speed Limit' UnitLabel='km/h' Factor='0.1' Min='0' Max='70'/>
|
|
||||||
|
|
||||||
<Value ID='Cons_Assist_Minspeed_Flag' Label='Min Limit Enabled' ValueType='bool' />
|
|
||||||
<Value ID='Cons_Assist_Minspeed' Label='Min Speed Limit' UnitLabel='km/h' Min='0' Max='70' />
|
|
||||||
|
|
||||||
<Value ID='Cons_Throttle_Maxspeed_Flag' Label='Throttle Limit Enabled' ValueType='bool'/>
|
|
||||||
<Value ID='Cons_Throttle_Maxspeed_Hi' Label='Throttle Speed Limit' UnitLabel='km/h' Factor='0.1' Min='0' Max='70' />
|
|
||||||
|
|
||||||
<Value ID='Cons_Geometry_Circ_Hi' Label='Wheel Circumference' IsWord='1' UnitLabel='mm' Min='0' Max='2300' Factor='1.5625' />
|
|
||||||
<Value ID='Cons_Assist_Mountain_Cap' Label='Mountain Cap' UnitLabel='%' Factor='1.5625' />
|
|
||||||
</Device>
|
</Device>
|
||||||
|
|
||||||
|
<Device Type='Battery'>
|
||||||
<Device Type="Motor">
|
<Value ID='Reg_Battery_Rev_Hw' Label='Hardware Version' ValueType='Plain' ReadOnly='true' />
|
||||||
<Value ID='Motor_Rev_Hw' Label='Hardware Version' />
|
<Value ID='Reg_Battery_Rev_Sw' Label='Software Version' ValueType='Plain' ReadOnly='true' />
|
||||||
<Value ID='Motor_Rev_Sw' Label='Software Version' />
|
|
||||||
<Value ID='Motor_Sn_Item_Hi' Label='Motor Part Number' IsWord='1'/>
|
|
||||||
<Value ID='Motor_Sn_Item_Hi' Label='Motor Serial Number' IsWord='1' />
|
|
||||||
<Value ID='Motor_Status_Temperature' Label='Motor Temperature' UnitLabel='°C' />
|
|
||||||
<Value ID='Motor_Assist_Maxspeed' Label='Motor max. Speed' Reader='Kmh' />
|
|
||||||
|
|
||||||
<Value ID='Motor_Geometry_Circ_Hi' Label='Wheel Circumference' IsWord='1' UnitLabel='mm' Min='0' Max='2300' Factor='1.5625' />
|
|
||||||
</Device>
|
</Device>
|
||||||
|
|
||||||
<Device Type="Battery">
|
<Device Type='Console'>
|
||||||
<Value ID='Battery_Rev_Hw' Label='Hardware Version' />
|
<Value ID='Cons_Rev_Hw' Label='Hardware Version' ValueType='Plain' ReadOnly='true' />
|
||||||
<Value ID='Battery_Rev_Sw' Label='Software Version' />
|
<Value ID='Cons_Rev_Sw' Label='Software Version' ValueType='Plain' ReadOnly='true' />
|
||||||
|
|
||||||
|
<Value ID='Cons_Sn_Product_Hi' Label='Product Number' IsWord='true' ValueType='Plain' ReadOnly='true'/>
|
||||||
|
<Value ID='Cons_Sn_Oem_Hi' Label='OEM Number' IsWord='true' ValueType='Plain' ReadOnly='true' />
|
||||||
|
|
||||||
|
<!--<Value ID='Cons_Assist_Initlevel' Label='Assistance Init Level' Min='0' Max='4' ValueType='Number'/>-->
|
||||||
|
<Value ID='Cons_Assist_Initlevel' Label='Assistance Init Level' Min='0' Max='100' UnitLabel='%' ValueType='Float'/>
|
||||||
|
<Value ID='Cons_Assist_Level_1' Label='Assistance Level 1' Factor='1.5625' UnitLabel='%' Min='0' Max='400' ValueType='Float'/>
|
||||||
|
<Value ID='Cons_Assist_Level_2' Label='Assistance Level 2' Factor='1.5625' UnitLabel='%' Min='0' Max='400' ValueType='Float'/>
|
||||||
|
<Value ID='Cons_Assist_Level_3' Label='Assistance Level 3' Factor='1.5625' UnitLabel='%' Min='0' Max='400' ValueType='Float'/>
|
||||||
|
<Value ID='Cons_Assist_Level_4' Label='Assistance Level 4' Factor='1.5625' UnitLabel='%' Min='0' Max='400' ValueType='Float'/>
|
||||||
|
|
||||||
|
<Value ID='Cons_Assist_Maxspeed_Flag' Label='Max Limit Enabled' ValueType='Bool' />
|
||||||
|
<Value ID='Cons_Assist_Maxspeed_Hi' Label='Max Speed Limit' UnitLabel='km/h' Factor='0.1' Min='0' Max='70' ValueType='Float'/>
|
||||||
|
|
||||||
|
<Value ID='Cons_Assist_Minspeed_Flag' Label='Min Limit Enabled' ValueType='Bool'/>
|
||||||
|
<Value ID='Cons_Assist_Minspeed' Label='Min Speed Limit' UnitLabel='km/h' Min='0' Max='70' ValueType='Float'/>
|
||||||
|
|
||||||
|
<Value ID='Cons_Throttle_Maxspeed_Flag' Label='Throttle Limit Enabled' ValueType='Bool'/>
|
||||||
|
<Value ID='Cons_Throttle_Maxspeed_Hi' Label='Throttle Speed Limit' UnitLabel='km/h' Factor='0.1' Min='0' Max='70' ValueType='Float'/>
|
||||||
|
|
||||||
|
<Value ID='Cons_Geometry_Circ_Hi' Label='Wheel Circumference' IsWord='true' UnitLabel='mm' Min='0' Max='2300' Factor='1.5625' ValueType='Number'/>
|
||||||
|
<Value ID='Cons_Assist_Mountain_Cap' Label='Mountain Cap' UnitLabel='%' Min="0" Max="100" Factor='1.5625' ValueType='Float'/>
|
||||||
</Device>
|
</Device>
|
||||||
|
|
||||||
</Bike>
|
</Bike>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
printf( " odo .....................: Percent0.2f Km" _NL _NL,
|
printf( " odo .....................: Percent0.2f Km" _NL _NL,
|
||||||
((getValue(CONSOLE, CONSOLE_STATS_BCValueTypeWord_1) << 24) +
|
((getValue(CONSOLE, CONSOLE_STATS_BCValueTypeWord_1) << 24) +
|
||||||
(getValue(CONSOLE, CONSOLE_STATS_BCValueTypeWord_2) << 16) +
|
(getValue(CONSOLE, CONSOLE_STATS_BCValueTypeWord_2) << 16) +
|
||||||
(getValue(CONSOLE, CONSOLE_STATS_BCValueTypeWord_3) << 8) +
|
(getValue(CONSOLE, CONSOLE_STATS_BCValueTypeWord_3) << 8) +
|
||||||
(getValue(CONSOLE, CONSOLE_STATS_BCValueTypeWord_4))) / (double)10
|
(getValue(CONSOLE, CONSOLE_STATS_BCValueTypeWord_4))) / (double)10
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Value ID='Cons_Stat_Dist_Hi' Label='' Reader='mm' Factor='0.1' />
|
<Value ID='Cons_Stat_Dist_Hi' Label='' Reader='mm' Factor='0.1' />
|
||||||
<Value ID='Cons_Stat_Dist_Lo' Label='' Reader='mm'/>
|
<Value ID='Cons_Stat_Dist_Lo' Label='' Reader='mm'/>
|
||||||
<Value ID='Cons_Stat_Avgspeed_Hi' Label='' Reader='mm' Factor='0.1' />
|
<Value ID='Cons_Stat_Avgspeed_Hi' Label='' Reader='mm' Factor='0.1' />
|
||||||
<Value ID='Cons_Stat_Avgspeed_Lo' Label='' Reader='mm'/>
|
<Value ID='Cons_Stat_Avgspeed_Lo' Label='' Reader='mm'/>
|
||||||
|
|
||||||
@@ -87,7 +84,7 @@
|
|||||||
<Value ID='Cons_Sn_Day' Label='' />
|
<Value ID='Cons_Sn_Day' Label='' />
|
||||||
|
|
||||||
<Value ID='Cons_Sn_Pn_Hi' Label='' />
|
<Value ID='Cons_Sn_Pn_Hi' Label='' />
|
||||||
<Value ID='Cons_Sn_Pn_Lo' Label='' />
|
<Value ID='Cons_Sn_Pn_Lo' Label='' />
|
||||||
<Value ID='Cons_Sn_Item_Hi' Label='' />
|
<Value ID='Cons_Sn_Item_Hi' Label='' />
|
||||||
<Value ID='Cons_Sn_Item_Lo' Label='' />
|
<Value ID='Cons_Sn_Item_Lo' Label='' />
|
||||||
|
|
||||||
@@ -133,7 +130,7 @@
|
|||||||
<Value ID='Cons_Preference_Codesrw_Lolo' Label='' />
|
<Value ID='Cons_Preference_Codesrw_Lolo' Label='' />
|
||||||
<Value ID='Cons_Preference_Throttle_Mode' Label='' />
|
<Value ID='Cons_Preference_Throttle_Mode' Label='' />
|
||||||
|
|
||||||
|
|
||||||
<Value ID='Cons_Throttle_Boost_Triggerlevel' Label='' Min='1.5' Max='50.0' Factor='1.5625' />
|
<Value ID='Cons_Throttle_Boost_Triggerlevel' Label='' Min='1.5' Max='50.0' Factor='1.5625' />
|
||||||
<Value ID='Cons_Preference_Flip_Side' Label='' />
|
<Value ID='Cons_Preference_Flip_Side' Label='' />
|
||||||
<Value ID='Cons_Config_Testmode' Label='' />
|
<Value ID='Cons_Config_Testmode' Label='' />
|
||||||
@@ -141,25 +138,25 @@
|
|||||||
|
|
||||||
<Value ID='Cons_Config_Last_Mode' Label='' />
|
<Value ID='Cons_Config_Last_Mode' Label='' />
|
||||||
<Value ID='Cons_Assist_Speedgain' Label='' Factor='0.1' />
|
<Value ID='Cons_Assist_Speedgain' Label='' Factor='0.1' />
|
||||||
|
|
||||||
|
|
||||||
<Value ID='Cons_Config_Last_Mode_On' Label='' />
|
<Value ID='Cons_Config_Last_Mode_On' Label='' />
|
||||||
<Value ID='Cons_Config_Last_Mode_Off' Label='' />
|
<Value ID='Cons_Config_Last_Mode_Off' Label='' />
|
||||||
|
|
||||||
<Value ID='Cons_Status_Slave' Label='' />
|
<Value ID='Cons_Status_Slave' Label='' />
|
||||||
|
|
||||||
<Value ID='Cons_Throttle_Raw_Hi' Label='' />
|
<Value ID='Cons_Throttle_Raw_Hi' Label='' />
|
||||||
<Value ID='Cons_Throttle_Raw_Lo' Label='' />
|
<Value ID='Cons_Throttle_Raw_Lo' Label='' />
|
||||||
<Value ID='Cons_Throttle_Position' Label='' Factor='1.5625'/>
|
<Value ID='Cons_Throttle_Position' Label='' Factor='1.5625'/>
|
||||||
|
|
||||||
<Value ID='Cons_Assist_Level_Rekuperation_3' Label='' Factor='1.5625'/>
|
<Value ID='Cons_Assist_Level_Rekuperation_3' Label='' Factor='1.5625'/>
|
||||||
<Value ID='Cons_Assist_Level_Rekuperation_4' Label='' Factor='1.5625'/>
|
<Value ID='Cons_Assist_Level_Rekuperation_4' Label='' Factor='1.5625'/>
|
||||||
<Value ID='Cons_Config_Service_Timestamp_Hi' Label='' />
|
<Value ID='Cons_Config_Service_Timestamp_Hi' Label='' />
|
||||||
<Value ID='Cons_Config_Service_Zimestamp_Lo' Label='' />
|
<Value ID='Cons_Config_Service_Zimestamp_Lo' Label='' />
|
||||||
<Value ID='Cons_Config_Service_Distance_Hi' Label='' />
|
<Value ID='Cons_Config_Service_Distance_Hi' Label='' />
|
||||||
<Value ID='Cons_Config_Service_Distance_Lo' Label='' />
|
<Value ID='Cons_Config_Service_Distance_Lo' Label='' />
|
||||||
|
|
||||||
<Value ID='Cons_Assist_Level_Rekuperation_1' Label='' Factor='1.5625'/>
|
<Value ID='Cons_Assist_Level_Rekuperation_1' Label='' Factor='1.5625'/>
|
||||||
<Value ID='Cons_Assist_Level_Rekuperation_2' Label='' Factor='1.5625'/>
|
<Value ID='Cons_Assist_Level_Rekuperation_2' Label='' Factor='1.5625'/>
|
||||||
|
|
||||||
-->
|
-->
|
||||||
|
|||||||
@@ -1,167 +0,0 @@
|
|||||||
/* appqss */
|
|
||||||
|
|
||||||
/* Alle QWidgets bekommen diesen Font */
|
|
||||||
QWidget
|
|
||||||
{
|
|
||||||
font-family: "Calibri", "Carlito", "Open Sans", sans-serif;
|
|
||||||
font-size: 10pt;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
QLabel#_headerLabel
|
|
||||||
{
|
|
||||||
font-size: 14pt;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
QToolButton
|
|
||||||
{
|
|
||||||
background-color: white;
|
|
||||||
color: #201F1E;
|
|
||||||
border: 1px solid #8A8886;
|
|
||||||
border-radius: 4px;
|
|
||||||
|
|
||||||
|
|
||||||
min-width: 64px;
|
|
||||||
max-width: 64px;
|
|
||||||
min-height: 64px;
|
|
||||||
max-height: 64px;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
QToolButton:hover
|
|
||||||
{
|
|
||||||
background-color: #F3F2F1;
|
|
||||||
border: 1px solid #323130;
|
|
||||||
}
|
|
||||||
|
|
||||||
QToolButton:pressed
|
|
||||||
{
|
|
||||||
background-color: #EDEBE9;
|
|
||||||
border: 1px solid #201F1E;
|
|
||||||
}
|
|
||||||
|
|
||||||
QToolButton:disabled
|
|
||||||
{
|
|
||||||
background-color: #F3F2F1;
|
|
||||||
color: #A19F9D;
|
|
||||||
border: 1px solid #EDEBE9;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* === QToolButton === */
|
|
||||||
QToolButton
|
|
||||||
{
|
|
||||||
background-color: transparent;
|
|
||||||
color: #000000;
|
|
||||||
border: none;
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 6px;
|
|
||||||
|
|
||||||
min-width: 64px;
|
|
||||||
max-width: 64px;
|
|
||||||
min-height: 64px;
|
|
||||||
max-height: 64px;
|
|
||||||
}
|
|
||||||
|
|
||||||
QToolButton:hover
|
|
||||||
{
|
|
||||||
background-color: #F9F9F9;
|
|
||||||
border: 1px solid #DDDDDD;
|
|
||||||
}
|
|
||||||
|
|
||||||
QToolButton:pressed
|
|
||||||
{
|
|
||||||
background-color: #E0E0E0;
|
|
||||||
}
|
|
||||||
|
|
||||||
QToolButton:checked
|
|
||||||
{
|
|
||||||
background-color: green;/*#0078D4;*/
|
|
||||||
color: #FFFFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
QToolButton:disabled
|
|
||||||
{
|
|
||||||
color: #A19F9D;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* === QTableView & QTableWidget === */
|
|
||||||
|
|
||||||
QTableView, QTableWidget
|
|
||||||
{
|
|
||||||
background-color: #FFFFFF;
|
|
||||||
color: #000000;
|
|
||||||
gridline-color: #E1DFDD;
|
|
||||||
border: 1px solid #E1DFDD;
|
|
||||||
border-radius: 4px;
|
|
||||||
selection-background-color: #0078D4;
|
|
||||||
}
|
|
||||||
|
|
||||||
QTableView::item:hover
|
|
||||||
{
|
|
||||||
background-color: #e8f4f8;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QScrollBar::handle:horizontal {
|
|
||||||
background-color: #C8C6C4;
|
|
||||||
min-width: 40px;
|
|
||||||
border-radius: 6px;
|
|
||||||
margin: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
QScrollBar::handle:horizontal:hover {
|
|
||||||
background-color: #A19F9D;
|
|
||||||
}
|
|
||||||
|
|
||||||
QScrollBar::handle:horizontal:pressed {
|
|
||||||
background-color: #8A8886;
|
|
||||||
}
|
|
||||||
|
|
||||||
QScrollBar::add-line:horizontal,
|
|
||||||
QScrollBar::sub-line:horizontal {
|
|
||||||
width: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
QScrollBar::add-page:horizontal,
|
|
||||||
QScrollBar::sub-page:horizontal {
|
|
||||||
background: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
QScrollBar:vertical {
|
|
||||||
background-color: transparent;
|
|
||||||
width: 12px;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
QScrollBar::handle:vertical {
|
|
||||||
background-color: #C8C6C4;
|
|
||||||
min-height: 40px;
|
|
||||||
border-radius: 6px;
|
|
||||||
margin: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
QScrollBar::handle:vertical:hover {
|
|
||||||
background-color: #A19F9D;
|
|
||||||
}
|
|
||||||
|
|
||||||
QScrollBar::handle:vertical:pressed {
|
|
||||||
background-color: #8A8886;
|
|
||||||
}
|
|
||||||
|
|
||||||
QScrollBar::add-line:vertical,
|
|
||||||
QScrollBar::sub-line:vertical {
|
|
||||||
height: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
QScrollBar::add-page:vertical,
|
|
||||||
QScrollBar::sub-page:vertical {
|
|
||||||
background: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user